dsong 发表于 2015-2-10 17:12

VB程序的破解思路总结、编译方式vs破解工具 比较

本帖最后由 dsong 于 2015-2-10 17:41 编辑

WARNING: 此文章非常长,如果你感兴趣但是没耐心看完,可以做个标记然后按浏览器的关闭按钮,等到下次有兴趣了再看。这里我尽量多和详细地解释了VB程序的破解(其实也可看到反破解)的相关东西,把一个简单的VB计时器程序研究透了,对于VB破解应有较大帮助,如果觉得无用的不要喷,谢谢!可能包含错误认识,如有错误欢迎指出。
VB程序也是一个非常有趣的东西,你去看VB的主程序,是用Microsoft Visual C++ 5.0编写的,也就是说,其实里面调用的各种命令和控件,都是一段VC++的代码。还有VB运行时必须的“库”(虚拟机):msvbvm50, msvbvm60, 都是Microsoft Visual C++ DLL,所以非常明显的,只要研究透了VB的这个VM虚拟机DLL,完全可以反编译出P-code的程序的源码。著名的程序就有比如VB Decompiler,它对于P-code的效果大家可以在下面的分析中看得出来,当然它对于编译成Native Code的程序效果也不错,只不过名称什么的都不太清楚。所以说,VB的P-code程序(其实Native Code程序也差不了多少,只不过虚拟机里的代码一部分都插入了程序里而已)和Flash的SWF还是有异曲同工之妙的:都可以反编译(可能可以得到源码),原因都在于它们用了比较“通用”的虚拟机。vb的就是vbvmXX.dll,flash的就是Flash Player XX。

为了更好地研究VB程序的破解,我特意使用了一个小程序来做演示。
另外,由于正向和逆向是有联系的,所以我这里写正向的时候可以类推到逆向,写逆向的时候可以类推到正向。
这个程序是某个同学给我的,听说我学破解,就想让我来看看他的程序编译到底是编译成P-code好还是编译成native code好,如果编译成native code又要不要优化一下呢?
我打算顺便骗到源码,但是居然不给我!不过他倒是送我一对注册名和注册码。拿到程序一看关于窗口还写着“演示版”,不就是传说中的Demo吗!算了,不管这些细节了。
我拿到的程序有以下几个:Timer_nc_speed.exe(256KB)、Timer_p-code.exe(80KB)、Timer_nc_length.exe(240KB)、Timer_nc_none.exe(240KB)。可以看到,P-code程序非常小,但是它运行必须要VB的VM DLL。
首先来看看这个程序是如何进行授权及验证的:
打开后主窗口:
上面有一个注册按钮正好遮掉计时器的“分”的十位(也就是说你计时不能超过10分钟,否则你自己都不知道过了多久),然后会过随机的时间跳出“请尽快注册”的窗口,输入了注册码之后会提示“注册码已存储,请立即重启程序,如果正确下次将不再有限制。”看来是纯重启验证类型的。不过貌似还有个突破点,就是按“倒”按钮(即倒计时)会提示“未注册版本不支持倒计时,是否立即注册?y/n”。也许可以从这个对话框入手哦!
另外,这个软件还有个版本更新历史(我去,都更新到构造23了),里面有一句话引起我的注意:
更改 VB 内部 MSGBOX 成为 user32.dll 的 API 里的 "MessageBoxA".
额,这么说,所有对话框在入口点前的API表(后面会提到)里下断点都是无效的了。

现在,拿出几个神器(网上有提到的): SMARTCHECK,WKTVBDebugger,VB Decompiler。当然OD也用来看看效果。
首先是P-code程序载入OD:入口点的特征就是push XXXXXXXX,Call XXXXXXXX。入口点上方是各种VB虚拟机DLL里面的API,下面就是各种OD识别不出的东西。(不是汇编代码当然识别不出啦)
然后是Native-code程序载入OD:其实做各种优化的都差不多,首先入口点特征与P-code的差不多,上方也是一张表(不过好像更大?),下方也有一段数据,但是再往下拉会发现:

00408C60   > \55            push ebp
00408C61   .8BEC          mov ebp,esp
00408C63   .83EC 18       sub esp,18
00408C66   .68 26314000   push <jmp.&MSVBVM60.__vbaExceptHandler> ;SE 句柄安装
00408C6B   .64:A1 0000000>mov eax,dword ptr fs:
00408C71   .50            push eax
00408C72   .64:8925 00000>mov dword ptr fs:,esp
00408C79   .B8 D0010000   mov eax,1D0
00408C7E   .E8 9DA4FFFF   call <jmp.&MSVBVM60.__vbaChkstk>
00408C83   .53            push ebx
00408C84   .56            push esi
00408C85   .57            push edi
00408C86   .8965 E8       mov dword ptr ss:,esp
00408C89   .C745 EC B8114>mov dword ptr ss:,Timer_nc.0040>
00408C90   .8B45 08       mov eax,dword ptr ss:
00408C93   .83E0 01       and eax,1
00408C96   .8945 F0       mov dword ptr ss:,eax
00408C99   .8B4D 08       mov ecx,dword ptr ss:
00408C9C   .83E1 FE       and ecx,FFFFFFFE这不是我们熟悉的汇编代码了嘛呵呵。
所以说,到目前为止,P-code的防破解作用远远大于Native-code的。
<破解思路1>在API上面下断点跟踪......
这个对于P-code程序是完全无效的了,但是对于Native Code的可以一试。
首先,以他的水平来说,比较注册码肯定是明码比较,但是我没那么无聊去做内存注册机,来爆破试试看。
打开Timer_nc_XXX.exe,在入口点前面的大表这里下断:
004032E2   $- FF25 B0104000 jmp dword ptr ds:[<&MSVBVM60.__vbaStrCmp>]         ;MSVBVM60.__vbaStrCmp运行程序,第一次断下先放行,结果窗口就出来了,说明第一次断下就已经到了关键.
重载程序,断下后F8,来到这里:

734793DA >FF7424 08       push dword ptr ss:
734793DE    FF7424 08       push dword ptr ss:
734793E2    6A 00         push 0
734793E4    E8 44E6FFFF   call MSVBVM60.__vbaStrComp
734793E9    C2 0800         retn 8
再按Alt+F9来到这里:
00414BAE   .50            push eax
00414BAF   .68 78734000   push Timer_nc.00407378
00414BB4   .E8 29E7FEFF   call <jmp.&MSVBVM60.__vbaStrCmp>
00414BB9   .F7D8          neg eax                                              ;here
00414BBB   .1BC0          sbb eax,eax
00414BBD   .F7D8          neg eax
00414BBF   .F7D8          neg eax
这里已经是程序的代码段了,可以更改代码了,继续跟踪看看。
00414BC1   .66:8985 68FEF>mov word ptr ss:,ax
00414BC8   .8D4D D8       lea ecx,dword ptr ss:
00414BCB   .E8 60E7FEFF   call <jmp.&MSVBVM60.__vbaFreeStr>
00414BD0   .8D4D B4       lea ecx,dword ptr ss:
00414BD3   .E8 B6E6FEFF   call <jmp.&MSVBVM60.__vbaFreeVar>
00414BD8   .0FBF85 68FEFF>movsx eax,word ptr ss:
00414BDF   .85C0          test eax,eax
00414BE1   .0F84 E60B0000 je Timer_nc.004157CD   ;这里跳了
00414BE7   .C745 FC 1F000>mov dword ptr ss:,1F
00414BEE   .66:8365 DC 00 and word ptr ss:,0
00414BF3   .C745 FC 20000>mov dword ptr ss:,20
00414BFA   .68 7C744000   push Timer_nc.0040747C                                 ;UNICODE "Timer_Regcode.inf"
00414BFF   .6A 01         push 1
00414C01   .6A FF         push -1
可以看到,00414BE1这里跳转跳了,但是应该是不要跳的,因为下面的代码才开始读取注册码. 于是NOP。

00414C03   .6A 01         push 1
00414C05   .E8 78E6FEFF   call <jmp.&MSVBVM60.__vbaFileOpen>
00414C0A   >C745 FC 21000>mov dword ptr ss:,21
00414C11   .6A 01         push 1
00414C13   .E8 64E6FEFF   call <jmp.&MSVBVM60.#571>
00414C18   .0FBFC0      movsx eax,ax
00414C1B   .85C0          test eax,eax
00414C1D   .0F85 8E000000 jnz Timer_nc.00414CB1
00414C23   .C745 FC 22000>mov dword ptr ss:,22
但是接下来问题也随之出现,就是说这个文件不存在,却要被打开(00414C05处),会出现异常的,所以这句代码也得NOP。不过这个程序令我惊讶的是,居然自带了异常处理程序!现在不能观摩,否则异常不断产生会导致程序卡死,先要把所有异常都处理好,不过那时候也不能再观摩了.
所以还要NOP:

00414C05   .E8 78E6FEFF   call <jmp.&MSVBVM60.__vbaFileOpen>
00414C13   .E8 64E6FEFF   call <jmp.&MSVBVM60.#571>
另外,为了不浪费程序的感情不断读取文件,我们把00414C1D的jnz改为jmp跳过读取阶段. 然后就到了这里:
00414CB1   > \C745 FC 2B000>mov dword ptr ss:,2B
00414CB8   .6A 01         push 1
00414CBA   .E8 ABE5FEFF   call <jmp.&MSVBVM60.__vbaFileClose>
00414CBF   .C745 FC 2C000>mov dword ptr ss:,2C
00414CC6   .C785 ECFEFFFF>mov dword ptr ss:,Timer_nc.004>
00414CD0   .C785 E4FEFFFF>mov dword ptr ss:,8008
00414CDA   .C785 DCFEFFFF>mov dword ptr ss:,Timer_nc.004>
00414CE4   .C785 D4FEFFFF>mov dword ptr ss:,8008
00414CEE   .8B45 08       mov eax,dword ptr ss:
00414CF1   .05 A4000000   add eax,0A4
00414CF6   .50            push eax
00414CF7   .8D85 E4FEFFFF lea eax,dword ptr ss:
00414CFD   .50            push eax
00414CFE   .8D45 B4       lea eax,dword ptr ss:
00414D01   .50            push eax
00414D02   .E8 57E5FEFF   call <jmp.&MSVBVM60.__vbaVarCmpNe>
00414D07   .50            push eax
00414D08   .8B45 08       mov eax,dword ptr ss:
00414D0B   .05 B4000000   add eax,0B4
00414D10   .50            push eax
00414D11   .8D85 D4FEFFFF lea eax,dword ptr ss:
00414D17   .50            push eax
00414D18   .8D45 A4       lea eax,dword ptr ss:
00414D1B   .50            push eax
00414D1C   .E8 3DE5FEFF   call <jmp.&MSVBVM60.__vbaVarCmpNe>
00414D21   .50            push eax
00414D22   .8D45 94       lea eax,dword ptr ss:
00414D25   .50            push eax
00414D26   .E8 39E5FEFF   call <jmp.&MSVBVM60.__vbaVarOr>
00414D2B   .50            push eax
00414D2C   .E8 6FE5FEFF   call <jmp.&MSVBVM60.__vbaBoolVarNull>
00414D31   .0FBFC0      movsx eax,ax
00414D34   .85C0          test eax,eax
00414D36   .0F84 6D090000 je Timer_nc.004156A9
一样的,需要NOP的:
00414CBA   .E8 ABE5FEFF   call <jmp.&MSVBVM60.__vbaFileClose>而在00414D36这里,如果跳转就是未注册了. 所以NOP.
继续:

00414D3C   .C745 FC 2D000>mov dword ptr ss:,2D
00414D43   .C785 ECFEFFFF>mov dword ptr ss:,Timer_nc.004>
00414D4D   .C785 E4FEFFFF>mov dword ptr ss:,8
00414D57   .8D95 E4FEFFFF lea edx,dword ptr ss:
00414D5D   .8B4D 08       mov ecx,dword ptr ss:
00414D60   .83C1 64       add ecx,64
00414D63   .E8 08E5FEFF   call <jmp.&MSVBVM60.__vbaVarCopy>
00414D68   .C745 FC 2E000>mov dword ptr ss:,2E
00414D6F   .C785 ECFEFFFF>mov dword ptr ss:,Timer_nc.004>
00414D79   .C785 E4FEFFFF>mov dword ptr ss:,8
00414D83   .8D95 E4FEFFFF lea edx,dword ptr ss:
00414D89   .8B4D 08       mov ecx,dword ptr ss:
00414D8C   .83C1 74       add ecx,74
00414D8F   .E8 DCE4FEFF   call <jmp.&MSVBVM60.__vbaVarCopy>
00414D94   .C745 FC 2F000>mov dword ptr ss:,2F
00414D9B   .C785 ECFEFFFF>mov dword ptr ss:,Timer_nc.004>
00414DA5   .C785 E4FEFFFF>mov dword ptr ss:,8008
00414DAF   .8B45 08       mov eax,dword ptr ss:
00414DB2   .05 A4000000   add eax,0A4
00414DB7   .50            push eax
00414DB8   .8D85 E4FEFFFF lea eax,dword ptr ss:
00414DBE   .50            push eax
00414DBF   .E8 0CE5FEFF   call <jmp.&MSVBVM60.__vbaVarTstEq>
00414DC4   .0FBFC0      movsx eax,ax
00414DC7   .85C0          test eax,eax
00414DC9   .74 05         je short Timer_nc.00414DD0
00414DCB   .E9 4A160000   jmp Timer_nc.0041641A
00414DC9这个跳转不跳的话就会产生1个异常,并且计时器的显示不正确,虽然可以正确及时,而且调整窗口是否全屏也会出错,不过现在可以顺便观摩一下异常处理窗口了:

异常处理程序
   10:48:02:异常发生.已拦截.无需进一步操作. 错误编号:0, 错误描述:, 引起错误在:“计时器”窗口.
   10:48:31:异常发生.已拦截.无需进一步操作. 错误编号:380, 错误描述:无效属性值, 引起错误在:“计时器”窗口.
   10:48:31:异常发生.已拦截.无需进一步操作. 错误编号:380, 错误描述:无效属性值, 引起错误在:“计时器”窗口.
   10:48:31:异常发生.已拦截.无需进一步操作. 错误编号:380, 错误描述:无效属性值, 引起错误在:“计时器”窗口.
   10:48:31:异常发生.已拦截.无需进一步操作. 错误编号:380, 错误描述:无效属性值, 引起错误在:“计时器”窗口.
程序已经成功处理了异常,这个窗口关闭后也可正常运行,但是一个或多个命令执行失败.
你可以将本窗口截屏或复制叙述并配以适当文字叙述(比如是在什么情况下引起异常,因为错误对象有时不准确),然后联系作者,会尽快处理问题. 谢谢!
                                                    关闭                                                   复制全部    复制选中    清感觉好高级的。呵呵。扯远了,重载程序,这里需要把00414DC9跳转改成jmp.
继续看:

00414DD0   > \C745 FC 32000>mov dword ptr ss:,32
00414DD7   .C785 ECFEFFFF>mov dword ptr ss:,1
00414DE1   .C785 E4FEFFFF>mov dword ptr ss:,2
00414DEB   .C785 DCFEFFFF>mov dword ptr ss:,1
00414DF5   .C785 D4FEFFFF>mov dword ptr ss:,2
00414DFF   .8D85 E4FEFFFF lea eax,dword ptr ss:
00414E05   .50            push eax
00414E06   .8B45 08       mov eax,dword ptr ss:
00414E09   .05 A4000000   add eax,0A4
00414E0E   .50            push eax
00414E0F   .8D45 B4       lea eax,dword ptr ss:
00414E12   .50            push eax
00414E13   .E8 3AE4FEFF   call <jmp.&MSVBVM60.__vbaLenVar>
00414E18   .50            push eax
00414E19   .8D85 D4FEFFFF lea eax,dword ptr ss:
00414E1F   .50            push eax
00414E20   .8D85 30FEFFFF lea eax,dword ptr ss:
00414E26   .50            push eax
00414E27   .8D85 40FEFFFF lea eax,dword ptr ss:
00414E2D   .50            push eax
00414E2E   .8B45 08       mov eax,dword ptr ss:
00414E31   .05 08010000   add eax,108
00414E36   .50            push eax
00414E37   .E8 1CE4FEFF   call <jmp.&MSVBVM60.__vbaVarForInit>
00414E3C   .8985 F8FDFFFF mov dword ptr ss:,eax
00414E42   .E9 0B020000   jmp Timer_nc.00415052
......
00415052   > \83BD F8FDFFFF>cmp dword ptr ss:,0
00415059   .^ 0F85 E8FDFFFF jnz Timer_nc.00414E47


00415059此处也得NOP。
经过了3段类似代码以后,终于来到关键跳(前面跳转必须全部改对才能执行到这里哦):
00415316   .E8 FBDEFEFF   call <jmp.&MSVBVM60.__vbaVarCmpGe>
0041531B   .50            push eax
0041531C   .8D45 84       lea eax,dword ptr ss:
0041531F   .50            push eax
00415320   .E8 75DFFEFF   call <jmp.&MSVBVM60.__vbaVarAnd>
00415325   .50            push eax
00415326   .E8 75DFFEFF   call <jmp.&MSVBVM60.__vbaBoolVarNull>
0041532B   .0FBFC0      movsx eax,ax
0041532E   .85C0          test eax,eax
00415330   .0F84 4F020000 je Timer_nc.00415585       ;***
00415330直接NOp了,这下后面的代码就是设置成已注册的了!

00415336   .C745 FC 3D000>mov dword ptr ss:,3D
0041533D   .8B45 08       mov eax,dword ptr ss:
00415340   .8B00          mov eax,dword ptr ds:
00415342   .FF75 08       push dword ptr ss:
00415345   .FF90 24030000 call dword ptr ds:
0041534B   .50            push eax
0041534C   .8D45 CC       lea eax,dword ptr ss:
0041534F   .50            push eax
00415350   .E8 23E0FEFF   call <jmp.&MSVBVM60.__vbaObjSet>
00415355   .8985 68FEFFFF mov dword ptr ss:,eax
0041535B   .6A 00         push 0
0041535D   .8B85 68FEFFFF mov eax,dword ptr ss:
00415363   .8B00          mov eax,dword ptr ds:
00415365   .FFB5 68FEFFFF push dword ptr ss:
0041536B   .FF90 94000000 call dword ptr ds:
00415371   .DBE2          fclex
很好,并且没有了注册按钮,而且程序开启还会显示已注册!(虽然注册名和注册码都是空的。)
先保存到文件,再来看看关于窗口,反正看了也不会怎么样吧。(因为某些原因,需要把学号和学校代号抹掉,呵呵)
关于
          计时器 中文版 版本1.7 构建23
         此软件由****开发.
    Copyright (c) 2015 ****. 保留所有权利.
            你正在使用演示版(未注册)
                本软件尚未注册!

注册名:未注册
注册码:为了支持软件开发,请及时注册软件! (暂
未对软件试用进行时间限制)

                      关闭一连3个未注册提示,额,有一种不祥的预感,不过至少现在没有注册提示框. 并且设置窗口大小、是否置顶都没出现任何问题。
于是,我再手贱地按了一下“倒”按钮(即倒计时)。结果:
12345678901234567890
123456789
      
            
    关于 返回额,果然有暗桩。我一开始以为本来功能就没有的,结果我用他给我的注册码一试,发现还是有倒计时功能而且完整的。所以再次拖入OD调试。
