具体来说,如果我在不同的时间读取ESP寄存器指向的地址(包含栈顶地址),如何判断这两个地址是否在同一页?我相信这些地址是物理地址而不是虚拟地址,对吧?这两个读数可能来自不同的进程。Windows是如何进行页面分配的?
补充:也许我明白了。那么如果我们使用一个 4KB 的页面,这是否意味着从 0x....XXXX0000 到 0x....XXXX1000 的地址在同一个页面中?
具体来说,如果我在不同的时间读取ESP寄存器指向的地址(包含栈顶地址),如何判断这两个地址是否在同一页?我相信这些地址是物理地址而不是虚拟地址,对吧?这两个读数可能来自不同的进程。Windows是如何进行页面分配的?
补充:也许我明白了。那么如果我们使用一个 4KB 的页面,这是否意味着从 0x....XXXX0000 到 0x....XXXX1000 的地址在同一个页面中?
你几乎是对的。这个想法是合理的,但范围是0x????0000
to 0x????0FFF
。如果您要使用DWORD_PTR
,或者ULONG_PTR
您也可以屏蔽低 12 位(ptr & 0xFFF)
并比较您得到的两个指针值。ULONG_PTR
并且DWORD_PTR
应该在 x64 和 x86 上都可以工作。
请记住,您的系统可能正在使用大页面。所以请确保分别使用GetNativeSystemInfo
和/或GetSystemInfo
。您正在寻找结构中的dwAllocationGranularity
值SYSTEM_INFO
。
所有这一切仅在同一进程内存空间内是正确的。
关于物理地址的问题:不,我重复不,用户模式进程可以看到实际的物理地址,除非某些驱动程序或内核本身搞砸了。
假设您谈论的是 DLL 中的地址,您无法对从 Vista 及其 ASLR 功能开始的共享页面做出正确的假设。