2015-08-29 3 views
0

Я пытаюсь найти адрес функции в libc.Где я могу найти конкретные адреса функций в объектных файлах libc?

Я знаю, что могу сделать что-то подобное в C:

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

Но я не знаю, если это дает мне базовый адрес системной функции в LIBC. Я предполагаю, что он дает какой-то косвенный указатель изнутри программы?

Я бегу GDB и сделал:

info files 

во время выполнения программы, но это дало мне много сегментов, и я не знаю, где искать, кроме тех, которые имеют libc.so в них?

Edit:

Это то, что я получаю в БГД, и мне интересно, где здесь я мог бы найти что-то вроде «системы», «Printf», «выход» и т.д. Я проверил rodata и был в состоянии найти систему, но я не знаю, если это сама функция:

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 
+1

Преобразование указателей в 'int' всегда неверно. Указатели функций еще более особенны, поскольку существуют архитектуры, в которых они не конвертируются в целые типы или даже «void *». Но во всех ваших вопросах звучит как проблема XY. Вы просите X, но вы хотите Y. Чего вы действительно пытаетесь достичь? –

+2

, чтобы напечатать указатель, используйте спецификатор формата «% p», для чего он создан. – user3629249

+0

только функции, используемые из библиотеки, фактически находятся в связанном/исполняемом коде. Их адрес может быть в любом месте в пространстве памяти исполняемого кода. То, что выводится вашим printf(), не имеет ничего общего с тем, где функция находится в библиотеке. – user3629249

ответ

1

Это, как вы можете найти адрес функции, отображенные в исполняемый.

$ 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 <[email protected]> 
+0

Но OP хочет найти * programaticcaly * адрес функций –

+0

Нигде не было сказано. Я думаю, что конечная цель - знать этот адрес. – 4pie0

+0

После редактирования видно, что ИМО. – 4pie0

0

Это может быть конкретная реализация. Я сосредоточен на Linux. Вы, вероятно, хотите

printf("[email protected]%p\n", (void*)system); 

и что делает дает адрес функции system. Вы можете хранить его в указатель на функцию:

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

затем позже вызов (*funptr)("date") вести себя так же, как system("date") так system (или значение внутри funptr) являетсяsystem(3) функция libc.

Педантично стандарт C не гарантирует, что указатель функции вписывается в общий void* (так в строгом смысле мой printf может быть неправильно); на практике, в Linux и POSIX, он подходит.

Если вы хотите программно найти адрес некоторой функции от его имени во время выполнения, используйте dlsym(3), возможно по программе ручки, полученному при пропускании NULL к dlopen(3) (и на Linux с GNU LIBC, dladdr(3) делает противоположное преобразование). Вы можете связать свою программу с -rdynamic и узнать больше о plugins и dynamic loading.

Однако (на Linux), то C standard library может быть (и часто) разделяемая библиотека (ELF разделяемый объект) libc.so и system может указывать на Procedure Linkage Table запись (см the chapter 10 книги Левина на линкеров и погрузчиков) ; Запись PLT представляет собой переход к первой реальной инструкции функции. См. this ответ и ссылки об общих объектах ELF.