开篇语: 本文只是我学习PE过程中的一些学习笔记,没有什么技术含量。:) PE格式是WINDOWS下最常用的可执行文件格式。本文将用win32汇编进行描述。 ------------------------------ | IMAGE_DOS_HEADER | <-------DOS MZ 文件头 ------------------------------ | DOS STUB | <-------DOS可分行代码块 ------------------------------ | IMAGE_NT_HEADERS | <-------PE文件头 ------------------------------ | SECTION TABLE | <-------节表 ------------------------------ | SECTION | <-------节 ------------------------------ | SECTION | ------------------------------ | ... | ------------------------------ PE文件格式一览 上图就是PE文件的基本结构,在PE文件中,代码、数据、资源什么的依据不同的属性而被存放到不同的SECTION(节)中,而每个SECTION的属性和位置等信息用一个IMAGE_SECTION_HEADER结构来描述,所有的IMAGE_SECTION_HEADER结构组成一个SECTION TABLE(节表)。 纵观PE格式,我们可以发现一个PE文件分为两大块:DOS部分(DOS文件头+DOS块)+WIN32部分(PE文件头+节表+节) DOS部分 MZ格式的文件头(IMAGE_DOS_HEADER)和可执行代码(DOS STUB)组成了DOS部分。MZ格式的DOS文件头是由IMAGE_DOS_HEADER结构定义的: IMAGE_DOS_HEADER STRUCT e_magic word ? ;00000000 DOS可执行文件标记,为"MZ",在Windows.inc中预定义为IMAGE_DOS_SIGNATURE。 e_cblp word ? e_cp word ? e_crlc word ? e_cparhdr word ? e_minalloc word ? e_maxalloc word ? e_ss word ? e_sp word ? e_csum word ? e_ip word ? e_cs word ? e_lfarlc word ? e_ovno word ? e_res word 4 dup(?) e_oemid word ? e_oeminfo word ? e_res2 word 10 dup(?) e_lfanew dword ? ;0000003ch 指向PE文件头,以此来引出PE文件头 一般我们只关心e_magic和e_lfanew这两个字段的值。而e_lfanew这个字段的值在这个结构中是最重要的。DOS的可执行代码部分(DOS STUB)一般只是简单的显示一句"This program connot be run in DOS mode."有的是"This program requires win32."这些代码一般是编译器自动完成的,当然我们也可以定制DOS STUB部分,只要在link时使用/stub:dos_file_name.exe选项进行链接就可以了。 :) 实践是检验真理的标准。 -----------------------------cut----------------------------------- .386 .model flat,stdcall option casemap:none include windows.inc include user32.inc include kernel32.inc includelib user32.lib includelib kernel32.lib .data szCaption db 'wensir!',0 szText db 'Hello World!',0 .code start: invoke MessageBox,NULL,offset szText,offset szCaption,MB_OK invoke ExitProcess,NULL end start ---------------------------cut--------------------------------------- 保存为*.asm,我这里保存为wensir.asm,然后编译之: ml /c /coff wensir.asm link /subsystem:windows wensir.obj 现在我们得到一个简单的"Hello World"的win32程序wensir.exe,当然,它是PE格式的。随便到哪里DOWN一个16进制编辑器来,我用的是UltraEdit,将wensir.exe用16进制编辑器打开: ---------------------------------------------------------------------------- 0 1 2 3 4 5 6 7 8 9 A B C D E F 00000000h: 4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 ; MZ?.......... 00000010h: B8 00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 ; ?......@....... 00000020h: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ; ................ 00000030h: 00 00 00 00 00 00 00 00 00 00 00 00 B0 00 00 00 ; ............?.. 00000040h: 0E 1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 ; ..?.???L?Th 00000050h: 69 73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F ; is program canno 00000060h: 74 20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 ; t be run in DOS 00000070h: 6D 6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 ; mode....$....... 00000080h: 5D 65 FD C8 19 04 93 9B 19 04 93 9B 19 04 93 9B ; ]e..摏..摏..摏 00000090h: 97 1B 80 9B 11 04 93 9B E5 24 81 9B 18 04 93 9B ; ?€?.摏?仜..摏 000000a0h: 52 69 63 68 19 04 93 9B 00 00 00 00 00 00 00 00 ; Rich..摏........ 000000b0h: 50 45 00 00 4C 01 03 00 1C 8C 45 42 00 00 00 00 ; PE..L....孍B.... ........ ----------------------------------------------------------------------------- 00000000h处的5A4D便是IMAGE_DOS_HEADER中e_magic字段的值"MZ",0000003ch处的值0000000bh值是e_lfanew,它指向PE文件头的位置。从00000040h-000000a0便是DOS STUB块,从上图中我们可以看到"This program cannot be run in dos mode"字样。 重头戏在WIN32部分。:) 欲知后事如何,请听下回分解。
探密PE文件格式(Portable Executable File Format)(上)
最新推荐文章于 2025-05-15 18:12:23 发布