使用二进制可执行文件和从中产生的进程的 /proc/pid/maps,我想将此时的运行时指令地址(可以通过 gdb 或任何调试器检索)映射到二进制可执行文件中相应的“静态”指令地址(可以通过 objdump、ida 或任何反汇编程序检索)。
例如,对于 PIE 可执行文件或共享库,这很容易:
xxxx-yyyy r-xp 0000000 ... path/to/mysharedlibrary.so
然后对于运行时地址zzzz
,其对应的静态地址可以通过以下方式计算
static-address = zzzz - xxxx
可以通过查看objdump或者IDA来验证计算出的地址。
然而,对于非 PIE 或静态链接的可执行文件,上述规则不适用:
400000-yyyy r-xp 000000 ... path/to/executable
我们不需要另外从运行时地址中减去基地址,运行时地址与静态地址相同。
我想知道计算正确地址的具体规则是什么,因为上述两个规则完全是凭经验的。
这也是不正确的。或者更确切地说,只有当二进制文件链接到地址时它才是正确的(这通常是(共享库和二进制文件)
0
的情况,但共享库预链接时情况并非如此。请参阅man prelink)。ET_DYNAMIC
PIE
您需要 2 个数字:内存地址(来自)
/proc/$pid/maps
和链接地址(来自readelf -Wl
——第一段)。PT_LOAD
.p_vaddr
从第一个中减去第二个可以得到重定位(在
nm
/objdump
等中看到的内容与实际内存地址之间的差异)。