2012-06-02 23 views
8

Estoy tratando de obtener el desplazamiento correcto al nombre de la sección accediendo al miembro de un archivo elf, pero sigue dándome cero, o nulo ...obteniendo el miembro sh_name en un archivo elf de cabecera de sección

supone que tengo que usar sólo mmap() y los elf.h - sin funciones cooperadoras

Así que lo hice:

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); 

pero cuando lo hago:

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

me sigue dando 0 ... ¿Qué estoy haciendo mal?

Respuesta

14

cuando hago printf("name offset = %d\n", (section->sh_name)); me sigue dando 0 ... ¿qué estoy haciendo mal?

Usted no está haciendo nada mal.

no es un puntero, es un desplazamiento en la sección .shstrtab, que contiene el nombre de la sección real.

Puede encontrar la sección .shstrtab en header->e_shstrndx.

Actualización:

isnt se supone que debe imprimir el desplazamiento como un int?

Se imprime 0. ¿Qué te hizo creer que 0 no es un int?

pero de ¿me imprimo el nombre?

Quizás este ejemplo explica?

#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

supongo que es un desplazamiento, pero ¿no se supone que debe imprimirse el desplazamiento como un int cuando lo puse en printf? ¿Cómo imprimo el valor? en cualquier forma que esté representado. También, ¿cómo obtengo el nombre real? Sé que obtengo el desplazamiento en la sección específica en .shstrtab, pero ¿debo imprimir el nombre? quiero decir, ¿cómo me refiero a la tabla de cadenas? Traté de hacer algo como printf ("% s", sction + header.shstrtab [nameoffset]); pero eso no funcionó para mí ... – user1431301

+0

@ user1431301 Ver la actualización. –

+0

@EmployedRussian: ¿Podría dar un ejemplo de cómo hacer el reverso, es decir, un ejemplo de código sobre cómo crear la tabla de cadenas y luego la sección con algunos valores? –

Cuestiones relacionadas