// 得到目标窗口所在进程的ID,篇幅原因假设已经知道窗口句柄
HWND hwnd = (HWND)0x000108F8;
DWORD dwProcessID;
DWORD dwTitleSize = 0x20;
DWORD dwDataLen = 0x30;
GetWindowThreadProcessId(hwnd, &dwProcessID);
HANDLE hProcess = OpenProcess(PROCESS_CREATE_THREAD | PROCESS_VM_OPERATION | PROCESS_VM_WRITE |
PROCESS_VM_READ, FALSE, dwProcessID);
// 在B 进程中申请空间以存放返回的窗口标题
LPBYTE pData = (LPBYTE)VirtualAllocEx(hProcess, 0, dwDataLen, MEM_COMMIT, PAGE_READWRITE);
// 填充参数
WriteProcessMemory(hProcess, pData, &dwTitleSize, 4, NULL);
WriteProcessMemory(hProcess, pData + 4, &hwnd, 4, NULL);
// 注入的代码长度
DWORD dwCodeLen = 0;
#ifdef _DEBUG
const DWORD dwSpyRealAddr = *(LPDWORD)((LPBYTE)(&GetWindowTextSpy)+1) + (DWORD)(&GetWindowTextSpy) + 5;
const DWORD dwEndReadAddr = *(LPDWORD)((LPBYTE)(&EndLabel)+1) + (DWORD)(&EndLabel) + 5;
#else
const DWORD dwSpyRealAddr = (DWORD)GetWindowTextSpy;
const DWORD dwEndReadAddr = (DWORD)EndLabel;
#endif
dwCodeLen = dwEndReadAddr - dwSpyRealAddr;
LPBYTE pCode = (LPBYTE)VirtualAllocEx(hProcess, 0, dwCodeLen, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
LPBYTE pCodeBuff = (LPBYTE)malloc(dwCodeLen);
memcpy((LPVOID)pCodeBuff, (LPVOID)dwSpyRealAddr, dwCodeLen);
// 调整代码
LPBYTE p = pCodeBuff;
while(*p != 0xE8){p++;}
*(DWORD*)(p+1) = (DWORD)&GetWindowText - (DWORD)(p - (LPBYTE)pCodeBuff + (LPBYTE)pCode) - 5;
WriteProcessMemory( hProcess, pCode, pCodeBuff, dwCodeLen, NULL);
HANDLE hRThread = CreateRemoteThread(hProcess, NULL, 0, (LPTHREAD_START_ROUTINE)pCode, pData, 0, 0);
WaitForSingleObject(hRThread, INFINITE);
char szTitle[100] = {0};
DWORD dwReadBytes = 0;
ReadProcessMemory(hProcess, pData + 8, szTitle, dwTitleSize, &dwReadBytes);
cout << szTitle << endl;
CloseHandle(hRThread);
free(pCodeBuff);
VirtualFreeEx(hProcess, pCode, dwCodeLen, MEM_RELEASE);
VirtualFreeEx(hProcess, pData, dwDataLen, MEM_RELEASE);
CloseHandle(hProcess);
}