程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> 匯編語言 >> PE文件結構剖析

PE文件結構剖析

編輯:匯編語言

大家都很清楚,了解可執行文件的結構有多麼的重要,DOS下如此,Windows下也同樣如此。如果你想加密程序,編寫病毒等,了解PE文件結構必是不可缺少的。大家也可能見到很多這方面的資料,但都是從理論上解說一下,很少見到拿一個具體文件開刀的。這裡,我就用前面“系列4”中的文件4.EXE為例來剖析一下PE文件格式,因時間關系,不可能一下子就寫的很完善,如可行,以後再慢慢補來。

=============================================================== 
對於本文件,紅色外框將文件分成4個部分,各部分的內容是:
Ⅰ - 文件頭;
Ⅱ - 代碼段;.text section
Ⅲ - 引入表;.rdata section
Ⅳ - 數據段;.data section

可以看出,每部分都有大量的垃圾數據,用綠色的叉號進行標注。

我們先從整體看一下文件的結構:(要結合PE剖析圖來看)
----------------------------------------------------------
1、IMAGE_DOS_HEADER
雖然你這是Windows下的程序,但保不准別人會拿它到DOS下執行,當然肯定不是想象的結果啦。該文件頭和DOS下可執行文件的文件頭基本上是一樣的,所以你也可以認為它是一個標准的DOS下的EXE文件,只不過程序執行的結果是顯示一個錯誤信息:This program cannot be run in DOS mode.,意思是這是Windows下的程序,到Windows下用吧!
該結構的最後一個元素e_lfanew指示PE文件頭的位置,是個重要的數據。
對本例,該元素位於文件偏移量是3C的位置,其值是000000B0。
2、dos下執行時的程序部分
3、dos執行時顯示的錯誤信息
4、垃圾數據
-----------------------------------------------------------
就是PE文件頭啦,它是一個IMAGE_NT_HEADERS STRUCT結構
5、PE文件標記,db 'PE',0,0
6、是一個IMAGE_FILE_HEADER結構
7、是一個IMAGE_OPTIONAL_HEADER結構
8、是一個IMAGE_DATA_DIRECTORY結構數組,共16項
9、是一個IMAGE_SECTION_HEADER結構數據,項數由結構6中 NumberOfSections 確定。
本例中位於偏移量B6處,其值是0003
-------------------------------------------------------------
10、程序的代碼部分,也就是.text section的內容
-------------------------------------------------------------
下面是.rdata section的內容,注意這裡的指針值都是“虛擬地址”,即在內存執行時的地址。

11、IDA (Import Address table)用來存放函數的地址值。加載器執行文件時會重寫該部分內容,程序中調用dll中的函數就是通過這裡轉到函數的真正位置的。
12、是一個IMAGE_IMPORT_DESCRIPTOR結構數組,項數怎麼定呢?
這麼說吧,假如你的程序中要調用N個動態鏈接庫中的函數,那麼項數就是N+1,總後一項結構中的數據全0,表示結束。
本例中的程序僅調用Kernell32.dll中的函數,所以此處有兩個這樣的結構。
13、是一個IMAGE_THUNK_DATA結構數組,該結構實際就是一個DWORD值,每個DWORD值指示一個IMAGE_IMPORT_BY_NAME結構,反應程序要調用的函數名。最後一個DWORD值為0,表示結束。
14、數據,由12、13中的內容指定。

==============================================================
下面是用UltraEdit打開4.exe後的抓圖(處理)

若下面沒圖,點這裡,可能還要刷新。

==============================================================
下面是用W32dasm反匯編4.exe後的詳細內容,供參考:
Disassembly of File: 4.exe
Code Offset = 00000400, Code Size = 00000200 ;在文件中的偏移量是400H,大小200H(調整後的)
Data Offset = 00000800, Data Size = 00000200 ;在文件中的偏移量是800H,大小200H(調整後的)

Number of Objects = 0003 (dec), Imagebase = 00400000h ;section的個數是3,基地址是400000H

