读写内存 大概轮廓

来源:互联网 发布:interbase数据库被淘汰 编辑:程序博客网 时间:2024/04/29 03:13
BOOL VirtualProtectEx(

HANDLE hProcess, // 要修改内存的进程句柄

LPVOID lpAddress, // 要修改内存的起始地址

DWORD dwSize, // 修改内存的字节

DWORD flNewProtect, // 修改后的内存属性

PDWORD lpflOldProtect // 修改前的内存属性的地址

);

BOOL WriteProcessMemory(

HANDLE hProcess, // 要写进程的句柄

LPVOID lpBaseAddress, // 写内存的起始地址

LPVOID lpBuffer, // 写入数据的地址

DWORD nSize, // 要写的字节数

LPDWORD lpNumberOfBytesWritten // 实际写入的子节数

);

BOOL ReadProcessMemory(

HANDLE hProcess, // 要读进程的句柄

LPCVOID lpBaseAddress, // 读内存的起始地址

LPVOID lpBuffer, // 读入数据的地址

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

LPDWORD lpNumberOfBytesRead // 实际读入的子节数

);










ReadProcessMemory 读另一个进程的内存,原形如下:
BOOL ReadProcessMemory(
HANDLE hProcess, // 被读取进程的句柄;
LPCVOID lpBaseAddress, // 读的起始地址;
LPVOID lpBuffer, // 存放读取数据缓冲区;
DWORD nSize, // 一次读取的字节数;
LPDWORD lpNumberOfBytesRead // 实际读取的字节数;
);
hProcess 进程句柄可由OpenProcess 函数得到,原形如下:
HANDLE OpenProcess(
DWORD dwDesiredAccess, // 访问标志;
BOOL bInheritHandle, // 继承标志;
DWORD dwProcessId // 进程ID;
);

---- 当然,用完别忘了用 CloseHandle 关闭打开的句柄。读另一个进程的内存 dwDesiredAccess 须指定为 PROCESS_VM_READ ,写另一个进程的内存 dwDesiredAccess 须指定为 PROCESS_VM_WRITE ,继承标志无所谓,进程ID可由 Process32First 和 Process32Next 得到,这两个函数可以枚举出所有开启的进程,这样进程的信息也就得到了。 Process32First 和 Process32Next是由 TLHelp32 单元提供的,需在 uses 里加上TLHelp32。ToolsHelp32 封装了一些访问堆、线程、进程等的函数,只适用于Win9x,原形如下:

BOOL WINAPI Process32First(
HANDLE hSnapshot //
由 CreateToolhelp32Snapshot 返回
的系统快照句柄;
LPPROCESSENTRY32 lppe // 指向一个 PROCESSENTRY32 结构;
);
BOOL WINAPI Process32Next(
HANDLE hSnapshot // 由 CreateToolhelp32Snapshot 返回
的系统快照句柄;
LPPROCESSENTRY32 lppe // 指向一个 PROCESSENTRY32 结构;
);
hSnapshot 由 CreateToolhelp32Snapshot 返回的系统快照句柄;
CreateToolhelp32Snapshot 原形如下:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags, // 快照标志;
DWORD th32ProcessID // 进程ID;
);
现在需要的是进程的信息,所以将 dwFlags
指定为 TH32CS_SNAPPROCESS,
th32ProcessID 忽略;PROCESSENTRY32 结构如下:
typedef struct tagPROCESSENTRY32 {
DWORD dwSize; // 结构大小;
DWORD cntUsage; // 此进程的引用计数;
DWORD th32ProcessID; // 进程ID;
DWORD th32DefaultHeapID; // 进程默认堆ID;
DWORD th32ModuleID; // 进程模块ID;
DWORD cntThreads; // 此进程开启的线程计数;
DWORD th32ParentProcessID;// 父进程ID;
LONG pcPriClassBase; // 线程优先权;
DWORD dwFlags; // 保留;
char szExeFile[MAX_PATH]; // 进程全名;
} PROCESSENTRY32;  

---- 至此,所用到的主要函数已介绍完,实现读内存只要从下到上依次调用上述函数即可,具体参见原代码:

 HANDLE hProcess;
 HANDLE hSnapshot;
 
 PROCESSENTRY32 FProcessEntry32;
 DWORD th32ProcessID;

 hSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
 FProcessEntry32.dwSize=sizeof(FProcessEntry32);
    int Flag=0;
 if(Process32First(hSnapshot,&FProcessEntry32))
 {
  do
  {
   if((CString)FProcessEntry32.szExeFile=="文件加密.EXE")
   {
    Flag=1;
    break;
   }
  }while (Process32Next(hSnapshot, &FProcessEntry32));

  if(Flag==1)
  {
   this->MessageBox(FProcessEntry32.szExeFile);
   th32ProcessID=FProcessEntry32.th32ProcessID;
   DWORD nSize;
   nSize=4;
   char * buff;

   buff=(char*)GlobalAlloc(GMEM_FIXED | GMEM_ZEROINIT,nSize);
   hProcess=OpenProcess(PROCESS_VM_READ,false,th32ProcessID);

   DWORD   dwRead;  
   ReadProcessMemory(hProcess,(LPCVOID)0x000283a2,buff,nSize,&dwRead);  //??
   this->MessageBox((CString)buff);
   
   GlobalFree(buff);
  }
  
 }

 CloseHandle(hSnapshot);

//2种


1.通过FindWindow读取窗体的句柄

2.通过GetWindowThreadProcessId读取查找窗体句柄进程的PID值

3.用OpenProcess(PROCESS_QUERY_INFORMATION Or PROCESS_VM_OPERATION Or PROCESS_VM_READ Or PROCESS_VM_WRITE, 0, ProcessId)打开查到PID值的进程. 此打开具备 读取,写入,查询的权限

4.ReadProcessMemory读出指定的内存地址数据
 
原创粉丝点击