CE搜索内存数据的原理
OpenProcess是必须的(不讲R0),MSDN上说,Read/Wirte一个进程虚拟内存时, 要先打开进程, 带有读写虚拟内存权限才行,VirtualQueryEx 函数是用来检查内存属性,因为并不是所有的内存地址都是可读可以写, 所以很明白,
操作顺序是 OpenProcess -> ReadProcessMemory(WriteProcessMemory) ->VirtualQueryEx , 等等, 很多问题,
VirtualQueryEx 是检查内存属性的, 已经读写了, 还检查个啥子??
所以变成 OpenProcess ->VirtualQueryEx-> ReadProcessMemory(WriteProcessMemory),
问题又出现了, VirtualQueryEx 是检查内存属性的, 那么应该从那个地址检查呢??
Windows 32位 系统, 内存寻址范围是 2 的32次方, 4G左右, 也就是要寻址4G的地址??? 这个地址非常的大,
再看MSDN, 发现 内存地址分成了两部分, 用户空间 和 内核空间(本文里不讲内核空间), 各用了2G的空间, 而且用户空间是不能直接访问内核空间的, 所以确定了搜索范围是 2G 内,即 0x7FFFFFF 个地址, 好,这个范围不会错误了, 问题又来了, 2G的地址, 我怎么知道那个地址是可读, 那个地址是可写???, VirtualQueryEx函数MSDN上说了
VirtualQueryEx provides information about a region of consecutive pages beginning at a specified address that share the following attributes:
The state of all pages is the same (MEM_COMMIT, MEM_RESERVE, MEM_FREE, MEM_PRIVATE, MEM_MAPPED, or MEM_IMAGE).
If the initial page is not free, all pages in the region are part of the same initial allocation of pages.
The access granted to all pages is the same (PAGE_READONLY, PAGE_READWRITE, PAGE_NOACCESS, PAGE_WRITECOPY, PAGE_EXECUTE, PAGE_EXECUTE_READ, PAGE_EXECUTE_READWRITE, PAGE_EXECUTE_WRITECOPY, PAGE_GUARD, or PAGE_NOCACHE).
The VirtualQueryEx function determines the attributes of the first page in the region and then scans subsequent pages until it scans the entire range of pages, or until it encounters a page with a nonmatching set of attributes. The function returns the attributes and the size of the region of pages with matching attributes, in bytes. For example, if there is a 40 megabyte (MB) region of free memory, and VirtualQueryEx is called on a page that is 10 MB into the region, the function will obtain a state of MEM_FREE and a size of 30 MB.
虽然我英语也是入门水平, MSDN说了, VirtualQueryEx 是可以检查出一个内存页面的属性,也就是要读写内存,属性就得是有读写属性(PAGE_READWRITE,PAGE_WRITECOPY,PAGE_EXECUTE_READWRITE,PAGE_EXECUTE_WRITECOPY), 那么到底是那个呢???
不多说, 跟踪下CE, 看看CE何如去搜索, 下面是跟踪的情况
只跟踪 VirtualQueryEx 函数即可
![点击查看原始大小图片](http://img.bbs.csdn.net/upload/201401/01/1388545468_619375.png)
跟踪可知, CE从 0x0400000这个地址开始搜索, 为什么从这个地址开始搜索呢?? 这里不多说, 请去了解下PE结构, 函数的第三个参数lpBuffer放了页面内存的属性,页面大小,保护状态等信息, 根据大小, 可计算出下一个要检查的位置, 跟进发现, CE并没有读写属性的页面, 所以, 我在程序里也将没有读写属性的过虑了, 这样就可以降低搜索范围,
![点击查看原始大小图片](http://img.bbs.csdn.net/upload/201401/01/1388545863_71400.png)
实现后的效果, 基本于CE一样
![](http://img.bbs.csdn.net/upload/201401/01/1388545992_539165.png)
下面贴下核心代码
![点击查看原始大小图片](http://img.bbs.csdn.net/upload/201401/01/1388546070_365187.png)
![](https://images2015.cnblogs.com/blog/923483/201612/923483-20161204141449740-1945578147.jpg)