从1个简单的ReverseMe开始谈PE文件结构的学习  申精

社区服务
高级搜索
猴岛论坛电脑百科从1个简单的ReverseMe开始谈PE文件结构的学习  申精
发帖 回复
倒序阅读 最近浏览的帖子最近浏览的版块
2个回复

从1个简单的ReverseMe开始谈PE文件结构的学习  申精

楼层直达
不懂也不知道

ZxID:10586231

等级: 禁止发言

举报 只看楼主 使用道具 楼主   发表于: 2010-07-10 0
从1个简单的ReverseMe开始谈PE文件结构的学习  申精
PE文件结构的学习,是脱壳以及逆向技术必须要学的一项内容。但是,由于网上的一些PE文件结构的文章比较抽象,因此,一些新手学起来会觉得比较困难。鉴于此,我就用1个简单的ReverseMe开始,来给大家简单的讲解一下PE文件结构,尤其是输入表这块。想学习脱壳技术的,输入表这块内容必须彻底掌握!

这个ReverseMe的任务很简单:
1.手动添加1个区段
2.创建1个对话框

要求:只用OD和16进制编辑器!

关于一些PE格式的基础知识,比如,有DOS MZ head,DOS Stub,有PE头,区块等等,就不在具体说了,本文的重点,是关于输入表(IAT)的一些内容。

OK,按照任务来吧!

一、添加1个区块

其实,我们用Lord PE以及其他的一些PE工具可以很方便的添加1个区块,但是,既然要求不能用工具,也为了巩固一下对PE结构的了解,我们就只用16进制工具来进行添加吧。

首先,我们来了解下区块的结构:

IMAGE_SIZEOF_SHORT_NAME equ 8

IMAGE_SECTION_HEADER STRUCT
Name1 db IMAGE_SIZEOF_SHORT_NAME dup(?)
union Misc
PhysicalAddress dd ?
VirtualSize dd ?
ends
VirtualAddress dd ?
SizeOfRawData dd ?
PointerToRawData dd ?
PointerToRelocations dd ?
PointerToLinenumbers dd ?
NumberOfRelocations dw ?
NumberOfLinenumbers dw ?
Characteristics dd ?
IMAGE_SECTION_HEADER ENDS

简单的了解一下区段的结构后,我们来看下原来所拥有的区段的一些信息:

 
文章内容比较简单,希望本文对大家学习PE文件结构有所帮助!
----ximo[LCG]

下载 (22 KB)

2008-10-24 10:33

翻转整理一下就得如下的信息:

Name:.text
VirtualSize:0x000E
VirtualAddress:0x1000
SizeOfRawData:0x200
PointerToRawData:0x0400
PointerToRelocations:0
PointerToLinenumbers:0
NumberOfRelocations:0
NumberOfLinenumbers:0
Characteristics:0x60000020
--
Name:.rdata
VirtualSize:0x0054
VirtualAddress:0x2000
SizeOfRawData:0x200
PointerToRawData:0x0600
PointerToRelocations:0
PointerToLinenumbers:0
NumberOfRelocations:0
NumberOfLinenumbers:0
Characteristics:0x40000040
--
Name:.data
VirtualSize:0x00e2
VirtualAddress:0x3000
SizeOfRawData:0x200
PointerToRawData:0x0800
PointerToRelocations:0
PointerToLinenumbers:0
NumberOfRelocations:0
NumberOfLinenumbers:0
Characteristics:0xC0000040

根据上面的一些信息,我们来构造1个新的区段;

Name:.ximo
VirtualSize:0x0100
VirtualAddress:0x4000
SizeOfRawData:0x0200
PointerToRawData:0x0A00
PointerToRelocations:0
PointerToLinenumbers:0
NumberOfRelocations:0
NumberOfLinenumbers:0
Characteristics:0xC0000040


很明显,从0x220处开始,就可以开始写入新的区段的信息了。注意字节以及数值的翻转(如:0040要改写成40 00)

填完后如下:



下载 (21 KB)

2008-10-24 10:33

填完区段信息后,必须要在后面填充相应大小的数据。如,本区段的大小为0x0200,因此在最后面添加0x0200大小的数据,用00填充即可!



下载 (22 KB)

2008-10-24 10:33

最后,把区段数改为4,位置在0xB6处,同时,镜象大小也改大些,改为5000即可,位置在0x100处。

至此,手动添加区段的操作就结束了。运行一下修改后的文件,没有提示错误!
借助PE编辑工具(Lord PE)看下修改后的信息吧:



下载 (12 KB)

2008-10-24 10:33


下载 (5 KB)

2008-10-24 10:33


二、手动添加函数

由于我们的任务是添加对话框,用到的函数自然就是MessageBoxA,其所在的DLL为USER32.DLL。
但是可以发现,原程序中并没有MessageBoxA这个函数,也没有USER32.DLL这个DLL,因此,一切得什么自己来添加。

首先,我们查找下原来程序IAT信息

来到0x3C处,它的值指向PE头,它的值为0xB0,PE头的骗移80处,既是此文件的RVA。



下载 (18 KB)

2008-10-24 10:33

也就是:0xB0+0x80=0x130

