分享
 
 
 

手工构造一个超微型的 PE 文件

王朝other·作者佚名  2006-01-08
窄屏简体版  字體: |||超大  

;==================================

; 标题:手工构造一个超微型的 PE 文件

; 作者:一块三毛钱

; 日期:2003.12.18

;==================================

最近构造了一个微型的 PE 文件,下面把构造的方法和一点心得写出来和大家交流,也算是

对 PE 格式的一个复习吧。

最终构造好的文件大小是 180 字节,可以在 Win2k 下运行,运行后会弹出一个消息框。

来看看最后生成的文件的内容:

00000000 4D 5A 00 00 50 45 00 00 4C 01 01 00 75 73 65 72 MZ..PE..L...user

00000010 33 32 2E 64 6C 6C 00 00 70 00 0F 01 0B 01 6A 00 32.dll..p.....j.

00000020 B8 8C 00 40 00 50 50 6A 00 EB 05 00 1E 00 00 00 ...@.PPj........

00000030 FF 15 78 00 40 00 C3 00 00 00 40 00 04 00 00 00 ..x.@.....@.....

00000040 04 00 00 00 04 00 00 00 00 00 00 00 04 00 00 00 ................

00000050 00 00 00 00 B4 00 00 00 00 00 00 00 00 00 00 00 ................

00000060 02 00 00 00 00 00 10 00 00 00 00 00 00 00 10 00 ................

00000070 00 10 00 00 00 00 00 00 C4 01 00 80 00 00 00 00 ................

