新手——010純手工編輯打造PE文件

新手——010純手工編輯打造PE文件

工具

1.010Editor :填充16進制碼

2.lordPE :檢查PE文件出錯原因

知識背景

1. PE知識 :(PE中結構體的字段分佈,PE加載器的原理)

2. 彙編知識 :(彙編調用MessageBoxA個ExitProcess)

目標:構造一個程序(CUI).exe

程序功能:

1. 調用MessageBoxA彈出消息框

2. 調用ExitProcess退出程序

思路

1.在Windows下PE文件格式的程序如何運行?

答:符合PE格式的文件+系統加載器,如何成功運行程序,失敗,報錯。

2.那麼系統加載的原理或者執行邏輯又是什麼呢?

答:

加載器:簡單執行流程如下

1.內存映射

2.修復IAT

3.修復重定位

tip:本次程序並沒有重定位,只需要考慮前2步即可。

3.PE文件如何構建?還可以做哪些優化呢?

答:

構建:

1.Dos頭:IMAGE_DOS_HEADER;

1.1->WORD e_magic; //標識符:MZ

1.2->LONG e_lfanew; //Dos頭部的大小

2.NT頭:IMAGE_NT_HEADERS32

2.1->DWORD Signature;

2.2->IMAGE_FILE_HEADER FileHeader;

2.3->IMAGE_OPTIONAL_HEADER32 OptionalHeader;

3.區段頭:IMAGE_SECTION_HEADER

3.1 ->.text

3.2 ->.rdata

4.區段數據:數據

4.1 ->代碼數據(OpCode) == 200+

4.2 ->導入數據(IAT、導入表、INT、HitName) == 200+

優化:

1.DosStub是個歷史遺留問題,在一定情況下也可在該區域填寫代碼,但在本次程序可以將該區域刪除。

2.區段減少到2個,.text、.rdata。(ps:其實還可以減少到只有一個區段.text)

3.對程序運行無影響的字段用0填充。

構造PE步驟

1.整理以上思路大致可以得到以下思維導圖

新手——010純手工編輯打造PE文件

仔細觀察PE文件的格式,就不難發現到處都體現出了頭部+身體,目錄+內容的管理數據的思想,那麼對於我們自己手工建立PE文件,同樣也可以以此作為思路開始構建PE文件。(在構建時最好同時去做這兩件事,有助於加快進度)

1.組成頭部:

1.1-Dos頭

typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

關鍵字段:

1. WORD e_magic; ==> MZ => 4D 5A (標識符)

2. LONG e_lfanew; ==> 40h => 40 00 00 00(DosStub去除後,IMAGE_DOS_HEADER 的結構體大小就是Dos頭大小)

4D 5A

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

40 00 00 00

1.2-NT頭

