win7pe纯手工 (win7pe制作)

工具

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.整理以上思路大致可以得到以下思维导图

仔细观察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位置,转内存偏移后为1电脑000h)

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: 200电脑0h+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

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文件-『加壳脱壳』-看雪安全论坛

本文由看雪论坛 韩逸 原创 转载请注明来自看雪社区