一步一步走进Linux HOOK API(四)

一步一步走进Linux HOOK API()

这一节主要是讲述的是符号节.要怎么才能找到符号节呢,其实只要在上一期讲的遍历节头的时候,判断每一个节类型是不是SHT_SYMTABSHT_DYNSYM,那么相应的节就是一个符号节了,符号节存放的是一张符号表,符号表也是一个连续存储的结构数组.

那什么叫符号呢?编程过程中用到的变量和函数都可以称之为符号,一个ELF文件中并不只有一个符号节,通常是两个,一个叫动态节,打印名称为".dynsym",它的类型是SHT_DYNSYM,所有引入的外部符号在这里有所体现.另一个类型值为SHT_SYMTAB,名字为".symtab",它保存了所有有用的符号信息.

[cpp]  view plain  copy
  1. typedef struct  
  2. {  
  3.   Elf32_Word    st_name;     /* Symbol name (string tbl index) */  
  4.   Elf32_Addr    st_value;    /* Symbol value */  
  5.   Elf32_Word    st_size;     /  * Symbol size */  
  6.   unsigned char st_info;     /* Symbol type and binding */  
  7.   unsigned char st_other;    /* Symbol visibility */  
  8.   Elf32_Section st_shndx;    /* Section index */  
  9. } Elf32_Sym;  


st_name; 符号的名字索引

这个成员是一个符号表对应的字符串表中的一个偏移,对应的字符串表可以通过该节link成员获取得到.

st_value; 符号地址

该成员给出了相应的符号值,根据符号类型和用途,它可能是个内存地址或者绝对值

st_size; 符号的字节大小

如果是数据对象,可能给出该数据对象占用的大小,如果是函数,可能给出了函数指令占用的大小.

st_info; 符号的信息

这个成员有2部分组成,第四位用来表示符号的类型.高四位表示这个符号的绑定类型,对于从动态库引入的函数,这个字段就应该为STB_GLOBAL,表示这个符号是全局符号.elf.h,给出了如下2个宏,用来获取符号信息

[cpp]  view plain  copy
  1. #define ELF32_ST_BIND(val)   (((unsigned char) (val)) >> 4)  
  2. #define ELF32_ST_TYPE(val)   ((val) & 0xf)  
  3. #define ELF32_ST_INFO(bind, type)   (((bind) << 4) + ((type) & 0xf))  

st_other; 此字段恒为0

st_shndx; 每个符号和某些节相关,这个字段给出了一个节头的索引.如果函数体所在的节不存于当前文件中,此字段为0.

下面就通过代码来看一下,怎么获取这些符号节表的信息.

代码写的不是很好,请主要关注怎么去获取这些信息~~

示例代码:

[cpp]  view plain  copy
  1. void display_dynsym(Elf32_Ehdr *ehdr,Elf32_Shdr *shdr)  
  2. {  
  3. Elf32_Sym *symb = (Elf32_Sym *)((char*)ehdr + shdr->sh_offset);  
  4. int  symbSize = shdr->sh_size / sizeof(Elf32_Sym);  
  5. char    *symName = (char*)(((Elf32_Shdr *)((char*)ehdr + ehdr->e_shoff + shdr->sh_link * sizeof(Elf32_Shdr)))->sh_offset   
  6. + (char*)ehdr);  
  7. printf("symName = 0x%x\n",(char*)symName);  
  8. printf("symb = 0x%x\n",(char*)symb);  
  9. printf("symbSize = 0x%x\n",(char*)symbSize);  
  10. printf("Symbol table '.dynsym' contains %d entries:\n",symbSize);  
  11. int i = 0;  
  12. printf("%7s:%-8s%-6s%-8s%-7s%-9s%-4s%s\n","Num","Value","Size",  
  13. "Type","Bind","Vis","Ndx","Name");  
  14. for(i = 0; i < symbSize;i++){  
  15. printf("%7d:",i);  
  16. printf("%-8x",symb->st_value);  
  17. printf("%-8d",symb->st_size);  
  18. printf("%-6x",ELF32_ST_TYPE(symb->st_info));  
  19. printf("%-8x",ELF32_ST_BIND(symb->st_info));  
  20. printf("%-7x",symb->st_other);  
  21. printf("%-9d",symb->st_shndx);  
  22. printf("%s",symName + symb->st_name);  
  23. printf("\n");  
  24. symb++;  
  25. }  
  26. }  
  27. void display_sym(Elf32_Ehdr *ehdr,Elf32_Shdr *shdr)  
  28. {  
  29. Elf32_Sym *symb = (Elf32_Sym *)((char*)ehdr + shdr->sh_offset);  
  30. int  symbSize = shdr->sh_size / sizeof(Elf32_Sym);  
  31. char    *symName = (char*)(((Elf32_Shdr *)((char*)ehdr + ehdr->e_shoff + shdr->sh_link * sizeof(Elf32_Shdr)))->sh_offset   
  32. + (char*)ehdr);  
  33. printf("symName = 0x%x\n",(char*)symName);  
  34. printf("symb = 0x%x\n",(char*)symb);  
  35. printf("symbSize = 0x%x\n",(char*)symbSize);  
  36. printf("Symbol table '.symtab' contains %d entries:\n",symbSize);  
  37. int i = 0;  
  38. printf("%7s:%-8s%-6s%-8s%-7s%-9s%-4s%s\n","Num","Value","Size",  
  39. "Type","Bind","Vis","Ndx","Name");  
  40. for(i = 0; i < symbSize;i++){  
  41. printf("%7d:",i);  
  42. printf("%-8x",symb->st_value);  
  43. printf("%-8d",symb->st_size);  
  44. printf("%-6x",ELF32_ST_TYPE(symb->st_info));  
  45. printf("%-8x",ELF32_ST_BIND(symb->st_info));  
  46. printf("%-7x",symb->st_other);  
  47. printf("%-9d",symb->st_shndx);  
  48. printf("%s",symName + symb->st_name);  
  49. printf("\n");  
  50. symb++;  
  51. }  
  52. }  
  53. void displaySmby(Elf32_Ehdr *ehdr,Elf32_Shdr *shdr)  
  54. {  
  55. int py = ehdr->e_shstrndx * sizeof(Elf32_Shdr);  
  56. Elf32_Shdr *symtab = (Elf32_Shdr *)((char*)shdr + py);  
  57. char *szShdrName = (char*)(symtab->sh_offset + (char*)ehdr);  
  58. int i = 0;  
  59. for(i = 0; i < ehdr->e_shnum; i++){  
  60. if(shdr->sh_type == SHT_SYMTAB){  
  61. display_sym(ehdr,shdr);  
  62. }else if(shdr->sh_type == SHT_DYNSYM){  
  63. display_dynsym(ehdr,shdr);  
  64. }  
  65. shdr++;  
  66. }  
  67. }  
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值