上一节,我们讲了如何手动通过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++;
- }
- }