首页
社区
课程
招聘
[原创]Android加壳过程中mprotect调用失败的原因及解决方案
发表于: 2021-3-18 18:33 12258

[原创]Android加壳过程中mprotect调用失败的原因及解决方案

2021-3-18 18:33
12258


函数抽取壳是当前最为流行的DEX加壳方式之一,这种加壳方式的主要流程包含两个步骤:一、将DEX中需要保护的函数指令置空(即抽取函数体);二、在应用启动的过程中,HOOK 类的加载过程,比如ClassLinker::LoadMethod函数,然后及时回填指令。

笔者在实现抽取壳的过程中遇到了一个问题,即在步骤二回填指令之前,需要先调用mprotect将目标内存设置为“可写”,但在初次尝试过程中一直调用失败,于是有了今天这篇文章。

本文探讨的主要内容是mprotect调用失败的根本原因,以及在加壳实现中的解决方案,通过本文的阐述,一方面能够帮助遇到同类问题的小伙伴解决心中的疑惑,另一方面能够给大家提供可落地的实现方案。



以下代码块截取自自定义LoadMethod函数,其目标是将目标函数指令所在内存页的属性修改为可写——通过mprotect函数的参数“PROT_WRITE”指定,实际结果是mprotect调用失败了,返回”-1“,errno为”13“。



”13“号errno的符号为EACCES,查看linux手册可知是权限问题。手册中给出一个可能的场景,即如果使用mmap映射一个以”只读“模式打开的文件,然后使用mprotect尝试修改内存属性为可写,就会返回EACCES错误。



接下来我们将沿着这个可能的场景,首先验证DEX文件是否以只读模式打开,然后再进行下一步分析。



使用strace跟踪应用的系统调用,验证了DEX文件的打开模式为只读模式——"O_RDONLY",然后通过mmap2将DEX文件映射进内存,内存属性为只读的私有映射。



为了进一步证实并彻底理清背后的逻辑,我研究了下mprotect的设计文档[1]。mprotect是用户空间PAX的一部分,它的核心目标是缓解可利用内存漏洞被利用的情况,所以我理解mprotect实际上就是“memory protect”,它的主要目的是从安全的角度保护内存:


The goal of MPROTECT is to help prevent the introduction of new executable

   code into the task's address space. This is accomplished by restricting the

   mmap() and mprotect() interfaces.


mprotect通过内存属性控制内存的访问权限,其中安全状态良好的属性组合包括如下几种:


VM_WRITE

VM_MAYWRITE

VM_WRITE | VM_MAYWRITE

VM_EXEC

VM_MAYEXEC

VM_EXEC | VM_MAYEXEC


即内存要么是“可写”的,要么是“可执行”的,“可写”与“可执行”必须互斥,这样才能阻断“写入并执行”的内存攻击。

理解了mprotect的设计理念之后,我们再回到本文所遇到的问题本身:为什么以只读方式打开的DEX文件映射到内存之后,无法使用mprotect修改为“可写”内存?

根据mprotect设计文档的阐述,mprotect主要通过VM_MAYWRITE控制内存是否可被设置为“可写”,该属性的设置时机在mmap调用之时:


VM_WRITE | VM_MAYWRITE or VM_MAYWRITE if PROT_WRITE was requested at

mmap() time


mmap首先将所有可能的属性标致置位,然后再进行合法性检查:


kernel/msm/+/refs/heads/android-msm-vega-4.4-oreo-daydream/mm/mmap.c


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

最后于 2021-3-18 19:12 被kxliping编辑 ,原因:
收藏
免费 10
支持
分享
最新回复 (7)
雪    币: 7
活跃值: (275)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
写得不错,感谢分享!!!
2021-3-18 21:08
0
雪    币: 19
活跃值: (78)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2021-3-18 21:12
0
雪    币: 6573
活跃值: (3873)
能力值: (RANK:200 )
在线值:
发帖
回帖
粉丝
4
从一个壳的分析直接分析到内核, 从教程到真实生产环境的发散,写的很清楚,继续期待新作
2021-3-22 11:24
0
雪    币: 1337
活跃值: (2422)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
5
LowRebSwrd 从一个壳的分析直接分析到内核, 从教程到真实生产环境的发散,写的很清楚,继续期待新作
多谢支持
2021-3-23 09:59
0
雪    币: 5330
活跃值: (5464)
能力值: ( LV9,RANK:170 )
在线值:
发帖
回帖
粉丝
6
mark
2021-3-23 09:59
1
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
7
请教个问题 我hook了MapFileAtAddress 但是传入的filename 始终没有我的dex是咋回事呀
2021-9-14 17:36
0
雪    币: 29
活跃值: (5647)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
可以尝试将修改后的内容写入临时文件,然后通过MAP_PRIVATE | MAP_FIXED覆盖内存
2021-9-14 19:41
0
游客
登录 | 注册 方可回帖
返回
//