加载
以安卓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=0x00000fffPAGE_MASK :PAGE_SIZE取反,那就是0xfffff000(32位)PAGE_START是获取当前地址所在页的起始地址,比如x=0x12345678,那么PAGE_START就是0x12345000PAGE_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_libraryelf_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
[培训]《冰与火的战歌:Windows内核攻防实战》!从零到实战,融合AI与Windows内核攻防全技术栈,打造具备自动化能力的内核开发高手。
#基础理论
---
来源: 看雪论坛
原文链接: https://bbs.kanxue.com/thread-291368.htm
[分享]linker详解
338 浏览
0 回复
暂无回复,快来抢沙发吧!