每个函数加载的 glibc 基址不同
Loaded glibc base address different for each function
我正在尝试计算二进制文件库的基地址。
我有 printf 的地址,puts ecc,然后我减去它的偏移量以获得库的基地址。
我这样做是为了 printf、put 和 signal,但每次我得到一个不同的基地址。
thispost里的东西我也试过了,但是也没得到正确的结果
ASLR 已禁用。
这是我取库函数地址的地方:
gdb-peda$ x/20wx 0x804b018
0x804b018 <signal@got.plt>: 0xf7e05720 0xf7e97010 0x080484e6 0x080484f6
0x804b028 <puts@got.plt>: 0xf7e3fb40 0x08048516 0x08048526 0xf7df0d90
0x804b038 <memset@got.plt>: 0xf7f18730 0x08048556 0x08048566 0x00000000
那么我有:
gdb-peda$ info proc mapping
process 114562
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x804a000 0x2000 0x0 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804a000 0x804b000 0x1000 0x1000 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804b000 0x804c000 0x1000 0x2000 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804c000 0x806e000 0x22000 0x0 [heap]
0xf7dd8000 0xf7fad000 0x1d5000 0x0 /lib/i386-linux-gnu/libc-2.27.so
0xf7fad000 0xf7fae000 0x1000 0x1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fae000 0xf7fb0000 0x2000 0x1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb0000 0xf7fb1000 0x1000 0x1d7000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb1000 0xf7fb4000 0x3000 0x0
0xf7fd0000 0xf7fd2000 0x2000 0x0
0xf7fd2000 0xf7fd5000 0x3000 0x0 [vvar]
0xf7fd5000 0xf7fd6000 0x1000 0x0 [vdso]
0xf7fd6000 0xf7ffc000 0x26000 0x0 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffc000 0xf7ffd000 0x1000 0x25000 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffd000 0xf7ffe000 0x1000 0x26000 /lib/i386-linux-gnu/ld-2.27.so
0xfffdd000 0xffffe000 0x21000 0x0 [stack]
和:
gdb-peda$ info sharedlibrary
From To Syms Read Shared Object Library
0xf7fd6ab0 0xf7ff17fb Yes /lib/ld-linux.so.2
0xf7df0610 0xf7f3d386 Yes /lib/i386-linux-gnu/libc.so.6
然后我找到了信号的偏移量并计算了libc的基地址。
base_with_signal_offset = 0xf7e05720 - 0x3eda0 = 0xf7dc6980
base_with_puts_offset = 0xf7e3fb40 - 0x809c0 = 0xf7dbf180
我期待 base_with_signal_offset = base_with_puts_offset = 0xf7dd8000
,但事实并非如此。
我做错了什么?
编辑(让您了解我在哪里得到这些偏移量):
readelf -s /lib/x86_64-linux-gnu/libc-2.27.so | grep puts
我得到:
191: 00000000000809c0 512 FUNC GLOBAL DEFAULT 13 _IO_puts@@GLIBC_2.2.5
422: 00000000000809c0 512 FUNC WEAK DEFAULT 13 puts@@GLIBC_2.2.5
496: 00000000001266c0 1240 FUNC GLOBAL DEFAULT 13 putspent@@GLIBC_2.2.5
678: 00000000001285d0 750 FUNC GLOBAL DEFAULT 13 putsgent@@GLIBC_2.10
1141: 000000000007f1f0 396 FUNC WEAK DEFAULT 13 fputs@@GLIBC_2.2.5
1677: 000000000007f1f0 396 FUNC GLOBAL DEFAULT 13 _IO_fputs@@GLIBC_2.2.5
2310: 000000000008a640 143 FUNC WEAK DEFAULT 13 fputs_unlocked@@GLIBC_2.2.5
I was expecting base_with_signal_offset = base_with_puts_offset = 0xf7dd8000
您的计算中有 3 个数字:
&puts_at_runtime - symbol_value_from_readelf == &first_executable_pt_load_segment_libc.
readelf
输出显示您得到其中一个 almost 正确:puts
在 64 位 /lib/x86_64-linux-gnu/libc-2.27.so
中的值是确实 0x809c0
,但那是 而不是 您实际使用的库。您需要在 实际使用的 32 位库上重复相同的操作:/lib/i386-linux-gnu/libc-2.27.so
.
对于第一个数字 -- &puts_at_runtime,您正在使用来自 puts@got.plt
导入存根的值。该值只能保证已被解析(指向 libc.so
中的实际 puts
)如果您在环境中设置了 LD_BIND_NOW=1
,或者您将可执行文件与 -z now
链接器链接标记,或者您实际上已经调用了 puts
。
在 GDB 中 print &puts
可能更好。
最后一个数字 -- &first_executable_pt_load_segment_libc 是正确的(因为 info shared
表明 libc.so.6
.text
部分从 0xf7df0610
开始,它介于 0xf7dd8000
和 0xf7fad000
.
所以把它们放在一起,唯一的错误是你使用了错误版本的 libc.so
来提取 symbol_value_from_readelf。
在我的系统上:
#include <signal.h>
#include <stdio.h>
int main() {
puts("Hello");
signal(SIGINT, SIG_IGN);
return 0;
}
gcc -m32 t.c -fno-pie -no-pie
gdb -q a.out
... set breakpoint on exit from main
Breakpoint 1, 0x080491ae in main ()
(gdb) p &puts
= (<text variable, no debug info> *) 0xf7e31300 <puts>
(gdb) p &signal
= (<text variable, no debug info> *) 0xf7df7d20 <ssignal>
(gdb) info proc map
process 114065
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /tmp/a.out
...
0x804d000 0x806f000 0x22000 0x0 [heap]
0xf7dc5000 0xf7de2000 0x1d000 0x0 /lib/i386-linux-gnu/libc-2.29.so
...
(gdb) info shared
From To Syms Read Shared Object Library
0xf7fd5090 0xf7ff0553 Yes (*) /lib/ld-linux.so.2
0xf7de20e0 0xf7f2b8d6 Yes (*) /lib/i386-linux-gnu/libc.so.6
鉴于以上,我们期望 readelf -s
分别为 puts
和 0xf7df7d20 - 0xf7dc5000 == 0x32d20
提供 0xf7e31300 - 0xf7dc5000 ==
0x6c300
和 signal
。
readelf -Ws /lib/i386-linux-gnu/libc-2.29.so | egrep ' (puts|signal)\W'
452: 00032d20 68 FUNC WEAK DEFAULT 14 signal@@GLIBC_2.0
458: 0006c300 400 FUNC WEAK DEFAULT 14 puts@@GLIBC_2.0
QED.
我正在尝试计算二进制文件库的基地址。 我有 printf 的地址,puts ecc,然后我减去它的偏移量以获得库的基地址。 我这样做是为了 printf、put 和 signal,但每次我得到一个不同的基地址。 thispost里的东西我也试过了,但是也没得到正确的结果
ASLR 已禁用。
这是我取库函数地址的地方:
gdb-peda$ x/20wx 0x804b018
0x804b018 <signal@got.plt>: 0xf7e05720 0xf7e97010 0x080484e6 0x080484f6
0x804b028 <puts@got.plt>: 0xf7e3fb40 0x08048516 0x08048526 0xf7df0d90
0x804b038 <memset@got.plt>: 0xf7f18730 0x08048556 0x08048566 0x00000000
那么我有:
gdb-peda$ info proc mapping
process 114562
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x804a000 0x2000 0x0 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804a000 0x804b000 0x1000 0x1000 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804b000 0x804c000 0x1000 0x2000 /home/ofey/CTF/Pwnable.tw/applestore/applestore
0x804c000 0x806e000 0x22000 0x0 [heap]
0xf7dd8000 0xf7fad000 0x1d5000 0x0 /lib/i386-linux-gnu/libc-2.27.so
0xf7fad000 0xf7fae000 0x1000 0x1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fae000 0xf7fb0000 0x2000 0x1d5000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb0000 0xf7fb1000 0x1000 0x1d7000 /lib/i386-linux-gnu/libc-2.27.so
0xf7fb1000 0xf7fb4000 0x3000 0x0
0xf7fd0000 0xf7fd2000 0x2000 0x0
0xf7fd2000 0xf7fd5000 0x3000 0x0 [vvar]
0xf7fd5000 0xf7fd6000 0x1000 0x0 [vdso]
0xf7fd6000 0xf7ffc000 0x26000 0x0 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffc000 0xf7ffd000 0x1000 0x25000 /lib/i386-linux-gnu/ld-2.27.so
0xf7ffd000 0xf7ffe000 0x1000 0x26000 /lib/i386-linux-gnu/ld-2.27.so
0xfffdd000 0xffffe000 0x21000 0x0 [stack]
和:
gdb-peda$ info sharedlibrary
From To Syms Read Shared Object Library
0xf7fd6ab0 0xf7ff17fb Yes /lib/ld-linux.so.2
0xf7df0610 0xf7f3d386 Yes /lib/i386-linux-gnu/libc.so.6
然后我找到了信号的偏移量并计算了libc的基地址。
base_with_signal_offset = 0xf7e05720 - 0x3eda0 = 0xf7dc6980
base_with_puts_offset = 0xf7e3fb40 - 0x809c0 = 0xf7dbf180
我期待 base_with_signal_offset = base_with_puts_offset = 0xf7dd8000
,但事实并非如此。
我做错了什么?
编辑(让您了解我在哪里得到这些偏移量):
readelf -s /lib/x86_64-linux-gnu/libc-2.27.so | grep puts
我得到:
191: 00000000000809c0 512 FUNC GLOBAL DEFAULT 13 _IO_puts@@GLIBC_2.2.5
422: 00000000000809c0 512 FUNC WEAK DEFAULT 13 puts@@GLIBC_2.2.5
496: 00000000001266c0 1240 FUNC GLOBAL DEFAULT 13 putspent@@GLIBC_2.2.5
678: 00000000001285d0 750 FUNC GLOBAL DEFAULT 13 putsgent@@GLIBC_2.10
1141: 000000000007f1f0 396 FUNC WEAK DEFAULT 13 fputs@@GLIBC_2.2.5
1677: 000000000007f1f0 396 FUNC GLOBAL DEFAULT 13 _IO_fputs@@GLIBC_2.2.5
2310: 000000000008a640 143 FUNC WEAK DEFAULT 13 fputs_unlocked@@GLIBC_2.2.5
I was expecting base_with_signal_offset = base_with_puts_offset = 0xf7dd8000
您的计算中有 3 个数字:
&puts_at_runtime - symbol_value_from_readelf == &first_executable_pt_load_segment_libc.
readelf
输出显示您得到其中一个 almost 正确:puts
在 64 位 /lib/x86_64-linux-gnu/libc-2.27.so
中的值是确实 0x809c0
,但那是 而不是 您实际使用的库。您需要在 实际使用的 32 位库上重复相同的操作:/lib/i386-linux-gnu/libc-2.27.so
.
对于第一个数字 -- &puts_at_runtime,您正在使用来自 puts@got.plt
导入存根的值。该值只能保证已被解析(指向 libc.so
中的实际 puts
)如果您在环境中设置了 LD_BIND_NOW=1
,或者您将可执行文件与 -z now
链接器链接标记,或者您实际上已经调用了 puts
。
在 GDB 中 print &puts
可能更好。
最后一个数字 -- &first_executable_pt_load_segment_libc 是正确的(因为 info shared
表明 libc.so.6
.text
部分从 0xf7df0610
开始,它介于 0xf7dd8000
和 0xf7fad000
.
所以把它们放在一起,唯一的错误是你使用了错误版本的 libc.so
来提取 symbol_value_from_readelf。
在我的系统上:
#include <signal.h>
#include <stdio.h>
int main() {
puts("Hello");
signal(SIGINT, SIG_IGN);
return 0;
}
gcc -m32 t.c -fno-pie -no-pie
gdb -q a.out
... set breakpoint on exit from main
Breakpoint 1, 0x080491ae in main ()
(gdb) p &puts
= (<text variable, no debug info> *) 0xf7e31300 <puts>
(gdb) p &signal
= (<text variable, no debug info> *) 0xf7df7d20 <ssignal>
(gdb) info proc map
process 114065
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0x0 /tmp/a.out
...
0x804d000 0x806f000 0x22000 0x0 [heap]
0xf7dc5000 0xf7de2000 0x1d000 0x0 /lib/i386-linux-gnu/libc-2.29.so
...
(gdb) info shared
From To Syms Read Shared Object Library
0xf7fd5090 0xf7ff0553 Yes (*) /lib/ld-linux.so.2
0xf7de20e0 0xf7f2b8d6 Yes (*) /lib/i386-linux-gnu/libc.so.6
鉴于以上,我们期望 readelf -s
分别为 puts
和 0xf7df7d20 - 0xf7dc5000 == 0x32d20
提供 0xf7e31300 - 0xf7dc5000 ==
0x6c300
和 signal
。
readelf -Ws /lib/i386-linux-gnu/libc-2.29.so | egrep ' (puts|signal)\W'
452: 00032d20 68 FUNC WEAK DEFAULT 14 signal@@GLIBC_2.0
458: 0006c300 400 FUNC WEAK DEFAULT 14 puts@@GLIBC_2.0
QED.