首页
社区
课程
招聘
[原创] 通过问题来理解linker01-为什么PT_LOAD有2段Maps文件有3段
发表于: 2021-11-17 09:47 20981

[原创] 通过问题来理解linker01-为什么PT_LOAD有2段Maps文件有3段

2021-11-17 09:47
20981

最新在做https://bbs.pediy.com/thread-270030.htm的分析研究, 主要目的是避免监守自盗, 同时也希望在实战中学习,在分析的过程中就遇到了一些疑惑

这里尝试做一些解答.

linker

linker

linker

通过上面的日志信息可以了解到, linker在Android10上面总计进行了6次mmap, 分别为

(1) ReadProgramHeaders

(2) ReadSectionHeaders

(3) ReadDynamicSection

(4) ReadDynamicSection

(5) LoadSegments(通过文件偏移, 可以知晓这里对应elf的第一个段)

(6) LoadSegments(通过文件偏移, 可以知道这里对应elf的第二个段)

其中最后2次映射由LoadSegments引发,也就是我们真正要关注的问题点. 通过mmap观察走两次mmap为正常行为,为什么maps有3段呢? 我们还需要进一步分析, 因此我又hook了mprotect的方法

(tips: 如果大家仔细观察, 这里又会有另外一个小疑问, 为什么mmap的偏移是0x34000, 但是elf的fileoffset是0x34D18. 这里后面再做详细解答)

第二次采集的时候通过hook补全了mprotect权限, 发现为了一行关键信息. linker使用mprotect进行了权限修改, 因此内核层便进行了maps分割

这里简单画了下对应信息, 方便能够理解背后的行为.

20211116191000

通过上面的分析的,便解答了心中的疑惑. 那么我们进一步思考linker为什么需要进行上面的行为呢? 这个问题我们就需要去linker源码里面寻找答案了,

堆栈信息已经给我们提供了阅读代码的线索, 我们也就可以去大海里遨游不怕迷路了.

ElfReader::ReadProgramHeaders 进行mmap, 在析构函数进行 munmap

ElfReader::ReadSectionHeaders 后续再分析

ElfReader::ReadDynamicSection 后续再分析

ElfReader::ReadDynamicSection 后续再分析

ElfReader::LoadSegments 这里进行一下详细阐述, linker其实是操作系统和elf的连接器, 既要满足elf的要求, 又要满足mmap的一些限制.

比如:

mmap需要按页分配, elf需要对齐

下图详细描述了虚拟地址空间映射和so文件之间的关系

linker

因为mmap时使用但是PAGE_START(phdr->p_offset), elf的fileoffset是0x34D18, 向上页对齐便是0x34000. 心里的疑惑也就解开了.

.bss 也叫做全局变量段

liner底层原理

https://github.com/yhnu/op7t

其中一个疑惑便是为什么elf文件里面只有2个段, 但是到内存后却有3段映射.
其中一个疑惑便是为什么elf文件里面只有2个段, 但是到内存后却有3段映射.
130|OnePlus7T:/data/local/tmp # dmesg -w|grep kr|grep sotest
[ 3142.307841] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51953000, len=0x1d0 prot=1, off=0x0(ReadProgramHeaders)
[ 3142.307861] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51952000, len=0xae0 prot=1, off=0x35000(ReadSectionHeaders)
[ 3142.307891] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51950000, len=0x1ca0 prot=1, off=0x34000(ReadDynamicSection)
[ 3142.307906] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b5194f000, len=0xaeb prot=1, off=0x0(ReadDynamicSection)
[ 3142.308172] [info]kr_mmap mmap file libsotest.so. vaddr=0x7abcd88000, len=0x34988 prot=5, off=0x0(LoadSegments)
[ 3142.308199] [info]kr_mmap mmap file libsotest.so. vaddr=0x7abcdcc000, len=0x11f8 prot=3, off=0x34000(LoadSegments)
130|OnePlus7T:/data/local/tmp # dmesg -w|grep kr|grep sotest
[ 3142.307841] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51953000, len=0x1d0 prot=1, off=0x0(ReadProgramHeaders)
[ 3142.307861] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51952000, len=0xae0 prot=1, off=0x35000(ReadSectionHeaders)
[ 3142.307891] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b51950000, len=0x1ca0 prot=1, off=0x34000(ReadDynamicSection)
[ 3142.307906] [info]kr_mmap mmap file libsotest.so. vaddr=0x7b5194f000, len=0xaeb prot=1, off=0x0(ReadDynamicSection)
[ 3142.308172] [info]kr_mmap mmap file libsotest.so. vaddr=0x7abcd88000, len=0x34988 prot=5, off=0x0(LoadSegments)
[ 3142.308199] [info]kr_mmap mmap file libsotest.so. vaddr=0x7abcdcc000, len=0x11f8 prot=3, off=0x34000(LoadSegments)
 
 
 
 
 
 
 
 
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51953000
        pc=0x7b52dace58 sp=0x7fe046bc00 c->sp=0x7fe046bc00 c->pc=0x7b52dace58 regs_len=320 stack_len=1024 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52cffeb0 /apex/com.android.runtime/bin/linker64+4feb0(__dlElfReader::ReadProgramHeaders())
        #03 0x7b52cff790 /apex/com.android.runtime/bin/linker64+4f790(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool))
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51952000
        pc=0x7b52dace58 sp=0x7fe046bc00 c->sp=0x7fe046bc00 c->pc=0x7b52dace58 regs_len=320 stack_len=1024 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52d000b4 /apex/com.android.runtime/bin/linker64+500b4(__dlElfReader::ReadSectionHeaders())
        #03 0x7b52cff79c /apex/com.android.runtime/bin/linker64+4f79c(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool)
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51950000
        pc=0x7b52dace58 sp=0x7fe046bbf0 c->sp=0x7fe046bbf0 c->pc=0x7b52dace58 regs_len=320 stack_len=1040 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52d00630 /apex/com.android.runtime/bin/linker64+50630(__dlElfReader::ReadDynamicSection())
        #03 0x7b52cff7a8 /apex/com.android.runtime/bin/linker64+4f7a8(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool)
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b5194f000
        pc=0x7b52dace58 sp=0x7fe046bbf0 c->sp=0x7fe046bbf0 c->pc=0x7b52dace58 regs_len=320 stack_len=1040 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52d006a8 /apex/com.android.runtime/bin/linker64+506a8(__dlElfReader::ReadDynamicSection())
        #03 0x7b52cff7a8 /apex/com.android.runtime/bin/linker64+4f7a8(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool)
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7abcd88000
        pc=0x7b52dace58 sp=0x7fe046c050 c->sp=0x7fe046c050 c->pc=0x7b52dace58 regs_len=320 stack_len=16304 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52d00be4 /apex/com.android.runtime/bin/linker64+50be4(__dlElfReader::LoadSegments())
        #02 0x7b52d007fc /apex/com.android.runtime/bin/linker64+507fc(__dlElfReader::Load(address_space_params*))
        #03 0x7b52cea6e4 /apex/com.android.runtime/bin/linker64+3a6e4(__dlLoadTask::load(address_space_params*))
        #04 0x7b52ce9d04 /apex/com.android.runtime/bin/linker64+39d04(__dlfind_libraries(android_namespace_t*, soinfo*, char const* const*, unsigned long, soinfo**, std::__1::vector<soinfo*, std::__1::allocator<soinfo*> >*, unsigned long, int, android_dlextinfo const*, bool, bool, std::__1::vector<android_namespace_t*, std::__1::allocator<android_namespace_t*> >*))
        #05 0x7b52cecba0 /apex/com.android.runtime/bin/linker64+3cba0(__dldo_dlopen(char const*, int, android_dlextinfo const*, void const*))
        #06 0x7b52ce80dc /apex/com.android.runtime/bin/linker64+380dc(__dl___loader_android_dlopen_ext)
        #07 0x7b4df5b0b8 /apex/com.android.runtime/lib64/bionic/libdl.so+10b8
        #08 0x7b4e2dcfd8 /apex/com.android.runtime/lib64/libnativeloader.so+7fd8
        #09 0x7b4e2dcc5c /apex/com.android.runtime/lib64/libnativeloader.so+7c5c
        #10 0x7acb748938 /apex/com.android.runtime/lib64/libart.so+37b938
        #11 0x7ac16e10e0 /apex/com.android.runtime/lib64/libopenjdkjvm.so+50e0
        #12 0x7164aaf4 /system/framework/arm64/boot.oat+b9af4
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7abcdcc000
        pc=0x7b52dace58 sp=0x7fe046c050 c->sp=0x7fe046c050 c->pc=0x7b52dace58 regs_len=320 stack_len=16304 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52d00be4 /apex/com.android.runtime/bin/linker64+50be4(__dlElfReader::LoadSegments())
        #02 0x7b52d007fc /apex/com.android.runtime/bin/linker64+507fc(__dlElfReader::Load(address_space_params*))
        #03 0x7b52cea6e4 /apex/com.android.runtime/bin/linker64+3a6e4(__dlLoadTask::load(address_space_params*))
        #04 0x7b52ce9d04 /apex/com.android.runtime/bin/linker64+39d04(__dlfind_libraries(android_namespace_t*, soinfo*, char const* const*, unsigned long, soinfo**, std::__1::vector<soinfo*, std::__1::allocator<soinfo*> >*, unsigned long, int, android_dlextinfo const*, bool, bool, std::__1::vector<android_namespace_t*, std::__1::allocator<android_namespace_t*> >*))
        #05 0x7b52cecba0 /apex/com.android.runtime/bin/linker64+3cba0(__dldo_dlopen(char const*, int, android_dlextinfo const*, void const*))
        #06 0x7b52ce80dc /apex/com.android.runtime/bin/linker64+380dc(__dl___loader_android_dlopen_ext)
        #07 0x7b4df5b0b8 /apex/com.android.runtime/lib64/bionic/libdl.so+10b8
        #08 0x7b4e2dcfd8 /apex/com.android.runtime/lib64/libnativeloader.so+7fd8
        #09 0x7b4e2dcc5c /apex/com.android.runtime/lib64/libnativeloader.so+7c5c
        #10 0x7acb748938 /apex/com.android.runtime/lib64/libart.so+37b938
        #11 0x7ac16e10e0 /apex/com.android.runtime/lib64/libopenjdkjvm.so+50e0
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51953000
        pc=0x7b52dace58 sp=0x7fe046bc00 c->sp=0x7fe046bc00 c->pc=0x7b52dace58 regs_len=320 stack_len=1024 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52cffeb0 /apex/com.android.runtime/bin/linker64+4feb0(__dlElfReader::ReadProgramHeaders())
        #03 0x7b52cff790 /apex/com.android.runtime/bin/linker64+4f790(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool))
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51952000
        pc=0x7b52dace58 sp=0x7fe046bc00 c->sp=0x7fe046bc00 c->pc=0x7b52dace58 regs_len=320 stack_len=1024 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52d000b4 /apex/com.android.runtime/bin/linker64+500b4(__dlElfReader::ReadSectionHeaders())
        #03 0x7b52cff79c /apex/com.android.runtime/bin/linker64+4f79c(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool)
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b51950000
        pc=0x7b52dace58 sp=0x7fe046bbf0 c->sp=0x7fe046bbf0 c->pc=0x7b52dace58 regs_len=320 stack_len=1040 path_len=1024
        #00 0x7b52dace58 /apex/com.android.runtime/bin/linker64+fce58(__dl_mmap64)
        #01 0x7b52cff5e8 /apex/com.android.runtime/bin/linker64+4f5e8(__dlMappedFileFragment::Map(int, long, unsigned long, unsigned long))
        #02 0x7b52d00630 /apex/com.android.runtime/bin/linker64+50630(__dlElfReader::ReadDynamicSection())
        #03 0x7b52cff7a8 /apex/com.android.runtime/bin/linker64+4f7a8(__dlElfReader::Read(char const*, int, long, long))
        #04 0x7b52cf35ac /apex/com.android.runtime/bin/linker64+435ac(__dlload_library(android_namespace_t*, LoadTask*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> > const&, bool))
        #05 0x7b52cf23f0 /apex/com.android.runtime/bin/linker64+423f0(__dlload_library(android_namespace_t*, LoadTask*, ZipArchiveCache*, std::__1::vector<LoadTask*, std::__1::allocator<LoadTask*> >*, int, bool)
----------------------------------
kr_openat tgid=7635 path=/proc/7635/maps
kr_openat vaddr=0x7b5194f000

[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

最后于 2021-11-17 09:48 被github_yhnu编辑 ,原因:
收藏
免费 2
支持
分享
最新回复 (2)
雪    币: 902
活跃值: (1120)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
发现了对我的分析,楼主对系统的研究很深啊,”mprotect由谁调用的,目的是什么?“,这个问题不是你自己也说了吗,"linker使用mprotect进行了权限修改",然后极其非常粗略又粗暴的解析:alloc出来是rw,mmap之后是r,所以根据PT_LOAD的flags字段,code段被mprotect成rx,bss段被mprotect成rw
2021-11-17 16:20
0
雪    币: 26
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
3
血舞长空 发现了对我的分析,楼主对系统的研究很深啊,”mprotect由谁调用的,目的是什么?“,这个问题不是你自己也说了吗,"linker使用mprotect进行了权限修改",然后极其非常 ...
 这个问题已经知晓了, github的链接里面有补充. 你的so分析后面再发出来哈
2021-11-23 11:02
0
游客
登录 | 注册 方可回帖
返回
//