#include <CATDLLInjector.h>
This class contains utility functions to inject a DLL into a process.
There are several methods available to do this, and all of them have tradeoffs. The two I expect to be most used are the CreateRemoteThread() method to force a LoadLibrary() call on a new thread into the target process, and the CreateProcess() method of creating a process in a halted state, inserting the DLL, then continuing execution. The first is embodied in CATDLLInjector::InjectIntoProcess(), the latter in CATDLLInjector::StartDLLWithProcess().
Much of the information on how to do DLL Injection and function hooking was gleaned from Jeffrey Richter's "Programming Applications for Microsoft Windows" (1572319968). Additional information is available in John Robbins' "Debugging Applications for Microsoft .NET and Microsoft Windows" (0735615365) and Feng Yuan's "Windows Graphics Programming: Win32 GDI and DirectDraw" (0130869856).
I'm avoiding the debugger methods and windows hook methods currently for a few reasons (although they may prove useful in the future and will get tossed in here if so).
When using StartDLLWithProcess, you'll need the following undecorated function exported from your injected DLL (e.g. use a .def file for it too):
extern "C" { void* gPassedData = 0; unsigned int gPassedDataLen = 0; void _declspec(dllexport) UnpatchProcess(void* passData, unsigned int passDataLen, void* startLoc, unsigned int patchSize, void* hostBuffer, unsigned int hostProcId) { // Open host process and read the stored bytes into our // hooked process over the start location, restoring the // original executable code. HANDLE hostProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, hostProcId); if (hostProcess != 0) { DWORD amountRead = 0; ReadProcessMemory(hostProcess,hostBuffer,startLoc,patchSize,&amountRead); if (passDataLen && passData) { gPassedDataLen = passDataLen; gPassedData = new BYTE[passDataLen]; ::ReadProcessMemory(hostProcess,passData,gPassedData,passDataLen,&amountRead); } CloseHandle(hostProcess); } // Got the data from the parent. Open the wait event and set it. CATWChar eventName[64]; wsprintf(eventName,L"UnpatchProcess_%d",hostProcId); HANDLE waitEvent = ::OpenEvent(GENERIC_READ|GENERIC_WRITE,FALSE,eventName); if (waitEvent != 0) { SetEvent(waitEvent); CloseHandle(waitEvent); } // Now, restore the stack and go back to the starting location __asm { mov esp,ebp // Get original base pointer pop ebp add esp,0x1c // Restore stack point to start of our code popfd popad ret } } }
Definition at line 119 of file CATDLLInjector.h.
Static Public Member Functions | |
static CATResult | GetProcessId (const CATWChar *processName, CATUInt32 &pid, CATUInt32 procIndex=-1) |
static CATResult | InjectIntoProcess (const CATWChar *dllPath, CATUInt32 pid) |
static CATResult | StartDLLWithProcess (const CATWChar *dllPath, const CATWChar *execFile, const CATWChar *commandLine, const void *passData=0, CATUInt32 passDataLen=0) |