--------------------------------------------
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.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 (区段属性可以自定义)
关键字段
1.DWORD AddressOfData1; ==> MessageBoxA ==>5C 20 00 00 00 00 00 00 (以0结尾)
2.DWORD AddressOfData2; ==> ExitProcess ==>75 20 00 00 00 00 00 00 (以0结尾)
tip:75、5C为字节偏移。
工具
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填充。
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
----------------------------------------------------------------------------------------------------
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
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!
最后于 2018-11-20 16:25
被Weaving编辑
,原因: