gpt4 book ai didi

linux - 计算函数在内存中的偏移量

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:48:57 26 4
gpt4 key购买 nike

我正在阅读 uprobe tracer 的文档并且有一条指令如何计算内存中函数的偏移量。我在这里引用它。

Following example shows how to dump the instruction pointer and %ax register at the probed text address. Probe zfree function in /bin/zsh:

# cd /sys/kernel/debug/tracing/
# cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
00400000-0048a000 r-xp 00000000 08:03 130904 /bin/zsh
# objdump -T /bin/zsh | grep -w zfree
0000000000446420 g DF .text 0000000000000012 Base zfree

0x46420 is the offset of zfree in object /bin/zsh that is loaded at 0x00400000.

我不知道为什么,但他们将输出 0x446420 减去 0x400000 得到 0x46420。这对我来说是一个错误。为什么是 0x400000?

我尝试在我的 Fedora 23 上用 4.5.6-200 内核做同样的事情。

首先我关闭了内存地址随机化

echo 0 > /proc/sys/kernel/randomize_va_space

然后我想出了二进制文件在内存中的位置

$ cat /proc/`pgrep zsh`/maps | grep /bin/zsh | grep r-xp
555555554000-55555560f000 r-xp 00000000 fd:00 2387155 /usr/bin/zsh

取了偏​​移量

marko@fedora:~ $ objdump -T /bin/zsh | grep -w zfree
000000000005dc90 g DF .text 0000000000000012 Base zfree

并通过 gdb 找出 zfree 的位置

$ gdb -p 21067 --batch -ex 'p zfree'
$1 = {<text variable, no debug info>} 0x5555555b1c90 <zfree>

marko@fedora:~ $ python
Python 2.7.11 (default, Mar 31 2016, 20:46:51)
[GCC 5.3.1 20151207 (Red Hat 5.3.1-2)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> hex(0x5555555b1c90-0x555555554000)
'0x5dc90'

你看,我得到了与 objdump 相同的结果,没有减去任何东西。

但后来我在另一台装有 SLES 的机器上尝试了相同的操作,结果与 uprobe 文档中的相同。

为什么会有这样的差异?那么我该如何计算正确的偏移量呢?

最佳答案

据我所知,差异可能仅由检查二进制文件的构建方式引起。更准确地说——ELF 是否有固定的加载地址。让我们做简单的实验。我们有简单的测试代码:

int main(void) { return 0; }

然后,通过两种方式构建它:

$ gcc -o t1 t.c      # create image with fixed load address
$ gcc -o t2 t.c -pie # create load-base independent image

现在,让我们检查这两个图像的加载基地址:

$ readelf -l --wide t1 | grep LOAD
LOAD 0x000000 0x0000000000400000 0x0000000000400000 0x00067c 0x00067c R E 0x200000
LOAD 0x000680 0x0000000000600680 0x0000000000600680 0x000228 0x000230 RW 0x200000
$ readelf -l --wide t2 | grep LOAD
LOAD 0x000000 0x0000000000000000 0x0000000000000000 0x0008cc 0x0008cc R E 0x200000
LOAD 0x0008d0 0x00000000002008d0 0x00000000002008d0 0x000250 0x000258 RW 0x2000

在这里您可以看到第一个图像需要固定的加载地址 - 0x400000,而第二个则完全没有地址要求。

现在我们可以比较 objdump 中关于 main 的地址:

$ objdump -t t1 | grep ' main'
00000000004004b6 g F .text 000000000000000b main
$ objdump -t t2 | grep ' main'
0000000000000710 g F .text 000000000000000b main

如我们所见,该地址是一个完整的虚拟地址,如果图像加载到地址,main 的第一个字节将占用该地址,存储在程序头中。当然,第二张图片永远不会加载到 0x0 处,而是加载到另一个随机选择的位置,这将偏移真实函数的位置。

关于linux - 计算函数在内存中的偏移量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37864773/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com