1

I am trying to find the address of a function in libc.

I know I can do something like this in C:

printf("%x", (int) system);

But I don't know if that gives me the base address of the system function in libc. I assume it gives some sort of indirect pointer from within the program?

I am running gdb and did:

info files

while running the program, but it gave me many segments and I am not sure where to look, other than the ones that have libc.so in them?

Edit:

This is what I get in gdb, and I am wondering where in here I would be able to find something like "system", "printf", "exit", etc. I checked rodata and was able to find system there, but I don't know if that's the function itself:

    0x08048154 - 0x08048167 is .interp
    0x08048168 - 0x08048188 is .note.ABI-tag
    0x08048188 - 0x080481ac is .note.gnu.build-id
    0x080481ac - 0x080481d0 is .gnu.hash
    0x080481d0 - 0x08048290 is .dynsym
    0x08048290 - 0x08048326 is .dynstr
    0x08048326 - 0x0804833e is .gnu.version
    0x08048340 - 0x08048380 is .gnu.version_r
    0x08048380 - 0x08048388 is .rel.dyn
    0x08048388 - 0x080483d8 is .rel.plt
    0x080483d8 - 0x080483fb is .init
    0x08048400 - 0x080484b0 is .plt
    0x080484b0 - 0x08048892 is .text
    0x08048894 - 0x080488a8 is .fini
    0x080488a8 - 0x08048994 is .rodata
    0x08048994 - 0x080489c8 is .eh_frame_hdr
    0x080489c8 - 0x08048a98 is .eh_frame
    0x08049f08 - 0x08049f0c is .init_array
    0x08049f0c - 0x08049f10 is .fini_array
    0x08049f10 - 0x08049f14 is .jcr
---Type <return> to continue, or q <return> to quit---
    0x08049f14 - 0x08049ffc is .dynamic
    0x08049ffc - 0x0804a000 is .got
    0x0804a000 - 0x0804a034 is .got.plt
    0x0804a034 - 0x0804a03c is .data
    0x0804a03c - 0x0804a054 is .bss
    0xb7fde114 - 0xb7fde138 is .note.gnu.build-id in /lib/ld-linux.so.2
    0xb7fde138 - 0xb7fde1f8 is .hash in /lib/ld-linux.so.2
    0xb7fde1f8 - 0xb7fde2dc is .gnu.hash in /lib/ld-linux.so.2
    0xb7fde2dc - 0xb7fde4ac is .dynsym in /lib/ld-linux.so.2
    0xb7fde4ac - 0xb7fde642 is .dynstr in /lib/ld-linux.so.2
    0xb7fde642 - 0xb7fde67c is .gnu.version in /lib/ld-linux.so.2
    0xb7fde67c - 0xb7fde744 is .gnu.version_d in /lib/ld-linux.so.2
    0xb7fde744 - 0xb7fde7b4 is .rel.dyn in /lib/ld-linux.so.2
    0xb7fde7b4 - 0xb7fde7e4 is .rel.plt in /lib/ld-linux.so.2
    0xb7fde7f0 - 0xb7fde860 is .plt in /lib/ld-linux.so.2
    0xb7fde860 - 0xb7ff67ac is .text in /lib/ld-linux.so.2
    0xb7ff67c0 - 0xb7ffa7a0 is .rodata in /lib/ld-linux.so.2
    0xb7ffa7a0 - 0xb7ffae24 is .eh_frame_hdr in /lib/ld-linux.so.2
    0xb7ffae24 - 0xb7ffd71c is .eh_frame in /lib/ld-linux.so.2
    0xb7ffecc0 - 0xb7ffef34 is .data.rel.ro in /lib/ld-linux.so.2
    0xb7ffef34 - 0xb7ffefec is .dynamic in /lib/ld-linux.so.2
    0xb7ffefec - 0xb7ffeff8 is .got in /lib/ld-linux.so.2
    0xb7fff000 - 0xb7fff024 is .got.plt in /lib/ld-linux.so.2
---Type <return> to continue, or q <return> to quit---
    0xb7fff040 - 0xb7fff878 is .data in /lib/ld-linux.so.2
    0xb7fff878 - 0xb7fff938 is .bss in /lib/ld-linux.so.2
    0xb7e16174 - 0xb7e16198 is .note.gnu.build-id in /lib/i386-linux-gnu/libc.so.6
    0xb7e16198 - 0xb7e161b8 is .note.ABI-tag in /lib/i386-linux-gnu/libc.so.6
    0xb7e161b8 - 0xb7e19ec8 is .gnu.hash in /lib/i386-linux-gnu/libc.so.6
    0xb7e19ec8 - 0xb7e23438 is .dynsym in /lib/i386-linux-gnu/libc.so.6
    0xb7e23438 - 0xb7e2915e is .dynstr in /lib/i386-linux-gnu/libc.so.6
    0xb7e2915e - 0xb7e2a40c is .gnu.version in /lib/i386-linux-gnu/libc.so.6
    0xb7e2a40c - 0xb7e2a898 is .gnu.version_d in /lib/i386-linux-gnu/libc.so.6
    0xb7e2a898 - 0xb7e2a8d8 is .gnu.version_r in /lib/i386-linux-gnu/libc.so.6
    0xb7e2a8d8 - 0xb7e2d2e8 is .rel.dyn in /lib/i386-linux-gnu/libc.so.6
    0xb7e2d2e8 - 0xb7e2d348 is .rel.plt in /lib/i386-linux-gnu/libc.so.6
    0xb7e2d350 - 0xb7e2d420 is .plt in /lib/i386-linux-gnu/libc.so.6
    0xb7e2d420 - 0xb7f5eb6e is .text in /lib/i386-linux-gnu/libc.so.6
    0xb7f5eb70 - 0xb7f5fafb is __libc_freeres_fn in /lib/i386-linux-gnu/libc.so.6
    0xb7f5fb00 - 0xb7f5fcfe is __libc_thread_freeres_fn in /lib/i386-linux-gnu/libc.so.6
