首页
社区
课程
招聘
[分享]linker详解
发表于: 2天前 598

[分享]linker详解

2天前
598

加载

以安卓4.4为例,从system.loadlibrary入手


进入doLoad方法





LoadNativeLibrary只截取关键部分



LoadNativeLibrary中执行了JNI_OnLoad函数

继续往下分析dlopen


find_library_internal是去找已经加载过的so文件,第一次加载走load_library



先看ReadElfHeader

看看header_是什么

就是ElfHeader结构体

然后看VerifyElfHeader,就是在验证ElfHeader


然后看ReadProgramHeader

下面是Elf32_Phdr的定义



先看一下PAGE_START   PAGE_END   PAGE_OFFSET的实现

PAGE_SIZE: (1<<12)-1=4095=0x00000fff

PAGE_MASK :PAGE_SIZE取反,那就是0xfffff000(32位)

PAGE_START是获取当前地址所在页的起始地址,比如x=0x12345678,那么PAGE_START就是0x12345000

PAGE_END是获取当前地址所在页的下一页的起始地址,而非页内最后一个字节,比如x=0x12345678,那么PAGE_END就是0x12346000



然后看ReserveAddressSpace,主要看phdr_table_get_load_size,还有load_bias


先解释load_bias,他是实际地址(start)与期望地址(addr)的差值。比如说,addr=0x1000, start=0x5000, 然后我们现在需要找到elf文件中某个地址0x1050(他是绝对地址),那么0x1050相对于addr的偏移就是0x50,在真实内存中的地址就是0x1050+(0x5000-0x1000)


写了注释的phdr_table_get_load_size


然后看LoadSegments




然后看FindPhdr



CheckPhdr函数如下

然后回到load_library

elf_reader.load_start以及下面几个函数

phdr_num_

load_start_

load_size_

load_bias_


然后再往前回到find_library_internal

往下就进入到了soinfo_link_image


链接


先分析phdr_table_get_dynamic_section


经过phdr_table_get_dynamic_section函数后,si->dynamic就指向了elf文件的程序头表中p_type=PT_DYNAMIC的元素


再分析soinfo_link_image,主要看第五步,和soinfo_relocate函数


第五步的话就是si->strtab+d->d_un.d_val; 


假设si->strtab=0x2d4c4, d->d_un.d_val=0x5c620, 那么si->strtab+d->d_un.d_val=0x89ae4。去elf中可以找到

再看soinfo_relocate





传播安全知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 2
打赏
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回