【问题标题】:Loaded glibc base address different for each function每个函数加载的 glibc 基地址不同
【发布时间】:2020-08-15 22:43:02
【问题描述】:

我正在尝试计算二进制文件库的基地址。 我有 printf 的地址,放入 ecc 然后我减去它的偏移量以获得库的基地址。 我正在为 printf、puts 和 signal 执行此操作,但每次我得到一个不同的基地址。 我也尝试过this帖子中的事情,但我也无法得到正确的结果。

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

然后我找到了信号的偏移量,并用puts计算了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

【问题讨论】:

  • 您正在有效地减去随机数。我可以看到0xf7e05720 0xf7e3fb40 来自哪里(它们是错误的数字),但不知道0x3eda0 0x809c0 来自哪里。请编辑您的问题以显示最后两个问题的来源。
  • @EmployedRussian 我希望现在更清楚

标签: linux reverse-engineering glibc dynamic-linking


【解决方案1】:

我期待 base_with_signal_offset = base_with_puts_offset = 0xf7dd8000

您的计算中有 3 个数字:

&puts_at_runtime - symbol_value_from_readelf == &first_executable_pt_load_segment_libc.

readelf 输出表明您得到了其中一个几乎正确:64 位 /lib/x86_64-linux-gnu/libc-2.27.soputs 的值确实是 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 链接器标志链接在一起,或者您实际上调用了@987654332 @已经。

在 GDB 中print &amp;puts 可能会更好。

最后一个数字 -- &first_executable_pt_load_segment_libc 是正确的(因为info shared 表明libc.so.6 .text 部分从0xf7df0610 开始,介于0xf7dd80000xf7fad000 之间。

综上所述,唯一的错误是您使用了错误版本的 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 分别为 puts0xf7df7d20 - 0xf7dc5000 == 0x32d20signal 提供 0xf7e31300 - 0xf7dc5000 == 0x6c300

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。

【讨论】:

  • 谢谢,我在这个问题上卡了 2 天,这只是一个分散注意力的错误。运行print &amp;puts 得到了与之前相同的地址(0xf7e3fb40),而不是运行info func puts 得到了一个列表(如 File iofputs_u.c: .....),最后非调试符号:0x0848500 puts @plt我不知道最后一件事,但我认为我获取 puts 地址的方法是正确的。该段似乎是正确的,但 readelf -Wl /lib/i386-linux-gnu/libc-2.27.so | grep PT_LOAD 没有显示任何内容。 info shared 和 `info proc mapping` 来自同一次运行。
  • 我不知道为什么info shared 给了我这些地址。
  • 我在二进制文件的同一个文件夹中有一个名为 libc_32.so.6 的文件,但我认为这不是原因。
猜你喜欢
  • 2021-01-07
  • 2013-03-20
  • 2016-04-27
  • 2016-02-08
  • 2014-09-19
  • 2019-04-05
  • 2014-09-04
  • 2021-12-18
  • 2018-08-31
相关资源
最近更新 更多