学HOOK学的 API 函数、、VirtualQuery、、VirtualProtect、、 WriteProcessMemory

  • Post author:
  • Post category:其他


先说一下MEMORY_BASIC_INFORMATION这个结构、、

typedef   struct  _MEMORY_BASIC_INFORMATION {

PVOID BaseAddress;   //区域基地址。与VirtualQuery函数的第一个参数lpAddr相同

PVOID AllocationBase; //分配基地址指明用VirtualAlloc函数分配内存区域的基地址,lpAddr在该区域内。

DWORD AllocationProtect; //区域被初次保留时赋予的保护属性。例PAGE_READWRITE允许读写、、

SIZE_T RegionSize;      //区域大小(字节)。用于指明内存块从基地址即BaseAddress开始的所有页面的大小(以字节为计量单位)

这些页面与含有用lpAddr参数设定的地址的页面拥有相//同的保护属性、状态和类型。

DWORD State;    //状态(MEM_FREE、MEM_RESERVE或MEM_COMMIT)。指明所有相邻页面的状态

//MEM_COMMIT指明已分配物理内存或者系统页文件。

//MEM_FREE空闲状态。该区域的虚拟地址不受任何内存的支持。该地址空间没有被保留。

//在此状态下AllocationBase、AllocationProtect、Protect  和Type等成员均未定义。

//MEM_RESERVE指明页面被保留,但是没有分配任何物理内存。该状态下Protect成员未定。

DWORD Protect;   //保护属性。意义同AllocationProtect

DWORD Type;  //类型。用于指明支持所有相邻页面的物理存储器的类型/(MEM_IMAGE,MEM_MAPPED或MEM_PRIVATE)。

//如果是Windows 98,那么这个成员将总是  MEM_PRIVATE 。

//MEM_IMAGE 指明该区域的虚拟地址原先受内存映射的映像文件(如.exe或DLL文件)的支持,但也许不再受映像文件的支持。

例如,当写入模块映像中的全局变量时,“写入时拷贝”的机制将由页文件来支持特定的页面,而不是受原始映像文件的支持。

//MEM_MAPPED 该区域的虚拟地址原先是受内存映射的数据文件的支持,但也许不再受数据文件的支持。

例如,数据文件可以使用“写入时拷贝”的保护属性来映射。对文件的任何写入操作都将导致页文件而不是原始数据支持特定的页面。                      //MEM_PRIVATE 指明该内存区域是私有的。不被其他进程共享。

} MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION;

VirtualQuery (lpAddr,  &mbi,  sizeof(mbi));

// VirtualQuery函数:查询地址空间中内存地址的信息。并填充MEMORY_BASIC_INFORMATION结构、

// DWORD VirtualQuery(

LPCVOID   lpAddress,查询内存的地址

PMEMORY_BASIC_INFORMATION   lpBuffer,指向MBI结构的指针,用于接收内存信息

DWORD  dwLength         MEMORY_BASIC_INFORMATION结构的大小。

);// 函数写入lpBuffer的字节数,如果不等于sizeof(MEMORY_BASIC_INFORMATION)表示失败

VirtualProtect (lpAddr,  sizeof(DWORD),  PAGE_READWRITE,  &dwOLD);

// BOOL VirtualProtect(

LPVOID lpAddress, //目标地址起始位置

DWORD dwSize, //大小 要变更的记忆体分页区域的大小(单位是字节)。

DWORD flNewProtect, //请求的保护方式

PDWORD lpflOldProtect //保存老的保护方式

);

WriteProcessMemory (GetCurrentProcess(),     lpAddr, &ADD, sizeof(DWORD), NULL);

//此函数能写入某一进程的内存区域。入口区必须可以访问

// BOOL WriteProcessMemory(

HANDLE hProcess, 由OpenProcess返回的进程句柄 这里是去获取目标进程的句柄

LPVOID lpBaseAddress,要写的内存首地址再写入之前,此函数将先检查目标地址是否可用,

并能容纳待写入的数据

LPVOID lpBuffer, 指向要写的数据的指针。

DWORD nSize,   要写入的字节数。

LPDWORD lpNumberOfBytesWritten 实际数据的长度 一般写为NULL、、

);返回值  非零值代表成功

转载于:https://blog.51cto.com/xzv587/1363194


关闭菜单