不过这个反破解有点坑,虽然不是最坑,但是想退出程序还真难!按“返回”按钮没有任何用处,按了开始计时按钮提示"00:00已用完."(这是正常的,因为我还没有设置过多长时间的倒计时),于是又一次手贱按了“设”按钮(设置),结果倒计时窗体不见了,只有一个设置窗口。再次手贱设置完了倒计时时间,还勾选了"允许超时",最后一次手贱就按了“关”按钮(关闭设置窗口),结果程序一个窗口都不见了......好窘。打开任务管理器,发现还在运行啊:
taskmgr.exe                  Admin...00   5,476 K
Timer_nc_none.exe            Admin...00   5,640 K       ;***
NOTEPAD.EXE                  Admin...00       832 K算了,先结束了进程,再载入OD调试看看:
按了一下“倒”按钮,发现真的又一次读取了注册码:
00427562   .F7D8          neg eax
00427564   .1BC0          sbb eax,eax
00427566   .F7D8          neg eax
00427568   .F7D8          neg eax
0042756A   .66:8985 68FEF>mov word ptr ss:,ax
00427571   .8D4D D8       lea ecx,dword ptr ss:
00427574   .E8 B7BDFDFF   call <jmp.&MSVBVM60.__vbaFreeStr>
00427579   .8D4D B4       lea ecx,dword ptr ss:
0042757C   .E8 0DBDFDFF   call <jmp.&MSVBVM60.__vbaFreeVar>
00427581   .0FBF85 68FEFF>movsx eax,word ptr ss:
00427588   .85C0          test eax,eax
0042758A   .0F84 0F0D0000 je Timer_nc.0042829F
00427590   .C745 FC 07000>mov dword ptr ss:,7
00427597   .66:8365 DC 00 and word ptr ss:,0
0042759C   .C745 FC 08000>mov dword ptr ss:,8
004275A3   .68 7C744000   push Timer_nc.0040747C                  ;UNICODE "Timer_Regcode.inf"于是我们也有思路了,只要搜索push 0040747C即可,把所有相关的都改掉. (改的东西都基本一模一样的,因为是单独的再次读取和验证,所以不可能改一处就完美,得一个一个改.......蛋疼啊。)<--此处反破解思路
总共有6处。都改完了以后......终于是完美的了。哈哈。

<破解思路2>使用动态调试程序SMARTCHECK快速定位
SMARTCHECK是NUMEGA公司推出的一款调试VB程序的程序。我找到的最新版是6.20(Build1286) RC2的,1999年发布的......老古董了。网上有几篇文章的,貌似很好用,其实限制也有,不信打开一个P-code程序试试看:
SmartCheck汉化版
Timer_p-code.exe 被编到p代码
   SmartCheck 是不能的提供调试工程信息为编了的p代码。
从 SmartCheck 得到,保证与这些 Visual Basic 编译器背景造这
个工程:
   - 编到本机代码
   - 没有优化
   - 创造符号调试信息
         继续打开程序( )               不打开程序( )
   不显示出这条消息( )悲剧的是,貌似同学给我的这几个程序都不符合要求:
Timer_nc_none.exe - 程序结果
   类型                              Qty.   合计 (字节)    类型            
                                                                                                                        No details)
                                                                              No events

            Results               Events

No source file于是,我联系同学,让他再给我发个符合要求的......终于来了,Timer_nc_none_dbg.exe就是这个了。(从这里可以看出,SMARTCHECK是为编程程序员设计的,不是为逆向而生......)
试试看......
what??还是没有结果,那这个程序就扔掉了吧。没用啊。
不过,幸好,我在扔掉前想到会不会是因为我用的是绿色版的原因,于是我费尽千辛万苦找到6.20 RC2 Retail安装包,安装以后发现要输序列号,不管,先用,结果发现程序没有正确的序列号就不能调试其他程序,显示试用期已过,于是爆破SCShell.dll,可以正常使用了。
结果再测试......发现其实之前的非P-code文件也是可以正常调试的,甚至被优化的也可正常调试,而且P-code程序也可以调试,而且也有有用的东西,只不过一些语句不太明确而已......真是白忙活了,绿色版害死人啊.
好吧,打开程序,调试,由于Timer事件不断产生,所以我们就点击一次注册按钮,再点击一次“倒”按钮,发现真的好清楚:
    Timer_nc_none.exe - 程序结果
   类型                              Qty.   合计 (字节)    类型            
                                                                                                                        No details)
                                                                              No events
            Results               Events
No source file
                  Thread 0
            Event reporting started: 2015-02-10 12:37:35
                  Form1 (Form) created
                  Form1_Load
                     OnError
                     Form1.hWnd
                     GetSystemMenu returns HMENU:6D058F
                     RemoveMenu returns BOOL:1
                     Form1.hWnd
                     GetSystemMenu returns HMENU:6D058F
                     RemoveMenu returns BOOL:1
                     Form1.hWnd
                     GetSystemMenu returns HMENU:6D058F
                     RemoveMenu returns BOOL:1
                     Form1.hWnd
                     SetWindowPos returns BOOL:1
                     sfd.Text <-- "1" (String)
                     Timer1.Interval <-- 1000 (Long)
                     Form1.Caption <-- "计时器" (String)
                     Label1.Caption <-- "00:00" (String)
                     Command1.Caption <-- "退出" (String)
                     comd2.Caption <-- "√" (String)
                     Command3.Caption <-- "X" (String)
                     Command4.Caption <-- "‖" (String)
                     Command7.Caption <-- "大" (String)
                     Command8.Caption <-- "关于" (String)
                     Command9.Caption <-- "常" (String)
                     Text1.Visible <-- False (Boolean)
                     Text2.Visible <-- False (Boolean)
                     Timer1.Enabled <-- False (Boolean)
                     comd2.Enabled <-- True (Boolean)
                     Command3.Enabled <-- False (Boolean)
                     Command4.Enabled <-- False (Boolean)
                     sfd.Visible <-- False (Boolean)
                     Timer2.Enabled <-- False (Boolean)看了老半天,没发现这些语句如何修改,于是只能做追码工具了......
我们先输入注册名注册码:(此程序貌似支持中文注册名啊......)
用户名:dsong@吾爱破解论坛 WwW.52PoJie.Cn
注册码:01234567890ABCDEFabcdef额,然后同一目录下生成了明码的注册码存储......
然后是长长的检验和计算过程:
                      Dir                        //获取目录
                     Open                         //打开
                     EOF                         //是否到最后一行
                     LineInputNum                         //输入
                     EOF                         //是否到最后一行
                     LineInputNum                         //输入
                     EOF                         //....
                     Close                         //关闭
                     Len returns LONG:1243848
                     Mid
                     OnError
                     Asc returns Integer:100
                     Hex
                     Resume
                     Visual Basic Runtime Error 20: 无错误恢复
                     Handling Visual Basic Runtime Error 20
                     Resuming from Visual Basic Runtime Error
                     Resume
                     String ("&H64") --> Long (100)
                     Hex
                     Mid
                     OnError
                     Asc returns Integer:115
                     Hex
                     Resume
                     Visual Basic Runtime Error 20: 无错误恢复
                     Handling Visual Basic Runtime Error 20
                     Resuming from Visual Basic Runtime Error
                     Resume
                     String ("&H73") --> Long (115)
                     Hex
                     Mid
                     OnError
                     Asc returns Integer:111
                     HexResume
                     Visual Basic Runtime Error 20: 无错误恢复
.......
                     Hex
                     String ("&HA0") --> Long (160)
                     String ("&HA0") --> Long (160)
                     Hex
                     String ("&H56") --> Long (86)
                     String ("&H56") --> Long (86)
                     Chr
                     Resume
                     Visual Basic Runtime Error 20: 无错误恢复
                     Handling Visual Basic Runtime Error 20
                     Resuming from Visual Basic Runtime Error
                     Resume
                     Mid
                     OnError
                     String ("&HBE") --> Long (190)
                     String ("&HBE") --> Long (190)
                     String ("&HBE") --> Long (190)
                     Hex
                     String ("&H74") --> Long (116)
                     String ("&H74") --> Long (116)
                     Chr
                     Resume
                     Visual Basic Runtime Error 20: 无错误恢复
                     Handling Visual Basic Runtime Error 20
                     Resuming from Visual Basic Runtime Error
                     Resume
                     Mid
                     OnError
                     String ("&H0A") --> Long (10)
                     String ("&H0A") --> Long (10)
                     Hex
                     String ("&H3A") --> Long (58)
                     String ("&H3A") --> Long (58)
                     String ("&H3A") --> Long (58)
                     Chr
......
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Mid
                     OnError
                     Trim               //注册码明码出现
                     Len returns LONG:1243832               //注册码明码出现
                     Timer2.Interval <-- 1000 (Long)               //定时弹出提醒注册窗口,看到这里要往前找
                     Timer2.Enabled <-- True (Boolean)
                     Form1.Height
                     Label1.FontSize
                     Form1.Height
                     Label1.Height
                     Form1.Width
                     Label1.Width
                     Text1.Text <-- "dsong@吾爱破解论坛 WwW.52PoJie.Cn" (String)               //注册名
                     Text2.Text <-- "01234567890ABCDEFabcdef" (String)      //注册码(假)
                     csy.Visible <-- False (Boolean)
                     csy.Text <-- "0" (String)
                     Resume
                     Visual Basic Runtime Error 20: 无错误恢复
                     Handling Visual Basic Runtime Error 20
                     Resuming from Visual Basic Runtime Error
                     Resume在注册码明码出现的时候,看旁边的细节窗口:
string (variant)
      String.bstrVal = 001559A4
               = "h1141X:if:2Vt:y78OTEiMr34VyX11HaF"
这就是我们的注册码了。使用这个注册码注册一下,然后看看关于窗口:
关于
          计时器 中文版 版本1.7 构建23
         此软件由****开发.
    Copyright (c) 2015 ****. 保留所有权利.
            你正在使用演示版(已注册)
                本软件已授权给:

注册名:dsong@吾爱破解论坛 WwW.52PoJie.Cn
注册码:h1141X:if:2Vt:y78OTEiMr34VyX11HaF

                      关闭
不过只看关于窗口是不够的,因为它这个程序只要检测到输入过注册码,就会显示已注册,所以我们再来按“倒”按钮:<--反破解思路
倒计时 已注册
00:00   
            
    关于 返回发现一切正常(这就好啦哈哈).
(其实如果软件设计成注册码分段验证的会更好,这样的话追码是不可能了,算法分析也会有阻碍.)
---拓展:算法分析
它这个算法也不难,不过是单向的,如果反过来就会检验错误。呵呵。所以只能是明码比较。算法贴出来,让他自己去改代码去。
由于SMARTCHECK代码太长,我这里来说一下它的大致算法。
首先把你的用户名逐位转换成HEX,然后把第一个HEX+4(第一个Hex指用户名第一位的HEX值,后面类推),第二个HEX+8,第三个HEX+C,第四个HEX+10,以此类推,然后取最小为0的hex即48(0x30),最大为z(区分大小写)的hex即122(0x7A),如果过小就+48(0x30),过大就-74(0x4A),然后最后组合起来就是注册码. 既然它程序使用VB写,那么我们也可以用VB来写写看。最后成品放在附件上了。
<3>使用静态反编译工具VB Decompiler快速找到爆破点并更清晰地分析算法
VB Decompiler 是神器了。用它作用非常的大,可以快速找到Native-Code编译的程序爆破点,而不像SMARTCHECK那样不能用来爆破程序。
并且,它不像SMARTCHECK一样渴望是Native Code的程序,它对于P-code的支持反而大于Native Code。看来真是分析了VB虚拟机的运作的成品啊!
应该说,它可以直接把程序算法给爆出来,如下:
loc_412296:   If CBool((global_164 <> vbNullString) Or (global_180 <> vbNullString)) Then
   loc_4122A3:   global_100 = vbNullString
   loc_4122B1:   global_116 = vbNullString
   loc_4122C5:   If (global_164 = vbNullString) Then
   loc_4122CA:       Exit Sub
   loc_4122CB:   End If
   loc_4122E2:   For var_108 = 1 To Len(global_164): global_264 = var_108 'Variant
   loc_41231B:       global_244 = ZFto16(CStr(Mid(global_164, CLng(global_264), 1)))
   loc_41235B:       global_244 = CStr((CVar(CLng("&H" & global_244)) + (global_264 * 4)))
   loc_41238E:       global_100 = global_100 & Hex(global_244)
   loc_4123A1:   Next var_108 'Variant
   loc_4123BD:   global_212 = Trim(global_100)
   loc_4123DB:   For var_12C = 1 To Len(global_212): global_264 = var_12C 'Variant
   loc_412421:       var_10C = ZFto16ZF(CStr(Mid(global_212, CLng(((2 * global_264) - 1)), 2)))
   loc_412433:       global_116 = global_116 & CVar(var_10C)
   loc_41244D:   Next var_12C 'Variant
   loc_412469:   global_228 = Trim(global_116)
   loc_41249C:   If CBool((global_180 = global_228) And (Len(global_228) >= 10)) Then
   loc_4124AD:       Me.Command5.Visible = False
   loc_4124BF:       global_296 = 0
   loc_4124D4:       Me.Timer3.Interval = &H7D0
   loc_4124EA:       Me.Timer3.Enabled = True
   loc_412500:       Me.Command6.Enabled = True
   loc_412512:       global_312 = 1
   loc_412519:   Else
   loc_41252C:       Me.Timer2.Interval = &H3E8
   loc_412542:       Me.Timer2.Enabled = True
   loc_412554:       global_312 = 0
   loc_412558:   End If
   loc_41255D:   Else
   loc_412570:   Me.Timer2.Interval = &H3E8
   loc_412586:   Me.Timer2.Enabled = True
   loc_412598:   global_312 = 0
   loc_41259C:   End If
   loc_4125A1: Else
   loc_4125B4:   Me.Timer2.Interval = &H3E8
   loc_4125CA:   Me.Timer2.Enabled = True
   loc_4125DC:   global_312 = 0
   loc_4125E0: End If恩,挺变态的吧,再试试看Native-code的:
loc_00414BC1: var_198 = (Dir("Timer_Regcode.inf", 7) = vbNullString)
   loc_00414BE1: If var_198 = 0 Then GoTo loc_004157CD
   loc_00414C05: Open "Timer_Regcode.inf" For Input As #1 Len = -1
   loc_00414C0A:
   loc_00414C1D: If EOF(1) <> 0 Then GoTo loc_00414CB1
   loc_00414C35: Line Input #1, Me
   loc_00414C47: If var_24 <> 0 Then GoTo loc_00414C67
   loc_00414C62: ecx = Me
   loc_00414C67: 'Referenced from: 00414C47
   loc_00414C73: If var_24 <> 1 Then GoTo loc_00414C93
   loc_00414C8E: ecx = Me
   loc_00414C93: 'Referenced from: 00414C73
   loc_00414C9E: var_24 = var_24 + 0001h
   loc_00414CA8: var_24 = var_24
   loc_00414CAC: GoTo loc_00414C0A
   loc_00414CB1: 'Referenced from: 00414C1D
   loc_00414CBA: Close #1
   loc_00414CC6: var_114 = vbNullString
   loc_00414CDA: var_124 = vbNullString
   loc_00414D02: var_ret_1 = (Me <> vbNullString)
   loc_00414D1C: var_ret_2 = (Me <> vbNullString)
   loc_00414D26: call Or(var_6C, var_ret_2, var_ret_1, var_34, var_6C, Me, var_34, var_6C, Me, var_34, var_6C, Me, var_34, var_6C, Me)
   loc_00414D36: If CBool(Or(var_6C, var_ret_2, var_ret_1, var_34, var_6C, Me, var_34, var_6C, Me, var_34, var_6C, Me, var_34, var_6C, Me)) = 0 Then GoTo loc_004156A9
   loc_00414D43: var_114 = vbNullString
   loc_00414D63: ecx = vbNullString
   loc_00414D6F: var_114 = vbNullString
   loc_00414D8F: ecx = vbNullString
   loc_00414D9B: var_114 = vbNullString
   loc_00414DC9: If (Me = vbNullString) = 0 Then GoTo loc_00414DD0
   loc_00414DCB: GoTo loc_0041641A
   loc_00414DD0: 'Referenced from: 00414DC9
   loc_00414E37: For Me = 1 To Len(Me) Step 1
   loc_00414E42: GoTo loc_00415052
   loc_00414E47:
   loc_00414EA4: var_eax = Timer.1788
   loc_00414EAA: var_198 = Timer.1788
   loc_00414EEC: ecx = var_2C
   loc_00414F3A: var_ret_4 = CLng("&H" & eax+000000F4h)
   loc_00414F3F: var_124 = var_ret_4
   loc_00414F98: var_2C = var_ret_4 + Me * 4
   loc_00414FA8: ecx = var_2C
   loc_00415012: ecx = Me & Hex(Me)
   loc_00415047: Next Me
   loc_0041504C: var_208 = Next Me
   loc_00415052: 'Referenced from: 00414E42
   loc_00415059: If var_208 <> 0 Then GoTo loc_00414E47
   loc_00415082: ecx = Trim(Me)
   loc_004150F6: For Me = 1 To Len(Me) Step 1
   loc_00415101: GoTo loc_00415284
   loc_00415106:
   loc_004151AD: var_eax = Timer.1792
   loc_004151B3: var_198 = Timer.1792
   loc_004151EC: var_210 = var_2C
   loc_004151FC: var_84 = var_210
   loc_0041522E: ecx = Me & var_210
   loc_00415279: Next Me
   loc_0041527E: var_20C = Next Me
   loc_00415284: 'Referenced from: 00415101
   loc_0041528B: If var_20C <> 0 Then GoTo loc_00415106
   loc_004152B4: ecx = Trim(Me)
   loc_00415320: var_ret_B = (Me = Me) And (Len(Me) >= 10)
   loc_00415330: If CBool(var_ret_B) = 0 Then GoTo loc_00415585
   loc_0041536B: Command5.Visible = False
   loc_00415373: var_19C = eax
   loc_004153DB: ecx = False
   loc_00415418: Timer3.Interval = CInt(2000)
   loc_0041541D: var_19C = eax
   loc_00415490: Timer3.Enabled = True
   loc_00415495: var_19C = eax
   loc_00415508: Command6.Enabled = True
   loc_00415510: var_19C = eax
   loc_0041557B: ecx = CInt(1)
   loc_00415580: GoTo loc_004156A4
   loc_00415585: 'Referenced from: 00415330
   loc_004155BD: Timer2.Interval = CInt(1000)
   loc_004155C2: var_19C = eax
   loc_00415635: Timer2.Enabled = True
   loc_0041563A: var_19C = eax
   loc_0041569F: ecx = False
   loc_004156A4: 'Referenced from: 00415580
   loc_004156A4: GoTo loc_004157C8
   loc_004156A9: 'Referenced from: 00414D36
   loc_004156E1: Timer2.Interval = CInt(1000)
   loc_004156E6: var_19C = eax
   loc_00415759: Timer2.Enabled = True
   loc_0041575E: var_19C = eax
   loc_004157C3: ecx = False
   loc_004157C8: 'Referenced from: 004156A4
   loc_004157C8: GoTo loc_004158EC
   loc_004157CD: 'Referenced from: 00414BE1
   loc_00415805: Timer2.Interval = CInt(1000)
   loc_0041580A: var_19C = eax
   loc_0041587D: Timer2.Enabled = True
   loc_00415882: var_19C = eax
   loc_004158E7: ecx = False恩,代码明显差很多,但是对于调试的帮助还是有挺多的,比如上面可以得出415330的跳转应该不跳,然后到OD里面前前后后看看即可爆破了,不需要再费尽心思猜API来入手了。
这里我也不多说明,但是很明显的,编译成P-code的程序在遇到VB Decompiler的时候马上就跪了,之前的硬壳直接被看穿。
<破解思路3>利用动态调试器WKTVBDebugger来动态调试与修改P-code的VB程序
之前的VB Decompiler对于P-code的程序支持很好,但是并没有很明显的线索去修改VB程序。这时使用WKTVBDebugger就可以按照它里面的帮助文件进行修改跳转等东西了。
注意事项:
1. 此程序只能用于动态调试VB的P-code程序,对于Native-Code程序没有任何用处。
2. XP下使用时为了不出错,要把要调试的程序放在WKTVBDebugger同一目录下。(XP以前的系统应该没有这个问题,以后的没测试)
还有,帮助文件也很重要,里面有P-code和opcode的对应,对于修改爆破程序是有必要稍微了解一些的,否则代码你看不懂的话怎么破解呢。
我们先来看帮助文件,我这里直接打开会显示“已取消到该网页的导航”,对于这种问题解决办法:
右键属性,在下部看到一个“安全”,按旁边的“解除锁定”即可。最后记得要按确定.
安全:       此文件来自其他计算机,可能
             被阻止以帮助保护该计算机。   解除锁定( )然后就正常了。点击目录中“操作码与助记符列表”,然后点击"标准设置",就是长长的一列对照表了。因为P-code与Intel的汇编代码完全不一样,所以得像初学OD那样先掌握一些P-code的含义。
目光聚焦到了这里:
1Eh Branch 3
1Ch BranchF 3
5Ch BranchFVar 3
1Dh BranchT 3 这里可以知道,1c就代表jnz,1d就代表je,1e就代表jmp。(至少我当时是这么稚嫩地认为的。)然后我就到处找,汇编中的NOP在P-code里面该怎么表示呢?我在里面看这张表,找了三遍都没找到相关指令。然后无意中看到了这篇文章:http://blog.sina.com.cn/s/blog_5000f4c901013iiy.html
里面有提到:
...... 所以解密插入一段代码是基本功,但在p-code里这样做比INTEL难。   看了下面的说明,你就会明白p-code语言插入语句为什么困难,如果你懂INTEL汇编,这事并不太难,加句NOP(90)很easy,但p-code不一样,他的语句大部分都与堆栈有关,比如:p-code里面转向语句一共有三个,
Branch (1E) ---- 无条件跳转
BranchT(1D) ---- 栈顶数据为真则跳转
BranchF(1F) ---- 栈顶数据为假则跳转
第一次接触p-code的人会想当然的认为,解密时可以把条件跳转,换成无条件跳转,比如BranchT(1D)换成Branch(1E)但这是错误的,我想这也是解密者犯的第一个错误,因为BranchTbranchF都有一个退栈动作,而Branch与堆栈无关,所以只能用BranchT与branchF互换,下面给出一段我想像的程序,看看他们与通常的机器语言有什么不同,假设一个过程,被调入的基址为00004000,我不知道怎么用p-code中标准术语描述,就称之为一个过程吧。在解密时,你不要想插入所谓空指令,因为栈会乱,改动程序要当心。 ......这一来,我才明白,原来P-code的vb程序不能像Intel程序一样,随便把je,jnz改成jmp,也没有NOP指令给你用了,必须要另辟途径。
好了,到这里准备工作也做得差不多了,把程序载入WKTVBDebugger。看一下关于窗口,发现是2001年的作品,说明最近十几年除了VB Decompiler在不断更新以外,其他的VB工具基本都停留在了10几年以前,这跟微软的保密策略肯定有着非常大的关系(未公开关于P-code的详细信息,不信你去百度或Google搜索,没有什么特别有价值的信息)。对于P-code研究最大的成果也就这么几个。扯远了,来看看程序。界面如下:
WKTVBDebugger v1.3 / 汉化:小生我怕怕
   -Code 代码源:Locs. Addr: 0012FA94h                      Proc. Range:   411F14h-412838h                     堆栈:
00411F14: 00 LargeBos
00411F16: 00 LargeBos                                                            0012F8B4: 00 00 00 00 00 00 00 00
                                                                                 0012F8AC: 80 FF 12 00 00 00 00 00                     ESP
00411F18: 4B OnErrorGoto 004126ECh                                             0012F8A4: 38 28 41 00 6B 3B 0E 66
00411F1B: 00 LargeBos                                                            0012F89C: EC FA 12 00 B4 F8 12 00                              Byte
00411F1D: 04 FLdRfVar 0012FA64h                                                0012F894: 98 DF 15 00 15 1F 41 00
00411F20: 05 ImpAdLdRf                                                         0012F88C: EC FA 12 00 02 02 00 00                     
                                                                                 0012F884: 00 00 00 00 00 00 00 00
00411F23: 24 NewIfNullPr Form1 004040FC                                                                                                         Word
                                                                                 0012F87C: 00 00 00 00 00 00 00 00
00411F26: 0D VCallHresult get__ipropHWNDFORM                                     0012F874: 8C F8 12 00 44 FF 00 10
00411F2B: F5 LitI4: -> 0h 0                                                      0012F86C: C4 FA 12 00 6C F8 12 00                              Dword
00411F30: 6C ILdRf 00000000h                                                   0012F864: 0A 00 00 00 44 F8 12 00
                                                                                 0012F85C: F8 FF FF FF B4 F8 12 00
00411F33: 5E ImpAdCallI4 user32!GetSystemMenu                                    0012F854: 10 00 00 00 58 4D 05 10
00411F38: 71 FStR4                                                               0012F84C: 00 00 00 00 12 00 12 00                        
00411F3B: 3C SetLastSystemError                                                0012F844: FF 00 00 FF 7A 9F 80 7C                              EBP
00411F3C: F5 LitI4: -> 1000h 4096                                                0012F83C: 9A 9A 83 7C 80 9F 80 7C
00411F41: F5 LitI4: -> FFFFF060h -4000                                                                                                             ESP
00411F46: 6C ILdRf 00000000h
00411F49: 0A ImpAdCallFPR4 user32!RemoveMenu
00411F4E: 3C SetLastSystemError                                                                                                                  Enable
00411F4F: 00 LargeBos

                                                                                                                                                                                                                                                                                  EBP
                                                                                                                                                                                       上一页                                       下一页 >
                                                                                                                                                                                                         内存转存 (Ctrl+M)
                                                                                                                                                                                                            加载模块符号
                                                                                                                                                                                                         字符串参考. (Ctrl+S)

Op: 00 02                                                               文件偏移:      00011F14                        编辑                              跟踪命令:                                                      断点

Form1!00411F14
                                                                                                                                                                                       单步跟踪 (F8)                                                API (Ctrl+B)
堆栈转存是启用的,相对到 ESP<-EBP.
                                                                                                                                                                                     执行到返回 (F12)                                       操作码(Ctrl+O)
                                                                                                                                                                                 跟踪当前指令 (F10)                                     执行断点 (Ctrl+E)
                                                                                                                                                                                          运行 (F5)                                             跟踪X行代码 (F6)
   反汇编信息保存         保存信息                  选项                  管理窗口 (Ctrl+F)                     管理杂项
                                           清除日志                  帮助                  深层信息 (Ctrl+I)                      高级信息
   命令 >比较有用的适合刚接触的就是“管理窗口 (Ctrl+F)”,使用这个,可以轻松地对程序载入、按钮按下等下断点。我们打开它,选择Form1(加载时默认的主窗口,如果不是可以一个一个慢慢试)。然后它会给你地址:
