PE格式:手工实现各种脱壳后的修复

本文涉及的产品
全局流量管理 GTM,标准版 1个月
公共DNS(含HTTPDNS解析),每月1000万次HTTP解析
云解析 DNS,旗舰版 1个月
简介: ### 手工修复导入表结构**实现手工修复导入表结构**1.首先需要找到加壳后程序的导入表以及导入了那些函数,使用PETools工具解析导入表结构,如下。

手工修复导入表结构

实现手工修复导入表结构

1.首先需要找到加壳后程序的导入表以及导入了那些函数,使用PETools工具解析导入表结构,如下。

image.png

2.发现目录FOA地址为0x00000800的位置,长度是0x000000A8定位过去看看,程序中只保留了一个LoadLibraryA和GetProcAddress这两个关键函数,通过这两个关键函数即可定位到所有的函数入口,一般壳都会只加载这两个API函数。

image.png

3.首先我们先来实现手工脱壳,使用ESP定律,开头运行F8一次,在ESP寄存器上右键选择内存窗口中转到,选择断点硬件访问四字节,脱壳环节省略,OEP位置如下。

image.png

4.找到了程序的OEP位置以后,我们可以找到以下代码,通常是在程序的最底部,我们可以顺藤摸瓜的找到内存IAT表的所在位置。

image.png

将地址转为地址,能够看到脱壳后的程序导入的函数,该程序导入了三个函数,分别在两个动态链接库中存储着。

image.png

而我们编写的PETOOLS工具并没有那么智能,他只能识别出文件中的导入表结构,也就是在没有装载入内存时的状态,很明显,此处识别的是外壳的导入表结构

image.png

我们接着脱壳,使用内置的脱壳工具进行内存转储即可,如下所示。

image.png

正常我们脱壳后,程序输入表会保留原始的带壳状态下的结构,如下。

image.png

使用X64DBG对其进行FixDump修复后,其结构表现如下,看样子是完全重构了它的输入表结构。

image.png

既然知道了解决方案,我们也来自己重构一下输入表结构,我们可以任意选择一处具有可读可写属性的内存,这里以2E00为例

首先我们先在20E0处构建一些导入字符串,格式如下。

00002118 => 指向ExitProcess字符串
00002126 => 指向CreateFileA字符串
00000000 => 代表换行符,将两个模块隔开
00002134 => 指向MessageBoxA字符串

之所以中间需要隔开,是因为前两个函数属于Kernel32.dll最后一个函数属于User32.dll 两者之间使用一个DWORD来分隔开,使用PETools工具解析后可以清晰的看出来。

image.png

构建的字符串结构如下所示

image.png

接着我们继续来构建IID结构数组,IID数组则选在2010得位置,以此类推。

000020E0 代表的是OriginFristThunk字段 -> 指向00002118 -> ExitProcess字符串
00002100 代表的是Name字段 -> 指向Kernel32.dll字符串
00002000 指向FristThunk -> 此处可指向一个空白空间,有PE装载器自动填充。

image.png

接着我们需要找到脱壳后的程序输入表位置,并填入。

image.png

image.png

最后的结构对应关系如下。

image.png

最后跳转到0x130处,修正地址为0x2010大小则是0x28

image.png

手工脱壳完成了。

image.png

处理不连续的输入表结构

有些输入表结构在内存中是不连续的,例如下面案例,我们使用PETools解析出来,首先目录FOA=0x0000A800其次大小是0x000005E8

image.png

将FOA转换为VA地址,0x0040E000 长度是5E8,也就是40e000 - 40E5E8这个范围内。

image.png

其中导入函数开始位置是 40e0ec 结束位置是 40e22C 长度是 00000140

image.png

image.png

脱壳修复时,填入对应地址,删除无效指针,即可自动新建一个新的导入表。

image.png

手工修正重定位表

重定位表一般出现在DLL中,因为DLL都是动态加载,所以地址不固定,DLL的入口点在整个执行过程中至少要执行2次,一次是在开始时执行初始化工作,一次则是在结束时做最后的收尾工作,重定位表则是解决DLL的地址问题,默认情况下,重定位表是如下方式构建的。

image.png

1000 表示重定位RVA地址,011c则表示重定位块的长度,后面则是每两个字节代表一个重定位块,1D是重定位地址,30则是重定位的类型,以此向下排列。

重定位表也是分页排列的,每一页大小都是1000字节,如下我们解析一下看看。

image.png

我们以第一个为例,查询一下1000页上的重定位结构。

image.png

重定位RVA: 0000101D是用 1000 加上 1D得到的。

image.png

重定位地址: 0040702C 则是建议装入地址,修正RVA: 0000702C 则是程序被PE加载器修正后的RVA地址,通常与基地址相加得到,如下。

image.png

接下来以 UPX3.01为例,我们来手工脱壳,DLL的脱壳往往需要经过两部,第一步修正导入表地址,第二部则是修正重定位表,UPX壳会破坏这两个表结构,我们需要自己修正一下,首先看一下加壳后的Section节。

image.png

upx壳,我们可以搜索popad命令来快速到达壳尾部的位置上,然后可看到如下,jmp语句则是跳转到解密后的地址处,由于壳没运行起来,这里是空的。

