|
楼主 |
发表于 2015-3-14 12:17
|
显示全部楼层
而在00414D36这里,如果跳转就是未注册了. 所以NOP.
继续:
- 00414D3C . C745 FC 2D000>mov dword ptr ss:[ebp-4],2D
- 00414D43 . C785 ECFEFFFF>mov dword ptr ss:[ebp-114],Timer_nc.004>
- 00414D4D . C785 E4FEFFFF>mov dword ptr ss:[ebp-11C],8
- 00414D57 . 8D95 E4FEFFFF lea edx,dword ptr ss:[ebp-11C]
- 00414D5D . 8B4D 08 mov ecx,dword ptr ss:[ebp+8]
- 00414D60 . 83C1 64 add ecx,64
- 00414D63 . E8 08E5FEFF call <jmp.&MSVBVM60.__vbaVarCopy>
- 00414D68 . C745 FC 2E000>mov dword ptr ss:[ebp-4],2E
- 00414D6F . C785 ECFEFFFF>mov dword ptr ss:[ebp-114],Timer_nc.004>
- 00414D79 . C785 E4FEFFFF>mov dword ptr ss:[ebp-11C],8
- 00414D83 . 8D95 E4FEFFFF lea edx,dword ptr ss:[ebp-11C]
- 00414D89 . 8B4D 08 mov ecx,dword ptr ss:[ebp+8]
- 00414D8C . 83C1 74 add ecx,74
- 00414D8F . E8 DCE4FEFF call <jmp.&MSVBVM60.__vbaVarCopy>
- 00414D94 . C745 FC 2F000>mov dword ptr ss:[ebp-4],2F
- 00414D9B . C785 ECFEFFFF>mov dword ptr ss:[ebp-114],Timer_nc.004>
- 00414DA5 . C785 E4FEFFFF>mov dword ptr ss:[ebp-11C],8008
- 00414DAF . 8B45 08 mov eax,dword ptr ss:[ebp+8]
- 00414DB2 . 05 A4000000 add eax,0A4
- 00414DB7 . 50 push eax
- 00414DB8 . 8D85 E4FEFFFF lea eax,dword ptr ss:[ebp-11C]
- 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:[ebp-4],32
- 00414DD7 . C785 ECFEFFFF>mov dword ptr ss:[ebp-114],1
- 00414DE1 . C785 E4FEFFFF>mov dword ptr ss:[ebp-11C],2
- 00414DEB . C785 DCFEFFFF>mov dword ptr ss:[ebp-124],1
- 00414DF5 . C785 D4FEFFFF>mov dword ptr ss:[ebp-12C],2
- 00414DFF . 8D85 E4FEFFFF lea eax,dword ptr ss:[ebp-11C]
- 00414E05 . 50 push eax
- 00414E06 . 8B45 08 mov eax,dword ptr ss:[ebp+8]
- 00414E09 . 05 A4000000 add eax,0A4
- 00414E0E . 50 push eax
- 00414E0F . 8D45 B4 lea eax,dword ptr ss:[ebp-4C]
- 00414E12 . 50 push eax
- 00414E13 . E8 3AE4FEFF call <jmp.&MSVBVM60.__vbaLenVar>
- 00414E18 . 50 push eax
- 00414E19 . 8D85 D4FEFFFF lea eax,dword ptr ss:[ebp-12C]
- 00414E1F . 50 push eax
- 00414E20 . 8D85 30FEFFFF lea eax,dword ptr ss:[ebp-1D0]
- 00414E26 . 50 push eax
- 00414E27 . 8D85 40FEFFFF lea eax,dword ptr ss:[ebp-1C0]
- 00414E2D . 50 push eax
- 00414E2E . 8B45 08 mov eax,dword ptr ss:[ebp+8]
- 00414E31 . 05 08010000 add eax,108
- 00414E36 . 50 push eax
- 00414E37 . E8 1CE4FEFF call <jmp.&MSVBVM60.__vbaVarForInit>
- 00414E3C . 8985 F8FDFFFF mov dword ptr ss:[ebp-208],eax
- 00414E42 . E9 0B020000 jmp Timer_nc.00415052
- ......
- 00415052 > \83BD F8FDFFFF>cmp dword ptr ss:[ebp-208],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:[ebp-7C]
- 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:[ebp-4],3D
- 0041533D . 8B45 08 mov eax,dword ptr ss:[ebp+8]
- 00415340 . 8B00 mov eax,dword ptr ds:[eax]
- 00415342 . FF75 08 push dword ptr ss:[ebp+8]
- 00415345 . FF90 24030000 call dword ptr ds:[eax+324]
- 0041534B . 50 push eax
- 0041534C . 8D45 CC lea eax,dword ptr ss:[ebp-34]
- 0041534F . 50 push eax
- 00415350 . E8 23E0FEFF call <jmp.&MSVBVM60.__vbaObjSet>
- 00415355 . 8985 68FEFFFF mov dword ptr ss:[ebp-198],eax
- 0041535B . 6A 00 push 0
- 0041535D . 8B85 68FEFFFF mov eax,dword ptr ss:[ebp-198]
- 00415363 . 8B00 mov eax,dword ptr ds:[eax]
- 00415365 . FFB5 68FEFFFF push dword ptr ss:[ebp-198]
- 0041536B . FF90 94000000 call dword ptr ds:[eax+94]
- 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:[ebp-198],ax
- 00427571 . 8D4D D8 lea ecx,dword ptr ss:[ebp-28]
- 00427574 . E8 B7BDFDFF call <jmp.&MSVBVM60.__vbaFreeStr>
- 00427579 . 8D4D B4 lea ecx,dword ptr ss:[ebp-4C]
- 0042757C . E8 0DBDFDFF call <jmp.&MSVBVM60.__vbaFreeVar>
- 00427581 . 0FBF85 68FEFF>movsx eax,word ptr ss:[ebp-198]
- 00427588 . 85C0 test eax,eax
- 0042758A . 0F84 0F0D0000 je Timer_nc.0042829F
- 00427590 . C745 FC 07000>mov dword ptr ss:[ebp-4],7
- 00427597 . 66:8365 DC 00 and word ptr ss:[ebp-24],0
- 0042759C . C745 FC 08000>mov dword ptr ss:[ebp-4],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 [thread id:2360 (0x938)]
- 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
复制代码
额,然后同一目录下生成了明码的注册码存储......
然后是长长的检验和计算过程:
在注册码明码出现的时候,看旁边的细节窗口:
string (variant)
String .bstrVal = 001559A4
= "h1141X:if:2Vt:y78OTEiMr34VyX11HaF"
这就是我们的注册码了。使用这个注册码注册一下,然后看看关于窗口:
- 关于
- 计时器 中文版 版本1.7 构建23
- 此软件由****开发.
- Copyright (c) 2015 ****. 保留所有权利.
- 你正在使用演示版(已注册)
- 本软件已授权给:
-
- 注册名:dsong@吾爱破解论坛 WwW.52PoJie.Cn
- 注册码:h1141X:if:2Vt:y78OTEiMr34VyX11HaF
-
- 关闭
复制代码
不过只看关于窗口是不够的,因为它这个程序只要检测到输入过注册码,就会显示已注册,所以我们再来按“倒”按钮:<--反破解思路
发现一切正常(这就好啦哈哈).
(其实如果软件设计成注册码分段验证的会更好,这样的话追码是不可能了,算法分析也会有阻碍.)
---拓展:算法分析
它这个算法也不难,不过是单向的,如果反过来就会检验错误。呵呵。所以只能是明码比较。算法贴出来,让他自己去改代码去。
由于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的对应,对于修改爆破程序是有必要稍微了解一些的,否则代码你看不懂的话怎么破解呢。
我们先来看帮助文件,我这里直接打开会显示“已取消到该网页的导航”,对于这种问题解决办法:
右键属性,在下部看到一个“安全”,按旁边的“解除锁定”即可。最后记得要按确定.
|
|