https://vb-audio.com/Voicemeeter/potato.htm
在下面这个帖子里,我已经提供了破解的方法:
虚拟声卡Voicemeeter8的爆破:https://www.52pojie.cn/thread-1047885-23-1.html
因为破解思路讲得比较笼统,有坛友跟帖希望我写个详细的分析过程。
其实在破解时走了一些弯路,最后给出的破解补丁用的话完全没问题,但并不是最完美,所以就借这个机会总结一下,给出一个完美的破解。
我认为的完美破解,就是以最少的修改量,达到最佳的破解效果。
言归正传。
Voicemeeter Potato 的保护方法就是用户名(邮箱)+注册码,重启会验证注册信息是否正确,算是比较传统的保护方法了,只是有一个特殊之处,重启验证的功能要等到一段时间之后才会出现,所以只破解注册框的话,明明显示已破解成功,但重启验证时仍然通不过。这个软件没有加壳,代码完全裸奔,新人练手很合适。
对于这一类的保护方法,最好从破解重启验证入手,因为重启验证一但通过,软件直接就是已注册状态了。
调试工具:x96dbg(x64dbg + x32dbg)
首先安装 Voicemeeter Potato 3.0.2.2,然后把系统时间往后调1年,让软件直接过期,运行软件(32位或64位)后,重启验证后提示:Unregistered Version,如下图:
image.png (96.88 KB, 下载次数: 0)
下载附件
2022-6-10 15:55 上传
先调试32位的主程序。
用x32dbg载入主程序,按一下F9,EIP暂停在主程序入口处。在主窗口处点击右键,选择:“搜索”——“当前模块”——“字符串”,出现字符串窗口后,搜索:Unregistered Version,有一条汇编指令对应这个字符串,双击这条指令,来到这个代码段。如下图:
image.png (130.13 KB, 下载次数: 0)
下载附件
2022-6-10 16:07 上传
这条指令一但执行,意味着软件已经进入未注册的处理流程了,在这条指令上边,一般会有另一个分支,即注册成功的处理流程。左边两条跳转分支线很清楚的表明,那才是正确的流程。
再往上看,其实还有一些分支是可以跳过未注册代码的:
image.png (118.95 KB, 下载次数: 0)
下载附件
2022-6-10 16:36 上传
分析这些分支代码:
首先,jmp指令是个标志,出现jmp指令,意味着下面的指令不可能再执行,也就是说,下面的指令,一定是从jmp后面的一条指令开始执行的,而且流程是从别处跳转过来的,所以jmp指令之前的代码段与我们分析的内容无关,我们只看它后面的代码就行了。当然有些复杂情况,我们还要追踪它从哪儿跳过来,一步一步往前分析,幸好,这个软件没那么复杂。
其次,jmp下面的跳转语句分成两组来对比一下,第1组判断条件稍微复杂一些,而且跳转的也比较远。第2组明显是在判断一个标志:标志为0,进入未注册代码,标志不为0,直接跳过未注册代码,来到子程序返回处。
通过上面分析,我们很清楚,要从第2组跳转指令入手,进行分析。
013E6510 | 833D A8CE5D01 00 | cmp dword ptr ds:[0x15DCEA8],0x0 |
013E6517 | 0F85 34010000 | jne voicemeeter8.13E6651 |
013E651D | 833D ACCE5D01 00 | cmp dword ptr ds:[0x15DCEAC],0x0 |
013E6524 | 0F85 27010000 | jne voicemeeter8.13E6651 |
有些人看到这里,就急着用jmp爆破,跳过未注册的代码段,不就完事了吗?答案是:不行!
重要提示:
这一类的软件注册,一般会有一个或多个注册标志,在程序运行期间,可能会反复多次去验证,仅仅跳过”未注册“的提示是不行的,那是自欺欺人,软件即便不显示”未注册“的信息,依然会限制软件的使用。根本的解决办法,就是找到软件在哪里对标志写数据,然后修改指令让它永远写入正确数据。
这里有两个注册标志,一个个分析。
现在我们知道,[0x15DCEA8]的值为0,就是”未注册“的标志,我们得想办法让它的值永远不为0。
对内存地址[0x15DCEA8]下硬件写断点,重新运行程序。
先是运行到这里断下来:
image.png (95.2 KB, 下载次数: 0)
下载附件
2022-6-10 17:03 上传
这段代码很显然是循环批量赋初值,不用管它。
按F9继续运行,然后再次中断到这里:
image.png (111.91 KB, 下载次数: 0)
下载附件
2022-6-10 17:10 上传
这里要把EAX的值填到标志位里,而且EAX=0。记住这里。
再往下运行(需要Shift+F9跳过异常),程序进入界面,显示未注册信息,再也没有中断了,说明上面这个写操作很关键,把EAX=0写到注册标志里了。
EAX的值是从哪儿来的?一般都是它上面的代码段计算出来的,而且上面一般都会有个关键的CALL是用于计算的。
01398D63 | E8 F86CF6FF | call voicemeeter8.12FFA60 |
反汇编这个CALL。x32dbg有个很好的功能,就是流程图,可以帮我们快速分析代码。在代码处点右键,选”流程图“,然后看这个CALL的流程最后的内容:
image.png (58.66 KB, 下载次数: 0)
下载附件
2022-6-10 17:23 上传
发现这个CALL有两个出口。出口2有一句跳不过的 xor eax,eax,也就是说这个出口是死路一条,很明显,另一个出口1才是一条生路。
分析出口1,有一句mov eax,ebx。沿着出口1向上追踪,从后往前倒着找关键路径:
image.png (85.79 KB, 下载次数: 0)
下载附件
2022-6-10 17:31 上传
image.png (79.64 KB, 下载次数: 0)
下载附件
2022-6-10 17:33 上传
image.png (82.36 KB, 下载次数: 0)
下载附件
2022-6-10 17:47 上传
经过上面的流程图分析,关键CALL从入口处开始,沿着”3—2—1“的分支流程走下去,并且在走到最后时,让EAX=1,就大功告成了。
根据这个分析,我们可以制定多种修改方案:
最直观的方案就是首先让”分支3“的最后一条指令直接jmp到”分支2“的起点,”分支2“最后一条指令直接jmp到”分支1“的起点,”分支1“最后一条指令直接jmp到后续流程,走到胜利的出口。
当然,我不是采用这个方案,我的方案是:
1、修改”分支3“一个字节,jmp到”分支2“;
2、修改”分支2“里 call voicemeeter8.12FF910 计算EAX的值,修改了1个字节,让EAX的值为1。后续流程自动走向”分支1“,自动走向那条生路。
这是一个纯属闲得蛋疼的修改方案,目的只为了最大程度减少对原程序的修改,纯爱好而已。
刚才提到,还有一个可能的标志是[0x15DCEAC],但我发现上面的修改完成后,软件已经完美破解,所以这个标志位也不管它了。
64位的主程序,破解思路完全一样,不再重复了。
最后附上x96dbg下的1337补丁,请自行调试,有什么不明白的跟帖交流,喜欢的请点个赞,谢谢。
voicemeeter8.rar
(247 Bytes, 下载次数: 383)
2022-6-10 18:08 上传
点击文件名下载附件
下载积分: 吾爱币 -1 CB