修改一個程式的過程如下:1、獲得程序的句柄 2、以一定的權限打開程序 3、調用ReadProcessMemory讀取記憶體,WriteProcessMemory修改記憶體,這也是記憶體更新檔的實作過程。下面貼出的是調用ReadProcessMemory的例程
#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修改記憶體的内容了,具體程式放在下篇文章中
通過WriteProcessMemory改寫程序的記憶體
以PROCESS_ALL_ACCESS權限打開程序以後既可以使用ReadProcessMemory讀取程式記憶體,也可以使用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,"button.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=97;//ascii:a
DWORD dwNumberOfBytesRead;
if(!::WriteProcessMemory(hProcess,(LPVOID)0x0040505d,&tmp,1,&dwNumberOfBytesRead))
{
::wsprintf(temp,"%s","寫入失敗");
::strcat(mess,temp);
}
else
{
::wsprintf(temp,"%s","寫入成功");
::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;
}