typedef struct _IMAGE_NT_HEADERS {

DWORD Signature;

IMAGE_FILE_HEADER FileHeader;

IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

關鍵字段:

1.2.1.DWORD Signature; ==> PE ==>50 45 00 00 (標識符)

1.2.2IMAGE_FILE_HEADER FileHeader;

typedef struct _IMAGE_FILE_HEADER {

WORD Machine;

WORD NumberOfSections;

DWORD TimeDateStamp;

DWORD PointerToSymbolTable;

DWORD NumberOfSymbols;

WORD SizeOfOptionalHeader;

WORD Characteristics;

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

關鍵字段

2.1 WORD Machine; ==> x86 ==> 4c 01 (0x014c 應用的機器型號)

2.2 WORD NumberOfSections; ==> 2個 ==> 02 00 (1.text 2.rdata)

2.3 WORD SizeOfOptionalHeader; ==> E0 ==> E0 00 (NT擴展頭大小)

2.4 WORD Characteristics; ==> 10F ==> 0F 01 (可以自定義)

1.2.3. IMAGE_OPTIONAL_HEADER32 OptionalHeader;

typedef struct _IMAGE_OPTIONAL_HEADER {

// // Standard fields. // WORD Magic;

BYTE MajorLinkerVersion;

BYTE MinorLinkerVersion;

DWORD SizeOfCode;

DWORD SizeOfInitializedData;

DWORD SizeOfUninitializedData;

DWORD AddressOfEntryPoint;

DWORD BaseOfCode;

DWORD BaseOfData;

// // NT additional fields. // DWORD ImageBase;

DWORD SectionAlignment;

DWORD FileAlignment;

WORD MajorOperatingSystemVersion;

WORD MinorOperatingSystemVersion;

WORD MajorImageVersion;

WORD MinorImageVersion;

WORD MajorSubsystemVersion;

WORD MinorSubsystemVersion;

DWORD Win32VersionValue;

DWORD SizeOfImage;

DWORD SizeOfHeaders;

DWORD CheckSum;

WORD Subsystem;

WORD DllCharacteristics;

DWORD SizeOfStackReserve;

DWORD SizeOfStackCommit;

DWORD SizeOfHeapReserve;

DWORD SizeOfHeapCommit;

DWORD LoaderFlags;

DWORD NumberOfRvaAndSizes;

IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

*PIMAGE_OPTIONAL_HEADER32;

關鍵字段

3.1 WORD Magic; ==> 10B ==>0B 01 (文件類型:PE32文件)

3.2 DWORD AddressOfEntryPoint; ==> 1000 ==>00 10 00 00(.text在文件中200h位置,轉內存偏移後為1000h)

3.2 DWORD ImageBase; ==> 40000 ==>00 00 04 00 (PE文件在內存的優先加載起始地址VA)

3.3 DWORD SectionAlignment; ==> 1000h ==>00 10 00 00 (內存對齊)

3.4 DWORD FileAlignment; ==> 200h ==>00 02 00 00 (文件對齊)

3.5 WORD MajorOperatingSystemVersion; ==> 6 ==>06 00

3.6 WORD MajorSubsystemVersion; ==> 6 ==>06 00

3.7 DWORD SizeOfImage; ==>207E ==> 7E 20 00 00 (加載到內存中鏡像大小)

3.8 DWORD SizeOfHeaders; ==>200h ==> 00 02 00 00 (Dos+NT+Section :在文件中未超過200h)

3.9 WORD Subsystem; ==> 3 ==>03 00 (使用界面的子系統:(CUI) subsystem)

3.10 WORD DllCharacteristics; ==> 8100 ==>00 81 (DLL文件屬性)

3.11 DWORD NumberOfRvaAndSizes; ==> 10h ==>10 00 (表示數據目錄結構的數量.默認16個)

3.12 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

==>Import Table ==> 10 20 00 00 (.rdata 在400h處,rva: 2000h+10h(IAT字節數))

==> 3C 00 00 00 (有2個DLL,即2個導入表結構體(結尾為20個00),即3Ch個字節)

--------------------------------------------

50 45 00 00

4c 01

02 00

00 00 00 00 00 00 00 00 00 00 00 00

E0 00

0F 01

0B 01

00

00

00 00 00 00

00 00 00 00

00 00 00 00

00 10 00 00

00 00 00 00

00 00 00 00

00 00 40 00

00 10 00 00

00 02 00 00

06 00

00 00

00 00

00 00

06 00

00 00

00 00 00 00

7E 20 00 00

00 02 00 00

00 00 00 00

03 00

00 81

00 00 00 00

00 00 00 00

00 00 00 00

00 00 00 00

00 00 00 00

10 00 00 00

00 00 00 00 00 00 00 00

10 20 00 00 3C 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

--------------------------------------------

1.3-區段頭

typedef struct _IMAGE_SECTION_HEADER {

BYTE Name[IMAGE_SIZEOF_SHORT_NAME];

union {

DWORD PhysicalAddress;

DWORD VirtualSize;

} Misc;

DWORD VirtualAddress;

DWORD SizeOfRawData;

DWORD PointerToRawData;

DWORD PointerToRelocations;

DWORD PointerToLinenumbers;

WORD NumberOfRelocations;

WORD NumberOfLinenumbers;

DWORD Characteristics;

} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

關鍵字段

1.text

1.1 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ==>.text ==> 2E 74 65 78 74 00 00 00(區段名稱)

1.2 DWORD VirtualSize; ==>22h ==> 22 00 00 00 (有效的OpCode數目)

1.3 DWORD VirtualAddress; ==>1000h ==> 00 10 00 00 (區段rva:200h映射到內存中為1000h)

1.4 DWORD SizeOfRawData; ==>200h ==> 00 02 00 00 (在文件中的對齊後大小)

1.5 DWORD PointerToRawData; ==>200h ==> 00 02 00 00 (在文件中相對與0的偏移)

1.6 DWORD Characteristics; ==>E00000E0 ==> E0 00 00 E0 (區段屬性可以自定義)

2.rdata

1.1 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ==>.rdata ==> 2E 72 64 61 74 61 00 00(區段名稱)

1.2 DWORD VirtualSize; ==>7Eh ==> 7E 00 00 00 (有效的字節數目)

1.3 DWORD VirtualAddress; ==>2000h ==> 00 20 00 00 (區段rva:400h映射到內存中為2000h)

1.4 DWORD SizeOfRawData; ==>200h ==> 00 02 00 00 (在文件中的對齊後大小)

1.5 DWORD PointerToRawData; ==>400h ==> 00 04 00 00 (在文件中相對與0的偏移)

1.6 DWORD Characteristics; ==>E00000E0 ==> E0 00 00 E0 (區段屬性可以自定義)

--------------------------------------------

2E 74 65 78 74 00 00 00

22 00 00 00

00 10 00 00

00 02 00 00

00 02 00 00

00 00 00 00

00 00 00 00

00 00

00 00

E0 00 00 E0

2E 72 64 61 74 61 00 00

7E 00 00 00

00 20 00 00

00 02 00 00

00 04 00 00

00 00 00 00

00 00 00 00

00 00

00 00

E0 00 00 E0

--------------------------------------------

tip:200對齊其餘填0

2.組成身體:

2.1-區段1.text

偽代碼如下:

push 0x0;

push 0x0;

push 0x0;

push 0x0;

call MessageBoxA;

push 0x0;

call ExitProcess;

vs程序IAT調用為:FF 15 XXXXXXXX(IAT地址)(有2個dll)

IAT1:FOA:400h ==> RVA: 2000h ==>VA:400000h + 2000h==>402000h

IAT2:FOA:408h ==> RVA: 2008h ==>VA:400000h + 2008h==>402008h

--------------------------------------------

6A 00

6A 00

6A 00

6A 00

FF 15 00 20 40 00

6A 00

FF 15 08 20 40 00

--------------------------------------------

tip:200對齊其餘填0

2.2-區段2.rdata

新手——010純手工編輯打造PE文件

1.IAT:

typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header WORD e_magic; // Magic number WORD e_cblp; // Bytes on last page of file WORD e_cp; // Pages in file WORD e_crlc; // Relocations WORD e_cparhdr; // Size of header in paragraphs WORD e_minalloc; // Minimum extra paragraphs needed WORD e_maxalloc; // Maximum extra paragraphs needed WORD e_ss; // Initial (relative) SS value WORD e_sp; // Initial SP value WORD e_csum; // Checksum WORD e_ip; // Initial IP value WORD e_cs; // Initial (relative) CS value WORD e_lfarlc; // File address of relocation table WORD e_ovno; // Overlay number WORD e_res[4]; // Reserved words WORD e_oemid; // OEM identifier (for e_oeminfo) WORD e_oeminfo; // OEM information; e_oemid specific WORD e_res2[10]; // Reserved words LONG e_lfanew; // File address of new exe header } IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;

關鍵字段:

1.WORD e_magic; ==> MZ => 4D 5A (標識符)

2.LONG e_lfanew; ==> 40h => 40 00 00 00(DosStub去除後,IMAGE_DOS_HEADER 的結構體大小就是Dos頭大小)

4D 5A

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00

00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00

40 00 00 00

1.2-NT頭

typedef struct _IMAGE_NT_HEADERS {

DWORD Signature;

IMAGE_FILE_HEADER FileHeader;

IMAGE_OPTIONAL_HEADER32 OptionalHeader;

} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;

關鍵字段:

1.2.1.DWORD Signature;

==> PE ==>50 45 00 00 (標識符)

1.2.2IMAGE_FILE_HEADER FileHeader;

typedef struct _IMAGE_FILE_HEADER {

WORD Machine;

WORD NumberOfSections;

DWORD TimeDateStamp;

DWORD PointerToSymbolTable;

DWORD NumberOfSymbols;

WORD SizeOfOptionalHeader;

WORD Characteristics;

} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;

關鍵字段

2.1 WORD Machine; ==> x86 ==> 4c 01 (0x014c 應用的機器型號)

2.2 WORD NumberOfSections; ==> 2個 ==> 02 00 (1.text 2.rdata)

2.3 WORD SizeOfOptionalHeader; ==> E0 ==> E0 00 (NT擴展頭大小)

2.4 WORD Characteristics; ==> 10F ==> 0F 01 (可以自定義)

1.2.3. IMAGE_OPTIONAL_HEADER32 OptionalHeader;

typedef struct _IMAGE_OPTIONAL_HEADER {

// // Standard fields. // WORD Magic;

BYTE MajorLinkerVersion;

BYTE MinorLinkerVersion;

DWORD SizeOfCode;

DWORD SizeOfInitializedData;

DWORD SizeOfUninitializedData;

DWORD AddressOfEntryPoint;

DWORD BaseOfCode;

DWORD BaseOfData;

// // NT additional fields. // DWORD ImageBase;

DWORD SectionAlignment;

DWORD FileAlignment;

WORD MajorOperatingSystemVersion;

WORD MinorOperatingSystemVersion;

WORD MajorImageVersion;

WORD MinorImageVersion;

WORD MajorSubsystemVersion;

WORD MinorSubsystemVersion;

DWORD Win32VersionValue;

DWORD SizeOfImage;

DWORD SizeOfHeaders;

DWORD CheckSum;

WORD Subsystem;

WORD DllCharacteristics;

DWORD SizeOfStackReserve;

DWORD SizeOfStackCommit;

DWORD SizeOfHeapReserve;

DWORD SizeOfHeapCommit;

DWORD LoaderFlags;

DWORD NumberOfRvaAndSizes;

IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

關鍵字段

3.1 WORD Magic; ==> 10B ==>0B 01 (文件類型:PE32文件)

3.2 DWORD AddressOfEntryPoint; ==> 1000 ==>00 10 00 00(.text在文件中200h位置,轉內存偏移後為1000h)

3.2 DWORD ImageBase; ==> 40000 ==>00 00 04 00 (PE文件在內存的優先加載起始地址VA)

3.3 DWORD SectionAlignment; ==> 1000h ==>00 10 00 00 (內存對齊)

3.4 DWORD FileAlignment; ==> 200h ==>00 02 00 00 (文件對齊)

3.5 WORD MajorOperatingSystemVersion; ==> 6 ==>06 00

3.6 WORD MajorSubsystemVersion; ==> 6 ==>06 00

3.7 DWORD SizeOfImage; ==>207E ==> 7E 20 00 00 (加載到內存中鏡像大小)

3.8 DWORD SizeOfHeaders; ==>200h ==> 00 02 00 00 (Dos+NT+Section :在文件中未超過200h)

3.9 WORD Subsystem; ==> 3 ==>03 00 (使用界面的子系統:(CUI) subsystem)

3.10 WORD DllCharacteristics; ==> 8100 ==>00 81 (DLL文件屬性)

3.11 DWORD NumberOfRvaAndSizes; ==> 10h ==>10 00 (表示數據目錄結構的數量.默認16個)

3.12 IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];

==>Import Table ==> 10 20 00 00 (.rdata 在400h處,rva: 2000h+10h(IAT字節數))

==> 3C 00 00 00 (有2個DLL,即2個導入表結構體(結尾為20個00),即3Ch個字節)

--------------------------------------------

50 45 00 00

4c 01

02 00

00 00 00 00 00 00 00 00 00 00 00 00

E0 00

0F 01

0B 01

00

00

00 00 00 00

00 00 00 00

00 00 00 00

00 10 00 00

00 00 00 00

00 00 00 00

00 00 40 00

00 10 00 00

00 02 00 00

06 00

00 00

00 00

00 00

06 00

00 00

00 00 00 00

7E 20 00 00

00 02 00 00

00 00 00 00

03 00

00 81

00 00 00 00

00 00 00 00

00 00 00 00

00 00 00 00

00 00 00 00

10 00 00 00

00 00 00 00 00 00 00 00

10 20 00 00 3C 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

00 00 00 00 00 00 00 00

--------------------------------------------

1.3-區段頭

typedef struct _IMAGE_SECTION_HEADER {

BYTE Name[IMAGE_SIZEOF_SHORT_NAME];

union {

DWORD PhysicalAddress;

DWORD VirtualSize;

} Misc;

DWORD VirtualAddress;

DWORD SizeOfRawData;

DWORD PointerToRawData;

DWORD PointerToRelocations;

DWORD PointerToLinenumbers;

WORD NumberOfRelocations;

WORD NumberOfLinenumbers;

DWORD Characteristics;

} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;

關鍵字段

1.text

1.1 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ==>.text ==> 2E 74 65 78 74 00 00 00(區段名稱)

1.2 DWORD VirtualSize; ==>22h ==> 22 00 00 00 (有效的OpCode數目)

1.3 DWORD VirtualAddress; ==>1000h ==> 00 10 00 00 (區段rva:200h映射到內存中為1000h)

1.4 DWORD SizeOfRawData; ==>200h ==> 00 02 00 00 (在文件中的對齊後大小)

1.5 DWORD PointerToRawData; ==>200h ==> 00 02 00 00 (在文件中相對與0的偏移)

1.6 DWORD Characteristics; ==>E00000E0 ==> E0 00 00 E0 (區段屬性可以自定義)

2.rdata

1.1 BYTE Name[IMAGE_SIZEOF_SHORT_NAME]; ==>.rdata ==> 2E 72 64 61 74 61 00 00(區段名稱)

1.2 DWORD VirtualSize; ==>7Eh ==> 7E 00 00 00 (有效的字節數目)

1.3 DWORD VirtualAddress; ==>2000h ==> 00 20 00 00 (區段rva:400h映射到內存中為2000h)

1.4 DWORD SizeOfRawData; ==>200h ==> 00 02 00 00 (在文件中的對齊後大小)

1.5 DWORD PointerToRawData; ==>400h ==> 00 04 00 00 (在文件中相對與0的偏移)

1.6 DWORD Characteristics; ==>E00000E0 ==> E0 00 00 E0 (區段屬性可以自定義)

--------------------------------------------

2E 74 65 78 74 00 00 00

22 00 00 00

00 10 00 00

00 02 00 00

00 02 00 00

00 00 00 00

00 00 00 00

00 00

00 00

E0 00 00 E0

2E 72 64 61 74 61 00 00

7E 00 00 00

00 20 00 00

00 02 00 00

00 04 00 00

00 00 00 00

00 00 00 00

00 00

00 00

E0 00 00 E0

--------------------------------------------

tip:200對齊其餘填0

結語

以上將16進制碼複製到010Editor中保存為.exe格式即可運行,運行環境為win10,並未考慮兼容性的問題,發帖的本意為0到1質變,1往後的變化希望大家自行發揮,例如:添加新的區段,在彈窗中添加文字,將代碼複雜化等等。

原文出自:[原創]新手--010純手工編輯打造PE文件-『加殼脫殼』-看雪安全論壇


分享到:


相關文章: