手工构造典型PE文件.docx

上传人:b****5 文档编号:4647438 上传时间:2022-12-07 格式:DOCX 页数:13 大小:23.78KB
下载 相关 举报
手工构造典型PE文件.docx_第1页
第1页 / 共13页
手工构造典型PE文件.docx_第2页
第2页 / 共13页
手工构造典型PE文件.docx_第3页
第3页 / 共13页
手工构造典型PE文件.docx_第4页
第4页 / 共13页
手工构造典型PE文件.docx_第5页
第5页 / 共13页
点击查看更多>>
下载资源
资源描述

手工构造典型PE文件.docx

《手工构造典型PE文件.docx》由会员分享,可在线阅读,更多相关《手工构造典型PE文件.docx(13页珍藏版)》请在冰豆网上搜索。

手工构造典型PE文件.docx

手工构造典型PE文件

手工构造典型PE文件

文章作者:

a1pass

    一直以来都在学习PE文件结构,从不敢轻视,但是即使如此还是发现自己在这方面有所不足,于是便想到了用纯手工方式打造一个完整的可执行的PE文件。

在这期间我也查了大量资料,但是这些资料都有一个通病就是不完整,看雪得那个只翻译了一部分,加解密技术内幕介绍的更是笼统,而且是打造一个只有180字节的PE文件,是高手们茶余饭后的怡情小游戏。

    鉴于此,心想为什么不自己摸索着手工打造一个完整些的呢?

一是加强一下自己对于PE文件的了解,二是写出一篇参考性比较强的文章,给有志于在此发展的朋友们铺一铺路,也算是干了一件利国利民的好事。

    对于手工打造PE文件,我个人认为至少要分为三篇文章来阐述,每篇相对独立,合起来形成一个相对的体系。

第一篇文章(也就是本文)用来介绍怎样用手工打造一个最典型、最简单的PE文件,而后两篇文章的问世还要引用潘爱民先生的一句话“还需要时日与机缘”。

    本文介绍的PE文件手工编辑方式,是本着以下三个原则所写的,望读者注意:

1、完整性:

对于手工打造PE文件所不需注意的字段也进行了必要的介绍,因此整文可能显得非常臃肿。

2、典型性:

完全按照典型的PE文件结构构造,因此对于某些不常见的PE文件结构有一定差距。

3、易学性:

对于字段之间的逻辑关系进行了比较细致的介绍,因此对于一部分底子比较好的读者来说可能显得有些啰嗦。

    为了方便各位阅读与查阅,我将文章分成了三各部分,以便各位读者各取所需,不用把宝贵的精力浪费在查找上。

1、PE文件整体信息,提供了一个剖析PE文件的图表,以便于读者对于PE文件有一个整体的了解,并监督自己的工作进度。

2、对于重点字段的介绍,以及字段之间的逻辑关系,建议首先从这里开始看。

3、手工构造PE文件字段清单,此清单包含构造一个完整PE文件的每一个字节,跟着这个清单走就可以构造一个PE文件。

      对于第一次手工打造PE文件的朋友们来说,你们可以以“一、整体性息”为大纲,并参考第三部分一块一块的慢慢打造,如果有不懂的地方就去看第二部分。

选读:

为什么要手工打造PE文件?

      我们知道,往往从一个系统可执行文件结构上,就可以看整个操作系统的一些特性。

也就是说PE里有Windows操作系统结构与运行机理的影子。

由此可见,PE文件必然是一个非常庞杂且逻辑复杂的结构,那么为什么我们还要“自取其辱”来手工制造一个PE文件呢?

这就要从PE文件的重要性说起了。

    

      我们现今组成Windows大家庭的主要成员就是PE文件了,里面包括EXE、DLL、OCX、SYS等一切最有价值的文件都是PE文件格式,出于对版权的考虑或对某种技术的渴求,任何一种与Windows系统相关的行为最终都要归集到这里--PE文件。

      特别是对于想学习加壳、破解、搞虚拟机的朋友们来说,熟知PE文件结构更是必不可少的基本功!

      但也正是由于PE文件的复杂性,我们才要采取一些特别的办法来攻克它,其中手工打造PE文件就是一条捷径。

      你可以想像一下,如果你都可以手工打造PE文件的话,那么对于PE文件的了解更是可见一斑了。

但是我还想提醒一下各位读者,即便是如此,我们所了解的也仅仅是一部分,不过一般情况下已经足够了。

一、整体性息

  这部分以图表的形式表示PE文件的整体结构。

-------------*-------------------------------------------------*

            |DOSHeader(IMAGE_DOS_HEADER)|-->64Byte

DOS头部  --------------------------------------------------

            |DOSStub                              |-->112Byte