---Type <return> to continue, or q <return> to quit---
    0xb7f5fd00 - 0xb7f81754 is .rodata in /lib/i386-linux-gnu/libc.so.6
    0xb7f81754 - 0xb7f81767 is .interp in /lib/i386-linux-gnu/libc.so.6
    0xb7f81768 - 0xb7f88c0c is .eh_frame_hdr in /lib/i386-linux-gnu/libc.so.6
    0xb7f88c0c - 0xb7fb9f68 is .eh_frame in /lib/i386-linux-gnu/libc.so.6
    0xb7fb9f68 - 0xb7fba3c6 is .gcc_except_table in /lib/i386-linux-gnu/libc.so.6
    0xb7fba3c8 - 0xb7fbd928 is .hash in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe1d4 - 0xb7fbe1dc is .tdata in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe1dc - 0xb7fbe220 is .tbss in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe1dc - 0xb7fbe1e8 is .init_array in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe1e8 - 0xb7fbe260 is __libc_subfreeres in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe260 - 0xb7fbe264 is __libc_atexit in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe264 - 0xb7fbe274 is __libc_thread_subfreeres in /lib/i386-linux-gnu/libc.so.6
    0xb7fbe280 - 0xb7fbfda8 is .data.rel.ro in /lib/i386-linux-gnu/libc.so.6
    0xb7fbfda8 - 0xb7fbfe98 is .dynamic in /lib/i386-linux-gnu/libc.so.6
    0xb7fbfe98 - 0xb7fbfff4 is .got in /lib/i386-linux-gnu/libc.so.6
    0xb7fc0000 - 0xb7fc003c is .got.plt in /lib/i386-linux-gnu/libc.so.6
    0xb7fc0040 - 0xb7fc0ebc is .data in /lib/i386-linux-gnu/libc.so.6
Skorpius
  • 2,135
  • 2
  • 26
  • 31
  • 1
    Converting pointers to `int` is always wrong. Function pointers are even more special because there are architectures where they don't convert to integer types or even `void*` at all. But in all your question sounds like an XY problem. You are asking for X but you want Y. What are you really trying to achieve? – Jens Gustedt Aug 29 '15 at 16:33
  • 2
    to printf a pointer, use the '%p' format specifier, That is what it is made for. – user3629249 Aug 29 '15 at 16:36
  • only the functions used from a library are actually in the linked/executable code. Their address could be anywhere within the memory space of the executable code. What is output by your printf() has nothing to do with where the function is located in the library. – user3629249 Aug 29 '15 at 16:38
  • @Skorpius have you tried my suggestion? – 4pie0 Aug 29 '15 at 16:55
  • I find your question unclear. I tried to guess what you really meant and gave my answer. – Basile Starynkevitch Aug 29 '15 at 17:03

2 Answers2

1

This is how you can find address of function mapped into your executable.

$ gdb program 
Reading symbols from ...done.
(gdb) print main
$1 = {int (int, char **)} 0x400d61 <main>
(gdb) print exit
$2 = {<text variable, no debug info>} 0x400910 <exit@plt>
4pie0
  • 29,204
  • 9
  • 82
  • 118
0

It might be implementation specific. I'm focusing on Linux. You probably want

printf("system@%p\n", (void*)system);

and that does gives you the address of the system function. You could store it in a function pointer:

int (*funptr)(const char*) = system;

then a later call to (*funptr)("date") behave the same as system("date") so system (or the value inside funptr) is the system(3) function of libc.

Pedantically the C standard does not guarantee that a function pointer fits into a generic void* (so stricto sensu my printf could be wrong); in practice, on Linux and POSIX, it does fit.

If you want to programmatically find the address of some function from its name at runtime, use dlsym(3), perhaps on the program handle obtained by passing NULL to dlopen(3) (and on Linux with GNU libc, dladdr(3) is doing the opposite transformation). You might want to link your program with -rdynamic and learn more about plugins and dynamic loading.

However (on Linux), the C standard library might be (and often is) a shared library (ELF shared object) libc.so, and system might point to a Procedure Linkage Table entry (see the chapter 10 of Levine's book on Linkers and Loaders); A PLT entry is a jump to the first real instruction of a function. See this answer and references about ELF shared objects.

Community
  • 1
  • 1
Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547