Abrufen des sh_name-Members in einer Abschnitts-Header-Elf-Datei

Lesezeit: 3 Minuten

Benutzeravatar von user1431301
Benutzer1431301

Ich versuche, den richtigen Offset für den Abschnittsnamen zu erhalten, indem ich auf die zugreife sh_name Mitglied einer Elfendatei, aber es gibt mir immer null oder null …

Ich soll nur benutzen mmap() und die elf.h – keine Hilfsfunktionen

So tat 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 das mache:

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

es gibt mir immer 0 … was mache ich falsch?

Benutzeravatar des beschäftigten Russen
Angestellter Russe

wenn ich es tue printf("name offset = %d\n", (section->sh_name)); es gibt mir immer 0 … was mache ich falsch?

Du tust es nicht irgendetwas falsch.

Das sh_name ist kein Zeiger, es ist ein Offset in .shstrtab Abschnitt, der den eigentlichen Abschnittsnamen enthält.

Sie finden die .shstrtab Abschnitt aus header->e_shstrndx.

Aktualisieren:

Soll der Offset nicht als Int gedruckt werden?

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

aber drucke ich den Namen?

Vielleicht erklärt dieses Beispiel?

#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'

  • Ich weiß, dass es sich um einen Offset handelt, aber soll der Offset nicht als Int gedruckt werden, wenn ich in printf eingebe? Wie drucke ich den Wert – auf welche Weise auch immer er dargestellt wird? Wie bekomme ich auch den tatsächlichen Namen – ich weiß, dass ich den Offset zu dem bestimmten Abschnitt in .shstrtab bekomme – aber drucke ich den Namen? Ich meine, wie beziehe ich mich auf die Zeichenfolgentabelle? Ich habe versucht, so etwas wie printf(“%s”,sction+header.shstrtab zu machen[nameoffset]); aber das hat bei mir nicht funktioniert…

    – Benutzer1431301

    3. Juni 2012 um 12:38 Uhr


  • @EmployedRussian: Könnten Sie ein Beispiel geben, wie man das Gegenteil macht, dh ein Codebeispiel, wie man die Zeichenfolgentabelle und dann den Abschnitt mit einigen Werten erstellt?

    – Die Maske

    15. März 2014 um 16:45 Uhr

  • @EmployedRussian müssen wir wirklich verwenden mmmap ? Können wir nicht einfach benutzen offen() ?

    – Trei

    19. Mai 2018 um 19:21 Uhr

  • @ Trey du müssen, zu … haben open bevor du es kannst mmap, und meine Beispiele tut. Ihre Frage lautet wahrscheinlich: “Können wir nicht einfach verwenden read Anstatt von mmap?”. Ja, du kannst.

    – Angestellter Russe

    19. Mai 2018 um 19:34 Uhr

  • @BarakB Baust du diesen Code mit -m32 Flagge? Wenn Sie es als 64-Bit-Binärdatei erstellen, müssen Sie es ersetzen Elf32 mit Elf64 überall, überallhin, allerorts.

    – Angestellter Russe

    1. Juni 2019 um 21:36 Uhr

1432610cookie-checkAbrufen des sh_name-Members in einer Abschnitts-Header-Elf-Datei

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy