MagicEXIF破解思路之VB程序破解

从0开始的VB程序破解

上周,为了整点乐子,我打算寻找一个简单的软件来进行破解。正好某群友有一个需要破解的应用,于是这个应用就不幸的成为了我的目标。

开始之前先来介绍一下这个程序,MagicEXIF一个非常强大的图片元数据编辑器。 分为免费版,专业版,旗舰版。

安装完程序后,先来看看程序的基本信息

一个使用Visual Basic编写的程序,且是32位的应用。 再来看看BinaryNinja的反编译结果。

我的评价是惨不忍睹,各种变量混在一起使用,字符串甚至是直接存在函数体里面的,只能说挺离谱的。

总的来说,直接看反编译的代码难度较大,不是很好整。 我又尝试了IDA,结果也是一样。

所以我得找点别的方法

简单进行了一下google,发现VB的程序实际上是运行在一个类似VB虚拟机上的程序。

简单来说,VB程序可以大致分为两个部分,一个为窗体部分,一个为代码部分。窗体部分主要负责软件界面的大致框架,代码部分则是由Pcode组成的一个个函数。 窗体部分通过调用不同的函数来实现不同的效果。

网上正好有一个decompiler可以反编译VB程序 (VB Decompiler),我把软件本体和decompiler都拖到沙箱里开始分析。

程序分析

打开VB Decompiler, 把fast decompile的勾给去掉,等待反编译完成。

可以看到注册的功能是在窗体frmRegister下的

在code段找到对应的代码,一个个点进去进行分析,我们可以得到用户名的长度必须大于8,注册码的长度为64。(因为只有这样激活按钮才可以被按)


继续看激活的过程,具体代码位于cmdActivate_click中,可以发现一旦激活成功后,软件会将激活信息明文储存在reg_info.cfg文件里,这个文件包含用户名,注册码,以及注册模式。注册模式这个之后会说。

观察软件对全局变量的修改与读取,我们同样可以知道0x68002c储存了软件的版本信息(即未注册,专业,旗舰)。 在BN里查找code reference之后,我们也可以推断出每个版本对应的数值。

1
2
3
0x87 = 旗舰版
0x63 = 专业版
0x1 = 免费版

激活完成后,程序会跳出一个窗口让用户重启,在这里可以合理推断验证注册码的代码会在程序启动的时候运行。

因为注册信息保存在reg_info.cfg里,这就给了我一个很好的突破口,查找哪些函数使用了reg_info.cfg这个字符串。于是我们就可以顺藤摸瓜找到对应的函数0x573BD0

可以看到软件先在软件的安装目录下加载了reg_info.cfg文件,并读取了保存的激活信息

从中我们也可以在发现几个重要的全局变量,0x680034保存了用户名(UserName),0x680038保存了注册码(ActivationCode),0x680032保存了激活模式(RegMode)。

再来看具体的注册码验证部分,简单概括一下逻辑

如果注册模式(RegMode为1),那么会调用第一个验证函数0x56e360检查注册码,如果注册模式为0,那么则会调用第二个验证函数0x56e9b0

这两个验证函数都会返回一个值,这个值会赋值给0x68002c也就是软件版本。

同时,这两个函数也会设置0x680030的值。 查看这个的值的cross reference,我们可以知道这个值代表了授权模式。

1
2
3
0 永久授权
1 企业永久授权
2 个人授权(时间有限)

这也是为什么在注册码验证的那部分里,如果这个值是2(也就是不是永久验证),他会去检查到期时间来确保验证码没有过期。

破解

了解了程序具体的具体验证思路,那么就可以进行破解了。

破解的思路比较粗暴,直接给那两个验证函数(0x56e360,0x56e9b0)打补丁,让那两个返回我们要的版本号,设置授权模式为我们想要的模式即可

1
2
3
4
5
6
7
8
; 设置为旗舰版(实际上没用这个代码没用
mov word [0x68002c], 0x87
; 设置为企业永久激活
mov word [0x680030], 1
; 设置返回值为旗舰版
xor eax,eax
mov eax, 0x87
ret

然后在程序目录下新建注册信息 reg_info.cfg

填入注册信息即可

效果

未解决的问题

如果我们再次用cross reference查找哪些地方调用注册码验证函数,我们发现了一个类似初始化函数的代码。

如图所示,我们可以发现他一共调用了两次验证函数,第一次使用arg3=0,第二次使用arg3=-1

奇怪的是,不管第一次的reg mode是啥,第二次都会变成0,运行一次第二个验证函数。 所以实际上只要给第二个验证函数打补丁就可以了。