首页
社区
课程
招聘
[原创]通过捕获段错误实现的自定义linker
发表于: 2019-11-19 12:43 7377

[原创]通过捕获段错误实现的自定义linker

2019-11-19 12:43
7377

最近在思考“如何在划水的同时让自己觉得不是在划水”,再加上一直对无源码的so加固方案有些兴趣,就找了自定义linker实现加固的方向在慢慢琢磨。
然而想着想着思路慢慢歪了,就有了这个四不像的玩意,于是就想着把这个思路分享给大家。当然目前只是一个demo版本,大部分工作只是完成了一个可以直接运行text段指令的自定义linker,距离真正意义上的加固还有很大的距离。

目前实现了如下的功能

xlinker的实现分为parser和loader两部分。
parser用以解析正常ELF文件,提取出其中的代码段,保存为.bin文件,并将解析获得的plt, got, rodata, bss等信息用json的形式保存下来,后简称plk;
loader即自定义的linker,加载bin,结合plk完成一系列的修复操作。
由于parser部分的代码还有不少坑需要填,这里主要讲loader这一块。

首先以PROT_NONE mmap足够大的页空间,从第二页开始将只含有指令数据的bin文件加载进来,并赋予bin文件所在的页以可读可写可执行的属性,这样text段的指令在访问plt/got/bss/rodata时就会抛出segv异常。

接下里解析plk文件,获取数据以及重定位相关的信息,plk文件形如

其中off表示距离代码加载基址的偏移,foo的含义视类型而定。plt项中foo表示符号名;got中表示全局变量名,由于plt在实现上先于got修复,这里为了实现方便(偷懒)只对canary指针和标准io流指针做了记录;rodata中foo表示常量的内容,这里未对字符串以外的内容做处理,需要继续完善;bss中foo代表变量距离bss段首地址的偏移。
将上述内容保存在内存中,修复因PROT_NONE引起的段错误时会用到。

首先需要设定segv_handler。

由于sa_flags = SA_SIGINFO,handler声明形如_segv_handler(int signal_number, siginfo_t* si, void* context),这里主要的思路就是主动去修改context中寄存器因为PROT_NONE而无法访问的内存地址的值,再return,利用内核jump会出错时的位置重新执行,重新执行时的上下文即为参数中context。
在摸索过程中一开始并没有意识到这一点,尝试用内联汇编修改寄存器以后主动pop pc跳回目标位置,但由于sp难以恢复到出错时的值,所以最后没有采用。这里一并分享给大家,可以主动恢复除了sp以外的寄存器。

而在实际实现中,由于只需修改context寄存器中存在异常的值,因此代码也比较简单,遍历一下解析的plk信息,遍历各个寄存器即可。
修复plt的代码如下:

xpltInfo中offset即为json中的off,value为foo。ctx+0x20的位置为r0的偏移,依次递增,0x60的位置为cpsr。
又由于调用plt桩的代码会用到形如add pc, r12, pc的指令,不能像bx,ldr一样有切换arm/thumb的效果。
图片描述
这里需要根据dlsym获取的地址最低位判断是arm还是thumb,并强制修改CPSR中的T位。

在修复got段的全局变量时,只对__stack_chk_guard_ptr与__sF做了记录,因此在代码里也写死处理了,需要后续完善。

got,rodata,bss的修复代码也类似,这里不再赘述,具体可见源码。

https://github.com/Umiade/xlinker
parser代码目前有不少坑要填,后面再传了(

执行loader目录中的build脚本,将编译出来的xlinker可执行文件、test/dm.bin与test/dm.plk push到手机,如/data/local/tmp目录,
执行如下命令:

图片描述
图片描述

....

 
 

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

最后于 2019-11-19 12:45 被Umiade编辑 ,原因:
收藏
免费 4
支持
分享
最新回复 (6)
雪    币: 6573
活跃值: (3893)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
2
good,工程量不小
2019-11-19 14:03
0
雪    币: 180
活跃值: (1313)
能力值: ( LV4,RANK:40 )
在线值:
发帖
回帖
粉丝
3
兄弟想法很奇特
2019-11-19 17:36
0
雪    币: 1110
活跃值: (3274)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
4
脑洞惊奇,期待楼主也填一下ARM64的坑
2019-11-19 20:36
0
雪    币: 26225
活跃值: (63302)
能力值: (RANK:135 )
在线值:
发帖
回帖
粉丝
5
感谢分享!
2019-11-25 13:53
0
雪    币: 2907
活跃值: (1301)
能力值: ( LV12,RANK:215 )
在线值:
发帖
回帖
粉丝
6
想法很棒,划水也是门艺术
2019-11-25 20:16
0
雪    币: 0
活跃值: (353)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
自定义linker 如何解决和系统的linker 冲突
2020-5-10 16:41
0
游客
登录 | 注册 方可回帖
返回
//