首页
社区
课程
招聘
[原创]逆向技巧之计算dump文件大小
发表于: 2018-12-27 10:27 7263

[原创]逆向技巧之计算dump文件大小

2018-12-27 10:27
7263

dump文件是逆向中经常会遇到的一个问题。如果病毒将恶意模块解密出来后,直接在内存中加载执行,就不会有文件释放。为了能够使用IDA分析恶意模块功能或者单独调试,需要将它dump下来,即转存为文件。

但dump之前有一个问题,原始文件的大小是多少呢?

比如像下面这样,病毒解密出PE文件内容后将其分段写入其他进程。这里我们可以定位到PE文件在内存中的起始地址0x011860D0,可以看到“MZ”标志。现在的问题是,结束地址是什么?

可以有3种方法:

直接往后拖,看到哪里像是文件末尾,就当做结束地址。这种方法需要非常丰富的逆向经验,适用于少数逆向大佬。

直接拖到内存块末尾,把它当做结束地址。这种方式也不是不可以,毕竟很多时候,解密出来的PE文件都是放在单独一块内存中的 ,而且就算dump出的文件末尾多了一些内容,也不会影响分析,但如果要提取文件的MD5的话就麻烦了。

我们先看一下PE文件的结构及其在内存中的映射方式。PE文件主要分为DOS头部PE文件头块表各区块以及文件末尾的不能映射部分(如调试信息等,在逆向时用处不大,而且很多时候都没有这部分)。

其中除了不能映射部分,其他部分的大小我们都是可以通过解析PE文件获取到的。我们现在只是需要获取总的大小,可以先把DOS头部、PE文件头、块表这几部分dump出来。只需要找到块表的位置即可,在内存中很容易找,一般带有“.text”、“.data”这样的区块名字符串,这里由于dump对象加了upx壳,所以区块名是“UPX0”“UPX1”,也是同样的道理。

如果不确定块表的结束地址的话,直接找到后面0x00结束的地方全部dump下来就可以了。这里是0x11864AA,大小为0x3DB。dump多了也没关系,这里不需要精准。

用LoadPE dump下来。

将dump下来的PE头放到DIE里面,主要关注“Offset”和“R.Size”两项,分别表示区块在文件中的偏移以及大小。我们直接找到最后一个区块“UPX2”的偏移以及大小:0x66a00,0x200。相加为0x66c00,即为需要dump文件除了文件末尾不能映射部分以外的大小。

重新dump。

Dump出的文件的hash值可以在VT中找到,说明这是一个完整的文件。

由于在这个例子中,被dump的文件没有文件末尾的不能映射部分,所以能够精确dump。如果有这部分内容的情况下,就不能做到精确了,毕竟PE文件末尾的这部分大小是没有办法通过计算获取到的。不过对于被dump的文件,这部分内容对于分析它是没有影响的,只是会影响提取MD5。


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 4
支持
分享
最新回复 (18)
雪    币: 4709
活跃值: (1575)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
2
明白了,学到。
2018-12-27 10:46
1
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
666 感谢分享!
2018-12-27 10:58
0
雪    币: 12848
活跃值: (9142)
能力值: ( LV9,RANK:280 )
在线值:
发帖
回帖
粉丝
4
PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)temp;
               PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HEADERS)(temp + dosheader->e_lfanew);

               PIMAGE_SECTION_HEADER pSecHeader = (PIMAGE_SECTION_HEADER)
                       ((PUCHAR)ntheader + offsetof(IMAGE_NT_HEADERS, OptionalHeader) + ntheader->FileHeader.SizeOfOptionalHeader);

               for (UINT i = 0; i < ntheader->FileHeader.NumberOfSections; i++)
               {
                       if (pSecHeader[i].PointerToRawData + pSecHeader[i].SizeOfRawData > fileSize)
                               fileSize = pSecHeader[i].PointerToRawData + pSecHeader[i].SizeOfRawData;
               }

不解释连招

