当前位置: 代码迷 >> Android >> 透过soinfo,查找函数表项,无法打印所有函数表项
  详细解决方案

透过soinfo,查找函数表项,无法打印所有函数表项

热度:75   发布时间:2016-04-28 03:56:35.0
通过soinfo,查找函数表项,无法打印所有函数表项
<testso.c>
#include <stdio.h>

void func1( void )
{
    printf( "---------------------------function1\n");
}

void func2( void )
{
    printf( "***************************function2\n");
}
这里定义了两个函数。在主函数里func=dlsym(handle,"func1"); func();是可以运行这两个函数的。
接下来查找func1表项。下面的函数里handle是打开testso.so的句柄,name=“func1”,addr是所求的func1的地址
void getaddr(void *handle,const char *name, void* addr)
{
if(!handle)  
return;  
Soinfo *si = (Soinfo*)handle; 
printf("so name:%s\n",si->name);
printf("so base:%0x\n",si->base);
printf("so size:%0x\n",si->size);
Elf32_Sym *symtab = si->symtab;  
const char *strtab = si->strtab;  

Elf32_Rel *rel = si->plt_rel;  
unsigned count = si->plt_rel_count;  
unsigned idx;
printf("plt_rel:\n");
for(idx=0; idx<count; idx++)
{   //遍历输出所有表项
       unsigned type = ELF32_R_TYPE(rel->r_info);  
        unsigned sym = ELF32_R_SYM(rel->r_info);  
        unsigned reloc = (unsigned)(rel->r_offset + si->base);  
        char *sym_name = (char *)(strtab + symtab[sym].st_name); 
printf("idx:%d    sym_name:%s\n",idx,sym_name);
if(type==R_ARM_GLOB_DAT && strcmp(sym_name, name)==0)
{  
printf("find addr success\n");
addr=*((unsigned*)reloc);
printf("addr:%0x\n");
}   
        rel++;  
}
}
打印结果为:
so name:testso.so
so base:80000000
so size:5000
plt_rel:
idx:0    sym_name:__cxa_begin_cleanup
idx:1    sym_name:memcpy
idx:2    sym_name:puts
idx:3    sym_name:__cxa_finalize
idx:4    sym_name:abort
idx:5    sym_name:__cxa_type_match
idx:6    sym_name:__cxa_atexit
idx:7    sym_name:__gnu_Unwind_Find_exidx
在这里没有sym_name为func1的项。
现在的问题是:rel-plt里存放的是所有函数的表项吗,如果是,那么为什么这里打印输出没有?如果不是,那么函数表项在哪里,如何获取?
------解决思路----------------------
你打印的是重定位表项。和你需要的函数表项没有任何关系。

想获得所有函数,可以打印符号表项中类型为FUNC的表项即可。

------解决思路----------------------
补充说明:plt是调用的外部函数的入口,而rel.plt是这些plt函数的重定位表项。
你得找个elf的资料仔细研读,否则没法明白。
------解决思路----------------------
举个例子:下表是某个动态库x.so的符号表项列表,可以通过readelf -s x.so获得,其中类型为FUNC的的符号项目就是函数。


Symbol table '.dynsym' contains 81 entries:
   Num:    Value  Size Type    Bind   Vis      Ndx Name
     0: 00000000     0 NOTYPE  LOCAL  DEFAULT  UND 
     1: 00000f30     0 SECTION LOCAL  DEFAULT    7 
     2: 00009000     0 SECTION LOCAL  DEFAULT   15 
     3: 00002360    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_ForcedUnwind
     4: 00001fd0   164 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_RaiseExcepti
     5: 00009024     4 OBJECT  GLOBAL DEFAULT   16 starzhu_e
     6: 0000221c     0 FUNC    GLOBAL DEFAULT    7 __gnu_Unwind_Save_VFP
     7: 0000233c    36 FUNC    GLOBAL DEFAULT    7 _Unwind_Resume_or_Rethrow
     8: 00001c68     8 FUNC    GLOBAL DEFAULT    7 __aeabi_unwind_cpp_pr0
     9: 000027d4    44 FUNC    GLOBAL DEFAULT    7 _Unwind_GetRegionStart
    10: 0000233c    36 FUNC    GLOBAL DEFAULT    7 ___Unwind_Resume_or_Rethr
    11: 00009038     0 NOTYPE  GLOBAL DEFAULT  ABS _bss_end__
    12: 00000f58   104 FUNC    GLOBAL DEFAULT    7 Java_topstar_test_Topstar
    13: 00002384    36 FUNC    GLOBAL DEFAULT    7 _Unwind_Backtrace
    14: 00000000     0 NOTYPE  WEAK   DEFAULT  UND __cxa_begin_cleanup
  相关解决方案