# 浅谈被加壳ELF文件的DUMP修复

Author: 乌云历史资料库 (@wooyun_archive)
Published: 2015-06-10T07:45:00Z
Canonical: https://wepostx.com/topics/848

> 乌云历史资料归档
>
> **原始作者：** 腾讯电脑管家
> **原始编号：** superkieran-wooyundrops:593
> **原始发布时间：** 2015-06-10 15:45
> **声明：内容仅用于技术研究和个人使用，版权归 wooyun.org。**

---

前面的文章中，我已经介绍了如何调试被加壳的ELF，这里不在叙述，直接进入正题，以某加固为例，如何DUMP和修复被加壳的ELF，使其能调试加载
我们先来看看被加壳ELF的头和Program Header

![原文图片](/media/2016/06/c5d64b3b8b039d4533dadbee96017463)

![原文图片](/media/2016/06/c70c83d11d83818f811bf708df9b4085)

首先我要让调试器停在入口点0x3860的位置
开始DUMP修复之旅，我的第一次DUMP修复的方法，延续了PE的思路，结果失败了
失败的原因并不是思路不对，而是细节上出现问题
第一次DUMP的方法：
1.废除不影响加载的section(直接把结构体填0)，只关心PT_LOAD和PT_DYNAMIC两种类型节 2.计算DUMP文件最大值 align_up(0x28ca4, 0x8000) = 0x31000 3.将offset和va变成相等值，filesize和memsize按照align对齐 4.根据PT_LOAD节数据把数据DUMP出来，把DUMP数据放进文件里
那么根据上图描述数据，应该有两块儿

```text
PT_LOAD : 0 ----align_up(0x12044, 0x8000) = 0 ----- 0x1B000 PT_LOAD : align_down(0x28ca4,0x1000) = 0x28000 ---- align_up(0x28ca4, 0x8000) = 0x31000
```
因为安卓也是linux内核，内存页对齐粒度为4K(0x1000)
按照上述方法DUMP完，我们来看看IDA加载以后，JNI_ONLOAD的样子

![原文图片](/media/2016/06/fbe4c6da6d35a8de06959ae375bc0aae)

看下红色的部分，奇怪了，本来应该有的代码去哪里了??
0x221b0这个地址竟然无效
可是动态调试器中明明可以看到这段代码：

![原文图片](/media/2016/06/57e6ccb11a5a3171da87ce762be92d4b)

对照Program Header, 再看0x221b0这个地址，PT_LOAD节中并没有描述这个地址 所以，失败就是在这个地方，壳的代码里一定是mmap了这段内存，将解密后的数据，放进去，并修改了内存属性
通过跟踪壳代码，发现确实如此，壳代码通过svc 0，调用了mmap,mprotect两个函数

```text
mmap(0x3000, 0x23710, 0x3, 0x32, 0xffffffff, 0x0) map页属性：PROT_READ | PROT_WRITE mprotect(0x3000, 0x23710, 0x5)
```
修改页属性：PROT_READ | PROT_EXEC 具体参数说明请参考帮助文档
这段区域起始地址：0x3000 大小：align_up(0x23710, 0x1000) = 0x24000 结束地址：0x3000 + 0x24000 = 0x27000 0x221b0这个地址正好在0x3000---|0x27000这个范围里
通过上述过程，重新总结DUMP方法如下

- 废除不影响加载的section(直接把结构体填0)，只关心PT_LOAD和PT_DYNAMIC两种类型节

- 计算DUMP文件最大值 align_up(0x28ca4, 0x8000) = 0x31000

- 只保留一个PT_LOAD节，从0到0x31000 将整块儿数据DUMP下来直接写入文件，修改align为0x1000，修改flag为RWE

- 修改PT_DYNAMIC节的offset,和VA相等 修复完的节表如下：

![原文图片](/media/2016/06/6e195fe875891eb514ab7c5082768267)

最后一个注意的地方，就是干掉INIT段或者是INIT_ARRAY段
干掉INIT方法：定位INIT描述的数据偏移，将偏移+8的数据，前移8个字节
干掉INIT_ARRAY方法：定位到VA处，按照结构，将数据填充为0xffffffff或者0
看下图，INIT段已经不存在了

![原文图片](/media/2016/06/1512e2bdf14b53323e392cb7f0523d7e)

我们来打开IDA，加载修复的文件，看看效果：

![原文图片](/media/2016/06/04a36e413e1ed6a31305498a911e63ff)

![原文图片](/media/2016/06/8d6ca7e2b7a95f3c583f90a94f788ab5)

数据完整，再看看动态加载的效果

![原文图片](/media/2016/06/379935db927d7e97f63cfa74b816cf63)

加载成功~~~
哈哈，至此，修复完成

## Replies