-------------*-------------------------------------------------*

            |"PE"00(Signature)                    |-->4Byte

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

            |IMAGE_FILE_HEADER                |-->20Byte

PE文件头--------------------------------------------------

            |IMAGE_OPTIONAL_HEADER32      |-->96Byte

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

            |数据目录表                            |-->128Byte

-------------*--------------------------------------------------*

            |IMAGE_SECTION_HEADER            |-->40Byte

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

  块表    |IMAGE_SECTION_HEADER            |-->40Byte

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

            |IMAGE_SECTION_HEADER            |-->40Byte  

-------------*--------------------------------------------------*

            |.text                                    |-->512Byte

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

  块      |.rdata                                  |-->512Byte

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

            |.data                                    |-->512Byte

-------------*-------------------------------------------------*

            |COFF行号                              |-->NULL

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

调试信息|COFF符号表                            |-->NULL

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

            |CodeView调试信息                    |-->NULL

-------------*--------------------------------------------------*

这部分内容的意义有二:

1、对于PE文件有一个整体的认识。

2、方便审查自己的构造进度。

    这里我们重点介绍怎样用其审查自己的构造进度,首先希望各位读者明白我们将要手工构造的一个体积为2560字节的这个小家伙,对于初次上手的读者们来说并不是一件小的工程,因此有必要知道自己现在正做什么,以及做到哪里了。

    记得我少年学画时老师教我们构图就要从整体到局部,后来自学编程仍然是先实现大的框架再去解决每一个细节问题。

OK,现在到了这里,很显然我们仍然需要本着从整体到局部的思想来构造我们的PE文件。

    那好,我们先搞明白第一个问题“我们的文件体积是怎么计算出来的呢”。

    首先我们要知道,PE文件自始至终都是以一种节的思想来构造的,那么我们就要从节开始。

    对于本文所讲述的PE文件来讲总共有三个区块(节),他们分别用来存放可执行代码、输入表信息以及全局变量,接触过PE文件的朋友对于区块的概念应该不陌生,我们知道Windows下的很多应用程序的文件对齐粒度,也就是大名鼎鼎的FileAlignment字段的值多为200hByte,也就是十进制的512Byte。

我们同样应该知道,对于不足512字节的区段,余下部分要用00h填充到512字节大小,对与超过部分(例如513字节的区段)我们就要在多分配给他512字节个空间。

    当然,这些基础知识我想有一部分读者应该比较熟悉,那么对于PE文件头部分呢?

也是如此吗?

例如本例中的PE头就占用了544个字节,但是很显然这要使其填充到1024(400h)字节处才能开始第一个区段.text段。

    正是如此,我们整个文件的体积就是PE头+3个区段的体积之和,也就是PE头(512*2)+3个区段(512*3)=2560,这也就是我们所构造的PE文件的最终大小了。

    其次我们提前搞清楚一些字段与区段的偏移量也是比较重要的,这里对于计算方式不再多说,请大家直接看下面的表:

1、PE头开始处000000B0h

2、IMAGE_OPTIONAL_HEADER32开始处000000C8h

3、数据目录表开始处00000128h

4、块表开始处000001A8h

5、.text块开始处00000400h

6、.rdata块开始处00000600h

7、.data块开始处00000800h

    当然,上面的那些Offset只是针对本文件而言,并不绝对,具体情况还要具体分析。

    到此,本段就告一段落了,剩下的两段为了提高效率我并没有加以润色,全都是干货,希望各位读者能吃下这两块营养丰富的压缩饼干……

二、重点字段介绍

    这里只对需手工构造的字段进行着重介绍,详细的PE文件结构字段清单请见第三部分。

1、DOS头部

  1-1  DOSHeader

  1-1-1  e_magic  [WORD]  -->4D5A(*DOS可执行文件头标记)

  注释:

此处值总是为MZ的16进制码。

  1-1-19  e_lfanew  [DWORD]  -->B0000000(*指向PE文件头的偏移量。

0xB0=64+112)

  注释:

此处的值正好为为DOS头部的大小,因为DOS头部后面就是PE文件头部分了。

2  PE文件头

  2-1  "PE"00

  2-1-1  Signature  [DWORD]-->50450000h(*PE文件头标记)

  注释:

此处的值总是为PE的16进制值加0000h。

  2-2  IMAGE_FILE_HEADER

  2-2-1  Machine  [WORD]  -->4C01(*可执行文件的目标CPU类型)

  注释:

此PE文件可以运行于哪个CPU下,其标志就为相应的值。

  *------------------------------*

  |    机器        |  标志  |

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

  |Inteli386      |14Ch  |

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

  |MIPSR3000  |162h  |

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

  |MIPSR4000  |166h  |

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

  |AlphaAXP    |184h  |

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

  |PowerPC      |1F0h  |

  *-----------------------------*

  2-2-2  NumberOfSections  [WORD]  -->0300(*区块数目)

  注释:

