有很多介绍PE文件的文章,但是我打算写一篇关于输入表的文章,因为它对于破解很有用。 
    我想解释它的最好的方法是举一个例子,你可以跟着我逐步深入,一步一步的思考,最后你将完全明白,我选择了一个我刚下载下来的小程序,它是用TASM编译的,有一个比较小的输入表,所以我想它应该是个不错的范例。 
    好了,让我们开始吧。首先我们得找到输入表,它的地址放在PE文件头偏移80处,所以我们用16进制编辑器打开我们的EXE文件,我们先得找到PE文件头的起始点,这很简单,因为它总是以PE,0,0开始,我们可以在偏移100处找到它。在一般的WIN32程序中文件头偏移被放在文件0X3C处,在那我们通常可看到00 01 00 00,由于数据存储时是低位在前,高位在后的,所以翻转过来实际就是00000100,就象前面我们说的。接下来我们就可以在PE文件中找到我们的输入表,100+80=180在偏移180处我们看到0030 0000,翻转一下,它其实应该是00003000,这说明输入表在内存3000处,我们必须把它转换成文件偏移。 
    一般来说,输入表总是在某个段的起始处,我们可以用PE编辑器来查看虚拟偏移,寻找3000并由此发现原始偏移。很简单的。打开我们看到: 
-CODE  00001000 00001000 00000200 00000600 
-DATA  00001000 00002000 00000200 00000800 
.idata 00001000 00003000 00000200 00000A00 
.reloc 00001000 00004000 00000200 00000C00 
    找一下,我们就发现.idata段的虚拟偏移是3000,原始偏移是A00,3000-A00=2600,我们要记住2600,以便以后转换其它的偏移。如果你没找到输入表的虚拟偏移,那么就找一下最接近的段。 
    来到偏移A00处,我们就看到被称为IMAGE_IMPORT_DESCRIPTORs(IID)的东东,它用5个字段表示每一个被调用DLL的信息,最后以Null结束。 
************************************************************************** 
(IID) IMAGE_IMPORT_DESCRIPTOR的结构包含如下5个字段: 
OriginalFirstThunk, TimeDateStamp, ForwarderChain, Name, FirstThunk

OriginalFirstThunk 
该字段是指向一32位以00结束的RVA偏移地址串,此地址串中每个地址描述一个输入函数,它在输入表中的顺序是不变的。

TimeDateStamp 
一个32位的时间标志,有特殊的用处。

ForwarderChain 
输入函数列表的32位索引。

Name 
DLL文件名(一个以00结束的ASCII字符串)的32位RVA地址。

FirstThunk 
该字段是指向一32位以00结束的RVA偏移地址串,此地址串中每个地址描述一个输入函数,它在输入表中的顺序是可变的。 
**************************************************************************

好了,你有没有理解?让我们看看我们有多少IID,它们从偏移A00处开始 
3C30 0000 / 0000 0000 / 0000 0000 / 8C30 0000 / 6430 0000 
{OrignalFirstThunk} {TimeDateStamp} {ForwardChain} {Name} {First Thunk} 
5C30 0000 / 0000 0000 / 0000 0000 / 9930 0000 / 8430 0000 
{OrignalFirstThunk} {TimeDateStamp} {ForwardChain} {Name} {First Thunk} 
0000 0000 / 0000 0000 / 0000 0000 / 0000 0000 / 0000 0000

每三分之一是个分界,我们知道每个IID包含了一个DLL的调用信息,现在我们有2个IID,所以我们估计这个程序调用了2个DLL。甚至我可以打赌,你能推测出我们将能找到什么。 
    每个IID的第四个字段表示的是名字,通过它我们可以知道被调用的函数名。第一个IID的名字字段是8C30 0000,翻转过来也就是地址0000308C,将它减去2600可以得到原始偏移,308C-2600=A8C,来到文件偏移A8C处,我们看到了什么?啊哈!原来调用的是KERNEL32.dll。 
    好了,接下来我们就要去找出KERNEL32.dll中被调用的函数。回到第一个IID。 
    FirstThunk字段包含了被调用的函数名的标志,OriginalFirstThunk仅仅是FirstThunk的备份,甚至有的程序根本没有,所以我们通常看FirstThunk,它在程序运行时被初始化。 
    KERNEL32.dll的FirstThunk字段值是6430 0000,翻转过来也就是地址00003064,减去2600得A64,在偏移A64处就是我们的IMAGE_THUNK_DATA,它存储的是一串地址,以一串00结束。如下:    
A430 0000/B230 0000/C030 0000/CE30 0000/DE30 0000/EA30 0000/F630 0000/0000 0000 
    通常在一个完整的程序里都将有这些。我们现在有了7个函数调用,让我们来看其中的两个: 
DE30 0000翻转后是30DE,减去2600后等于ADE,看在偏移ADE处的字符串是ReadFile, 
EA30 0000翻转后是30EA,减去2600后等于AEA,看在偏移AEA处的字符串是WriteFile, 
    你可能注意到了,在函数名前还有2个这字节的00,它是被作为一个提示。 
    很简单吧,你可以自己来试一下。回到A00,看第二个DLL的调用 
5C30 0000 / 0000 0000 / 0000 0000 / 9930 0000 / 8430 0000 
{OrignalFirstThunk} {TimeDateStamp} {ForwardChain} {Name} {First Thunk} 
    先找它的DLL文件名。9930翻转为3099-2600 =A99,在偏移A99处找到USER32.dll。再看FirstThunk字段值:8430翻转为3084-2600=A84,偏移A84处保存的地址为08310000,翻转后3108-2600=B08,偏移B08处字符串为MessageBoxA。明白了吧,接下来你就可以把这些用在你自己的EXE文件上了。 
    摘要: 
    在PE文件头+80偏移处存放着输入表的地址,输入表包含了DLL被调用的每个函数的函数名和FirstThunk,通常还有Forward Chain和TimeStamp。 
    当运行程序时系统调用GetProcAddress,将函数名作为参数,换取真正的函数入口地址,并在内存中写入输入表。当你对一个程序脱壳时你可能注意到你有了一个已经初始化的FirstThunk。例如,在我的WIN98上,函数GetProcAddress的入口地址是AE6DF7BF,在98上,所有的KERNEL32.dll函数调用地址看上去地址都象:xxxxF7BF,如果你在输入表中看到这些,你可以利用orignal thunk重建它,或者重建这个PE程序。

第二个实例:

如果我们需要保护自己的程序,可以修改PE头的大小和起始位。

实例下载

解说:

前提:需要用16进制编辑工具打开,比如:winhex,ultraedit,cs32asm等

1.       如果IMAGE_NT_HEADERS的signature域值等于"PE\0\0",那么就是有效的PE文件。我们看此处偏移0100处就是50 45,代表偏移头。

2.       我们前面讲过,在DOSMZ中有一项是用来指定PE头的起始位置的,那就在002c和002d处的值就是00 01,反过来写就是0100了。

PE头的起始位置

100  60 00

01 00

00 01

PE头的大小:

224个字节    00 E0,这个值我们前面讲过,其PE头的大小我们可以从中看到在0114 0115处。

修改的PE头:

24*16=384字节  180 反过来80 01偏移移到了0060处

然后根据需要修改偏移及大小即可完成pe头的修改。

