欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

一种基于虚拟机分支判断的加密狗破解方法

程序员文章站 2022-03-12 17:34:32
今天一朋友的公司拿到和他们同类产品的软件,想参考分析该软件,但该软件有加密狗保护,无狗无法运行,因此叫我分析一下该软件,看是否可以无狗情况下也能运行。折腾了大半天,发现该软件有反调试、虚拟机等...
今天一朋友的公司拿到和他们同类产品的软件,想参考分析该软件,但该软件有加密狗保护,无狗无法运行,因此叫我分析一下该软件,看是否可以无狗情况下也能运行。折腾了大半天,发现该软件有反调试、虚拟机等保护手段,通过模拟构造狗的数据难以成功,后来想出这种基于虚拟机分支判断的方法,破解成功。这种方法不需要加密狗,也不需要关心数据的加解密算法,也不需要分析虚拟机的handler。
技术思路是,根据记录虚拟机的执行流程,观察虚拟指令的跳转过程。通过观察错误条件下的虚拟指令执行流程,分析跳转处的2个分支功能,并且通过修正虚拟机数据,让其执行正确的分支。通过反复记录与修正,最终找到正确的路径。

现在简单描述一下这种方法,和大家讨论。

1.  初步分析与判断
直接运行该软件,出现提示:
一种基于虚拟机分支判断的加密狗破解方法
找到打开狗的驱动和读取狗数据的位置比较简单,在此并不重要,在进行一系列的狗数据的加解密计算后,程序会返回到这里:
一种基于虚拟机分支判断的加密狗破解方法
多次运行验证可以看出,函数00C06D20即是判断有无加密狗并验证数据合法性的函数,并且可以确认,假如有合法的加密狗,该函数应该返回0,但是如果直接将返回值修改为0的话,程序仍然会出现提示,这表示接下去的程序执行会使用到该函数的数据计算结果。

2.  虚拟机结构的基本分析
接下去的程序执行很明显又进入虚拟机循环执行。
虚拟机看上去是标准的循环执行结构,如图:
一种基于虚拟机分支判断的加密狗破解方法
在此可以看出虚拟机的结构:00BD974C地址保存虚拟机指令IP地址,并且是指令长度固定的虚拟机,即每条指令长度是8字节。 www.2cto.com

3.  关键问题
由于虚拟机指令长度固定,因此根据记录虚拟机的执行流程,很容易观察到虚拟指令的跳转过程。通过观察无狗条件下的虚拟指令执行流程,能够分析出跳转处的2个分支功能,并且通过修正虚拟机数据,让其执行正确的分支。通过反复记录与修正,最终找到正确的路径。
首先,将00C06D20的返回值修改为0后进行一次虚拟指令的运行记录,如图:
一种基于虚拟机分支判断的加密狗破解方法
指令记录的结果如下:
一种基于虚拟机分支判断的加密狗破解方法
可以看出,在虚拟机指令IP==00BD9D58时进行了分支跳转,软件出现了提示,因此可以判断,00BD9D58是一条判断指令,合法的执行应该是继续执行00BD9D60。通过设置条件断点观察,也确实可以证明这一点:
一种基于虚拟机分支判断的加密狗破解方法
即判断[[00BD9748]]是否为0,如果不为0就进行虚拟指令跳转。
可以用Mdebug脚本来完成这些自动化的执行和修正:
bp 00BE6C87, "ecx==00BD9D58"
g
bc*
[[00BD9748]] = 0

修正以后,继续重复上述步骤,寻找下一个分支判断点,直到软件最终正确运行。(用脚本功能可以很方便地将被调试程序停止在当前操作点)
脚本最后如下:
bc*
g 00BFDE17
eax=0

bp 00BE6C87, "ecx==00BD9D58"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD9E88"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD8360"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD8390"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD9988"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD9a88"
g
bc*
[[00BD9748]] = 0

bp 00BE6C87, "ecx==00BD9AB0"
g
bc*
[[00BD9748]] = 0


最后附上软件运行界面:
一种基于虚拟机分支判断的加密狗破解方法

4.  总结
这种方法只是对于虚拟机或加密狗的分析的其中一种思路,不一定在所有情况下都适用。对于可变指令长度或更复杂的虚拟机,要配合虚拟机指令的反编译器,结合控制流图和调用流图的分析才能达到结果。