网站建设佰首选金手指十二/品牌营销策略
前言
读进程内存只能一次读一页以内或读页的倍数.
没有试验读页的倍数字节.
试验了读页不对齐的情况.
如果不分多次读(读小于页边界的字节数 + 读整页字节数), ReadProcessMemory会失败.
代码预览
BOOL CProcessHelper::ReadProcessMemoryEx(HANDLE hProcess,LPCVOID lpBaseAddress,LPVOID lpBuffer,SIZE_T nSize,SIZE_T * lpNumberOfBytesRead)
{// 考虑跨页读问题, 要读多次. // e.g. 跨多页的问题// e.g. 从0x00401234 读 0x12345个字符到缓冲区BOOL bRc = FALSE;DWORD dwPos = 0;DWORD dwRd = 0;DWORD dwRdBack = 0;const DWORD dwPageCb = 0x1000; ///< 一页内存的sizeDWORD dwRemainder = 0;if (NULL != lpNumberOfBytesRead) {*lpNumberOfBytesRead = 0;}// 读第一部分, 不对齐页的部分, 比一页小, 只读一次dwRemainder = dwPageCb - ((DWORD)lpBaseAddress % dwPageCb);if (nSize <= dwRemainder) {// 在页中间读的, 读的数据长度不到页尾, 一次读完返回bRc = ReadProcessMemory(hProcess, (void*)((DWORD)lpBaseAddress + dwPos), (void*)((DWORD)lpBuffer + dwPos), nSize,&dwRdBack);if (NULL != lpNumberOfBytesRead) {*lpNumberOfBytesRead += dwRdBack;}if ((!bRc) || (dwRdBack != nSize)) {return FALSE;}return bRc;}// 要读的数据超过页边界的if (dwRemainder > 0) {nSize -= dwRemainder;bRc = ReadProcessMemory(hProcess, (void*)((DWORD)lpBaseAddress + dwPos), (void*)((DWORD)lpBuffer + dwPos), dwRemainder,&dwRdBack);if (NULL != lpNumberOfBytesRead) {*lpNumberOfBytesRead += dwRdBack;}if ((!bRc) || (dwRdBack != dwRemainder)) {return FALSE;}dwPos += dwRdBack;}// 重复读第2部分, 整页的读while (nSize >= dwPageCb) {nSize -= dwPageCb;bRc = ReadProcessMemory(hProcess, (void*)((DWORD)lpBaseAddress + dwPos), (void*)((DWORD)lpBuffer + dwPos), dwPageCb, &dwRdBack);if (NULL != lpNumberOfBytesRead) {*lpNumberOfBytesRead += dwRdBack;}if ((!bRc) || (dwRdBack != dwPageCb)) {return FALSE;}dwPos += dwRdBack;}// 读尾巴部分, 比一页小, 只读一次就够了if (nSize > 0) {bRc = ReadProcessMemory(hProcess, (void*)((DWORD)lpBaseAddress + dwPos), (void*)((DWORD)lpBuffer + dwPos), nSize, &dwRdBack);if (NULL != lpNumberOfBytesRead) {*lpNumberOfBytesRead += dwRdBack;}if ((!bRc) || (dwRdBack != nSize)) {return FALSE;}}return TRUE;
}