The handle to the trampoline (original) function.
This is the function that will be detoured.
HWND hNotepad;
DWORD __stdcall InitThread(PVOID pData)
{
UNREFERENCED_PARAMETER(pData);
STARTUPINFOA si = {sizeof(STARTUPINFO)};
PROCESS_INFORMATION pi = {0};
//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.
TRAMP_FUNCTION_1_PARAM(HWND, WINAPI *, FindTextW_Trampoline, LPFINDREPLACE, 0);
//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.
HWND WINAPI FindTextW_Detour(LPFINDREPLACE lpfr)
{
//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);
else
{
//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)
{
RemoveOurDetours(GetCurrentThread());
Beep(500, 500);
Beep(700, 700);
return 0;
}
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
UNREFERENCED_PARAMETER(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);
break;
}
case DLL_PROCESS_DETACH:
{
DetouritDetach(DetachNotepadExample, NULL);
break;
}
}
return TRUE;
}