获得sh_name成员节头ELF文件 [英] getting the sh_name member in a section header elf file

查看:195
本文介绍了获得sh_name成员节头ELF文件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图得到正确的通过访问一个ELF文件的 sh_name 成员偏移的节名,但是它不断给我零,或空..

我应该只使用的mmap() elf.h中 - 没有辅助功能

所以,我所做的:

 无效* map_start = MMAP(0,fd_stat.st_size,PROT_READ | PROT_WRITE,MAP_SHARED,FD,0))
标题=(Elf32_Ehdr *)map_start;
secoff =报头 - > e_shoff;
部分=(个Elf32_Shdr *)(map_start + secoff);

但是当我做:

 的printf(名偏移=%d个\\ N(本条> sh_name));

它不断给我0 ...
我究竟做错了什么?


解决方案

  

当我这样做的printf(名偏移=%d个\\ N(本条> sh_name)); 它不断给我0 ...我是什么我doiing错了吗?


您不这样做的任何的错误。

sh_name 是不是一个指针,它是一个偏移量 .shstrtab 部分,它包含实际的节名

您可以找到从 .shstrtab 部分报头 - 方式> e_shstrndx

更新:


  

心不是它想打印的偏移量为int?


它打印 0 。是什么让你相信 0 不是一个int?


  

但做我打印的名字吗?


也许这个例子会解释?

 的#include< SYS / stat.h>
#包括LT&; SYS / mman.h>
#包括LT&;&elf.h中GT;
#包括LT&;&stdio.h中GT;
#包括LT&;&fcntl.h GT;
INT print_shdr(为const char * const的FNAME,为size_t大小){
  INT FD =开(FNAME,O_RDONLY);
  字符* p值= MMAP(0,大小,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 ++我){
    的printf(%2D:4D%'%s'的\\ n,我,SHDR [I] .sh_name,
           sh_strtab_p + SHDR [I] .sh_name);
  }  返回0;
}INT主(INT ARGC,CHAR *的argv [])
{
  struct stat中ST;
  为const char * FNAME =的/ proc /自/ EXE  如果(argc个大于1)
    FNAME =的argv [1];  如果(统计(FNAME,&放大器;!ST)= 0){
    PERROR(STAT);
    返回1;
  }
  返回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标签
 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。动态
22:204'.GOT
23:209'.got.plt
24:218'。数据
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

I'm trying to get the correct offset to the section name by accessing the sh_name member of an elf file, but it keep giving me zero, or null...

I'm supposed to only use mmap() and the elf.h - no helper functions

So I did:

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

but when I do:

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

it keeps giving me 0... what am I doing wrong?

解决方案

when i do printf("name offset = %d\n", (section->sh_name)); it keeps giving me 0... what am I doiing wrong?

You are not doing anything wrong.

The sh_name is not a pointer, it's an offset into .shstrtab section, which contains the actual section name.

You can find the .shstrtab section from header->e_shstrndx.

Update:

isnt it suppose to print the offset as an int?

It prints 0. What made you believe that 0 is not an int?

but of do i print the name?

Perhaps this example will explain?

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

这篇关于获得sh_name成员节头ELF文件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