1. Create a DLL. The entry point contains the subclassing code. It will also have your window procedure.
2. Put the DLL in the same folder as the target EXE.
3. Use CreateRemoteThread() with the function LoadLibrary and your DLL name to force the target process to load your DLL.
4. Bingo.
It's worked for me before. Here's some code:
Code:
const std::string strMod = "easy.dll";
HWND hWnd = FindWindow(0,"Calculator");
DWORD dwProc;
GetWindowThreadProcessId(hWnd,&dwProc);
HANDLE hProc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, dwProc);
HMODULE hKern = GetModuleHandle("kernel32.dll");
WNDPROC lpfLoadLibraryA = reinterpret_cast<WNDPROC>
(GetProcAddress(hKern,"LoadLibraryA"));
LPVOID lpMemAddress = VirtualAllocEx(hProc,0,strMod.length() + 1,MEM_COMMIT,PAGE_READWRITE);
SIZE_T stBytesWritten;
WriteProcessMemory(hProc,lpMemAddress,(LPVOID)strMod.c_str(),
strMod.length() + 1,&stBytesWritten);
DWORD dwThreadID;
HANDLE hRemThread = CreateRemoteThread(hProc,0,0,reinterpret_cast<LPTHREAD_START_ROUTINE>(lpfLoadLibraryA),lpMemAddress,0,&dwThreadID);
WaitForSingleObject(hRemThread,INFINITE);
That's all chopped and changed, but you see the basic idea. You get the address of LoadLibraryA (the same for every process), place the DLL name (parameter of LoadLibraryA) in the target process, and call CreateRemoteThread() to force the target process to load the DLL. Then any code executed by your DLL is inside the target process. It's yours (provided you have correct access rights)!