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

一步一步走进Linux HOOK API()

上一节,我们讲了如何手动通过GDB来拦截printf的参数,其实ELF远远不止我们介绍的那点东西,在经过一轮实战之后,我们得继续回到ELF文件格式的探索之旅了.今天我们这里就要讲什么的,好了,今天我们轻松一点,看一下动态节,

动态节的类型是SHT_DYNAMIC,

先看一下动态节的定义:

typedef struct
{
  Elf32_Sword	d_tag;	 /* Dynamic entry type */
  union
    {
      Elf32_Word d_val;	 /* Integer value */
      Elf32_Addr d_ptr;	 /* Address value */
    } d_un;
} Elf32_Dyn;

乍看之下,这个结构貌似挺简单的嘛,2成员,一个岁居然是联合体.这就郁闷了,什么时候用d_val.什么时候用d_prt?

在动态节中有很多不同的类型.成员d_tag给出了结构的类型值,d_un成员是由d_val.还是d_prt就要看这个结构体的类型了,庆幸的是,我们主要知道DT_NEEDED,DT_NEEDED被定义为常量1,对于DT_NEEDED类型的动态结构他的d_val成员其实是一个字符串表中的索引,它给出的字符串就是这个ELF文件所依赖的外部动态库的名称.你的ELF文件需要依赖多少个动态库就有多少个DT_NEEDED类型的动态结构出现在动态表中.

下面给出示例代码,跟打印符号表几乎一样:

#include "readDyn.h"
DynType	dynName[] = {
"DT_NULL",0,"DT_NEEDED",	1,"DT_PLTRELSZ","DT_PLTGOT",
3,"DT_HASH",4,"DT_STRTAB",	5"DT_SYMTAB",	6,"DT_RELA",	7,
"DT_RELASZ",	8,"DT_RELAENT",9,"DT_STRSZ",10,"DT_SYMENT",
11,"DT_INIT",12,"DT_FINI",13,"DT_SONAME",14,"DT_RPATH",15,
"DT_SYMBOLIC",16,"DT_REL",17,"DT_RELSZ",18,"DT_RELENT",19,
"DT_PLTREL",	20,"DT_DEBUG",21,"DT_TEXTREL",	22,"DT_JMPREL",
23,"DT_BIND_NOW",24,"DT_INIT_ARRAY",25,"DT_FINI_ARRAY",26,
"DT_INIT_ARRAYSZ",27,"DT_FINI_ARRAYSZ",28,"DT_RUNPATH",29,
"DT_FLAGS",30,"DT_ENCODING",32,"DT_PREINIT_ARRAY",32,
"DT_PREINIT_ARRAYSZ", 33,"DT_NUM",34,"DT_LOOS",0x6000000d,
"DT_HIOS",0x6ffff000,"DT_LOPROC",0x70000000,"DT_HIPROC",
0x7fffffff,
};
char* findDynTypeName(unsigned int type)
{
int i = 0;
for(i = 0;i < sizeof(dynName) / sizeof(DynType);i++){
if(dynName[i].type == type){
return dynName[i].typeName;
break;
}
}
return dynName[0].typeName;
}
void display_dyn(Elf32_Ehdr *ehdr,Elf32_Shdr *shdr)
{
Elf32_Dyn *dyn = (Elf32_Dyn *)((char*)ehdr + shdr->sh_offset);
char 	*symName = (char*)(((Elf32_Shdr *)((char*)ehdr + ehdr->e_shoff + shdr->sh_link * sizeof(Elf32_Shdr)))->sh_offset 
+ (char*)ehdr);
printf("symb = 0x%x\n",(char*)dyn);
printf("symName = 0x%x\n",(char*)symName);
printf("Dynamic section at offset 0x%x contains entries:\n",dyn);
int i = 0;
printf("%-10s%-10s%s\n","Tag","Type","Name/Value");
do{
printf("%-10x",dyn->d_tag);
printf("%-10s",findDynTypeName(dyn->d_tag));
if(dyn->d_tag == DT_NEEDED){
printf("%s",symName + dyn->d_un.d_ptr);
}else{
printf("%x",dyn->d_un.d_val);
}
printf("\n");
}while(dyn->d_tag != DT_NULL && dyn++);
}
void displayDyn(Elf32_Ehdr *ehdr,Elf32_Shdr *shdr)
{
int py = ehdr->e_shstrndx * sizeof(Elf32_Shdr);
Elf32_Shdr *symtab = (Elf32_Shdr *)((char*)shdr + py);
char *szShdrName = (char*)(symtab->sh_offset + (char*)ehdr);
int i = 0;
for(i = 0; i < ehdr->e_shnum; i++){
if(shdr->sh_type == SHT_DYNAMIC){
display_dyn(ehdr,shdr);
}
shdr++;
}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值