对象属性
Form1
地址: 004040FCh
Picture
Label
TextBox
Frame
Command
CheckBox
Option
ComboBox
ListBox
HScrollBar
VScrollBar
Timer
Printer
Screen
Clipboard
DriveListBox
DirListBox
FileListBox
Menu
Shape
Line
Image
PropiertyPage
UserControl
Unknow Controls可以说,非常齐全,但是它只能根据控件来进行下断。而我们根据之前的分析,它在Form_Load的时候就检测了注册码。(如果没有重启验证,那么可以在按钮上下断点。)所以我们不得不再想另外的办法。<--反破解思路,做成纯重启验证也有它的好处。
再次打开VB Decompiler,发现Form_Load事件是在412838,于是打开WKTVBDebugger,下断412838,结果发现断不下!再仔细看看,发现这其实并不是代码的地址,而是窗体地址。所以在VB Decompiler反编译结果的窗口中选中第一句的地址411F26,再下断。
测试成功!这时候就可以取消断点,把VB Decompiler拖到注册验证段,开始是4121F0,再下断。
这里的跳转应该是不跳的,现在这里跳了,所以必须改掉。
这里为了验证BranchF/BranchT不能改成Branch,我们先改了试试看。
点击编辑,把目前的1c改成1e,然后运行。发现也没什么问题啊,请问那篇文章的真实性?我不得而知,望大牛来解释一下。
好,重新来一次。到这里以后看看代码:
004121D2: 3A LitVarStr 'Timer_Regcode.inf'
004121D7: 4E FStVarCopyObj 0012FA3Ch
004121DA: 04 FLdRfVar 0012FA3Ch
004121DD: 0B ImpAdCallI2 rtcDir on address 660D4F71h
004121E2: 23 FStStrNoPop
004121E5: 1B LitStr: ''
004121E8: 3D NeStr
004121EA: 2F FFree1Str
004121ED: 35 FFree1Var
004121F0: 1C BranchF 004125A1 (Jump ?       ;在这
004121F3: 00 LargeBos
004121F5: F4 LitI2_Byte: -> 0h 0
004121F7: 70 FStI2 0012FA36
004121FA: 00 LargeBos
004121FC: 1B LitStr: 'Timer_Regcode.inf'
004121FF: F4 LitI2_Byte: -> 1h 1
00412201: F4 LitI2_Byte: -> FFh 255
00412203: FE Lead3/OpenFile
00412207: 00 LargeBos004121F0的opcode为:1c 8d 06 先改成1c 00 00可以看到:
004121F0: 1C BranchF 00411F14 (Jump ?而我们的目标为BranchF 00412296(那里开始注册码的校验,由于这里没有NOP指令,只能先跳过读取阶段),而412296-411F14=382,所以我们就可以改为:1c 82 03 。值得注意的是,这里又和Intel的汇编指令不同,汇编指令的跳转是以当前地址为参照,而这里P-code是以起始代码为参照的。这样一改,反而还挺好的,没有注册码就跳过读取阶段,有就不跳过,这样的话可以随意改写注册文件了。
然后就到了验证注册码的第一个环节:
00412296: 1C BranchF 0041255D (Jump ?             ;在这
00412299: 00 LargeBos
0041229B: 3A LitVarStr ''
004122A0: 08 FLdPr
004122A3: FD Lead2/MemStVarCopy
004122A7: 00 LargeBos
004122A9: 3A LitVarStr ''
004122AE: 08 FLdPr
004122B1: FD Lead2/MemStVarCopy
004122B5: 00 LargeBos
004122B7: 08 FLdPr
004122BA: 06 MemLdRfVar
004122BD: 3A LitVarStr ''
004122C2: 5D HardType
004122C3: 33 EqVarBool
004122C5: 1C BranchF 004122CB ?
004122C8: 00 LargeBos
004122CA: 13 ExitProcHresult
004122CB: 00 LargeBos依葫芦画瓢,后面的跳转也可这样改,比如00412296这里要跳到412299即下一行,于是412299-411F14=385,于是改成1c 85 03即可。后面的修改也都是差不多的,参照VB Decompiler里面的指令修改起来会很准确很清楚。(不知道如果我使用WKTVBDebugger像OD一样熟练还会不会要VB Decompiler)
Native Code和P-code程序的比较和各种破解VB程序的工具的比较就到这里告一个段落了,如果你能看完整篇文章,那我承认你对于它是极度感兴趣了,呵呵。
最后做个总结: VB的Native Code程序爆破起来比较简单(主要是OD用熟练了),分析算法的话用VB Decompiler就要多花点心思。而P-code的程序追码和分析算法都非常简单,而爆破就要多花一些时间了(主要是WKTVBDebugger不太熟悉)。
顺便加个对话:
我: 各有利弊,.......(上面总结的话)......,你自己看着办吧。
小A: 哦,那我就用Native Code吧,反正反编译出来的源码就不那么直接清楚了。
我: 不过你那个程序算法太简单了一点,加个重壳吧。
小A: 不,加了重壳以后计时的延迟就太大了。
我: 我已经写出你那个软件的注册机了。
小A: 啊?......算了,我换一种编程语言写吧。
我: ......P.S.: 经过我的百般祈求,我的那个小A同学仍然不同意我把他的程序公开。对不起了,大家还是用自己的程序试炼一下吧。恩不过他没说我不能把注册机放出来......呵呵,我相信他不会打我的。

制作总结性的东西总是很累,这个笔记就当大家的参考吧,以后遇到VB程序脱了壳后破解起来应该会挺方便了吧。希望大家支持一下哦!写这篇文章差点写到浏览器卡死...... 下一篇帖子估计要等到一年半以后了。(初二下和初三应该没时间再来研究逆向这种耗费时间的东西了。)

一些提到的软件的链接:(解压密码全部为dsong@52PoJie.Cn)
1. Numega SmartCheck:
链接: http://pan.baidu.com/s/1qWzAlqc 密码: 2oh1

2. DotFix VB Decompiler:
链接: http://pan.baidu.com/s/1i3L3jvR 密码: bf8v

3. WKTVBDebugger:
链接: http://pan.baidu.com/s/1bnF9KV9 密码: ikce

4. Timer's Keygen:
链接: http://pan.baidu.com/s/1ntolbKl 密码: ilal

zeromaggot 发表于 2015-2-10 20:14

果然非常长,还是收藏了慢慢看吧

chornam 发表于 2015-2-10 18:44

期待有大神和楼主交流讨论,也好我从中学习一二。

wanxia 发表于 2015-2-10 18:42

高手,仔细看完了~~

卿少~爱装逼 发表于 2015-2-10 18:15

什么也看不到。。。。。

Hmily 发表于 2015-2-10 17:18

dsong最近几篇文章科普性技术性极高,感谢分享,加精鼓励,已经获得3篇精华贴,自动获得大牛认证勋章!

Avenshy 发表于 2015-2-10 17:22

感谢大神 刚刚全部看完了才回复的

蚯蚓翔龙 发表于 2015-2-10 17:23

{:1_903:}学习了,多谢。。虽然有点长

29565633 发表于 2015-2-10 17:26

高手的文章,一定要好好看看,很长知识的.{:17_1068:}

小楠 发表于 2015-2-10 17:27

其实我很想看完,但是太长了。真的太长了,这让我正在学习c++的人觉得,我的c++的人生才刚刚开始!

qwe86453242 发表于 2015-2-10 17:40

现在还不太懂先收藏吧{:301_998:}

XhyEax 发表于 2015-2-10 17:43

写得好!给楼主一个赞,不过太长没看完,先收藏了

凌云9 发表于 2015-2-10 17:45

前来膜拜大神的

双菜鱼 发表于 2015-2-10 18:02

谢谢大牛,虽然不懂编程,但依旧涨了好多知识{:1_931:}真心膜拜
页: [1] 2 3 4 5 6 7 8 9 10
查看完整版本: VB程序的破解思路总结、编译方式vs破解工具 比较