我在控制台程序裡用代碼在宿主進程裡注入一個MessageBox函數,能夠成功運行,宿主進程顯示對話框後一切正常,可是我用相同的代碼在MFC創建的基於對話框程的序裡,使用按鈕來實現時,注入的對話框能夠成功顯示,但是一旦關閉注入的對話框,宿主進程就崩潰,我就納悶了。我試過權限的問題,管理員權限運行也不行,在代碼裡改令牌也不行,請問到底什麼原因導致的這種現象。以下是代碼。
控制台程序
#include <windows.h>
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
struct RemoteParam
{
char sShow[12];
DWORD dwMessageBox;
};
DWORD WINAPI threadProc(LPVOID lpParameter)
{
RemoteParam *rp=(RemoteParam*)lpParameter;
PFN_MESSAGEBOX pfnMessageBox=(PFN_MESSAGEBOX)(rp->dwMessageBox);
pfnMessageBox(NULL,rp->sShow,rp->sShow,0);
return 0;
}
void main()
{
DWORD proId;
const DWORD dwThreadSize=4096;
HWND windHandle=::FindWindow(NULL,"MyGame");
::GetWindowThreadProcessId(windHandle,&proId);
HANDLE proHandle=::OpenProcess(PROCESS_ALL_ACCESS,false,proId);
void* allcAddr=::VirtualAllocEx(proHandle,0,dwThreadSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE);
::WriteProcessMemory(proHandle,allcAddr,&threadProc,dwThreadSize,0);
HMODULE hUser32=::LoadLibrary("User32.dll");
RemoteParam RemoteData;
ZeroMemory(&RemoteData,sizeof(RemoteParam));
RemoteData.dwMessageBox=(DWORD)::GetProcAddress(hUser32,"MessageBoxA");
strcat(RemoteData.sShow,"Hello\0");
RemoteParam* paramAndFunc=(RemoteParam*)::VirtualAllocEx(proHandle,0,sizeof(RemoteData),MEM_COMMIT,PAGE_READWRITE);
::WriteProcessMemory(proHandle,paramAndFunc,&RemoteData,sizeof(RemoteData),0);
DWORD dwId;
HANDLE hRemoteHandle=::CreateRemoteThread(proHandle,NULL,0,(LPTHREAD_START_ROUTINE)allcAddr,paramAndFunc,0,&dwId);
CloseHandle(hRemoteHandle);
FreeLibrary(hUser32);
}
MFC按鈕消息響應函數裡的代碼
typedef int (__stdcall * PFN_MESSAGEBOX)(HWND, LPCTSTR, LPCTSTR, DWORD);
struct RemoteParam
{
char sShow[12];
DWORD dwMessageBox;
};
DWORD WINAPI threadProc(LPVOID lpParameter)
{
RemoteParam *rp=(RemoteParam*)lpParameter;
PFN_MESSAGEBOX pfnMessageBox=(PFN_MESSAGEBOX)(rp->dwMessageBox);
pfnMessageBox(NULL,rp->sShow,rp->sShow,0);
return 0;
}
void CMyDlg::OnButtonPourinto()
{
//enableDebugPriv();
DWORD proId;
const DWORD dwThreadSize=4096;
HWND windHandle=::FindWindow(NULL,"MyGame");
::GetWindowThreadProcessId(windHandle,&proId);
HANDLE proHandle=::OpenProcess(PROCESS_ALL_ACCESS,false,proId);
void* allcAddr=::VirtualAllocEx(proHandle,0,dwThreadSize,MEM_COMMIT|MEM_RESERVE,PAGE_EXECUTE_READWRITE
);
::WriteProcessMemory(proHandle,allcAddr,&threadProc,dwThreadSize,0);
RemoteParam RemoteData;
ZeroMemory(&RemoteData,sizeof(RemoteParam));
HINSTANCE hUser32 = LoadLibrary("User32.dll");
RemoteData.dwMessageBox=(DWORD)::GetProcAddress(hUser32,"MessageBoxA");
strcat(RemoteData.sShow,"Hello\0");
RemoteParam* paramAndFunc=(RemoteParam*)::VirtualAllocEx(proHandle,0,sizeof(RemoteData),MEM_COMMIT,PAGE_READWRITE);
::WriteProcessMemory(proHandle,paramAndFunc,&RemoteData,sizeof(RemoteData),0);
DWORD dwId;
HANDLE hRemoteHandle=::CreateRemoteThread(proHandle,NULL,0,(LPTHREAD_START_ROUTINE)allcAddr,paramAndFunc,0,&dwId);
CloseHandle(hRemoteHandle);
FreeLibrary(hUser32);
}
不會是Debug/Release版本的問題吧?