新手——010纯手工编辑打造PE文件

新手——010纯手工编辑打造PE文件_第1张图片

工具

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文件_第2张图片

仔细观察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文件_第3张图片

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

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

你可能感兴趣的:(新手——010纯手工编辑打造PE文件)