定位到0x130处看下:



下载 (17 KB)

2008-10-24 10:33

可以发现,其RVA的值为08200000,翻转下就是00002008,大小为28000000,翻转下就是00000028

用LordPE验证下:



下载 (12 KB)

2008-10-24 10:33


数据都吻合!


继续来看,由于RVA=2008,那么具体的偏移值为多少呢?也就是在16进制工具中所对应的值
可以发现,2008在此PE文件的.rdata段,.rdata段的Voffset=0x2000,Roffset=0x600,
则ΔH=0x2000-0x600=0x1A00 (这个偏移值一会将一直用到)

所以,RVA所指向的地址为:0x2008-0x1A00=0x608

开始分析0x608开始的数据:

这个就是IID(IMAGE_IMPORT_DESCRIPTOR)数组:

IMAGE_IMPORT_DESCRIPTOR STRUCT
union
Characteristics dd ?
OriginalFirstThunk dd ?
ends
TimeDateStamp dd ?
ForwarderChain dd ?
Name1 dd ?
FirstThunk dd ?
IMAGE_IMPORT_DESCRIPTOR ENDS


OriginalFirstThunk:30200000
TimeDateStamp:00000000
ForwarderChain:00000000
Name:46200000
FirstThunk:00200000

翻转1下为:
OriginalFirstThunk:0x2030
TimeDateStamp:0x0000
ForwarderChain:0x0000
Name:0x2046
FirstThunk:0x2000

简单的分析下:

定位到0x608处,可以发现数据为30200000,也就是00002030,换算1下:0x2030-0x1A00=0x630
接着定位到0x630,数据为38200000,翻转下,就是00002038,换算1下:0x2038-0x1A00=0x638
再定位到0x638,可以在旁边的窗口,很明显的看到,此API为ExitProcess。


同理:0x2046所指向的既是KERNEL32.DLL这个DLL

整理1下可得:

OriginalFirstThunk:0x2030(ExitProcess)
TimeDateStamp:0x0000
ForwarderChain:0x0000
Name:0x2046(KERNEL32.DLL)
FirstThunk:0x2000(ExitProcess)
有了上面的基础,我们开始来自己添加1个输入函数:USER32.MessageBoxA

由于不想破坏原来的输入表结构,怕损坏以至无法运行,因此,我们把他移动到我们自己所加的区段里

再来计算下新的偏移量:

ΔH=0x4000-0xA00=0x3600

我们在自己加的区段写那函数吧!

找个地址:0xA00,开始写吧

然后,再找个地址写入输入表信息(0xA21)

根据写入函数的地址,构造个新的IID数据结构如下:

OriginalFirstThunk:0x4019(MessageBoxA)
TimeDateStamp:0x0000
ForwarderChain:0x0000
Name:0x4000(USER32.DLL)
FirstThunk:0x4019(MessageBoxA)


下面可以开始写信息了:

原来所有的函数就不必要自己写了,直接用原来的数据吧:

3020 0000 0000 0000 0000 0000 4620 0000 0020 0000(原来那个函数)

1940 0000 0000 0000 0000 0000 0040 0000 1940 0000(新添加的函数)



下载 (18 KB)

2008-10-24 10:33

添加完数据后,来到0x130处,把RVA的值改为0xA21+0x3600=0x4021,也就是2140 0000

OK,保存一下吧。

再次运行,发现没有问题,说明,添加函数成功了!

再次借助工具验证下:



下载 (8 KB)

2008-10-24 10:33

发现已经添加成功了!

三、写代码,调用对话框

下面的任务就是很简单的了,在OD里写代码,调用对话框吧。

看下MessageBoxA的原型:

int MessageBox(
HWND hWnd,// handle of owner window
LPCTSTR lpText,// address of text in message box
LPCTSTR lpCaption,// address of title of message box
UINT uType // style of message box
);


反汇编后就是:

push 0
push title
push caption
push 0
call MessageBoxA


打开OD,找个新区段的代码处,如:00404080

随便找2个地方写字符串:

如:4040A0写title:www.52pojie.cn
4040C0写caption:Hello!I am ximo!

然后在00404080处写入如下代码:

push 0
push 4040A0
push 4040C0
push 0
call dword ptr [00404019]

最后别忘了跳回原来的代码处:

jmp 00401000

保存一下,当然,此时还是无法运行的,因为入口代码还是以前的。
下面来修正下入口代码:

打开16进制编辑器;定位到:0xD8处,把原来的数据0010 0000修改为8040 0000

OK,保存一下。运行看看情况:






出现对话框了吧。

工作到此结束吧!

本帖de评分: 1 条评分 DB +20
DB+20

感谢分享

┌.淫穆”

ZxID:10737016

等级: 上将
..

举报 只看该作者 沙发   发表于: 2010-07-10 0
Re:从1个简单的ReverseMe开始谈PE文件结构的学习  申精
谢谢分享,
iΜ。

ZxID:10566305

等级: 贵宾
决定很重要。

举报 只看该作者 板凳   发表于: 2010-07-10 0
Re:从1个简单的ReverseMe开始谈PE文件结构的学习  申精
谢谢分享
« 返回列表
发帖 回复