您的位置:首页 > 移动开发 > Android开发

Android逆向(6)——脱壳前奏,激动人心的so源码分析

2018-03-16 08:18 1251 查看

首发于I春秋,未经允许,禁止转载。感谢蛋总栽培~

0x00 前言

之前看来dex加载的过程是不是特别开心。现在我们就更接近脱壳了。so的动态加载,链接,等等,你都会在这篇文章里看到。当然还是要自己进行一个研究才可以。

0x01 so的加载初步分析

so的加载分析。

我们还是从源码入手。

主要函数 dlopen



这里dlopen的函数有一个重点就是do_dlopen。

我们追踪到do_dlopen.



这里看到的两个函数就是我们的重点部分。

首先来看CallConstructors



来看看这两个字段。

CallFunction("DT_INIT", init_func);
CallArray("DT_INIT_ARRAY", init_array, init_array_count, false);


这里就是.init和.initarray的执行部分。

我们知道在.init部分最先执行的地方。

然后我们再来看看另外一个函数,说到这个函数那我们就要进行另一个部分分析了。

0x02 so加载的步骤

1.find_library部分分析

首先,我们来打开find_library的源码,find_library是整个so加载的开始流程。也是我们要研究的主控部分。



这里调用了find_library_internal函数,跟踪,进入源码查看



这里我们看到一个load_library函数,这个就是开始加载的部分,简单的说就是现find然后再load。

现在来看load_library



然后看到了这个elf_reader。我们先来看看名字,elf reader,是不是就是读取elf,elf就是我们的so文件。

我们进入.load字段查看。



ReadElfHeader() &&
VerifyElfHeader() &&
ReadProgramHeader() &&
ReserveAddressSpace() &&
LoadSegments() &&
FindPhdr();


我们来一个一个看,ReadElfHeader()读取elf头部信息

VerifyElfHeader(),校验elf头部信息

ReadProgramHeader(),读取程序头

ReserveAddressSpace() 预留地址空间

LoadSegments() 加载segments

FindPhdr(); 我们来看下解释,Returns the address of the program header table as it appears in the loaded segments in memory. This is in contrast with ‘phdr_table_’ which is temporary and will be released before the library is relocated.

也就是说这里装载对比phdr_table_ 这个字段



之前看过一些文章,说可以进行segments加密。利用只加载segments的原理实现的。看到了系统源码之后就会有了很深的理解了。

我们接着回头去看load_library。



soinfo_alloc函数,返回一个结构体。



结束之后就到了连接部分。

回到find_library_internal部分。



跟踪到soinfo_link_image函数



这里可以详细看到链接的过程。

首先是Extract dynamic section。提取动态部分,也就是找到动态节区。



接下来就是Extract useful information from dynamic section,从动态部分提取有用的信息。也就是说这里在解析动态节区。



下一步,Sanity checks.检查



接下来进行判断If this is the main executable, then load all of the libraries from LD_PRELOAD now.如果这是主要的可执行文件,然后加载所有的Library的ld_preload。



在这里调用了soinfo_relocate,我们跟踪进行查看。



这里是做了一个.dynsym的符号信息导入,这里参考大神的一张图。



有了这个图就应该好理解多了。

至此,link就分析到这里。

以上

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: