2024年6月15日发(作者:)
VB程序的克星SmartCheck及重启验证型破解实例
文章录入: 责任编辑: 更新时间:2010-10-21 9:51:02 644
文/图 落叶树
想必大家都知道,VB属于解释执行型的语言,它生成的程序是一边翻译一边执行的。以前老的版本由于语言
解释器的存在,我们平时习惯使用的OllyDbg等调试工具在跟踪VB程序的时候经常不停地跳来跳去,让你
晕头转向,这是因为我们跟进了解释器的地盘,里面的东西是相当难搞明白的。不过现在的VB6程序已经不
再是单纯的解释执行,大部分的内容取而代之变成了编译后的代码。虽然如此,还是不能像VC、Delphi程
序反编译后的那么直观:压入一堆你看不明白的参数,call一些不知道什么意思的过程,动辄错误、中止。
用OD来跟还是不够方便啊!怎么办呢,对于Native Code程序(P-code是封装代码或者说中间件伪代码,
相对的Native Code就是原始的未使用P-code的代码,本文不涉及P-code),我们可以使用SmartCheck来
轻易对付它。
这次我们破解的对象是一个网站信息收集工具,用PEiD查看得到的内容是:Microsoft Visual Basic 5.0 /
6.0,这说明软件用VB5以上版本编写,未加壳!呵呵,省去脱壳的麻烦了。下面我们进入实战部分。
工具配置
在开始分析前我们需要先把SmartCheck(下文简称SC)配置好,这个步骤很重要,否则有些关键
事件可能会没保留下来。运行SC,载入要破解的软件,然后点快捷按钮栏的“程序->设置”,接下来按照图
1和图2所示设置即可,其余的可以使用默认配置。
【字体:小 大】
javascript:zes(this,0,null); border=0>
图1
javascript:zes(this,0,null); border=0>
图2
初步分析
设置完后按F5运行软件,首先显示的是一个输入注册码的窗口,这里我们就随便输入
“1212121212”吧,点“注册”后程序一声不吭就退出了,看来还是一个重启验证型软件嘛。这时我们看SC
的界面,分析已经随着程序退出而中止了,不然我们还得自己按“停止”来结束分析。乍眼看上去一大堆东
西,不过只要写过VB程序的人应该不会觉得陌生,就算不懂VB的也不打紧,我们慢慢看自然会明白其中的
意思。现在显示的是从软件启动到输入完注册码退出后的特定事件,我们在图3左栏的窗口里逐一点击查看
(如果看不到这个界面,把“程序结果”窗口最大化即可,因为分栏是缩在边上的)。
图3
嗯,发现刚才注册窗口显示的序列号了(这个相当于机器码,不同电脑上可能会不一样),估计这之前是计
算序列号的过程,不过这个我们不用关心,继续往下面看。展开Command1_Click过程,呵呵,发现我们输
入的注册码了,毫无疑问,这个按钮事件就是对应注册码算法的,重点锁定在这里。一路看下来,蛮多VB
函数调用的,后面再次出现了序列号,过程结尾处有一串数字“2658271399346741”,如图4
所示。
图4
难道这就是注册码吗?试试看,重新F5运行,输入这串数字,注册,退出。再重新运行(别忘了是重启验证
型,就算是正确的注册码也需要第二次运行才能知道是否成功注册),呃,看来不对,还是那个可恶的注册
窗口。这串数字到底是什么意思呢?
详细分析
刚才我们一直看的是特定事件分析结果,这样虽然找明码比较快,但现在这种没有明码比较的情况
就需要慢慢跟踪流程了。接着上面还是输入那串数字,注册退出后选择快捷栏上的“查看->显示所有事件”,
这下出来的东西就多多啦,对应图4字符串的地方下面是一个比较语句,如图5所示。
图5
两个字符串比较,看来关键就在这里,刚才我们经过试验得知String2这串28位的数字不对。而一般情况下
比较语句都是比较两者是否相等,这里假设如果String1=String2则注册成功,那么第一步就先搞清楚
String2是怎么来的吧。可能有些朋友想说:为什么图5里的String1“511”就不能是注册码呢?
别忘了,我们输入两次不同的假注册码都是显示同一String2字符串,可见它是相对固定的,而String1则
是每次都变化,可见跟输入的注册码有关,所以此时的String1不会是注册码,而我们输入的假码是怎么转
化成String2(String1=String2注册成功)才是关键!
我们往上面一直拉到Command1_Click,再次逐一看下来,如图6所示。由于这次是详细分析,所以
大家如果不熟悉VB函数的话最好通过搜索引擎来找一下相关函数的作用看看。这次SC显示的事件很多,为
了不占用版面,我只挑关键的地方截图,其它的就讲讲大概意思,大家自己跟一下就很清楚了。
Command1_Click过程一开始分配空间构成一个字符数组,这里我们把它称为T,内容是:
{'C','A','J','K','E','3','U','V','4','Q','X','7','S','H','Y','P','5','M','F','W'},接下来把我
们输入的假注册码前三位去掉,再逐位取剩下的字符和T数组里的字符比较,相等则生成对应数组下标数字
的字符。假设我们输入的注册码是xxxCAJKE,那么这里就会生成字符串“01234”。我们前面输入的假码
“2658271399346741”经过一番运算后变成了“118”,我们先把这设为S1。奇怪,
怎么跟图5的String1不一样呢?再往下面看,哦,原来是把S1按奇偶位分别取成两段,然后把偶数位段反
取,最后两段连接起来才组成了String1。OK,我们搞清楚其中一半关键了,接下来只要弄清楚
String2“2658271399346741”是怎么来的再逆推回去不就可以得到注册码了吗?看完
String1的生成过程后(比较长,大家要有耐心)序列号终于出现了,如图7所示。
图6
VB程序的克星SmartCheck及重启验证型破解实例
文章录入: 责任编辑: 更新时间:2010-10-21 9:51:02 644
文/图 落叶树
【字体:小 大】
想必大家都知道,VB属于解释执行型的语言,它生成的程序是一边翻译一边执行的。以前老的版本由于语言
解释器的存在,我们平时习惯使用的OllyDbg等调试工具在跟踪VB程序的时候经常不停地跳来跳去,让你
晕头转向,这是因为我们跟进了解释器的地盘,里面的东西是相当难搞明白的。不过现在的VB6程序已经不
再是单纯的解释执行,大部分的内容取而代之变成了编译后的代码。虽然如此,还是不能像VC、Delphi程
序反编译后的那么直观:压入一堆你看不明白的参数,call一些不知道什么意思的过程,动辄错误、中止。
用OD来跟还是不够方便啊!怎么办呢,对于Native Code程序(P-code是封装代码或者说中间件伪代码,
相对的Native Code就是原始的未使用P-code的代码,本文不涉及P-code),我们可以使用SmartCheck来
轻易对付它。
这次我们破解的对象是一个网站信息收集工具,用PEiD查看得到的内容是:Microsoft Visual Basic 5.0 /
6.0,这说明软件用VB5以上版本编写,未加壳!呵呵,省去脱壳的麻烦了。下面我们进入实战部分。
工具配置
在开始分析前我们需要先把SmartCheck(下文简称SC)配置好,这个步骤很重要,否则有些关键
事件可能会没保留下来。运行SC,载入要破解的软件,然后点快捷按钮栏的“程序->设置”,接下来按照图
1和图2所示设置即可,其余的可以使用默认配置。
javascript:zes(this,0,null); border=0>
图1
javascript:zes(this,0,null); border=0>
图2
初步分析
设置完后按F5运行软件,首先显示的是一个输入注册码的窗口,这里我们就随便输入
“1212121212”吧,点“注册”后程序一声不吭就退出了,看来还是一个重启验证型软件嘛。这时我们看SC
的界面,分析已经随着程序退出而中止了,不然我们还得自己按“停止”来结束分析。乍眼看上去一大堆东
西,不过只要写过VB程序的人应该不会觉得陌生,就算不懂VB的也不打紧,我们慢慢看自然会明白其中的
意思。现在显示的是从软件启动到输入完注册码退出后的特定事件,我们在图3左栏的窗口里逐一点击查看
(如果看不到这个界面,把“程序结果”窗口最大化即可,因为分栏是缩在边上的)。
图3
嗯,发现刚才注册窗口显示的序列号了(这个相当于机器码,不同电脑上可能会不一样),估计这之前是计
算序列号的过程,不过这个我们不用关心,继续往下面看。展开Command1_Click过程,呵呵,发现我们输
入的注册码了,毫无疑问,这个按钮事件就是对应注册码算法的,重点锁定在这里。一路看下来,蛮多VB
函数调用的,后面再次出现了序列号,过程结尾处有一串数字“2658271399346741”,如图4
所示。
图4
难道这就是注册码吗?试试看,重新F5运行,输入这串数字,注册,退出。再重新运行(别忘了是重启验证
型,就算是正确的注册码也需要第二次运行才能知道是否成功注册),呃,看来不对,还是那个可恶的注册
窗口。这串数字到底是什么意思呢?
详细分析
刚才我们一直看的是特定事件分析结果,这样虽然找明码比较快,但现在这种没有明码比较的情况
就需要慢慢跟踪流程了。接着上面还是输入那串数字,注册退出后选择快捷栏上的“查看->显示所有事件”,
这下出来的东西就多多啦,对应图4字符串的地方下面是一个比较语句,如图5所示。
图5
两个字符串比较,看来关键就在这里,刚才我们经过试验得知String2这串28位的数字不对。而一般情况下
比较语句都是比较两者是否相等,这里假设如果String1=String2则注册成功,那么第一步就先搞清楚
String2是怎么来的吧。可能有些朋友想说:为什么图5里的String1“511”就不能是注册码呢?
别忘了,我们输入两次不同的假注册码都是显示同一String2字符串,可见它是相对固定的,而String1则
是每次都变化,可见跟输入的注册码有关,所以此时的String1不会是注册码,而我们输入的假码是怎么转
化成String2(String1=String2注册成功)才是关键!
我们往上面一直拉到Command1_Click,再次逐一看下来,如图6所示。由于这次是详细分析,所以
大家如果不熟悉VB函数的话最好通过搜索引擎来找一下相关函数的作用看看。这次SC显示的事件很多,为
了不占用版面,我只挑关键的地方截图,其它的就讲讲大概意思,大家自己跟一下就很清楚了。
Command1_Click过程一开始分配空间构成一个字符数组,这里我们把它称为T,内容是:
{'C','A','J','K','E','3','U','V','4','Q','X','7','S','H','Y','P','5','M','F','W'},接下来把我
们输入的假注册码前三位去掉,再逐位取剩下的字符和T数组里的字符比较,相等则生成对应数组下标数字
的字符。假设我们输入的注册码是xxxCAJKE,那么这里就会生成字符串“01234”。我们前面输入的假码
“2658271399346741”经过一番运算后变成了“118”,我们先把这设为S1。奇怪,
怎么跟图5的String1不一样呢?再往下面看,哦,原来是把S1按奇偶位分别取成两段,然后把偶数位段反
取,最后两段连接起来才组成了String1。OK,我们搞清楚其中一半关键了,接下来只要弄清楚
String2“2658271399346741”是怎么来的再逆推回去不就可以得到注册码了吗?看完
String1的生成过程后(比较长,大家要有耐心)序列号终于出现了,如图7所示。
图6
图7
经过生成String1代码的考验后,现在看这段就简单多了,呵呵。流程就是先把序列号“QJCL-JIEE-SMGN-B
PJI-MRNS-PQMR-XKVH”中的“-”去掉变成“QJCLJIEESMGNBPJIMRNSPQMRXKVH”,再从后往前逐一把字符从A
SCII值转成十进制后取个位数,如字符“H”的ASCII值为48H(H表示十六进制),用十进制表示就是72,
取个位就是2;而字符“V”的十进制是86,取个位数6„„最终就变成了我们熟悉的String2“26582710382
73441”。到了这里相信大家应该明白算法过程了吧?我们要做的就是让注册码变换后的Strin
g1等于系列号变换后的String2,目前可以得到已知条件String2,下面让我们通过实例来学习怎样用已知
条件String2逆推注册码Regstr。
String1是由S1分成的两段奇偶参差而成,其中第二段还需倒取,这样我们先把“2658271399
346741”分成相等的两段:26582710382734,41;41倒取:860;这
样奇数位段26582710382734和偶数位段860都出来了,最终还原S1为:2190933872
1783640。S1是由Regstr查表T得出,我们用S1的数字还原回去,T[2]=’J’,T[1]=’A’„„,由于一开
始就把注册码的前三位去掉了,这里我们还要补上随意的三位字母,最终得出注册码Regstr为:xxxJAUE3V
4UJEVKAQCQKK4VJAV4KUEC。呵呵,过程还算是比较简单吧,不知道大家弄清楚了没有?直观简洁!这就是S
martCheck的魅力。
后话
由于SmartCheck不像OD那样可以复制代码且过程比较长,所以本文只能尽量在一些比较关键的地方用截图
表示,不过大体的算法流程还是说明白了,大家最好能参照文章动手跟一下,这样印象会深刻许多的,实践
是不断进步的重要秘诀
图7
经过生成String1代码的考验后,现在看这段就简单多了,呵呵。流程就是先把序列号“QJCL-JIEE-SMGN-B
PJI-MRNS-PQMR-XKVH”中的“-”去掉变成“QJCLJIEESMGNBPJIMRNSPQMRXKVH”,再从后往前逐一把字符从A
SCII值转成十进制后取个位数,如字符“H”的ASCII值为48H(H表示十六进制),用十进制表示就是72,
取个位就是2;而字符“V”的十进制是86,取个位数6„„最终就变成了我们熟悉的String2“26582710382
73441”。到了这里相信大家应该明白算法过程了吧?我们要做的就是让注册码变换后的Strin
g1等于系列号变换后的String2,目前可以得到已知条件String2,下面让我们通过实例来学习怎样用已知
条件String2逆推注册码Regstr。
String1是由S1分成的两段奇偶参差而成,其中第二段还需倒取,这样我们先把“2658271399
346741”分成相等的两段:26582710382734,41;41倒取:860;这
样奇数位段26582710382734和偶数位段860都出来了,最终还原S1为:2190933872
1783640。S1是由Regstr查表T得出,我们用S1的数字还原回去,T[2]=’J’,T[1]=’A’„„,由于一开
始就把注册码的前三位去掉了,这里我们还要补上随意的三位字母,最终得出注册码Regstr为:xxxJAUE3V
4UJEVKAQCQKK4VJAV4KUEC。呵呵,过程还算是比较简单吧,不知道大家弄清楚了没有?直观简洁!这就是S
martCheck的魅力。
后话
由于SmartCheck不像OD那样可以复制代码且过程比较长,所以本文只能尽量在一些比较关键的地方用截图
表示,不过大体的算法流程还是说明白了,大家最好能参照文章动手跟一下,这样印象会深刻许多的,实践
是不断进步的重要秘诀
发布评论