ARP联盟图文中心下载中心手机频道最近更新软件最近更新文章网络热点
您当前的位置→图文中心安全防范体验修改PE文件的乐趣
站内搜索:

体验修改PE文件的乐趣


2009/3/21  编辑:佚名 来源:本站整理 

体验修改PE文件的乐趣
适合读者:程序员、破解爱好者

前置知识:汇编语法

体验修改PE文件的乐趣    

文/图 牛渊                 

我们大家都知道,在Windows 9x、NT、2000下,所有的可执行文件都是基于Microsoft设计的一种新的文件格式Portable Executable File Format(可移植的执行体),即PE格式。有一些时候,我们需要对这些可执行文件进行修改,下面文字试图详细的描述PE文件的格式及对PE格式文件的修改。

PE文件框架构成

dos MZ header

dos Stub

PE header

Section table

Section 1

Section 2

Section...

Section n
 

上表是PE文件结构的总体层次分布。所有 PE文件(甚至32位的 DLLs) 必须以一个简单的 dos MZ header开始,在偏移0处有dos下可执行文件的“MZ标志”,有了它,一旦程序在dos下执行,dos就能识别出这是有效的执行体,然后运行紧随MZ header之后的dos Stub。紧接着dos Stub的是PE header。PE header是PE相关结构IMAGE_NT_HEADERS的简称,其中包含了许多PE装载器用到的重要域。可执行文件在支持PE文件结构的操作系统中执行时,PE装载器将从dos MZ header的偏移3CH处找到PE header的起始偏移量。因而跳过了dos Stub直接定位到真正的文件头PE header。

小知识:dos Stub实际上是个有效的EXE,在不支持PE文件格式的操作系统中,它将简单显示一个错误提示,类似于字符串“This program cannot run in dos mode”或者程序员可根据自己的意图实现完整的dos代码。通常dos Stub由汇编器/编译器自动生成,对我们的用处不是很大,它简单调用中断21h服务9来显示字符串“This program cannot run in dos mode”。

PE文件的真正内容划分成块,称之为Sections(节)。每节是一块拥有共同属性的数据,比如“.text”节等,那么,每一节的内容都是什么呢?实际上PE格式的文件把具有相同属性的内容放入同一个节中,而不必关心类似“.text”、“.data”的命名,其命名只是为了便于识别,所有,我们如果对PE格式的文件进行修改,理论上讲可以写入任何一个节内,并调整此节的属性就可以了。

PE header 接下来的数组结构Section table(节表)。每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE文件里有5个节,那么此结构数组内就有5个成员。

以上就是PE文件格式的物理分布,下面将总结一下装载一PE文件的主要步骤:
1.PE文件被执行,PE装载器检查dos MZ header里的PE header偏移量。如果找到,则跳转到PE header。
2.PE装载器检查PE header的有效性。如果有效,就跳转到PE header的尾部。
3.紧跟 PE header的是节表。PE装载器读取其中的节信息,并采用文件映射方法将这些节映射到内存,同时附上节表里指定的节属性。

4.PE文件映射入内存后,PE装载器将处理PE文件中类似Import table(引入表)逻辑部分。

PE文件头定义

我们可以在Winnt.h这个文件中找到关于PE文件头的定义:

