2016-06-22 32 views
0

Ich studiere den Haufen Glibc.Warum gibt es in der libc.so-Symboltabelle keine main_arena, während es in malloc.c von glibc2.23 eine gibt?

Es gibt kein main_arena-Symbol in libc.so, auch wenn ich versuche, es mit pwntool auszugeben. Wenn ich jedoch ein Testprogramm debugge, kann ich die main_arena-Struktur drucken.

gdb-peda$ p main_arena 
$1 = { 
    mutex = 0x0, 
    flags = 0x0, 
    fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 
    top = 0x0, 
    last_remainder = 0x0, 
    bins = {0x0 <repeats 254 times>}, 
    binmap = {0x0, 0x0, 0x0, 0x0}, 
    next = 0x7ffff7dd1b20 <main_arena>, 
    next_free = 0x0, 
    attached_threads = 0x1, 
    system_mem = 0x0, 
    max_system_mem = 0x0 
} 

Und außerdem, wenn ich Testprogramm mit -m32 kompiliere, kann main_arena auch nicht gefunden werden.

Antwort

2

main_arena ist ein lokales Symbol und ist speziell nicht exportiert. Die Liste der exportierten Symbole wird über die Dateien Version im glibc-Quellenbaum gesteuert. Dies ist vom Design her dazu gedacht, die Leute davon abzuhalten, mit zufälligen Symbolen, die glibc intern verwendet, in Verbindung zu treten (um den Namespace nicht zu belasten, wie es von POSIX und anderen Standards gefordert wird).

gdb kann es finden, weil Sie Debug-Symbole zur Verfügung haben ... Entweder die C lib wird nicht entfernt, oder Sie haben die geteilten Debug-Symbole in /usr/lib/debug/ und gdb findet diese. wenn Sie gdb starten, werden Sie Dinge wie Reading symbols from /usr/lib/debug/xxxxx sagen.

Die einzige Möglichkeit, eine Verknüpfung mit dem Symbol herzustellen, besteht darin, glibc aus der Quelle neu zu erstellen und die Exportliste zu ändern.

Alternativ könnten Sie Code in Ihre App schreiben, um sich wie gdb zu verhalten. Öffnen Sie die Debug-Datei, verarbeiten Sie die darin enthaltenen ELF/DWARF-Informationen, wenden Sie die Umlagerungen mithilfe der aktiv geladenen Bibliotheksinformationen an (siehe dl_iterate_phdr) und starten Sie dann den Speicher direkt.

Wenn das zu viel Arbeit ist, könnte eine Hackerlösung fork() + popen() gdb gegen Ihren eigenen Prozess sein und es im Stapelmodus ausführen, um Symbolinformationen auszugeben.

char *cmd; 
FILE *fp; 

asprintf(&cmd, "gdb -q -p %i -batch -ex 'p &main_arena'", getpid()); 
fp = popen(cmd, "r"); 
// parse the output of |fp| here looking for the address. 

free(cmd); 
fclose(fp); 
+0

Vielen Dank. Das ist eine sehr tiefe Antwort! –

0

Die libc.so.6 ist entfernt. Und die Debug-Version ist es nicht. Deshalb zeigt readelf main_arena nicht an.

Ich frage mich immer noch, wie gdb den Symbolnamen kennt, auch wenn die Bibliothek entfernt wird.

+0

es ist nicht nur eine Frage des Strippings - 'main_arena' nicht * * exportiert wird, so dass auch mit einer unstripped Version, Sie können nicht gegen sie verbinden (mit Absicht). Wenn Sie sich die glibc-Quelle ansehen, definieren alle 'Versions'-Dateien die Exporttabelle. Aus welchem ​​Grund gdb es finden kann, haben Sie möglicherweise Debug-Symbole für die C-Bibliothek verfügbar. –

+0

Danke! Ich weiß jetzt, dass das Versionsskript von ld exportierte Symbole spezifizieren kann. Und nachdem ich das libc6-dbg-Paket entfernt habe, identifiziert gdb main_arena nicht mehr. Noch eine Sache, die ich verwirrt bin, 'so sogar mit einer unstripped-Version, können Sie nicht dagegen binden', wenn ich' readelf -s /usr/lib/debug/lib/x86_64-linux-gnu/libc-2.23. so | grep main_arena', bekomme ich '896: 00000000003c3b20 2192 OBJEKT LOKALER STANDARD 33 main_arena' –