EzDetour Macro
Detour the specified function. 
BOOL EzDetour(
   PVOID *pfTrampoline,
   PVOID pfDetour,
   BOOL Suspend = 1,
type: PVOID *
            The handle to the trampoline (original) function.
            This is the function that will be detoured.
type: PVOID
            The handle to the replacement function.
            This is the function you will be able to write your code in. 
type: char *
            Description of the detour.
Return Value:
If the function succeeds, the function returns TRUE.
If the function fails, the function returns FALSE.
//You have to be injected in a process in order to detour a function.
//And in order to inject, you need to have a dll-file.
//The example below shows you how to create a simple dll-file, inject into Notepad.exe and detour a function.
//To activate the detoured function, press ctrl + F or go to Edit->Find.
//Please note that you will need at least one character entered or it will not activate.
#include "detourit.h"
#include "detours.h"
HWND hNotepad;
DWORD __stdcall InitThread(PVOID pData)
    //Here we start the Notepad.exe we are going to inject into.
    CreateProcessA(NULL, "C:/Windows/System32/Notepad.exe", NULL, NULL, FALSE, NULL, NULL, NULL, &si, &pi);
    //The CPipePacket will contain information about the injection when it is completed.
    CPipePacket *pipe = new CPipePacket;
    pipe->pid = pi.dwProcessId;
    pipe->threadid = pi.dwThreadId;
    //This will make DetourIt inject our dll into NotePad.exe
    InjectByPID(pi.dwProcessId, pipe);
    //Delete pipe to prevent memory leaking.
    delete pipe;
    return 1;
//The TRAMP_FUNCTION macro is to make it easier to define a trampoline.
//A function with 1 parameter should use the TRAMP_FUNCTION_1_PARAM.
//A function with 4 parameters should use the TRAMP_FUNCTION_4_PARAM and so on.
//The parameters need to be exactly like the one(s) in the to be detoured function.
//This is our replacement function.
//You can replace the functionality with your own or just intercept and monitor the variables, etc.
//You can either return the trampoline (this lets the original function process and return) or not call it and return your own values.
    //This is where the detoured function ends up. Here you can do anything you want
    //In this example we are going to enter "Hello DetourIt! and then return 0, so that the find window doesnt pop up"
    //This will remove one character from the notepad window
    int length = GetWindowTextLength(hNotepad);
    for (int i = 0; i < length; i ++)
        SendKey(hNotepad, VK_BACK);
    BYTE keys[16] = "Hello DetourIt!";
    for (int i = 0; i < 16; i ++)
        SendKey(hNotepad, keys[i]);
    return 0;
    //If we had wanted to process the original function, this is how we would have done it:
    //return FindTextW_Trampoline(lpfr);
DWORD __stdcall AttachNotepadExample(LPVOID pData)
    if ((DWORD)pData == 1)
        return (DWORD)CreateThread(NULL, 0, InitThread, pData, 0, NULL);
        //This definition is just to make it easier to write the following code. The paramaters need to be exactly like the detoured function.
        typedef HWND (WINAPI *FindTextW_t)(LPFINDREPLACE); 
        //This sets the Trampoline variable to the physical location of the function we are about to detour
        FindTextW_Trampoline = (FindTextW_t)(DWORD *)GetProcAddress(GetModuleHandle(L"Comdlg32.dll"), "FindTextW");
        //This call will detour the function.
        BOOL ret = EzDetour(FindTextW_Trampoline, FindTextW_Detour, "FindTextW");
        HWND hWndParent = FindWindow(NULL, L"Untitled - Notepad");
        hNotepad = FindWindowEx(hWndParent, NULL, L"Edit", NULL);
        //The FindText function is only called if there is text in the edit box
        BYTE info[29] = "Press CTRL + F or F3 to demo";
        for (int i = 0; i < 29; i ++)
            SendKey(hNotepad, info[i]);
        return 0;
    return 1;
DWORD __stdcall DetachNotepadExample(LPVOID pData)
    Beep(500, 500);
    Beep(700, 700);
    return 0;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
    //There are two things we need to process in DllMain;
    //When we Attach to a process and when we Detach from it.
    switch (ul_reason_for_call)
        case DLL_PROCESS_ATTACH:
            DetouritAttach(hModule, AttachNotepadExample, TRUE);
        case DLL_PROCESS_DETACH:
            DetouritDetach(DetachNotepadExample, NULL);
    return TRUE;