【发布时间】:2021-08-16 04:54:02
【问题描述】:
此代码示例:
int x = 75;
int *p = &x;
printf("%llx\n",p);
写入一个 64 位数字。我要问的是,这个数字到底是多少?是的,它是一个地址。
但它是存储值 75 的虚拟内存中的绝对地址吗?或者它可能从某个页面标记偏移,或者从程序内存块的“起点”偏移?
如果重要的话,我要问的是典型 x64 英特尔芯片上的 64 位 Windows 10。
【问题讨论】:
此代码示例:
int x = 75;
int *p = &x;
printf("%llx\n",p);
写入一个 64 位数字。我要问的是,这个数字到底是多少?是的,它是一个地址。
但它是存储值 75 的虚拟内存中的绝对地址吗?或者它可能从某个页面标记偏移,或者从程序内存块的“起点”偏移?
如果重要的话,我要问的是典型 x64 英特尔芯片上的 64 位 Windows 10。
【问题讨论】:
是的,它是你程序virtual address space中的绝对地址。
这不是偏移量。
在 16 位 Windows(30 年前很常见)中,使用了 segmented memory model,其中指针被分段,由 16 位段指针和 16 位偏移量组成(共 32 位) .
但是,32 位和 64 位 Windows 都使用flat memory model,它使用绝对地址。
【讨论】:
kernel32.dll,总是映射到每个进程中的相同虚拟地址。此外,不能保证每个虚拟地址都映射到物理地址。即使是有效的虚拟地址也不一定映射到物理地址。例如,虚拟地址的内容可以是paged到磁盘,这样它甚至不存在于内存中。
ReadProcessMemory时,还必须指定目标进程。您传递给该函数的地址适用于目标进程的虚拟地址空间。
它是一个虚拟地址,它是一个虚拟页码和一个从页面开始的偏移量。翻译机制在进程的页表中查找相应的物理页码,并结合偏移量得出物理地址。
【讨论】: