Я ожидал, что base_with_signal_offset = base_with_puts_offset = 0xf7dd8000
В ваших вычислениях есть 3 числа:
&puts_at_runtime - symbol_value_from_readelf == &first_executable_pt_load_segment_libc.
Вывод readelf
показывает, что вы получили один из них почти правильно: значение puts
в 64-битном /lib/x86_64-linux-gnu/libc-2.27.so
действительно 0x809c0
, но это , а не библиотека, которую вы фактически используете. Вам нужно повторить то же самое для фактически используемой 32-битной библиотеки: /lib/i386-linux-gnu/libc-2.27.so
.
Для первого числа - & put_at_runtime вы используете значение из заглушки импорта puts@got.plt
, Это значение гарантированно будет разрешено только (указывают на фактическое значение puts
в libc.so
), если у вас установлено LD_BIND_NOW=1
в среде, или вы связали свой исполняемый файл с флагом компоновщика -z now
, или вы фактически вызвали puts
уже.
Может быть лучше print &puts
в ГБД.
Последний номер - & first_executable_pt_load_segment_lib c правильный (потому что 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
$1 = (<text variable, no debug info> *) 0xf7e31300 <puts>
(gdb) p &signal
$2 = (<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
даст нам 0xf7e31300 - 0xf7dc5000 ==
0x6c300
для puts
и 0xf7df7d20 - 0xf7dc5000 == 0x32d20
для 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
КЭД.