您的位置:首页 > 其它

ReadProcessMemory

2012-08-08 10:37 197 查看
 函数功能描述:该函数用来读取指定进程的空间的数据,此空间必须是可以访问的,否则读取操作会失败!函数原型

  BOOL ReadProcessMemory(

   HANDLE hProcess, // 目标进程句柄

   LPCVOID lpBaseAddress, // 读取数据的起始地址

   LPVOID lpBuffer, // 存放数据的缓存区地址

   DWORD nSize, // 要读取的字节数

   LPDWORD lpNumberOfBytesRead // 实际读取数存放地址

  );

  参数

  hProcess

   目标进程的句柄,该句柄必须对目标进程具有PROCESS_VM_READ 的访问权限。

  lpBaseAddress

   从目标进程中读取数据的起始地址。在读取数据前,系统将先检验该地址的数据是否可读,如果不可读,函数将调用失败。

  lpBuffer

   用来接收数据的缓存区地址。

  nSize

   从目标进程读取数据的字节数。

  lpNumberOfBytesRead

   实际被读取数据大小的存放地址。如果被指定为NULL,那么将忽略此参数。

  返回值

   如果函数执行成功,返回值非零。

  如果函数执行失败,返回值为零。调用 GetLastError 函数可以获取该函数执行错误的信息。

  如果要读取一个进程中不可访问空间的数据,该函数就会失败。

  

  备注

   ReadProcessMemory 函数从目标进程复制指定大小的数据到自己进程的缓存区,任何拥有PROCESS_VM_READ 权限句柄的进程都可以调用该函数,目标进程的地址空间很显然要是可读的,但也并不是必须的,如果目标进程处于被调试状态的话。

  使用环境[包括适合WINDOWS的版本、所需头文件、所需链接库]

  读取内存流程

  

  1.获得程序的句柄---->findwindow

  2.获得进程ID---->GetWindowThreadProcessId

  3.获得进程句柄---->OpenProcess

  4.内存操作(读取写放)---->ReadProcessMemory

修改一个程序的过程如下: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修改内存的内容了,具体程序放在下篇文章中
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: