手工修复导入表结构

实现手工修复导入表结构

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

手工脱壳完成了。

处理不连续的输入表结构

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

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

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

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

手工修正重定位表

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

关于附加数据的修正

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

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

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

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

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

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

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

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

  1. 手工实现各种脱壳后的修复

    手工修复导入表结构 实现手工修复导入表结构 1.首先需要找到加壳后程序的导入表以及导入了那些函数,使用PETools工具解析导入表结构,如下. 2.发现目录FOA地址为0x00000800的位置,长度 ...

  2. PE格式详细讲解4 - 系统篇04|解密系列

    PE格式详细讲解4 - 系统篇04 让编程改变世界 Change the world by program   到此为止,小甲鱼和大家已经学了许多关于 DOS header 和 PE header 的 ...

  3. PE格式详细讲解11 - 系统篇11|解密系列

    PE格式详细讲解11 - 系统篇11 让编程改变世界 Change the world by program   今天我们来谈谈资源部分,资源部分可以说是 PE 文件所有结构中,最复杂的一部分,也最让 ...

  4. PE格式第七讲,重定位表

    PE格式第七讲,重定位表 作者:IBinary 出处:http://www.cnblogs.com/iBinary/ 版权所有,欢迎保留原文链接进行转载:) 一丶何为重定位(注意,不是重定位表格) 首 ...

  5. 写一个PE的壳_Part 5:PE格式修复+lief源码修改

    系列汇总 写一个PE的壳_Part 1:加载PE文件到内存 写一个PE的壳_Part 2:ASLR+修复输入表(IAT)+重定位表支持(.reloc) 写一个PE的壳_Part 3:Section里实 ...

  6. PE格式:导入表与IAT内存修正

    本章教程中,使用的工具是上次制作的PE结构解析器,如果还不会使用请先看前一篇文章中对该工具的介绍,本章节内容主要复习导入表结构的基础知识点,并通过前面编写的一些小案例,实现对内存的转储与导入表的脱壳修 ...

  7. PE格式详细讲解1 - 系统篇01|解密系列

    PE格式详细讲解1 - 系统篇01 让编程改变世界 Change the world by program 由于时间关系,这里只整理出必要的课件内容,详细请下载具体课件和详细讲解视频. [codesy ...

  8. 反编译之将脱壳后的dex文件重新打包成apk

    前言:通过上一篇文章反编译之脱去乐固加固的壳,已经可以拿到dex文件了,那么我们怎么将dex文件重新打包回新的apk呢?如果有这样的疑问,就看看这篇文章吧!一定会帮到你的! 得到dex文件之后该做什么 ...

  9. 学破解 一 PE格式之MS-DOS MZ header

    from:http://www.2cto.com/Article/201203/123125.html PE的意思就是这个the Protable Executable (PE) file forma ...

最新文章

  1. PL/SQL导入/导出dmp文件-Oracle表空间不一致
  2. java hdfs 新建目录_如何用java在hdfs中创建一个新目录?
  3. r语言和python-r语言和python的详细对比
  4. mybatis {arg0} 与 {0}
  5. FreeSql (三)实体特性
  6. cp210x驱动运行不了怎么解决_【问题】解决Android8.0以上运行不了uiautomatorviewer的办法...
  7. 单节2A锂电池充电芯片方案,PD和QC快充充电器5-12V输入
  8. 我为什么选择使用Go语言?
  9. 前端通过Ajax请求从后台返回数据到页面显示,实现分页功能
  10. 玩客云刷入openwrt系统
  11. 数据库 三级封锁协议
  12. 像素及其表示,灰度图
  13. android remoteviews view,Android 理解RemoteViews
  14. 亚洲研究院微软笔试题
  15. Trends, Limitations and Open Challenges inAutomatic Readability Assessment Research翻译
  16. 主题 07:如何进行 Java 系统性能优化(下)
  17. DHCP option82字段
  18. 计算机三级网络技术第六章(第一轮)
  19. 大学生居家上网课,“最佳拍档”找到了吗?
  20. 教师管理助手平台有哪些功能特别好,使其非常受学生们喜欢

热门文章

  1. 为什么集成墙面已经慢慢让大家接受了?
  2. 【nginx】配置ssl模块及使用HTTPS(fastDFS、网页等等)
  3. 在win10中搭建zircon开发调试环境
  4. Mac安装hadoop伪分布式
  5. 软件工程与计算II重点整理(第6-7章)
  6. 计算机动画技术 增强现实,AR技术是什么 增强现实技术介绍
  7. 学习记录(一)制作python版本的CIFAR10数据集
  8. 新鲜!宁盾dKey手机动态口令牌简介
  9. QTlineedit关于setPlaceholderText(背景文字的实现)
  10. 在福禄克DSX2-5000基础上配CFP2-Q-ADD测试光纤