从 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 版本)从分发到分发(例如,不同的编译器会产生不同的结果)。
那么还有哪些查找此地址的其他方法?
你需要两件事:
libc.so.6
中变量的地址,由nm
和readelf
打印:
nm -D /usr/lib64/libc.so.6 | grep __environ
0000000000202d00 B __environ@@GLIBC_2.2.5
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()
。
有没有办法找到 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 版本)从分发到分发(例如,不同的编译器会产生不同的结果)。
那么还有哪些查找此地址的其他方法?
你需要两件事:
libc.so.6
中变量的地址,由nm
和readelf
打印:
nm -D /usr/lib64/libc.so.6 | grep __environ
0000000000202d00 B __environ@@GLIBC_2.2.5
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()
。