从 shell 代码访问未链接的 libc 全局变量

Accessing unlinked libc global variable from shell code

有没有办法找到 libc 中尚未链接到可执行文件(因此不在 got/plt 中)的全局变量的地址?我想在我的 shell 代码中访问 __environ 全局变量。

网络搜索目前只找到了一种方法,首先从plt中的实体中找到共享库中的偏移量,并将偏移量与plt中的运行时值相加以获得运行时地址共享库中的所需变量。有没有其他不依赖于共享库版本的方法?

谢谢。

Is there another way that would not depend on the version of the shared library?

没有

__environ 的地址可以通过多种方式轻松找到,除了“首先从 plt 中的实体找到共享库中的偏移量,并将偏移量添加到plt 以获取所需变量的运行时地址”,但该地址 取决于 libc.so.6 的确切构建,并且会因版本而异(并且对于确切的相同的 GLIBC 版本)从分发到分发(例如,不同的编译器会产生不同的结果)。

那么还有哪些查找此地址的其他方法?

你需要两件事:

  1. libc.so.6中变量的地址,由nmreadelf打印:
nm -D /usr/lib64/libc.so.6 | grep __environ
0000000000202d00 B __environ@@GLIBC_2.2.5
  1. libc.so.6 自身在给定进程中的位置,可通过例如/proc/$pid/maps.
 grep libc.so.6 /proc/37/maps
7f34d2865000-7f34d2891000 r--p 00000000 08:10 67606                      /usr/lib64/libc.so.6
7f34d2891000-7f34d2a07000 r-xp 0002c000 08:10 67606                      /usr/lib64/libc.so.6
...

以上输出告诉我 __environ 应该在进程 37 中的 0x7f34d2865000+0x0000000000202d00

gdb -q -p 37
...
(gdb) p/a 0x7f34d2865000+0x0000000000202d00
 = 0x7f34d2a67d00 <environ>

(gdb) p &__environ
 = (char ***) 0x7f34d2a67d00 <environ>

QED.

P.S。还有其他方法可以发现 (1)——您可以直接读取 .dynsym 而无需使用 nm,以及 (2)——您可以在目标进程中使用 dladdr()