dlsym 如何查看一个so里面的_Android so 文件进阶<二> 从dlsym()源码看android 动态链接过程...

本文详细剖析了Android系统中dlsym()函数的实现原理,包括RTLD_DEFAULT、RTLD_NEXT两种情况下的查找流程,重点解析了dlsym_linear_lookup()和soinfo_elf_lookup()函数,探讨了动态链接过程中符号表的使用和动态链接器如何找到符号的地址。
摘要由CSDN通过智能技术生成

0x00  前言

这篇文章其实是我之前学习elf文件关于符号表的学习笔记,网上也有很多关于符号表的文章,怎么说呢,感觉像是在翻译elf文件格式的文档一样,千篇一律,因此把自己的学习笔记分享出来。dlsym()的源码是分析的android4.4的源码,android自己实现的bonic C库。

0x01  基本流程

android中关于elf文件,关于so文件信息的结构体:

structsoinfo {public:charname[SOINFO_NAME_LEN];const Elf32_Phdr*phdr;

size_t phnum;

Elf32_Addr entry;

Elf32_Addrbase;

unsigned size;

uint32_t unused1;//DO NOT USE, maintained for compatibility.

Elf32_Dyn*dynamic;

uint32_t unused2;//DO NOT USE, maintained for compatibility

uint32_t unused3; //DO NOT USE, maintained for compatibility

soinfo*next;

unsigned flags;const char*strtab;

Elf32_Sym*symtab;

size_t nbucket;

size_t nchain;

unsigned*bucket;

unsigned*chain;

unsigned*plt_got;

Elf32_Rel*plt_rel;

size_t plt_rel_count;

Elf32_Rel*rel;

size_t rel_count;

linker_function_t*preinit_array;

size_t preinit_array_count;

linker_function_t*init_array;

size_t init_array_count;

linker_function_t*fini_array;

size_t fini_array_count;

linker_function_t init_func;

linker_function_t fini_func;#if defined(ANDROID_ARM_LINKER)

//ARM EABI section used for stack unwinding.

unsigned*ARM_exidx;

size_t ARM_exidx_count;#elif defined(ANDROID_MIPS_LINKER)unsigned mips_symtabno;

unsigned mips_local_gotno;

unsigned mips_gotsym;#endifsize_t ref_count;

link_map_t link_map;boolconstructors_called;//When you read a virtual address from the ELF file, add this//value to get the corresponding address in the process' address space.

Elf32_Addr load_bias;boolhas_text_relocations;boolhas_DT_SYMBOLIC;voidCallConstructors();voidCallDestructors();voidCallPreInitConstructors();private:void CallArray(const char* array_name, linker_function_t* functions, size_t count, boolreverse);void CallFunction(const char*function_name, linker_function_t function);

};

soinfo

然后就是我们关心的dlsym()函数,

void*dlsym(void*handle,constchar*symbol)

dlsym()的实现对于handle是分三种情况

(1)  handle = RTLD_DEFAULT;

(2)  handle = RTLD_NEXT;

(3) 其他,也就是我们平常调用dlopen()的返回值。

0x02  RTLD_DEFAFULT

soinfo* found =NULL;

Elf32_Sym* sym =NULL;if (handle ==RTLD_DEFAULT) {

sym= dlsym_linear_lookup(symbol, &found, NULL);

}///bonic/linker/Linker.cpp

Elf32_Sym* dlsym_linear_lookup(const char* name, soinfo** found, soinfo*start) {

unsigned elf_hash= elfhash(name); //计算符号名称的hash值

if (start ==NULL) {//static soinfo* solist = &libdl_info; libdl_info是soinfo类型的全局变量包含libdl.so的信息

start =solist;

}

接下来就开始循环调用soinfo_elf_lookup() 遍历soinfo的链表

Elf32_Sym* s =NULL;for (soinfo* si

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值