浅谈VMProtectV2.13.8的IAT修复

|------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
| 调试环境:吾爱汇编XP虚拟机 加密方式:默认 一、 壳到OEP的大致流程(只列出关键) 首先,载入OD后,先停在的VMP1区段。 接触过VMP的人应该都知道 VirtualProtect 这个函数吧,找OEP用的。说通俗一点这其实就是一个改写 区段访问权限 的函数,VMP壳就是利用这个函数来清除我们在代码段 和 IAT 设置的内存访问断点。只要过了这个函数就可以在代码段设置访问断点了。 另外提一点,我们设置的 硬件访问 和 硬件写入 断点并不会被壳检测到,但是硬件执行断点会被检测到。 知道了 大致流程 和 哪些断点不被检测,我们就可以很轻易地找OEP了。这里给大家提供我找OEP的方法 (仅针对VMP 2.13.8): 先把程序运行起来,然后数据窗口定位到 代码段 的头部,往下拉,找到最后一个有效值(最后一个不是00的值),下一个硬件访问断点,重载程序,F9按两次(一次断在写入时,一次断在干扰时),再在代码段设置内存访问断点。就可以直接断在OEP了。 二、 api调用的分析 1.首先大家应该都知道,程序调用IAT的代码一般是: CALL [IAT] JMP [IAT] mov e?? , [iat] 这三种(好像还有一种不太常见的,VC程序没有这种调用,所以这里不讲) 以下简称FF15,FF25,MOV型 2.然后,我们要知道,VMP壳对原先的IAT调用改成什么样子了。这里展示三个例子:CALL [IAT]: 加壳前: 加壳后: JMP [IAT]: 加壳前: 加壳后: mov e??,[IAT] 加壳前: 加壳后: 可以发现,FF 15 型的调用是 6 字节的,但重定向后的E8 是 5 字节的。 这里我们又要补充一个关于VMP对IAT重定向的知识: VMP在加壳时会直接对代码段进行改写,将 大部分 的IAT调用均重定向到 VMP0 区段进行解密(这里和大部分加密壳不一样,大部分加密壳是对IAT表进行改写)。 又因为重定向的代码为E8,是 5 字节的,因此壳会随机填充一个字节。 填充的位置在 E8 call 的上面或者下面都有可能。 以下是VMP 重定向 和 原来的API调用 对比: (此处没有 esp ) 可以发现,关于寄存器EAX的iat调用,和VMP的重定向调用 一样,都是5字节的,也就意味着,对于mov eax,[IAT]这种类型,VMP在加壳时 是没有进行 补码 的。 那我们怎么知道一个被重定向的API,原先是什么,是以哪种方式进行调用的呢?这里我给大家提供一个我原创的方法。 首先我们先要知道,被重定向的API,进入了 VMP0 区段,再经过一系列的运算,得到真实的API的地址,放入堆栈,然后通过 RET 的方法进入真实的API。看图: 这是重定向CALL ,一直F7就可以到这一步。 这里我们用OD的跟踪步入功能,将条件设置为: 两个地址自己在区段表查看,每一次加壳后的 地址都不一样,不是固定的。 这个一定要全程开着。脱壳脚本也要依赖这个。 设置好后,我们随便找一个 重定向CALL,设置为新EIP,然后手动 F7步入,然后点跟踪步入,之后OD就直接停在 出RET的第一句。 区别1:(这里我直接贴结论,你自己去程序试) 先把除了ESP,EBP以外的寄存器全部置0。不改ESP,EBP是防止程序崩溃。 对加壳前FF 15,FF 25 类型的调用,加壳后,通过上面操作,RET出来的第一句就是原API地址。 对加壳前MOV类型的调用,加壳后,通过上面操作,RET出来的第一句是在代码段。API放入寄存器的相应位置。 依照上面的区别,我们可以写出一个初步判断脚本,可以判断出原型是否为MOV型。 区别2:(这里我直接贴结论,你自己去程序试) 我们先将 [ESP]置1,[ESP+4]置2,[ESP+8]置3。(有助于判断) 进CALL前的堆栈:(各个类型都一样这样设置) 原FF 15,且补码在前:RET到真实API后,堆栈: 原FF 15,且补码在后:RET到真实API后,堆栈: 原FF 25,且补码在前:RET到真实API后,堆栈: 原FF 25,且补码在后:RET到真实API后,堆栈: 原MOV,且补码在前:RET回代码段后,堆栈: 原MOV,且补码在后:RET回代码段后,堆栈: 通过区别1和区别2,我们就可以很清楚地知道,这个被重定向的API,原来是什么,是怎么被调用。然后修复是应该从哪个地址开始修改代码。 (若补码在前,则在重定向CALL的地址 -1 处开始修改,若补码在后,则直接从重定向CALL的地址开始修改) 我利用这两个区别,就能写一个完整的判断脚本,判断这个CALL的原型,并且补码在前还是在后。(记得把跟踪步入的条件设置好哦) 结论: 先经过区别1将MOV型和FF15、FF25型分开 若已知不是MOV型: RET到API,且[ESP]=1:FF25型,补码在后 RET到API,且[ESP+4]=2:FF15型,补码在前 RET到API,且[ESP+4]=1:FF15型,且补码在后 RET到API,且[ESP+4]=3:FF25型,且补码在前 若已知是MOV型: RET回代码段,且[ESP]=1:补码在后 否则补码在前 例如:我们再用到上面的图。 看上面展示的FF15型的图,重复发不了。 我们是因为有未加壳的原程序,才知道他的原型是FF 15,且补码在前。 那么我们假设,我们并不知道它的原型, 那我们来跑一遍刚刚的脚本来判断他的类型。 (判断脚本我会提供,当然了我说了原理,所以你们也可以自己写) 在这个CALL右键点击此处为新EIP,然后运行我写的判断类型脚本。就可以知道他的原型和RET出来之后的地址了。 以上61B71D就是出RET后的第一句(EIP会停在出RET的第一句,这看来是一个二次重定向啊),然后看信息框,原型是FF15,且补码在前(qian)。 至于为什么用拼音不用中文,因为记事本的编码问题,用中文会乱码。你们自己改判断脚本吧。 三、 修复脚本的逻辑解释 注意上面有说,脚本要依赖 OD 的跟踪步入,记得设置好条件 脚本的大致步骤: 1.从代码段头开始搜索 符合条件的CALL (也就是CALL VMP0区段 的) 2.判断这个CALL的原始类型(上面讲了判断的方法) 3.修复这个IAT调用(通过上面的判断来选择修复方法。改写代码段,使其恢复原本的调用类型) 4.搜索下一个符合条件的CALL(若不存在,跳转到结束) 5.返回 步骤2 以下是一些细节: 1. 修复的方式: 修复前: 修复后: 他会将原本的API填入IAT表。顺序是搜索符合条件的顺序。 2.每获得一个API,脚本就会遍历已修复了的API,看看是否有重复的,若无重复,则填入iat下一个地址,若有重复,就不填入IAT,再修改代码段对应代码 指向 重复的地址。 不填入重复的API可以保证填入的API个数不会超过 原定IAT中API的个数,也就是不会溢出,覆盖其他有效数据。 3.对于修复不了重定位,会在C盘输出一个TXT,里面的地址就是需要你手动进行修复的地址。 4.因为OD脚本插件的一些BUG,所以有一些明明符合特征的CALL,有时却没有搜索得到,此时要右键分析代码,再跑一次脚本(又要改一个数据)。 关于这个脚本,并不是直接可以用的,要根据你的程序,特定的数据进行修改。 例如: 还有一个特征码(用于寻找CALL VMP0段 的地址),这个根据VMP0区段的地址范围来找。首先你要知道一个 e8调用时后面跟的是函数地址相对于当前地址的偏移量。 举个找特征码的例子: Vmp0 区段的地址是 从 53C000 ~ 615000 那么,你去代码段的头,输入 CALL 615000(VMP0段尾) 得到: 00401000 E8 FB3F2100 call 未加壳_v.00615000 再到代码段的尾(不用真的到尾,接近就行了),输入 CALL 53C000(VMP0段首)得到: 004801E3 E8 18BE0B00 call 未加壳_v.0053C000 这样,你就可以得到两个极限值,也就是说所有的CALL VMP0段的CALL,E8后面的数值肯定 大于 18BE0B00 ,小于 FB3F2100 (小端序程序,以字节为个体从后往前看) 我们就可以得到 特征码: ,, , , ,, 合并一下同类项: E8????2?00 E8????1?00 E8????0F00 E8????0E00 E8????0D00 E8????0C00 E8????0B00 这就是要填入脚本的特征码了,有多少个特征码,就至少要运行多少次脚本。 修改的方法举个例子: 假设你用E8????1?00当特征码修复了若干个函数弹出脚本运行完成。那么改法如下: 这个IAT改成下一个要填充的地址,然后再把红框中的特征码改掉。 然后再运行一次脚本。结束后这两个数据又要改。直到你将所有的特征码都试完。 (不过上文我有说,OD跑脚本插件有BUG,可能有一些第一次没被搜索到,所以你可以试着多跑几次脚本。但记得改上图中IAT那个数据。) (就算是脚本,也要修复挺久的,更别说手动修复了。) 四、 手动修复 上面跑完所有特征码后,就可以将绝大部分的重定向API都修复好,这时打开C盘,看看有没有用脚本修复失败的API,手动修复。 确实有一个:476FB8 其实这个我试了很多次,是至少必有一个函数是修复失败的。我们利用我上面提供的判断类型的脚本。可以先知道它的类型。 FF15型,补码在前,RET出来后停在77FE0000。 其实这个呢,就是一个被偷掉开头的函数,从77FE0000,到77FE0003,就是VMP偷走的函数头,下一个JMP就是跳回那个函数的对应行。我们将这个头以二进制形式复制下来,然后跟入下面那个CALL,将头补回去,你就可以知道这个函数是什么了。 我们直接手动在 476FB8-1 这个地址修改就行了。记得将API记录下来,手动填到IAT中。 其实干完这一步,我们就已经修复完所有的API了。可以用OD自带的插件DUMP出来一份(保留以下现场),这是可以运行的但是跨平台不能运行。但此时你用REC也修复不了,因为我们修复出来的IAT是乱序的,并不是以一个一个DLL的顺序排列好。 所以我们要先用UIF进行修复(也就是帮我们排序)。不得不说UIF是真的强大。 但是用UIF前,我们先要先进行其他的操作。 用ODdump出来的那一份程序进行修改: 1.将dump出来那一份脱壳版拖进 StudyPE+ x86 ,给它加一个区段,用于存放我们UIF修复的API。(在原有的IAT进行修复可能会出错) 2.再将添加了区段的脱壳版 拖进OD,在我们修复的IAT中找到二次重定位的API,将它更改,直接填入真实的API。(因为UIF识别不了重定向的api,会修复错误。) 很好找的, 看看数据和其他对比一下大小就知道了。(一般有两个二次重定向) 3.打开UIF,填入PID,代码段的头,代码段的尾,和我们添加的区段的头部地址。勾选修复输入表。然后点击修复。 修复后,排好了顺序 3.用UIF修复完后,我们就可以直接用REC进行跨平台修复了。选择我们加了区段的脱壳版,填好OEP偏移,和UIF修复后的地址(也就是我们新加的区段头地址)。点获取。 然后修复转存到 你加了区段的脱壳版 上就可以完美修复了。 XP系统下脱壳修复,WIN10上运行: |

相关推荐
西岸行者2 天前
学习笔记:SKILLS 能帮助更好的vibe coding
笔记·学习
悠哉悠哉愿意2 天前
【单片机学习笔记】串口、超声波、NE555的同时使用
笔记·单片机·学习
别催小唐敲代码2 天前
嵌入式学习路线
学习
毛小茛2 天前
计算机系统概论——校验码
学习
babe小鑫2 天前
大专经济信息管理专业学习数据分析的必要性
学习·数据挖掘·数据分析
winfreedoms2 天前
ROS2知识大白话
笔记·学习·ros2
在这habit之下2 天前
Linux Virtual Server(LVS)学习总结
linux·学习·lvs
我想我不够好。2 天前
2026.2.25监控学习
学习
im_AMBER2 天前
Leetcode 127 删除有序数组中的重复项 | 删除有序数组中的重复项 II
数据结构·学习·算法·leetcode
CodeJourney_J2 天前
从“Hello World“ 开始 C++
c语言·c++·学习