typedef struct _IMAGE_NT_HEADERS {
DWORD Signature;

//PE文件头标志 :“PE\0\0”。在开始dos header的偏移3CH处所指向的地址开始
IMAGE_FILE_HEADER FileHeader;        //PE文件物理分布的信息
IMAGE_OPTIONAL_HEADER32 OptionalHeader;    //PE文件逻辑分布的信息
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
typedef struct _IMAGE_FILE_HEADER {
WORD    Machine;            //该文件运行所需要的CPU,对于Intel平台是14Ch
WORD    NumberOfSections;        //文件的节数目
DWORD   TimeDateStamp;        //文件创建日期和时间
DWORD   PointerToSymbolTable;    //用于调试
DWORD   NumberOfSymbols;        //符号表中符号个数
WORD    SizeOfOptionalHeader;    //OptionalHeader 结构大小
WORD    Characteristics;        //文件信息标记,区分文件是exe还是dll
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
typedef struct _IMAGE_OPTIONAL_HEADER {
WORD    Magic;            //标志字(总是010bh)
BYTE    MajorLinkerVersion;        //连接器版本号
BYTE    MinorLinkerVersion;        //
DWORD   SizeOfCode;            //代码段大小
DWORD   SizeOfInitializedData;    //已初始化数据块大小
DWORD   SizeOfUninitializedData;    //未初始化数据块大小
DWORD   AddressOfEntryPoint;   

PE装载器准备运行的PE文件的第一个指令的RVA,若要改变整个执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行(以往许多文章都有介绍RVA,请大家先了解)。

DWORD   BaseOfCode;            //代码段起始RVA
DWORD   BaseOfData;            //数据段起始RVA
DWORD   ImageBase;            //PE文件的装载地址
DWORD   SectionAlignment;        //块对齐
DWORD   FileAlignment;        //文件块对齐
WORD    MajorOperatingSystemVersion;//所需操作系统版本号
WORD    MinorOperatingSystemVersion;//
WORD    MajorImageVersion;        //用户自定义版本号
WORD    MinorImageVersion;        //
WORD    MajorSubsystemVersion;    //win32子系统版本。若PE文件是专门为Win32设计的
WORD    MinorSubsystemVersion;    //该子系统版本必定是4.0否则对话框不会有3维立体感
DWORD   Win32VersionValue;        //保留
DWORD   SizeOfImage;            //内存中整个PE映像体的尺寸
DWORD   SizeOfHeaders;        //所有头+节表的大小
DWORD   CheckSum;            //校验和
WORD    Subsystem;            //NT用来识别PE文件属于哪个子系统
WORD    DllCharacteristics;        //
DWORD   SizeOfStackReserve;        //
DWORD   SizeOfStackCommit;        //
DWORD   SizeOfHeapReserve;        //
DWORD   SizeOfHeapCommit;        //
DWORD   LoaderFlags;            //
DWORD   NumberOfRvaAndSizes;    //
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
//IMAGE_DATA_DIRECTORY 结构数组。每个结构给出一个重要数据结构的RVA,比如引入地址表等
} IMAGE_OPTIONAL_HEADER32, *PIMAGE_OPTIONAL_HEADER32;

typedef struct _IMAGE_DATA_DIRECTORY {
DWORD   VirtualAddress;        //表的RVA地址
DWORD   Size;                //大小
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;

PE文件头后是节表,在winnt.h下如下定义
typedef struct _IMAGE_SECTION_HEADER {
BYTE    Name[IMAGE_SIZEOF_SHORT_NAME];//节表名称,如“.text”
union {
    DWORD   PhysicalAddress;    //物理地址           
    DWORD   VirtualSize;        //真实长度
} Misc;
DWORD   VirtualAddress;        //RVA
DWORD   SizeOfRawData;        //物理长度
DWORD   PointerToRawData;        //节基于文件的偏移量
DWORD   PointerToRelocations;    //重定位的偏移
DWORD   PointerToLinenumbers;    //行号表的偏移
WORD    NumberOfRelocations;    //重定位项数目
WORD    NumberOfLinenumbers;    //行号表的数目
DWORD   Characteristics;        //节属性
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;以上结构就是在Winnt.h中关于PE文件头的定义,如何我们用C/C++来进行PE可执行文件操作,就要用到上面的所有结构,它详细的描述了PE文件头的结构。修改PE可执行文件
    现在让我们把一段代码写入任何一个PE格式的可执行文件,代码如下:

-- test.asm --
.386p
.model flat, stdcall
option casemap:none

include \masm32\include\windows.inc
include \masm32\include\user32.inc
includelib \masm32\lib\user32.lib

.code

start:
    INVOKE MessageBoxA,0,0,0,MB_ICONINFORMATION or MB_OK
    ret
end start以上代码只显示一个MessageBox框,编译后得到二进制代码如下:

unsigned char writeline[18]={
0x6a,0x40,0x6a,0x0,0x6a,0x0,0x6a,0x0,0xe8,0x01,0x0,0x0,0x0,0xe9,0x0,0x0,0x0,0x0
};好,现在让我们看看该把这些代码写到那。现在用Tdump.exe显示一个PE格式得可执行文件信息,可以发现如下描述:
Object table:
#   Name      VirtSize    RVA     PhysSize  Phys off  Flags  
--  --------  --------  --------  --------  --------  --------
01  .text     0000CCC0  00001000  0000CE00  00000600  60000020 [CER]
02  .data     00004628  0000E000  00002C00  0000D400  C0000040 [IRW]
03  .rsrc     000003C8  00013000  00000400  00010000  40000040 [IR]

Key to section flags:
  C - contains code
  E - executable
  I - contains initialized data
  R - readable
  W - writeable上面描述此文件中存在3个段及每个段的信息,实际上我们的代码可以写入任何一个段,这里我选择“.text”段。用光盘中提供的代码可以得到一个PE格式可执行文件的头信息。

由于在PE格式的文件中,所有的地址都使用RVA地址,所以一些函数调用和返回地址都要经过计算才可以得到。以上都是我在实践中的心得,希望大家能够得到受益,另外如果大家有更好的思路和方法,希望大家能告诉我,多多交流。

参考消息:http://www.arpun.com/(文中涉及到的源代码已收录到杂志配套光盘“杂志相关”栏目,按文章名查找即可)

更多精彩,请查看本类栏目: 安全防范
除非注明,ARP联盟文章来于网络,投稿原创等,转载请以链接形式标明本文地址。
本文地址:http://www.arpun.com/article/2552.html

相关文章
  • ·[图文]OPPO R9开箱图赏与简单体验评测
  • ·ios9.3beta7新增哪些体验
  • ·[图文]首席体验师闪退怎么办 首席体验师闪退解决办法
  • ·[图文]二十年内被宣布死亡三次,最后一次濒死体验发生怪事身体飘入宇宙
  • ·iOS9.3 Beta2体验报告
  • ·安卓/iPhone QQ6.2体验版发布 附近功能新增亮点
  • ·[图文]QQ8.0体验版群文件可创建文件夹
  • ·[图文]美科学家亲身体验濒死,发现灵魂或离开大脑进入宇宙
  • 发表评论
    栏目列表
    阅读排行
    本类最新
    网站帮助 - 广告合作 - 下载声明 - 网站地图