00000080 00 00 00 00 9C 00 00 00 28 00 00 00 5A 54 53 B1 ........(...ZTS.

00000090 E0 D0 B4 00 B4 00 00 00 00 00 00 00 B4 00 00 00 ................

000000A0 00 00 00 00 00 00 00 00 0C 00 00 00 78 00 00 00 ............x...

000000B0 E0 00 00 E0 ....

用 dumpbin 显示文件结构如下:

FILE HEADER VALUES

14C machine (i386)

1 number of sections

72657375 time date stamp Sat Oct 26 21:21:57 2030

642E3233 file pointer to symbol table

6C6C number of symbols

70 size of optional header

10F characteristics

Relocations stripped

Executable

Line numbers stripped

Symbols stripped

32 bit word machine

OPTIONAL HEADER VALUES

10B magic #

106.00 linker version

40008CB8 size of code

6A505000 size of initialized data

5EB00 size of uninitialized data

1E RVA of entry point <----

7815FF base of code

C30040 base of data

400000 image base

4 section alignment

4 file alignment

4.00 operating system version

0.00 image version

4.00 subsystem version

0 Win32 version

B4 size of image

0 size of headers

0 checksum

2 subsystem (Windows GUI)

0 DLL characteristics

100000 size of stack reserve

0 size of stack commit

100000 size of heap reserve

1000 size of heap commit

0 loader flags

800001C4 number of directories

0 [ 0] RVA [size] of Export Directory

9C [ 28] RVA [size] of Import Directory <----

0 [ 0] RVA [size] of Resource Directory

0 [ 0] RVA [size] of Exception Directory

0 [ 0] RVA [size] of Certificates Directory

0 [ 0] RVA [size] of Base Relocation Directory

0 [ 0] RVA [size] of Debug Directory

0 [ 0] RVA [size] of Architecture Directory

0 [ 0] RVA [size] of Special Directory

0 [ 0] RVA [size] of Thread Storage Directory

0 [ 0] RVA [size] of Load Configuration Directory

0 [ 0] RVA [size] of Bound Import Directory

0 [ 0] RVA [size] of Import Address Table Directory

0 [ 0] RVA [size] of Delay Import Directory

0 [ 0] RVA [size] of Reserved Directory

0 [ 0] RVA [size] of Reserved Directory

现在开始具体的步骤

1. Dos Header

IMAGE_DOS_HEADER STRUCT

e_magic <-- 4D 5A

... <-- 其他的都填 0

e_lfanew <-- 04 00 00 00

IMAGE_DOS_HEADER ENDS

为了把文件做得尽可能的小,所以 PE Header 准备放在文件偏移 4 的地方,本来还可以

往前放,由于 Dos Header 的 e_lfanew 必须指向 PE Header 的偏移位置。当放在偏移

4 的地方,Dos Header 的 e_lfanew 正好对应着 PE Header 的 SectionAlignment,

我们只需要把 SectionAlignment 设为 4 就可以达到两个目的。

2. PE Header

IMAGE_NT_HEADERS STRUCT

Signature <-- 50 45 00 00

FileHeader

OptionalHeader

IMAGE_NT_HEADERS ENDS

下面打了 * 标志的意味着不能随便填数据,具体的数据可以参考上面 dumpbin 显示的数

据。凡是没有打 * 标志的可以填入任意数据,我们的代码就准备塞在这些结构里面。

IMAGE_FILE_HEADER STRUCT

Machine *

NumberOfSections *

TimeDateStamp

PointerToSymbolTable

NumberOfSymbols

SizeOfOptionalHeader *

Characteristics *

IMAGE_FILE_HEADER ENDS

IMAGE_OPTIONAL_HEADER32 STRUCT

Magic *

MajorLinkerVersion

MinorLinkerVersion

SizeOfCode

SizeOfInitializedData

SizeOfUninitializedData

AddressOfEntryPoint *

BaseOfCode

BaseOfData

ImageBase *

SectionAlignment *

FileAlignment *

MajorOperatingSystemVersion *

MinorOperatingSystemVersion *

MajorImageVersion *

MinorImageVersion *

MajorSubsystemVersion *

MinorSubsystemVersion *

Win32VersionValue *

SizeOfImage *

SizeOfHeaders *

CheckSum

Subsystem *

DllCharacteristics *

SizeOfStackReserve *

SizeOfStackCommit *

SizeOfHeapReserve *

SizeOfHeapCommit *

LoaderFlags

NumberOfRvaAndSizes *

DataDirectory

IMAGE_OPTIONAL_HEADER32 ENDS

对于 DataDirectory 中不需要的成员可以不要,只留下 Export Directory 和 Import Directory。

整个 PE Header 的大小为 88h 字节,其中 Optional Header 的大小为 70h 字节。

3. Section Table

IMAGE_SECTION_HEADER STRUCT

Name1 <-- ZTS 编写

union Misc

PhysicalAddress

VirtualSize <-- B4 00 00 00

ends

VirtualAddress <-- 00 00 00 00

SizeOfRawData <-- B4 00 00 00

PointerToRawData <-- 00 00 00 00

PointerToRelocations <-- 00 00 00 00

PointerToLinenumbers <-- 00 00 00 00

NumberOfRelocations <-- 00 00

NumberOfLinenumbers <-- 00 00

Characteristics <-- E0 00 00 E0

IMAGE_SECTION_HEADER ENDS

整个文件的内容就是节的内容,最后文件的全部内容会被完整的映射到 400000h 的地址处。

因为映射到内存中后文件的内容后面都是 0,所以相当于节表以一个全 0 元素结束。

4. Import

文件只需要从 user32.dll 中输入一个函数 MessageBoxA,所以输入表中有一个非 0 成员

和一个结束的全 0 成员。就因为要保证有一个全 0 成员来结束输入表,所以也把输入表放

在文件的末尾,和节的情况一样,当文件被映射到内存中后,文件后面的内容都是 0,就相当

于有一个全 0 成员。

一个输入表成员的大小是 20 字节,在节表当中找出没有被利用的域用来放输入表,找到了从

SizeOfRawData 开始的位置。输入表中的 OriginalFirstThunk ,TimeDateStamp 和

ForwarderChain 都是没用的域,不用管他们是什么值,所以不会因为在节表中插入输入表而

改变节表中有用的域:SizeOfRawData 和 PointerToRawData 。

还有的就是 Name 和 FirstThunk 啦,在文件中找到偏移 0Ch 的地方写入 user32.dll,然

后把 Name 指向偏移 0Ch,这个偏移就是文件头中 TimeDateStamp 的偏移位置。在文件中再

找到一个偏移位置 78h 来放 IAT,然后把 FirstThunk 指向偏移 78h,这个偏移是文件头中

NumberOfRvaAndSizes 的偏移位置。在上面虽然说了 NumberOfRvaAndSizes 域不能随便填

数据(打了 * 标志),但这个域只要不填 2 以下的值就可以,所以我们可以利用。

填好的样子如下:

00000070 C4 01 00 80 00 00 00 00 ................

00000080

00000090 B4 00 00 00 ................

000000A0 00 00 00 00 00 00 00 00 0C 00 00 00 78 00 00 00 ............x...

为了减少文件的大小,输入 MessageBoxA 函数是通过序号的方式引入的。

手工写好输入表之后把输入表的偏移和大小填到 DataDirectory 数组的 Import Directory

成员中去,偏移为 9Ch,大小为 28h。

5. 代码

所有准备工作做完就开始写代码,代码也需要从文件头中间找没用的域来存放。找找文件头发现

还有两个地方没有被使用,一个是 MajorLinkerVersion 开始的 14 个字节,偏移为 1Eh,另

一个是 BaseOfCode 开始的 8 个字节,偏移为 30h。

需要的代码写好就是下面的样子:

0000001E: 6A00 push 0

00000020: B88C004000 mov eax,40008C

00000025: 50 push eax

00000026: 50 push eax

00000027: 6A00 push 0

00000029: EB05 jmp 000000030

00000030: FF1578004000 call dword ptr [00400078]

00000036: C3 ret

把代码对应的 16 进制值填到偏移 1Eh 和 30h 处就行了。

保存文件,所有的工作就结束了。最后把注意事项再总结一下:

1. 如果 FileAlignment 小于 200h,则要求 FileAlignment == SectionAlignment >= 2

2. 如果 FileAlignment 小于 200h,则要求 VirtualAddress == PointerToRawData

3. VirtualSize <= SizeOfRawData

4. SizeOfHeaders < SizeOfImage

5. NumberOfRvaAndSizes >= 2 数据目录结构的数量要求不小于 2

6. 节表和输入表都要求有一个结束的全 0 成员

胡乱写了一点,希望不会浪费大家太多时间,如果有错误还望各位大侠指点指点,也好让象我这

样的菜鸟能多学一些东西。

http://tongtian.net/pediybbs/download.php?id=696&sid=43a348bf4f599d7be75756d1086b1703

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有