Section 相對虛擬地址 在文件中的偏移量 調整後的大小 段屬性標記
Object01: .text RVA: 00001000 Offset: 00000400 Size: 00000200 Flags: 60000020
Object02: .rdata RVA: 00002000 Offset: 00000600 Size: 00000200 Flags: 40000040
Object03: .data RVA: 00003000 Offset: 00000800 Size: 00000200 Flags: C0000040

+++++++++++++++++++ IMPORTED FUNCTIONS ++++++++++++++++++
Number of Imported Modules = 1 (decimal) ;程序僅調用一dll中的函數

Import Module 001: KERNEL32.dll

+++++++++++++++++++ IMPORT MODULE DETAILS +++++++++++++++

Import Module 001: KERNEL32.dll 

Addr:00002064 hint(013D) Name: GetStdHandle ;將調用Kernel32中的三個函數
Addr:00002074 hint(02B9) Name: WriteFile ;這個Addr給出的值可不函數的真正地址
Addr:00002048 hint(0075) Name: ExitProcess ;執行時加載器會修改這三個值

+++++++++++++++++++ ASSEMBLY CODE LISTING ++++++++++++++++++
//********************** Start of Code in Object .text **************
Program Entry Point = 00401000 (4.exe File Offset:00001600)

* Possible StringData Ref from Data Obj ->"How are you !"
|

//******************** Program Entry Point ********
:00401000 6800304000 push 00403000
:00401005 E80E000000 call 00401018
:0040100A 6A00 push 00000000

* Reference To: KERNEL32.ExitProcess, Ord:0075h
|
:0040100C E801000000 Call 00401012
:00401011 CC int 03

* Referenced by a CALL at Address:
|:0040100C 
|

* Reference To: KERNEL32.ExitProcess, Ord:0075h
|
:00401012 FF2508204000 Jmp dword ptr [00402008]

* Referenced by a CALL at Address:
|:00401005 
|
:00401018 55 push ebp
:00401019 8BEC mov ebp, esp
:0040101B 83C4F4 add esp, FFFFFFF4
:0040101E 6AF5 push FFFFFFF5

* Reference To: KERNEL32.GetStdHandle, Ord:013Dh
|
:00401020 E863000000 Call 00401088
:00401025 8945FC mov dword ptr [ebp-04], eax
:00401028 FF7508 push [ebp+08]
:0040102B E820000000 call 00401050
:00401030 8945F4 mov dword ptr [ebp-0C], eax
:00401033 6A00 push 00000000
:00401035 8D45F8 lea eax, dword ptr [ebp-08]
:00401038 50 push eax
:00401039 FF75F4 push [ebp-0C]
:0040103C FF7508 push [ebp+08]
:0040103F FF75FC push [ebp-04]

* Reference To: KERNEL32.WriteFile, Ord:02B9h
|
:00401042 E847000000 Call 0040108E
:00401047 8B45F8 mov eax, dword ptr [ebp-08]
:0040104A C9 leave
:0040104B C20400 ret 0004


:0040104E CC int 03
:0040104F CC int 03

* Referenced by a CALL at Address:
|:0040102B 
|
:00401050 55 push ebp
:00401051 8BEC mov ebp, esp
:00401053 53 push ebx
:00401054 8B4508 mov eax, dword ptr [ebp+08]
:00401057 8D5003 lea edx, dword ptr [eax+03]

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040106F(C)
|
:0040105A 8B18 mov ebx, dword ptr [eax]
:0040105C 83C004 add eax, 00000004
:0040105F 8D8BFFFEFEFE lea ecx, dword ptr [ebx+FEFEFEFF]
:00401065 F7D3 not ebx
:00401067 23CB and ecx, ebx
:00401069 81E180808080 and ecx, 80808080
:0040106F 74E9 je 0040105A
:00401071 F7C180800000 test ecx, 00008080
:00401077 7506 jne 0040107F
:00401079 C1E910 shr ecx, 10
:0040107C 83C002 add eax, 00000002

* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00401077(C)
|
:0040107F D0E1 shl cl, 1
:00401081 1BC2 sbb eax, edx
:00401083 5B pop ebx
:00401084 C9 leave
:00401085 C20400 ret 0004

* Referenced by a CALL at Address:
|:00401020 
|

* Reference To: KERNEL32.GetStdHandle, Ord:013Dh
|
:00401088 FF2500204000 Jmp dword ptr [00402000] ;轉去IDA表中對應的函數

* Reference To: KERNEL32.WriteFile, Ord:02B9h
|
:0040108E FF2504204000 Jmp dword ptr [00402004]

==============================================================
下面是PE文件剖析時設計到的結構,來自Windows.inc文件,供參考:

IMAGE_DOS_HEADER STRUCT
e_magic WORD ?
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 ?
IMAGE_DOS_HEADER ENDS

IMAGE_NT_HEADERS STRUCT
Signature DWORD ?
FileHeader IMAGE_FILE_HEADER <>
OptionalHeader IMAGE_OPTIONAL_HEADER32 <>
IMAGE_NT_HEADERS ENDS

IMAGE_FILE_HEADER STRUCT
Machine WORD ?
NumberOfSections WORD ?
TimeDateStamp DWORD ?
PointerToSymbolTable DWORD ?
NumberOfSymbols DWORD ?
SizeOfOptionalHeader WORD ?
Characteristics WORD ?
IMAGE_FILE_HEADER ENDS

IMAGE_NUMBEROF_DIRECTORY_ENTRIES equ 16

IMAGE_OPTIONAL_HEADER32 STRUCT
Magic WORD ?
MajorLinkerVersion BYTE ?
MinorLinkerVersion BYTE ?
SizeOfCode DWORD ?
SizeOfInitializedData DWORD ?
SizeOfUninitializedData DWORD ?
AddressOfEntryPoint DWORD ?
BaseOfCode DWORD ?
BaseOfData DWORD ?
ImageBase DWORD ?
SectionAlignment DWORD ?
FileAlignment DWORD ?
MajorOperatingSystemVersion WORD ?
MinorOperatingSystemVersion WORD ?
MajorImageVersion WORD ?
MinorImageVersion WORD ?
MajorSubsystemVersion WORD ?
MinorSubsystemVersion WORD ?
Win32VersionValue DWORD ?
SizeOfImage DWORD ?
SizeOfHeaders DWORD ?
CheckSum DWORD ?
Subsystem WORD ?
DllCharacteristics WORD ?
SizeOfStackReserve DWORD ?
SizeOfStackCommit DWORD ?
SizeOfHeapReserve DWORD ?
SizeOfHeapCommit DWORD ?
LoaderFlags DWORD ?
NumberOfRvaAndSizes DWORD ?
DataDirectory IMAGE_DATA_DIRECTORY IMAGE_NUMBEROF_DIRECTORY_ENTRIES dup(<>)
IMAGE_OPTIONAL_HEADER32 ENDS

IMAGE_OPTIONAL_HEADER equ 

IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD ?
isize DWORD ?
IMAGE_DATA_DIRECTORY ENDS

IMAGE_SIZEOF_SHORT_NAME equ 8

IMAGE_SECTION_HEADER STRUCT
Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?)
union Misc
PhysicalAddress dd ?
VirtualSize dd ?
ends
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
IMAGE_SECTION_HEADER ENDS

IMAGE_IMPORT_DESCRIPTOR STRUCT
union
Characteristics dd ?
OriginalFirstThunk dd ?
ends
TimeDateStamp dd ?
ForwarderChain dd ?
Name1 dd ?
FirstThunk dd ?
IMAGE_IMPORT_DESCRIPTOR ENDS


IMAGE_IMPORT_BY_NAME STRUCT
Hint dw ?
Name1 db ?
IMAGE_IMPORT_BY_NAME ENDS

IMAGE_THUNK_DATA32 STRUCT
union u1
ForwarderString dd ?
Function dd ?
Ordinal dd ?
AddressOfData dd ?
ends
IMAGE_THUNK_DATA32 ENDS

IMAGE_THUNK_DATA EQU

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved