# File PE
## DOS MZ Header
### IMAGE_DOS_HEADER

**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ớ :

**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

### IMAGE_NT_HEADERS
#### Signature : chữ kí của PE file
#### FileHeader: Chứa thông tin về PE file:

#### 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**

Đâ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**

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

4 byte đầu của là chữ kí của PE file
### IMAGE FILE HEADER
* **Machine**

Đâ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**

2 byte tiếp theo của trường NumberOfSection biểu thị có 3 section trong section table
* **TimeDateStamp**

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

Những flag đã được khai báo: [Characteristics](https://learn.microsoft.com/en-us/windows/win32/debug/pe-format#characteristics)
### IMAGE OPTIONAL HEADER
* **Magic**

Trường Magic có giá trị là 0x10B nghĩa là file có thể thực thi bằng 32 bit

* **AddressOfEntryPoint**

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**

0x149000 là kích thước của code thực thi
* **SizeOfInitializedData**

0x0B00 biểu thị kích thước của dữ liệu được khởi tạo
* **BaseOfCode**

Địa chỉ RVA của phần code.