顺便一提很多易语言大手子喜欢把PE文件大小写在MZ前面四个字节
2018-12-27 11:22
0
雪    币: 612
活跃值: (184)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Le0
5
hzqst PIMAGE_DOS_HEADER dosheader = (PIMAGE_DOS_HEADER)temp; PIMAGE_NT_HEADERS ntheader = (PIMAGE_NT_HE ...
666,代码实现很奈斯
2018-12-27 11:43
0
雪    币: 6314
活跃值: (952)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
6
感谢分享
2018-12-27 22:01
0
雪    币: 783
活跃值: (1121)
能力值: ( LV5,RANK:78 )
在线值:
发帖
回帖
粉丝
7
文章不错..不过我一般都是工具党..直接exeinfo删除附加数据 - -
2018-12-27 22:32
0
雪    币: 612
活跃值: (184)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Le0
8
bambooqj 文章不错..不过我一般都是工具党..直接exeinfo删除附加数据 - -
这个方法不错
2018-12-28 09:13
0
雪    币: 3725
活跃值: (614)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
9
上个月还在想, 准备写一个OD插件来专门dump这种内存包含PE的数据, 年底比较忙, 各种报告PPT要写, 一直都没空写代码.
理论上找到PE头的地址, 通过解析PE头获取PE文件大小信息, dump整个PE文件是没有问题的, 多谢楼主的实践贴.
这种dump插件以后还可以扩展成upx/asp脱壳工具, 这样的话比ollydump那个插件还要好用了.  ^_^
2018-12-28 11:35
0
雪    币: 267
活跃值: (438)
能力值: ( LV9,RANK:190 )
在线值:
发帖
回帖
粉丝
10
Dump出的文件的效验原始的 hash值或md5值 在这里说出来真是简单! 事实中效验成功的能有几例?
2018-12-28 12:17
0
雪    币: 2473
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
这三种方法只能对付循规蹈矩一次性NEW足够大的空间 然后连接读取PE的
如果是分段NEW分段读取 或者是尽可能的抹PE头 这三种方法都无效
2018-12-28 14:19
0
雪    币: 612
活跃值: (184)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Le0
12
逻辑错误 上个月还在想, 准备写一个OD插件来专门dump这种内存包含PE的数据, 年底比较忙, 各种报告PPT要写, 一直都没空写代码. 理论上找到PE头的地址, 通过解析PE头获取PE文件大小信息, du ...
跟脱壳的情况应该还不太一样,脱壳时应该是dump的映射后的内存映像
2018-12-28 14:25
0
雪    币: 612
活跃值: (184)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Le0
13
linziqingl Dump出的文件的效验原始的 hash值或md5值 在这里说出来真是简单![em_1][em_1][em_1] 事实中效验成功的能有几例?[em_19][em_19][em_19]
确实是的,所以后面我也说了
2018-12-28 14:29
0
雪    币: 612
活跃值: (184)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
Le0
14
PYGame 这三种方法只能对付循规蹈矩一次性NEW足够大的空间 然后连接读取PE的 如果是分段NEW分段读取 或者是尽可能的抹PE头 这三种方法都无效
没错,毕竟攻防无止尽的
最后于 2018-12-28 14:31 被Le0编辑 ,原因:
2018-12-28 14:31
0
雪    币: 3725
活跃值: (614)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
15
aWelBs 跟脱壳的情况应该还不太一样,脱壳时应该是dump的映射后的内存映像[em_4]
差不多的, 一个是文件对齐, 一个是内存对齐. 用4楼的for循环, 拓展一下代码, 就可以从文件展开到内存, 也可以从内存保存到文件.
2018-12-28 20:06
0
雪    币: 43
活跃值: (388)
能力值: ( LV9,RANK:140 )
在线值:
发帖
回帖
粉丝
16
如果是拷贝exe的话我有个更简单的办法,直接dump一大段数据下来,然后用objcopy拷贝出来。完全不用计算。缺点就是dump下来的文件md5变了。
2018-12-28 23:20
0
雪    币: 45
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
讲解得很不错,学习中
2018-12-28 23:59
0
雪    币: 9057
活跃值: (1615)
能力值: ( LV2,RANK:15 )
在线值:
发帖
回帖
粉丝
18
感谢楼主分享这么好的东西,受益匪浅…
2018-12-29 10:42
0
雪    币:
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
19
66666666
2020-9-19 10:08
0
游客
登录 | 注册 方可回帖
返回
//