2

I'm trying to calculate the base address of the library of a binary file. I have the address of printf, puts ecc and then I subtract it's offset to get the base address of the library. I was doing this for printf, puts and signal, but every time I got a different base address. I also tried to do the things in this post, but I couldn't get the right result either.

ASLR is disabled.

this is where I take the address of the library function:

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

then I have:

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]

and :

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

I then found the offset of signal and puts to calculate the base libc address.

base_with_signal_offset = 0xf7e05720 - 0x3eda0 =  0xf7dc6980
base_with_puts_offset = 0xf7e3fb40 - 0x809c0 = 0xf7dbf180

I was expecting base_with_signal_offset = base_with_puts_offset = 0xf7dd8000, but that's not the case. What I'm doing wrong? EDIT(To let you understand where I got those offset):

readelf -s /lib/x86_64-linux-gnu/libc-2.27.so  | grep puts

I get :

    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
malloc
  • 313
  • 2
  • 10
  • You are subtracting effectively random numbers. I can see where `0xf7e05720 ` and `0xf7e3fb40 ` came from (they are the wrong numbers to use), but have no idea where `0x3eda0 ` and `0x809c0 ` came from. Please edit your question to show the origin of the last two. – Employed Russian May 01 '20 at 14:05
  • @EmployedRussian I hope that now is more clear – malloc May 01 '20 at 14:11

1 Answers1

2

I was expecting base_with_signal_offset = base_with_puts_offset = 0xf7dd8000

There are 3 numbers in your calculation:

&puts_at_runtime - symbol_value_from_readelf == &first_executable_pt_load_segment_libc.

The readelf output shows that you got one of these almost correct: the value of puts in 64-bit /lib/x86_64-linux-gnu/libc-2.27.so is indeed 0x809c0, but that is not the library you are actually using. You need to repeat the same on the actually used 32-bit library: /lib/i386-linux-gnu/libc-2.27.so.

For the first number -- &puts_at_runtime, you are using value from the puts@got.plt import stub. That value is only guaranteed to have been resolved (point to actual puts in libc.so) IFF you have LD_BIND_NOW=1 set in the environment, or you linked your executable with -z now linker flag, or you actually called puts already.

It may be better to print &puts in GDB.

The last number -- &first_executable_pt_load_segment_libc is correct (because info shared shows that libc.so.6 .text section starts at 0xf7df0610, which is between 0xf7dd8000 and 0xf7fad000.

So putting it all together, the only error was that you used the wrong version of libc.so to extract the symbol_value_from_readelf.

On my system:

#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

Given above, we expect readelf -s to give us 0xf7e31300 - 0xf7dc5000 == 0x6c300 for puts and 0xf7df7d20 - 0xf7dc5000 == 0x32d20 for signal respectively.

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.

Employed Russian
  • 199,314
  • 34
  • 295
  • 362
  • Thank you, I was stuck on this for 2 days and it was just a distraction error. Running `print &puts` got me the same address of before (0xf7e3fb40), instead running `info func puts` got me a list of things (like File iofputs_u.c: .....) and at the end Non-debugging symbols: 0x0848500 puts@plt I don't know about this last thing but I think that my way to get the address of puts is correct. The segment seems to be correct but `readelf -Wl /lib/i386-linux-gnu/libc-2.27.so | grep PT_LOAD` doesn't show anything. `info shared` and ` info proc mapping` came from the same run. – malloc May 01 '20 at 16:17
  • I don't know why `info shared` got me those address. – malloc May 01 '20 at 16:19
  • I have a file called libc_32.so.6 in the same folder of the binary but I don't think that this could be the cause of that. – malloc May 01 '20 at 16:19