2012-06-02 12 views
8

Ich versuche, den richtigen Offset zum Abschnitt Name durch Zugriff auf die Mitglied einer Elf-Datei, aber es geben mir Null oder Null ...Abrufen der sh_name Mitglied in einem Abschnitt Header Elf-Datei

ich soll nur mmap() verwenden und die elf.h - keine Hilfsfunktionen

Also habe ich:

void* map_start = mmap(0, fd_stat.st_size, PROT_READ | PROT_WRITE , MAP_SHARED, fd, 0)) 
header = (Elf32_Ehdr *) map_start; 
secoff = header->e_shoff;  
section = (Elf32_Shdr *)(map_start + secoff); 

aber wenn ich tun:

printf("name offset = %d\n", (section->sh_name)); 

es hält mich 0 ... was mache ich falsch?

Antwort

14

wenn ich mache printf("name offset = %d\n", (section->sh_name)); es hält mich 0 ... was mache ich falsch?

Sie tun nicht irgendetwas falsch.

Die ist kein Zeiger, es ist ein Offset in .shstrtab Abschnitt, der den tatsächlichen Abschnittsname enthält.

Sie können den .shstrtab Abschnitt von header->e_shstrndx finden.

Update:

nicht wahr nehme den Offset als int zu drucken?

Es druckt 0. Was hat dich dazu gebracht zu glauben, dass 0 kein int ist?

aber von drucke ich den Namen?

Vielleicht wird dieses Beispiel erklären?

#include <sys/stat.h> 
#include <sys/mman.h> 
#include <elf.h> 
#include <stdio.h> 
#include <fcntl.h> 


int print_shdr(const char *const fname, size_t size) { 
    int fd = open(fname, O_RDONLY); 
    char *p = mmap(0, size, PROT_READ, MAP_PRIVATE, fd, 0); 

    Elf32_Ehdr *ehdr = (Elf32_Ehdr*)p; 
    Elf32_Shdr *shdr = (Elf32_Shdr *)(p + ehdr->e_shoff); 
    int shnum = ehdr->e_shnum; 

    Elf32_Shdr *sh_strtab = &shdr[ehdr->e_shstrndx]; 
    const char *const sh_strtab_p = p + sh_strtab->sh_offset; 

    for (int i = 0; i < shnum; ++i) { 
    printf("%2d: %4d '%s'\n", i, shdr[i].sh_name, 
      sh_strtab_p + shdr[i].sh_name); 
    } 

    return 0; 
} 

int main(int argc, char *argv[]) 
{ 
    struct stat st; 
    const char *fname = "/proc/self/exe"; 

    if (argc > 1) 
    fname = argv[1]; 

    if (stat(fname, &st) != 0) { 
    perror("stat"); 
    return 1; 
    } 
    return print_shdr(fname, st.st_size); 
} 

$ gcc -g dump_shdr.c -m32 -std=c99 
$ ./a.out 
0: 0 '' 
1: 27 '.interp' 
2: 35 '.note.ABI-tag' 
3: 49 '.note.gnu.build-id' 
4: 72 '.hash' 
5: 68 '.gnu.hash' 
6: 78 '.dynsym' 
7: 86 '.dynstr' 
8: 94 '.gnu.version' 
9: 107 '.gnu.version_r' 
10: 122 '.rel.dyn' 
11: 131 '.rel.plt' 
12: 140 '.init' 
13: 135 '.plt' 
14: 146 '.text' 
15: 152 '.fini' 
16: 158 '.rodata' 
17: 166 '.eh_frame' 
18: 176 '.ctors' 
19: 183 '.dtors' 
20: 190 '.jcr' 
21: 195 '.dynamic' 
22: 204 '.got' 
23: 209 '.got.plt' 
24: 218 '.data' 
25: 224 '.bss' 
26: 229 '.comment' 
27: 238 '.debug_aranges' 
28: 253 '.debug_pubnames' 
29: 269 '.debug_info' 
30: 281 '.debug_abbrev' 
31: 295 '.debug_line' 
32: 307 '.debug_frame' 
33: 320 '.debug_str' 
34: 331 '.debug_loc' 
35: 17 '.shstrtab' 
36: 1 '.symtab' 
37: 9 '.strtab' 
+0

ich weiß, es soll ein Offset sein, aber ist es nicht angenommen, den Offset als Int zu drucken, wenn ich printf einlege? Wie drucke ich den Wert - in welcher Form auch immer dargestellt? Wie bekomme ich auch den tatsächlichen Namen - ich weiß, ich bekomme den Offset auf den spezifischen Abschnitt in .shstrtab - aber von dem drucke ich den Namen? Ich meine, wie beziehe ich mich auf die String-Tabelle? Ich habe versucht, etwas wie printf ("% s", sction + header.shstrtab [nameoffset]); aber das hat nicht funktioniert für mich ... – user1431301

+0

@ user1431301 Siehe update. –

+0

@EmployedRussian: Könnten Sie ein Beispiel geben, wie man das Gegenteil macht, d. H. Ein Codebeispiel, wie man die Zeichenkettentabelle erstellt, und dann den Abschnitt mit einigen Werten? –

Verwandte Themen