此值决定此PE文件的区块数目,本文件为3个区块。

  2-2-6  SizeOfOptionalHeadr  [WORD]  -->E000(*PE头(IMAGE_OPTIONAL_HEADER32)大小)

  注释:

此值表示PE文件头的大小。

  2-2-7  Characteristics  [WORD]  -->0F01(*文件属性)

  注释:

此值为文件的执行属性。

EXE文件此值一般为010Fh,DLL文件此值一般为0210h。

  2-3  IMAGE_OPTIONAL_HEADER32

  2-3-1  Magic  [WORD]  -->0B01(*标记字)

  注释:

此处是一个标记字,用于描述次PE文件的映像类型。

ROM映像为0107h;普通可执行映像010Bh;PE32+则是020Bh。

  2-3-7  AddressOfEntryPoint  [DWORD]-->00100000(*程序执行入口RAV)

  注释:

通俗的说就是指向可执行代码区块(例如.text)的首地址。

  2-3-10  ImageBase  [DWORD]-->00004000(*程序默认装入基地址)

  注释:

是指文件在内存中首选的装入地址。

  2-3-11  SectionAlignment  [DWORD]-->00100000(*内存中区块对齐值)

  注释:

PE文件被装入内存中时的块对齐大小,也叫做块粒度。

其默认的对其尺寸是CPU的页尺寸。

  2-3-12  FileAlignment  [DWORD]-->00020000(*文件中区块对齐值)

  注释:

磁盘上PE文件的区块对齐大小。

这个值必须是2的幂,并且最小为200h。

  2-3-17  MajorSubsystemVersion  [WORD]  -->0400(*运行所需最低子系统主版本号)

  注释:

要求最低的子系统主版本号,一般情况下都为4。

  2-3-18  MinorSubsystemVersion  [WORD]  -->0000(*运行所需最低子系统次版本号)

  注释:

要求最低的子系统次版本号,一般情况下都为0。

  2-3-20  SizeOfImage  [DWORD]-->00400000(*映像装入内存后的总尺寸)

  注释:

指的是装入文件从ImageBase到最后一个区块的总大小。

  2-3-21  SizeOfHeaders  [DWORD]-->00400000(*DOS头、PE头、区块表的总大小)

  注释:

指的是DOS头、PE头与区块表的总大小,并且所有这些项目都出现在PE文件中任何代码或数据块之前。

此值遵守文件对齐粒度。

  2-3-23  Subsystem[WORD]  -->0300(*文件子系统)

  注释:

标明可执行文件所期望的子系统(用户界面类型)。

      *----*-------------------------------------*

      |值|      子系统                  |

      *----*-------------------------------------*

      |0  |未知                          |

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

      |1  |不需要子系统(如驱动程序)|

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

      |2  |图形接口子系统(GUI)      |

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

      |3  |字符子系统(CUI)            |

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

      |5  |OS/2字符子系统              |

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

      |7  |POSIX字符子系统              |

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

      |8  |保留                            |

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

      |9  |WindowsCE图形界面          |

      *----*--------------------------------------*

  2-3-30  NumberOfRvaAndSizes  [DWORD]-->10000000(*数据目录标的项数,默认总为16)

  注释:

数据目录的项数。

这个字段字NT系统发布以来就一直是16。

  2-4  数据目录表

  2-4-2  ImportTable

  注释:

输入表

    2-4-2-1  VirtualAddress[DWORD]-->10200000(*数据块的起始RAV)

    注释:

输入表的起始地址,要去除IAT所占空间,直接从第一个IID开始。

    2-4-2-2  Size  [DWORD]-->3C000000(*数据块的长度)

    注释:

从第一个IID到最后一个IMAGE_IMPORT_BY_NAME的总长度。

3  块表

  3-1  IMAGE_SECTION_HEADER(1.text)

  3-1-1  Name  [BYTE]  -->2E74657874000000(*8个字节的块名)

  注释:

此区块的名称,限制在8字节以内。

  3-1-2  VirtualSize  [DWORD]-->26000000(*被实际使用的区块大小)

  注释:

此区块包含数据的大小。

  3-1-10  Characteristics  [DWORD]-->20000060(*该区块的读写、执行属性)

  注释:

      *----------------------------------------------------------------*

      |  字段值  |          用途                            |

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

      |00000020h|包含代码,常与10000000h一起设置|

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

      |00000040h|包含已初始化数据                    |

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

      |00000080h|包含未初始化数据                    |

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

      |02000000h|可以被丢弃                            |

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

      |10000000h|共享块                                |

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

      |20000000h|可执行                                |

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

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 高中教育 > 高中教育

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1