我在测试的时候,发现在64位系统中,编译32位的调试器,调用 NtQueryInformationProcess 获取 PEB的基址总是错误的,
如下代码:
[Asm] 纯文本查看 复制代码
0:000:x86> !peb
PEB at 0000000000337000
InheritedAddressSpace: No
ReadImageFileExecOptions: No
BeingDebugged: Yes
ImageBaseAddress: 0000000000400000
Ldr 00007ff8056653a0
*** unable to read Ldr table at 00007ff8056653a0
SubSystemData: 0000000000000000
ProcessHeap: 00000000004d0000
ProcessParameters: 00000000004d3ca0
CurrentDirectory: 'C:\Windows\'
WindowTitle: 'Z:\Code\Code_2020\OllyDBG\Debug Demo\TraceMe.exe'
ImageFile: 'Z:\Code\Code_2020\OllyDBG\Debug Demo\TraceMe.exe'
CommandLine: '"Z:\Code\Code_2020\OllyDBG\Debug Demo\TraceMe.exe"'
DllPath: '< Name not readable >'
Environment: 00000000004d1120
peb基址明明是 0337000, 而调用 NtQueryInformationProcess 获取到的确是 0338000.
获取到的基址和实际的基址总是相差一个分页的大小(0x1000).
在网上搜到一个回答:
而上面说win8又开始失效了.而win8中的1分页也改成2分页了.
以后有机会再细测这些吧.
暂时就先这样用着...
-------------------------------------------------------------------
2023.06.15
这两天又阳了, 一直不在状态,一个断链写了几天还没写好...
现在已经搞清楚了, 在64系统中,32位进程会有两套PEB.
32位和64位的PEB偏移正好相差 0x1000.
如果cpudbg是64位的, 则使用 NtQueryInformationProcess 或者 GS:[0x60] 获取的PEB是64位的.
相反如果cpudbg是32位的, 则使用 NtQueryInformationProcess 或者 FS:[0x30] 获取的PEB是32位的.
在使用64位调试器里, 要想使用32位的 PEB 只需将得到的 PEB 加上 0x1000 即可.如下:
[C++] 纯文本查看 复制代码
pbi.PebBaseAddress = (PPEB)((DWORD64)pbi.PebBaseAddress+0x1000);
这里需要注意的是, 如果是64位程序, 在获取32位进程的LDR,有部分使用指针类型的,在64位程序上是8字节的, 因此需要重定义.
否则因为偏移不一致,得到数据看上去可能是凌乱的.
-------------------------------------------------------------------
end...
|