image.png

我们让壳单步运行一段距离,观察尾部的jmp所指向的地址处是否解码(不能让壳跑到这里,我们手动定位过来观察)发现解码后,直接找一处可能会重定位的地址。

例如:call 0x401167 此处在载入时必然会发生重定位,我们就数据窗口跟随。

image.png

跟随40127B ,然后在第一个四字节出右键,选择断点,内存写入断点,设置好以后,运行1-4次左右,就会停到重定位地址处,如下所示。

image.png

我们来到程序OEP处,将内存转储,并修正镜像。

image.png

接着我们将UPX外壳的重定位数据提取出来,依次循环拿到ebx中的地址,如下0017106E - 00171000 = 6E得到的6E就是需要修正的地址。

image.png

再次循环结果变为了0017108D - 00171000 = 8D 得到8D这条数据。

image.png

最终我们需要手动创建一个新节,然后写入我们得到的重定位数据,自己手动重建一个重定位表,这个过程很麻烦,我就不在演示了。

image.png

最后不要忘记调整,重定位表的位置,第一处为相对RVA偏移,第二处则为重定位块大小。

image.png

关于附加数据的修正

附加数据就是在最后一个节的后面增加的一段数据,这段数据没有节区属性,所以附加数据不会被动态装入内存,附加数据一般起点是最后一个区块的末尾,终点则是文件的末尾字节,例如下面的一个案例中,附加数据就在文件偏移 0x00003200 + 0x00000600 = 3800的位置处。

image.png

使用WinHex定位过去看看,会发现数据,这段数据由于没有被载入内存,所以我们是不可能通过PETools工具对其进行分析的,当然专业的PE工具依然可以识别出来。

image.png

我们首先使用X64DBG,并配合ESP定律,快速脱壳并修复程序,保存后,接着就是在文件末尾创建一段空款区域。

image.png

将附加数据拷贝过来,有时附加数据并没有在程序中引用,这种的可以不复制,有的不行,程序运行会引用这些数据块,我们需要修正。

image.png

当我们打开程序时,程序会自动调用CreateFile打开自身,并将文件指针移动到附加数据位置,我们需要手动修正读取偏移,下一个CreateFile断点,运行程序会断下,回溯一层。

image.png

向下跟进,修改0x3800这个是脱壳前默认附加数据的位置,此时我们脱壳后附加数据改到了,B400的位置此处也要修正。

image.png

修正后直接打补丁,此时即可正常读取出附加数据了。

image.png


相关文章
|
存储 iOS开发 Windows
利用Dism修复系统步骤,以及dism找不到源文件解决方案
利用Dism修复系统步骤,以及dism找不到源文件解决方案
6188 0
利用Dism修复系统步骤,以及dism找不到源文件解决方案
pe_xscan优化了几处代码
pe_xscan优化了几处代码
|
2月前
|
Windows
pe_xscan做了几个改动
pe_xscan做了几个改动
|
安全 Linux
Linux常见维护报错,修复MBR引导/修复grub2菜单/内核文件丢失
Linux常见维护报错,修复MBR引导/修复grub2菜单/内核文件丢失
135 0
Linux常见维护报错,修复MBR引导/修复grub2菜单/内核文件丢失
|
存储 安全 小程序
PE格式:手工给程序插入ShellCode
PE格式是 Windows下最常用的可执行文件格式,理解PE文件格式不仅可以了解操作系统的加载流程,还可以更好的理解操作系统对进程和内存相关的管理知识,而有些技术必须建立在了解PE文件格式的基础上,如文件加密与解密,病毒分析,外挂技术等,本次实验的目标是手工修改或增加节区,并给特定可执行程序插入一段ShellCode代码,实现程序运行自动反弹一个Shell会话。
398 0
PE格式:手工给程序插入ShellCode
|
存储 API 数据安全/隐私保护
PE格式:导入表与IAT内存修正
关于Dump内存原理,我们可以使用调试API启动调试事件,然后再程序的OEP位置写入CC断点让其暂停在OEP位置,此时程序已经在内存解码,同时也可以获取到程序的OEP位置,转储就是将程序原封不动的读取出来并放入临时空间中,然后对空间中的节表和OEP以及内存对齐进行修正,最后将此文件在内存保存出来即可。
322 0
PE格式:导入表与IAT内存修正
|
Windows
Windows 技术篇 - win10复制文件或文件夹时出错,提示“文件或目录损坏且无法读取“问题解决。windows驱动器、磁盘修复方法
Windows 技术篇 - win10复制文件或文件夹时出错,提示“文件或目录损坏且无法读取“问题解决。windows驱动器、磁盘修复方法
534 0
Windows 技术篇 - win10复制文件或文件夹时出错,提示“文件或目录损坏且无法读取“问题解决。windows驱动器、磁盘修复方法
|
安全 Windows
使用系统文件检查器工具修复丢失或损坏的系统文件win10、win7
以管理员运行CMD命令行 sfc /scannow 流程结束后,你可能收到以下消息之一: Windows 资源保护找不到任何完整性冲突。这表示您没有任何丢失或损坏的系统文件。Windows 资源保护无法执行请求的操作。
1738 0