修改一个程序的过程如下:1、获得进程的句柄 2、以一定的权限打开进程 3、调用ReadProcessMemory读取内存,WriteProcessMemory修改内存,这也是内存补丁的实现过程。下面贴出的是调用ReadProcessMemory的例程
Code
#include <windows.h>
#include <tlhelp32.h>
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam);//枚举记事本中的子窗口
char mess[999999];
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
HWND nphWnd=::FindWindow("notepad",NULL);
if(nphWnd)
{
char temp[1024];
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获得进程列表的快照,第一个参数可以有其他选项,详细请参考MSDN
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
::MessageBox(NULL,"CreateToolhelp32Snapshot error","error",MB_OK);
return 0;
}
HANDLE hProcess;
BOOL bMore=::Process32First(hProcessSnap,&pe32);//获得第一个进程的信息
while(bMore)
{
::wsprintf(temp,"%s",pe32.szExeFile);
if(!::strcmp(temp,"Maxthon.exe"))
{
hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)pe32.th32ProcessID);
if(hProcess==NULL)
{
::wsprintf(temp,"%s","打开进程失败!");
::strcat(mess,temp);
}
else
{
::wsprintf(temp,"%s","打开进程成功!");
::strcat(mess,temp);
//读取内存中内容
int tmp;
DWORD dwNumberOfBytesRead;
if(!::ReadProcessMemory(hProcess,(LPCVOID)0x00400000,&tmp,4,&dwNumberOfBytesRead))
{
::wsprintf(temp,"%s","读取失败");
::strcat(mess,temp);
}
else
{
::wsprintf(temp,"%x",tmp);
::strcat(mess,temp);
}
}
break;
}
bMore=::Process32Next(hProcessSnap,&pe32);//获得其他进程信息
}
::EnumChildWindows(nphWnd,EnumChildWindowProc,0);//获得记事本的edit窗口,打印进程信息
return 0;
}
else
{
::MessageBox(NULL,"please open notepad","error",MB_OK);
return 0;
}
}
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam)
{
char temp1[256];
if(hWnd)
{
::GetClassName(hWnd,temp1,255);
if(!::strcmp(temp1,"Edit"))//得到edit子窗口句柄
{
::SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)mess);
return 0;
}
}
return true;
}
程序读取400000地址4个字节的数据,对于exe文件,也就是PE文件,读出来的内容永远都是905a4d,翻译成ASCII字符也就是“MZ”,下面要进行的就是调用WriteProcessMemory修改内存的内容了,具体程序放在下篇文章中
#include <windows.h>
#include <tlhelp32.h>
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam);//枚举记事本中的子窗口
char mess[999999];
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPSTR lpCmdLine,int nShowCmd)
{
HWND nphWnd=::FindWindow("notepad",NULL);
if(nphWnd)
{
char temp[1024];
PROCESSENTRY32 pe32;
pe32.dwSize=sizeof(pe32);
HANDLE hProcessSnap=::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);//获得进程列表的快照,第一个参数可以有其他选项,详细请参考MSDN
if(hProcessSnap==INVALID_HANDLE_VALUE)
{
::MessageBox(NULL,"CreateToolhelp32Snapshot error","error",MB_OK);
return 0;
}
HANDLE hProcess;
BOOL bMore=::Process32First(hProcessSnap,&pe32);//获得第一个进程的信息
while(bMore)
{
::wsprintf(temp,"%s",pe32.szExeFile);
if(!::strcmp(temp,"Maxthon.exe"))
{
hProcess=::OpenProcess(PROCESS_ALL_ACCESS,false,(DWORD)pe32.th32ProcessID);
if(hProcess==NULL)
{
::wsprintf(temp,"%s","打开进程失败!");
::strcat(mess,temp);
}
else
{
::wsprintf(temp,"%s","打开进程成功!");
::strcat(mess,temp);
//读取内存中内容
int tmp;
DWORD dwNumberOfBytesRead;
if(!::ReadProcessMemory(hProcess,(LPCVOID)0x00400000,&tmp,4,&dwNumberOfBytesRead))
{
::wsprintf(temp,"%s","读取失败");
::strcat(mess,temp);
}
else
{
::wsprintf(temp,"%x",tmp);
::strcat(mess,temp);
}
}
break;
}
bMore=::Process32Next(hProcessSnap,&pe32);//获得其他进程信息
}
::EnumChildWindows(nphWnd,EnumChildWindowProc,0);//获得记事本的edit窗口,打印进程信息
return 0;
}
else
{
::MessageBox(NULL,"please open notepad","error",MB_OK);
return 0;
}
}
BOOL CALLBACK EnumChildWindowProc(HWND hWnd,LPARAM lParam)
{
char temp1[256];
if(hWnd)
{
::GetClassName(hWnd,temp1,255);
if(!::strcmp(temp1,"Edit"))//得到edit子窗口句柄
{
::SendMessage(hWnd,WM_SETTEXT,0,(LPARAM)mess);
return 0;
}
}
return true;
}