首页
社区
课程
招聘
[原创]提取嵌入文件中的 PE 文件
发表于: 2010-11-29 17:12 21964

[原创]提取嵌入文件中的 PE 文件

2010-11-29 17:12
21964

有时候会遇到某些程序把整个 PE 文件(就像整个 .exe, .dll, .sys, ...)嵌入到数据段中,在需要的时候才释放出来。
要提取这类程序中的文件,只有动态调试或者手工静态提取。

Exeinfo 本身带有提取功能,但是它的提取方法是找到一个有效的文件头之后就从文件头一直提取到整个文件的末尾。
这样虽然拨出了萝卜,但是带出了不少泥。

只好自己动手写一个程序了。
原理:
标准的 PE 文件结构是:Dos头|PE头|区段表|区段1,区段2,区段3,...
这样要提取出完整的文件,就是从Dos头开始,一直到最后一个区段的末尾。
思路:
先把目标文件映射到内存,获取文件在内存中的指针,遍历整个文件内容。
把所有疑似 PE 文件的内容都保存出来。

相关代码如下:

把文件映射到内存之后,通过内存指针来判断是否是一个 PE 文件,通过简单的判断 DOS 头和 PE 头来确定。

[font=Comic Sans MS][color=#008000]// 是否疑似 PE 文件?
[/color][/font][font=Fixedsys][color=#000000]BOOL IsPeLike[/color][color=#000080]([/color][color=#000000]LPVOID lpImageBase[/color][color=#000080])
{
    [/color][color=#000000]PIMAGE_DOS_HEADER    pDosHeader[/color][color=#000080];
    [/color][color=#000000]PIMAGE_NT_HEADERS    pNtHeader[/color][color=#000080];

    [/color][color=#000000]pDosHeader    [/color][color=#000080]=    ([/color][color=#000000]PIMAGE_DOS_HEADER[/color][color=#000080])[/color][color=#000000]lpImageBase[/color][color=#000080];
    
    [/color][color=#0000FF]if [/color][color=#000080]([/color][color=#000000]IMAGE_DOS_SIGNATURE [/color][color=#000080]!= [/color][color=#000000]pDosHeader[/color][color=#000080]->[/color][color=#000000]e_magic[/color][color=#000080])    [/color][color=#0000FF]return    [/color][color=#000000]FALSE[/color][color=#000080];

    [/color][color=#000000]pNtHeader    [/color][color=#000080]=    ([/color][color=#000000]PIMAGE_NT_HEADERS[/color][color=#000080])(([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]pDosHeader [/color][color=#000080]+ [/color][color=#000000]pDosHeader[/color][color=#000080]->[/color][color=#000000]e_lfanew[/color][color=#000080]);
    [/color][/font][font=Comic Sans MS][color=#008000]// 如果偏移落在结构体范围之外,说明数据是错误的。跳过。
    [/color][/font][font=Fixedsys][color=#0000FF]if[/color][color=#000080](([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]pDosHeader[/color][color=#000080]->[/color][color=#000000]e_lfanew [/color][color=#000080]> (([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]lpImageBase [/color][color=#000080]+ [/color][color=#0000FF]sizeof[/color][color=#000080]([/color][color=#000000]IMAGE_DOS_HEADER[/color][color=#000080]) + [/color][color=#0000FF]sizeof[/color][color=#000080]([/color][color=#000000]IMAGE_NT_HEADERS[/color][color=#000080])))    [/color][color=#0000FF]return    [/color][color=#000000]FALSE[/color][color=#000080];
    [/color][color=#0000FF]if [/color][color=#000080](([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]pNtHeader [/color][color=#000080]> (([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]lpImageBase [/color][color=#000080]+ [/color][color=#0000FF]sizeof[/color][color=#000080]([/color][color=#000000]IMAGE_DOS_HEADER[/color][color=#000080]) + [/color][color=#0000FF]sizeof[/color][color=#000080]([/color][color=#000000]IMAGE_NT_HEADERS[/color][color=#000080])))    [/color][color=#0000FF]return    [/color][color=#000000]FALSE[/color][color=#000080];

    [/color][color=#0000FF]if [/color][color=#000080]([/color][color=#000000]IMAGE_NT_SIGNATURE [/color][color=#000080]!= [/color][color=#000000]pNtHeader[/color][color=#000080]->[/color][color=#000000]Signature[/color][color=#000080])    [/color][color=#0000FF]return    [/color][color=#000000]FALSE[/color][color=#000080];

    [/color][color=#0000FF]return    [/color][color=#000000]TRUE[/color][color=#000080];
}[/color][/font]
[font=Comic Sans MS][color=#008000]// 获取 PE 文件真实大小
[/color][/font][font=Fixedsys][color=#000000]DWORD WINAPI GetRealSize[/color][color=#000080]([/color][color=#000000]LPVOID    lpImageBase[/color][color=#000080])
{
    [/color][color=#000000]PIMAGE_DOS_HEADER    pDosHeader[/color][color=#000080];
    [/color][color=#000000]PIMAGE_NT_HEADERS    pNtHeader[/color][color=#000080];
    [/color][color=#000000]PIMAGE_FILE_HEADER    pFileHeader[/color][color=#000080];
    [/color][color=#000000]PIMAGE_SECTION_HEADER    pSectionHeader[/color][color=#000080];

    [/color][color=#000000]pDosHeader    [/color][color=#000080]=    ([/color][color=#000000]PIMAGE_DOS_HEADER[/color][color=#000080])[/color][color=#000000]lpImageBase[/color][color=#000080];
    [/color][color=#000000]pNtHeader    [/color][color=#000080]=    ([/color][color=#000000]PIMAGE_NT_HEADERS[/color][color=#000080])(([/color][color=#000000]DWORD[/color][color=#000080])[/color][color=#000000]pDosHeader [/color][color=#000080]+ [/color][color=#000000]pDosHeader[/color][color=#000080]->[/color][color=#000000]e_lfanew[/color][color=#000080]);
    [/color][color=#000000]pSectionHeader    [/color][color=#000080]=    [/color][color=#000000]IMAGE_FIRST_SECTION[/color][color=#000080]([/color][color=#000000]pNtHeader[/color][color=#000080]);
    [/color][color=#000000]pFileHeader    [/color][color=#000080]=    ([/color][color=#000000]PIMAGE_FILE_HEADER[/color][color=#000080])&[/color][color=#000000]pNtHeader[/color][color=#000080]->[/color][color=#000000]FileHeader[/color][color=#000080];
    [/color][color=#000000]pSectionHeader    [/color][color=#000080]+=    ([/color][color=#000000]pFileHeader[/color][color=#000080]->[/color][color=#000000]NumberOfSections [/color][color=#000080]- [/color][color=#800080]1[/color][color=#000080]);    [/color][/font][font=Comic Sans MS][color=#008000]//定位到最后一个区块表的开头

    [/color][/font][font=Fixedsys][color=#0000FF]return [/color][color=#000080]([/color][color=#000000]pSectionHeader[/color][color=#000080]->[/color][color=#000000]PointerToRawData [/color][color=#000080]+ [/color][color=#000000]pSectionHeader[/color][color=#000080]->[/color][color=#000000]SizeOfRawData[/color][color=#000080]); [/color][/font][font=Comic Sans MS][color=#008000]// 文件实际大小 = 文件结尾偏移 = 最后一个区段的磁盘偏移 + 最后一个区段的磁盘大小

[/color][/font][font=Fixedsys][color=#000080]}[/color][/font]

[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (34)
雪    币: 13
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
不错
很 强大 的
搬个沙发坐着 玩玩啦
2010-11-29 17:39
0
雪    币: 412
活跃值: (30)
能力值: ( LV5,RANK:70 )
在线值:
发帖
回帖
粉丝
3
多谢分享。。。
2010-11-29 21:13
0
雪    币: 291
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
支持一下~呵呵  不错~
2010-11-29 21:21
0
雪    币: 191
活跃值: (345)
能力值: ( LV9,RANK:450 )
在线值:
发帖
回帖
粉丝
5
只要萝卜,不要泥.
2010-11-29 21:33
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
6
现在大多数那啥里的包含的pe文件都会把dosheader的放在其他地方存在~
2010-11-30 00:07
0
雪    币: 6
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我下下来怎么没有可执行程序啊,也没有源码啊,楼主是否能共享下
2010-11-30 17:28
0
雪    币: 149
活跃值: (151)
能力值: ( LV5,RANK:60 )
在线值:
发帖
回帖
粉丝
8
这贴也解决了我不少疑惑。
2010-11-30 19:42
0
雪    币: 291
活跃值: (169)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
干坏事的好东东
2010-11-30 20:36
0
雪    币: 2323
活跃值: (4113)
能力值: ( LV12,RANK:530 )
在线值:
发帖
回帖
粉丝
10
谢谢分享~~
2010-11-30 20:40
0
雪    币: 1149
活跃值: (888)
能力值: ( LV13,RANK:260 )
在线值:
发帖
回帖
粉丝
11
学习了。。。。。。
2010-12-1 02:36
0
雪    币: 8142
活跃值: (2731)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
12
学习了.好文章..谢谢分享.
2010-12-1 08:59
0
雪    币: 95
活跃值: (15)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
13
学习.....
2010-12-1 10:45
0
雪    币: 72
活跃值: (52)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
14
谢谢分享  打把dota 一会慢慢欣赏
2010-12-1 12:26
0
雪    币: 303
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
15
又见PE  支持LZ好文。
2010-12-1 14:16
0
雪    币: 45
活跃值: (30)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
16
good article thanks
2010-12-2 08:17
0
雪    币: 384
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
强人啊 学习 谢谢分享
2010-12-2 16:06
0
雪    币: 57
活跃值: (55)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
18
有个地方不明白,还请大大解释下:

在判断疑似PE文件时,下面这一句没搞明白……
if ((DWORD)pNtHeader > ((DWORD)lpImageBase + sizeof(IMAGE_DOS_HEADER) + sizeof(IMAGE_NT_HEADERS)))    return    FALSE;

IMAGE_DOS_HEADER与IMAGE_NT_HEADERS之间不是还有个DOS STUB吗?如果将DOS STUB调的很大,它也是满足这个条件的,但还是一个pe呀……
2010-12-2 17:23
0
雪    币: 411
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
19
非常感谢,很不错的文章。
2010-12-2 19:53
0
雪    币: 289
活跃值: (77)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
20
学习中..............................
2010-12-2 22:33
0
雪    币: 40
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
21
如果嵌入的PE是加密过的,就只有动态调试的时候dump出来了...
2010-12-3 14:33
0
雪    币: 534
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
22
学习了 谢谢楼主发帖
2010-12-3 15:57
0
雪    币: 242
活跃值: (25)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
23
好文齐分享~
2010-12-3 20:35
0
雪    币: 1708
活跃值: (586)
能力值: ( LV15,RANK:670 )
在线值:
发帖
回帖
粉丝
24
这个值不是很靠谱,一般的软件都是只显示一条消息。
2010-12-3 20:52
0
雪    币: 301
活跃值: (300)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
25
收藏,感谢
2010-12-4 07:40
0
游客
登录 | 注册 方可回帖
返回
//