---
# System prepended metadata

title: File PE

---


# File PE

## DOS MZ Header
### IMAGE_DOS_HEADER
![](https://i.imgur.com/0fMOAj0.png)

 **e_magic** : Chữ ký của PE file, giá trị: 4Dh, 5Ah (Ký tự “MZ”, tên của người sáng lập MS-DOS: Mark Zbikowsky). Giá trị này đánh dấu một DOS Header hợp lệ và được phép thực thi tiếp.
 **e_cblp**: Số byte sử dụng ở trang cuối
 Nhận giá trị 0 khi sử dụng hết byte của trang đó (vì nó sẽ không trống ô nào cả)
 **e_cp** : Số trang trong file đó (Stand for “Count of page”)
 **e_crlc**: Kích thước của giá trị checksum(kiểm tra tính toàn vẹn của PE file để xác thực rằng file không bị giả mạo và có thể thực thi an toàn)
 **e_cparhdr**: Kích thước của chương trình thực thi MS-DOS
 **e_minalloc** : Số đoạn tối thiểu của bộ nhớ
 **e_maxalloc** : Số đoạn tối đa của bộ nhớ
 Một bộ nhớ 16 byte
VD một đoạn bộ nhớ :
 ![](https://i.imgur.com/hDh9J2q.png)
 **e_ss**: giá trị ban đầu của thanh ghi ss (stack segment)
 **e_sp**: giá trị ban đầu của thanh ghi sp (stack pointer)
 **e_csum**: giá trị checksum
 **e_ip**: giá trị ban đầu của các thanh ghi IP (instruction pointer)
 **e_cs**: giá trị ban đầu của các thanh ghi CS (code segment)
 **e_lfarlc**: Địa chỉ của relocation table (là bảng liệt kê tất cả các phần của PE file cần vá lỗi trước khi được tải ở địa chỉ không phải là mặc định)
 **e_ovno**: số lớp phủ của phần hiện tại
 **e_res[4]**: dự trữ không gian để sử dụng trong tương lai
 **e_oemid**: khai báo OEM (Original equipment manufacturer)
 **e_oeminfo**: Thông tin OEM
 **e_lfanew**: địa chỉ của PE Header 
+ cho biết khoảng cách giữa phần đầu của tệp và tiêu đề PE

## MS-DOS Stub Program: 
Hiển thị một tin nhắn tới người dùng như là : “This program cannot be run in DOS mode.”
## PE Header
![](https://i.imgur.com/MEGX9V8.png)
### IMAGE_NT_HEADERS 
#### Signature : chữ kí của PE file
#### FileHeader: Chứa thông tin về PE file: 
![](https://i.imgur.com/5bpMhy2.png)
#### OptionalHeader: chứa dữ liệu tùy chọn về PE file. Một vài trường cần biết:

**Machine**: xác định loại machine của file (Intel 386, Intel 64, MIPS, ARM, …).
**NumberofSections**: số lượng section trong section table.
**SizeOfOptionalHeader**: kích thước của Optional header.
**Characteristics**: xác định đặc điểm của file (exe, dll, …).


* **Magic**: Chứa giá trị để xác định xem file đó có thể thực thi bằng 32-bit hay 64-bit 
* **AddressOfEntryPoint** : Địa chỉ để chỉ đến nơi để thực thi đầu tiên. Nêu không có EP (Entry Point) thì trường này = 0
* **BaseOfCode**: giữ địa chỉ RVA (trí ảo tương đối) của phần code
* **BaseOfData** giữ địa chỉ RVA (trí ảo tương đối) của phần data

+ **ImageBase**: Địa chỉ cơ sở mà hình ảnh được tải vào bộ nhớ
+ **SectionAlignment**: Căn chỉnh của các phần trong tệp khi nó được tải vào bộ nhớ (Chỉ ảnh hưởng với các phần trong bộ nhớ chứ không ảnh hưởng đến tệp)
+ **FileAlignment**: Căn chỉnh các phần trong tệp (Có ảnh hưởng đến tệp)
+ **SizeOfImage**: Kích thước bộ nhớ đã dùng bởi file PE
+ **Subsystem**: dùng để xác định môi trường mà tệp thực thi để chọn hệ thống con thích hợp để tải và thực thi chương trình
## Data directory
* **ExportTable**: Xuất thư mục
* **ImportTable**: Nhập thư mục
-Resource: Thư mục tài nguyên
-Exception: Thư mục ngoại lệ
-Security: Thư mục bảo mật
-Relocation: Bảng di dời cơ sở
-Debug: Thư mục gỡ lỗi
-Copyright: Chuỗi mô tả
-Globalptr: Giá trị máy (MIPS GP)
-Tls Table: Thư mục TLS
-LoadConfig: Tải thư mục cấu hình
-BoundImport: Thư mục nhập giới hạn
-IAT: Bảng địa chỉ nhập (Chứa địa chỉ của các hàm đã nhập)
-DelayImport: Thư mục nhập trễ (Chứa thông tin về các chức năng không được tải cho đến khi cần)
-COM: Thư mục mô tả (Chứa thông tin mà các thành phần được sử dụng bởi tệp thực thi)
-Reserved: Thư mục riêng (Chứa cấu trúc dữ liệu chưa được sử dụng và để sử dụng trong tương lai)

## Section Table : 
Mỗi phần tử chứa thông tin về một section
-Một vài trường quan trọng:
+ VirtualSize: Kích thước thật sự của dữ liệu trên section
+VirtualAddress: RVA(Relative Virtual Address) của section
+SizeOfRawData: Kích thước section data trên ổ đĩa
+PointerToRawData: là offset từ vị trí đầu file tới section data
+Characteristics: đặc tính của section
*Section
Có nhiều section, một file PE cần có tối thiểu 2 section: .data và .code
Một số section thông dụng
+ Executable Code Section: .text , CODE 
+ Data Sections: .data, .rdata, .bss, DATA 
+ Resources Section: .rsrc
+ Export Data Section: .edata
+ Import Data Section: . idata
+ Debug Information Section: .debug
# Phân tích file rufus-3.21.exe
## DOS MZ HEADER
* **e_magic**
![](https://i.imgur.com/q39uz7c.png)
Đây là chữ kí của PE file, đánh dấu DOS header hợp lệ và được phép thực thi tiếp

 * **e_lfanew**
![](https://i.imgur.com/hFl9YPZ.png)

Tiếp theo là ở offset 0x3C chứ offset bắt đầu của PE header. Windows loader sẽ đọc e_lfanew để bỏ qua DOS stub và đi đến PE header
## PE HEADER

### Signature
![](https://i.imgur.com/sutfcOH.png)
4 byte đầu của là chữ kí của PE file

### IMAGE FILE HEADER
* **Machine**
![](https://i.imgur.com/SroW5Bg.png)
Đây là trường machine có giá trị là 0x014C nên đây là IMAGE_FILE_MACHINE_I386
Có thể tham khảo thêm ở link [này](https://learn.microsoft.com/en-us/windows/win32/sysinfo/image-file-machine-constants)
* **NumberOfSections**
![](https://i.imgur.com/AjxDPmu.png)
2 byte tiếp theo của trường NumberOfSection biểu thị có 3 section trong section table
* **TimeDateStamp**
![](https://i.imgur.com/wWGqVlQ.png)
Trường TimeDateStamp có giá trị là 6384E639 có nghĩa là Monday, November 28, 2022 4:47:53 PM
Chuyển đổi tại: [Epoch Converter](https://www.epochconverter.com/)
* **Characteristics**
Một trường cần chú ý là Characteristics có giá trị là 030E chỉ ra các thuộc tính của file 
![](https://i.imgur.com/8YOO4Wm.png)
Những flag đã được khai báo: [Characteristics](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#characteristics)


### IMAGE OPTIONAL HEADER
* **Magic**
![](https://i.imgur.com/A0i75Pe.png)
Trường Magic có giá trị là 0x10B nghĩa là file có thể thực thi bằng 32 bit
![](https://i.imgur.com/fk6IklB.png)
* **AddressOfEntryPoint**
![](https://i.imgur.com/hfrXaas.png)
Trường này lưu địa chỉ ảo tương đối(RVA) của câu lệnh thực thi đầu tiên là 0x3D99A0 
* **SizeOfCode**
![](https://i.imgur.com/4D5Y6Ja.png)
0x149000 là kích thước của code thực thi
* **SizeOfInitializedData**
![](https://i.imgur.com/K71f7QE.png)
0x0B00 biểu thị kích thước của dữ liệu được khởi tạo
* **BaseOfCode**
![](https://i.imgur.com/kwRiz1Z.png)
Địa chỉ RVA của phần code.

