修改一个程序的过程如下:1、获得进程的句柄 2、以一定的权限打开进程 3、调用ReadProcessMemory读取内存,WriteProcessMemory修改内存,这也是内存补丁的实现过程。下面贴出的是调用ReadProcessMemory的例程
03 | BOOL CALLBACK EnumChildWindowProc( HWND hWnd, LPARAM lParam); |
05 | int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) |
07 | HWND nphWnd=::FindWindow( "notepad" ,NULL); |
12 | pe32.dwSize= sizeof (pe32); |
13 | HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); |
14 | if (hProcessSnap==INVALID_HANDLE_VALUE) |
16 | ::MessageBox(NULL, "CreateToolhelp32Snapshot error" , "error" ,MB_OK); |
20 | BOOL bMore=::Process32First(hProcessSnap,&pe32); |
23 | ::wsprintf(temp, "%s" ,pe32.szExeFile); |
24 | if (!:: strcmp (temp, "Maxthon.exe" )) |
26 | hProcess=::OpenProcess(PROCESS_ALL_ACCESS, false ,( DWORD )pe32.th32ProcessID); |
29 | ::wsprintf(temp, "%s" , "打开进程失败!" ); |
34 | ::wsprintf(temp, "%s" , "打开进程成功!" ); |
38 | DWORD dwNumberOfBytesRead; |
39 | if (!::ReadProcessMemory(hProcess,( LPCVOID )0x00400000,&tmp,4,&dwNumberOfBytesRead)) |
41 | ::wsprintf(temp, "%s" , "读取失败" ); |
46 | ::wsprintf(temp, "%x" ,tmp); |
52 | bMore=::Process32Next(hProcessSnap,&pe32); |
54 | ::EnumChildWindows(nphWnd,EnumChildWindowProc,0); |
59 | ::MessageBox(NULL, "please open notepad" , "error" ,MB_OK); |
63 | BOOL CALLBACK EnumChildWindowProc( HWND hWnd, LPARAM lParam) |
68 | ::GetClassName(hWnd,temp1,255); |
69 | if (!:: strcmp (temp1, "Edit" )) |
71 | ::SendMessage(hWnd,WM_SETTEXT,0,( LPARAM )mess); |
以PROCESS_ALL_ACCESS权限打开进程以后既可以使用ReadProcessMemory读取程序内存,也可以使用WriteProcessMemory改写程序的内存,这也是一些内存补丁使用的招数,以下是程序的实现代码
03 | BOOL CALLBACK EnumChildWindowProc( HWND hWnd, LPARAM lParam); |
05 | int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd) |
07 | HWND nphWnd=::FindWindow( "notepad" ,NULL); |
12 | pe32.dwSize= sizeof (pe32); |
13 | HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); |
14 | if (hProcessSnap==INVALID_HANDLE_VALUE) |
16 | ::MessageBox(NULL, "CreateToolhelp32Snapshot error" , "error" ,MB_OK); |
20 | BOOL bMore=::Process32First(hProcessSnap,&pe32); |
23 | ::wsprintf(temp, "%s" ,pe32.szExeFile); |
24 | if (!:: strcmp (temp, "button.exe" )) |
26 | hProcess=::OpenProcess(PROCESS_ALL_ACCESS, false ,( DWORD )pe32.th32ProcessID); |
29 | ::wsprintf(temp, "%s" , "打开进程失败!" ); |
34 | ::wsprintf(temp, "%s" , "打开进程成功!" ); |
38 | DWORD dwNumberOfBytesRead; |
39 | if (!::WriteProcessMemory(hProcess,( LPVOID )0x0040505d,&tmp,1,&dwNumberOfBytesRead)) |
41 | ::wsprintf(temp, "%s" , "写入失败" ); |
46 | ::wsprintf(temp, "%s" , "写入成功" ); |
52 | bMore=::Process32Next(hProcessSnap,&pe32); |
54 | ::EnumChildWindows(nphWnd,EnumChildWindowProc,0); |
59 | ::MessageBox(NULL, "please open notepad" , "error" ,MB_OK); |
63 | BOOL CALLBACK EnumChildWindowProc( HWND hWnd, LPARAM lParam) |
68 | ::GetClassName(hWnd,temp1,255); |
69 | if (!:: strcmp (temp1, "Edit" )) |
71 | ::SendMessage(hWnd,WM_SETTEXT,0,( LPARAM )mess); |
程序的功能是改写名为button.exe程序中内存地址为0x0040505d的值为97,即ASCII值的a,此处内存的原内容为ASCII值的m
被修改的程序实现代码如下:
03 | LRESULT CALLBACK _procWinMain( HWND , UINT , WPARAM , LPARAM ); |
04 | int WINAPI WinMain( HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) |
06 | HWND hWinMain,hButton1,hButton2; |
08 | WNDCLASSEX stWndClass; |
09 | RtlZeroMemory(&stWndClass, sizeof (stWndClass)); |
11 | stWndClass.hCursor=::LoadCursor(0,IDC_ARROW); |
12 | stWndClass.hInstance=hInstance; |
13 | stWndClass.cbSize= sizeof (WNDCLASSEX); |
14 | stWndClass.style=CS_HREDRAW||CS_VREDRAW; |
15 | stWndClass.lpfnWndProc=_procWinMain; |
16 | stWndClass.hbrBackground=( HBRUSH )GetStockObject(BLACK_BRUSH); |
17 | stWndClass.lpszClassName= "myclass" ; |
18 | ::RegisterClassEx(&stWndClass); |
20 | hWinMain=::CreateWindowEx(WS_EX_CLIENTEDGE, "myclass" , "firstwindow" ,WS_OVERLAPPEDWINDOW,100,100,600,400,NULL,NULL,hInstance,NULL); |
22 | hButton1=::CreateWindowEx(NULL, "BUTTON" , "button1" ,WS_VISIBLE|WS_CHILD,300,200,60,20,hWinMain,( HMENU )1,hInstance,NULL); |
23 | hButton2=::CreateWindowEx(NULL, "BUTTON" , "button2" ,WS_VISIBLE|WS_CHILD,100,200,60,20,hWinMain,( HMENU )2,hInstance,NULL); |
25 | ::ShowWindow(hWinMain,SW_SHOWNORMAL); |
26 | ::UpdateWindow(hWinMain); |
29 | if (::GetMessage(&stMsg,NULL,0,0)==0) |
33 | ::TranslateMessage(&stMsg); |
34 | ::DispatchMessage(&stMsg); |
39 | LRESULT CALLBACK _procWinMain( HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) |
43 | ::DestroyWindow(hWnd); |
45 | else if (uMsg==WM_DESTROY) |
47 | ::PostQuitMessage(NULL); |
49 | else if (uMsg==WM_COMMAND) |
51 | char temp1[256],temp2[256]; |
52 | ::itoa(( int )wParam,temp1,10); |
53 | :: strcpy (temp2, "wParam: " ); |
54 | :: strcat (temp2,temp1); |
55 | :: strcat (temp2, " lParam: " ); |
56 | ::itoa(( int )lParam,temp1,10); |
57 | :: strcat (temp2,temp1); |
58 | :: strcat (temp2, " mess" ); |
59 | ::MessageBox(NULL,temp2, "command" ,MB_OK); |
63 | return ::DefWindowProc(hWnd,uMsg,wParam,lParam); |
这个程序的功能是在窗口上建立两个button,点击任何一个button都会弹出一个对话框,输出button回调函数的wParam、lParam参数的值,外加一段字符串“mess”,我们要修改的就是字符串“mess”的第一个字符“m”为“a”。
0则评论给“ReadProcessMemory 与 WriteProcessMemory”