破解软件感悟-PE文件格式之实例总结(五)的更多相关文章

  1. 破解软件感悟-PE文件格式之Import Table(引入表)(四)

    先来看一个可执行文件的实例:本例程打开一PE文件,将所有引入dll和对应的函数名读入一编辑控件,同时显示 IMAGE_IMPORT_DESCRIPTOR 结构各域值. C:\QQDownload\bl ...

  2. PE文件格式详解(五)

    0x00 前言 前一篇了解了区块虚拟地址和文件地址转换的相关知识,这一篇该把我们所学拿出来用用了.这篇我们将了解更为重要的一个知识点——输入表和输出表的知识. 0x01 输入表 首先我们有疑问.这个输 ...

  3. C++PE文件格式解析类(轻松制作自己的PE文件解析器)

    PE是Portable Executable File Format(可移植的运行体)简写,它是眼下Windows平台上的主流可运行文件格式. PE文件里包括的内容非常多,详细我就不在这解释了,有兴趣 ...

  4. PE文件格式详解(六)

    0x00 前言 前面两篇讲到了输出表的内容以及涉及如何在hexWorkShop中找到输出表及输入DLL,感觉有几个地方还是没有理解好,比如由数据目录表DataDirectory[16]找到输出表表后以 ...

  5. 深入理解 Win32 PE 文件格式

    深入理解 Win32 PE 文件格式 Matt Pietrek 这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什 ...

  6. PE文件格式分析

    PE文件格式分析 PE 的意思是 Portable Executable(可移植的执行体).它是 Win32环境自身所带的执行文件格式.它的一些特性继承自Unix的Coff(common object ...

  7. 深入理解 Win32 PE 文件格式 Matt Pietrek(慢慢体会)

    这篇文章假定你熟悉C++和Win32. 概述 理解可移植可执行文件格式(PE)可以更好地了解操作系统.如果你知道DLL和EXE中都有些什么东西,那么你就是一个知识渊博的程序员.这一系列文章的第一部分, ...

  8. PE文件格式详解(七)

    PE文件格式详解(七)   Ox00 前言 前面好几篇在讲输入表,今天要讲的是输出表和地址的是地址重定位.有了前面的基础,其实对于怎么找输出表地址重定位的表已经非常熟悉了.   0x01 输出表结构 ...

  9. PE文件格式详解(一)

    PE文件格式介绍(一) 0x00 前言 PE文件是portable File Format(可移植文件)的简写,我们比较熟悉的DLL和exe文件都是PE文件.了解PE文件格式有助于加深对操作系统的理解 ...

随机推荐

  1. URAL 1233 - Amusing Numbers

    首先计算出k至少为第几位,如果m小于这个数,那么输出0 还有一种情况, 就是10的i次方的这种情况,如果i+1等于m,那么直接输出k,否则输出0 其他的情况,就是二分,然后判断计算其插入到k之前的数的 ...

  2. MVVM知识库总结

    1.关于MVVM概念的理解和实际运用中的解析: http://www.cnblogs.com/hielvis/archive/2011/03/22/1991959.html http://msdn.m ...

  3. MySQL 备份恢复

    1:备份常用工具: mysqldump, xtrabackup mysqldump: 原生数据导出工具,以sql的形式导出保存 xtrabackup: percona团队提供的备份工具,基于文件系统的 ...

  4. Ruby Scripting - Array

    A literal array is created by putting squarebrackets around a comma-separated list of elements eg: # ...

  5. C#操作注册表全攻略

    相信每个人对注册表并不陌生,在运行里面输入“regedit”就可以打开注册表编辑器了.这东西对Windows系统来说可是比较重要的,也是病 毒常常会光顾的地方,比如病毒和恶意软件常常会在注册表的启动项 ...

  6. Android 百度地图定位(手动+自动) 安卓开发教程

    近由于项目需要,研究了下百度地图定位,他们提供的实例基本都是用监听器实现自动定位的.我想实现一种效果:当用户进入UI时,不定位,用户需要定位的时候,自己手动点击按钮,再去定位当前位置.  经过2天研究 ...

  7. 视频流服务器配置[windows平台][转]

    视频流服务器配置[windows平台] 搭建一个Flv视频播放服务器 作者:笨小孩 发布于:2013-9-1 20:18 分类:环境架设 IIS,Apache,Nginx环境都可以很好的支持视频的播放 ...

  8. Javascript加载执行问题探索

    转自:http://www.cnblogs.com/huangxincheng/archive/2011/12/04/2275988.html 前言 最近研究MongoDB数据库,无意间发现的好博客, ...

  9. jqgrid 获取当前页码

    jqgrid 获取当前页码 $('#gridTable').getGridParam('page'); /** *刷新,jqGrid刷新当前列表页代码 */ function refresh(url) ...

  10. Visual Studio Code 1.0.1 for python

    1. 安 F1健 ext install python E:\test\.vscode下的三个文件 2.launch.json { "version": "0.1.0&q ...