<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