且行且远
分类: 逆向手札 由 ssfighter 于 2006年6月2日 发表

【破文标题】十万个为什么 – 知识问答2006 破解分析
【破文作者】ssfighter@newsmth
【作者邮箱】ssfighter@gmail.com
【作者主页】
【破解工具】OllyICE PEiD0.94 VBExplorer
【破解平台】WinXP
【软件名称】十万个为什么 – 知识问答2006语言版
【软件大小】4.7M
【原版下载】
【保护方式】AsPack加壳,未注册有30次使用限制
【软件简介】一个知识问答的软件,有语言提示。
【破解声明】只是感兴趣,没有任何目的,如有错误之处还请大侠指出
————————————————————————
在天空软件站上找到的这个软件,题库还是很大的,没事的时候休闲一下还是很不错的选择,当然,我们的目的是破解这个软件。首先用PEiD侦壳,显示为 ASPack 2.12 -> Alexey Solodovnikov。用AsPackDie脱壳不表。脱壳之后程序无法启动,估计是有文件大小的检验,侦壳发现是用VB编写的。顺便说一句,这个程序防破解的限制还是比较多的,因此要有点耐心。
用Ollydbg载入,直接下API断点bp rtcFileLen,Ctrl+F9返回后来到这里:
004F0619   .  FF15 98114000 call    near ds:[<&MSVBVM60.#578>]       ;  MSVBVM60.rtcFileLen
004F061F   .  3D 70190800   cmp     eax, 81970                       ;  比较文件大小
004F0624   .  7E 12         jle     short unpacked.004F0638
004F0626   .  C745 FC 05000>mov     dword ptr ss:[ebp-4], 5
004F062D   .  FF15 34104000 call    near ds:[<&MSVBVM60.__vbaEnd>]   ;  MSVBVM60.__vbaEnd
若要这里跳过文件大小校验,只要把jle改成jmp强制跳转即可,这样程序就可以启动了。

但是如果你是用Ollydbg等调试器载入的,程序会出错并自动关机,说明程序检验了调试器,虽然我是用odbg的修改版OllyICE载入的,可以正常启动不会出问题,但是还是先把检验去掉好些。用Ultra String Reference插件搜索所有UNICODE字符串,找Ollydbg,发现了两处参考,先到第一处看看,来到这里:
0055B668   .  68 58804400   push    unpacked.00448058                ;  ollydbg
0055B66D   .  8D4D CC       lea     ecx, ss:[ebp-34]
0055B670   .  51            push    ecx
0055B671   .  FF15 B8114000 call    near ds:[<&MSVBVM60.__vbaStrToAn>;  MSVBVM60.__vbaStrToAnsi
0055B677   .  50            push    eax
0055B678   .  6A 00         push    0
0055B67A   .  6A 00         push    0
0055B67C   .  E8 0BC9EEFF   call    unpacked.00447F8C
0055B681   .  8945 A4       mov     ss:[ebp-5C], eax
0055B684   .  FF15 5C104000 call    near ds:[<&MSVBVM60.__vbaSetSyst>;  MSVBVM60.__vbaSetSystemError
0055B68A   .  8B55 A4       mov     edx, ss:[ebp-5C]
0055B68D   .  8955 D8       mov     ss:[ebp-28], edx
0055B690   .  8D4D CC       lea     ecx, ss:[ebp-34]
0055B693   .  FF15 10124000 call    near ds:[<&MSVBVM60.__vbaFreeStr>;  MSVBVM60.__vbaFreeStr
0055B699   .  C745 FC 10000>mov     dword ptr ss:[ebp-4], 10
0055B6A0   .  837D D8 00    cmp     dword ptr ss:[ebp-28], 0
0055B6A4   .  0F84 93000000 je      unpacked.0055B73D

注意这个跳转,如果不跳的话会来到这里:
0055CBD7   .  C745 FC 11000>mov     dword ptr ss:[ebp-4], 11
0055CBDE   .  C745 B4 F0834>mov     dword ptr ss:[ebp-4C], unpacked.>;  rundll32 user.exe,exitwindows
0055CBE5   .  C745 AC 08000>mov     dword ptr ss:[ebp-54], 8
0055CBEC   .  8D55 AC       lea     edx, ss:[ebp-54]
0055CBEF   .  8D4D BC       lea     ecx, ss:[ebp-44]
0055CBF2   .  FF15 BC114000 call    near ds:[<&MSVBVM60.__vbaVarDup>>;  MSVBVM60.__vbaVarDup
0055CBF8   .  6A 00         push    0
0055CBFA   .  8D55 BC       lea     edx, ss:[ebp-44]
0055CBFD   .  52            push    edx
0055CBFE   .  FF15 14114000 call    near ds:[<&MSVBVM60.#600>]       ;  MSVBVM60.rtcShell
0055CC04   .  DD5D A4       fstp    qword ptr ss:[ebp-5C]
0055CC07   .  8D4D BC       lea     ecx, ss:[ebp-44]
0055CC0A   .  FF15 20104000 call    near ds:[<&MSVBVM60.__vbaFreeVar>;  MSVBVM60.__vbaFreeVar
0055CC10   .  C745 FC 12000>mov     dword ptr ss:[ebp-4], 12
0055CC17   .  C745 B4 30844>mov     dword ptr ss:[ebp-4C], unpacked.>;  shutdown -s
0055CC1E   .  C745 AC 08000>mov     dword ptr ss:[ebp-54], 8
0055CC25   .  8D55 AC       lea     edx, ss:[ebp-54]
0055CC28   .  8D4D BC       lea     ecx, ss:[ebp-44]
0055CC2B   .  FF15 BC114000 call    near ds:[<&MSVBVM60.__vbaVarDup>>;  MSVBVM60.__vbaVarDup
0055CC31   .  6A 00         push    0
0055CC33   .  8D45 BC       lea     eax, ss:[ebp-44]
0055CC36   .  50            push    eax
0055CC37   .  FF15 14114000 call    near ds:[<&MSVBVM60.#600>]       ;  MSVBVM60.rtcShell

呵呵,看到上面的东西了吧,当程序检测到有调试器在运行的时候就会运行shutdown -s命令关机,因此把55B6A4处的je改成jmp强制跳转即可。当然,这还没完,程序还检测了一次调试器,记得刚才的ollydbg有两处参考吧,来到第二处,在这里:
0055E2A4   .  68 08854400   push    unpacked.00448508                ;  ollydbg
0055E2A9   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>>;  MSVBVM60.__vbaStrCmp
0055E2AF   .  F7D8          neg     eax
0055E2B1   .  1BC0          sbb     eax, eax
0055E2B3   .  40            inc     eax
0055E2B4   .  F7D8          neg     eax
0055E2B6   .  66:0BF0       or      si, ax

往前后翻翻看一看,这里简直汇集了众多破解工具,程序当检测到任何一种破解工具就会自动关机。来到下面的判断的地方:
0055E65A   .  83C4 64       add     esp, 64
0055E65D   .  0FBF8D ECFDFF>movsx   ecx, word ptr ss:[ebp-214]
0055E664   .  85C9          test    ecx, ecx
0055E666   .  0F84 E6000000 je      unpacked.0055E752
把这里的跳转也改成jmp即可,到此为止,放破解的限制基本解除,但是程序还是不允许Smart Check调试,我不知道他还有什么地方还有限制了,而且这个程序一启动的时候是启动一个fpj.frm的窗口,这个窗口先检查有没有调试器正在跟踪,如果没有的话就运行,否则自动关机。

到这里的时候我已经运行了20多次了,因此必须赶紧知道程序对30次使用限制的东西在哪儿,用 RegSnap可以看到程序在每次运行在注册表HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\QQPP里面修改了 jiv1b这个键值,这里记录的就是已经使用的次数。注意,如果前面没有把放破解的限制去掉的话,是不能在程序运行的时候使用RegSnap的,否则就会关机,当然最简单的办法是在程序运行前执行一次扫描,程序运行后再执行一次扫描,呵呵,这属于小trick了,本不属于本文的范围的。

言归正传,来到选择帮助-注册菜单,程序又退出了,看来作者也真够狡猾的,这里居然又验了一次文件大小,仍然下API断点bp rtcFileLen,停在这里:
00566A6B    FF15 98114000   call    near ds:[<&MSVBVM60.#578>]       ; MSVBVM60.rtcFileLen
00566A71    3D 52FA0800     cmp     eax, 8FA52
00566A76    7E 0D           jle     short unpacked.00566A85
仍然是把这里对jle改成jmp强制跳转即可,至此所有限制都已取消了,就剩下分析注册码的计算过程了。

用VBExplorer查看一下确定按钮的地址00566B30,在这里下断点,odbg载入,运行,填入用户名ssfighter,注册码12345,确定后断在这里:
00566B30   > \55            push    ebp
00566B31   .  8BEC          mov     ebp, esp
00566B33   .  83EC 18       sub     esp, 18
00566B36   .  68 D6474000   push    <jmp.&MSVBVM60.__vbaExceptHandle>;  SE 处理程序安装
00566B3B   .  64:A1 0000000>mov     eax, fs:[0]
00566B41   .  50            push    eax

由于VB的程序比较长,全写下来太占地方了,我们一点点跟踪,略过前面一堆代码,来到这里:
00566FEF   .  50            push    eax                                  ;  用户名
00566FF0   .  FF15 24104000 call    near ds:[<&MSVBVM60.__vbaLenBstr>]   ;  取用户名长度
00566FF6   .  8BF0          mov     esi, eax
00566FF8   .  F7DE          neg     esi
00566FFA   .  1BF6          sbb     esi, esi
00566FFC   .  46            inc     esi
00566FFD   .  F7DE          neg     esi
00566FFF   .  8B4D B0       mov     ecx, ss:[ebp-50]
00567002   .  51            push    ecx                                  ;  注册码
00567003   .  FF15 24104000 call    near ds:[<&MSVBVM60.__vbaLenBstr>]   ;  取注册码长度
00567009   .  F7D8          neg     eax
0056700B   .  1BC0          sbb     eax, eax
0056700D   .  40            inc     eax
0056700E   .  F7D8          neg     eax
00567010   .  66:0BF0       or      si, ax
00567013   .  66:89B5 68FEF>mov     ss:[ebp-198], si
0056701A   .  8D55 B0       lea     edx, ss:[ebp-50]
0056701D   .  52            push    edx
0056701E   .  8D45 B4       lea     eax, ss:[ebp-4C]
00567021   .  50            push    eax
00567022   .  6A 02         push    2
00567024   .  FF15 8C114000 call    near ds:[<&MSVBVM60.__vbaFreeStrList>;  MSVBVM60.__vbaFreeStrList
0056702A   .  83C4 0C       add     esp, 0C
0056702D   .  8D4D 90       lea     ecx, ss:[ebp-70]
00567030   .  51            push    ecx
00567031   .  8D55 94       lea     edx, ss:[ebp-6C]
00567034   .  52            push    edx
00567035   .  6A 02         push    2
00567037   .  FF15 40104000 call    near ds:[<&MSVBVM60.__vbaFreeObjList>;  MSVBVM60.__vbaFreeObjList
0056703D   .  83C4 0C       add     esp, 0C
00567040   .  0FBF85 68FEFF>movsx   eax, word ptr ss:[ebp-198]
00567047   .  85C0          test    eax, eax
00567049   .  0F84 CB000000 je      unpacked.0056711A
这里只要用户名和注册码都不是空的即可,再往下跟,来到这里:

0056719B   > \6A 01         push    1
0056719D   .  8B4D B4       mov     ecx, ss:[ebp-4C]
005671A0   .  51            push    ecx
005671A1   .  FF15 D8114000 call    near ds:[<&MSVBVM60.#616>]           ;  MSVBVM60.rtcLeftCharBstr
这里是取用户名最左边一位,再往后看

00567245   > \6A 01         push    1
00567247   .  8B45 B4       mov     eax, ss:[ebp-4C]
0056724A   .  50            push    eax
0056724B   .  FF15 E4114000 call    near ds:[<&MSVBVM60.#618>]           ;  MSVBVM60.rtcRightCharBstr
这里是取用户名最后一位

00567251   .  8BD0          mov     edx, eax
00567253   .  8D4D DC       lea     ecx, ss:[ebp-24]
00567256   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
0056725C   .  8D4D B4       lea     ecx, ss:[ebp-4C]
0056725F   .  FF15 10124000 call    near ds:[<&MSVBVM60.__vbaFreeStr>]   ;  MSVBVM60.__vbaFreeStr
00567265   .  8D4D 94       lea     ecx, ss:[ebp-6C]
00567268   .  FF15 14124000 call    near ds:[<&MSVBVM60.__vbaFreeObj>]   ;  MSVBVM60.__vbaFreeObj
0056726E   .  C745 FC 0E000>mov     dword ptr ss:[ebp-4], 0E
00567275   .  8B4D BC       mov     ecx, ss:[ebp-44]
00567278   .  51            push    ecx
00567279   .  FF15 44104000 call    near ds:[<&MSVBVM60.#516>]           ;  MSVBVM60.rtcAnsiValueBstr
0056727F   .  66:6BC0 0B    imul    ax, ax, 0B                           ;  用户名第一位ascii码乘以0B, 记作a
00567283   .  0F80 17110000 jo      unpacked.005683A0
00567289   .  66:8945 B8    mov     ss:[ebp-48], ax
0056728D   .  C745 FC 0F000>mov     dword ptr ss:[ebp-4], 0F
00567294   .  8B55 DC       mov     edx, ss:[ebp-24]
00567297   .  52            push    edx
00567298   .  FF15 44104000 call    near ds:[<&MSVBVM60.#516>]           ;  MSVBVM60.rtcAnsiValueBstr
0056729E   .  66:2D 4E00    sub     ax, 4E                               ;  用户名最后一位ascii码减去4E,记作b
005672A2   .  0F80 F8100000 jo      unpacked.005683A0
005672A8   .  66:8945 D0    mov     ss:[ebp-30], ax
005672AC   .  C745 FC 10000>mov     dword ptr ss:[ebp-4], 10
005672B3   .  66:8B45 B8    mov     ax, ss:[ebp-48]
005672B7   .  66:0345 D0    add     ax, ss:[ebp-30]                      ;  a+b,记作c
005672BB   .  0F80 DF100000 jo      unpacked.005683A0
005672C1   .  66:8945 D8    mov     ss:[ebp-28], ax
005672C5   .  C745 FC 11000>mov     dword ptr ss:[ebp-4], 11
005672CC   .  6A 04         push    4
005672CE   .  66:8B4D D8    mov     cx, ss:[ebp-28]
005672D2   .  51            push    ecx
005672D3   .  FF15 08104000 call    near ds:[<&MSVBVM60.__vbaStrI2>]     ;  c转化成字符串(10进制)
005672D9   .  8BD0          mov     edx, eax
005672DB   .  8D4D B4       lea     ecx, ss:[ebp-4C]
005672DE   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
005672E4   .  50            push    eax
005672E5   .  FF15 E4114000 call    near ds:[<&MSVBVM60.#618>]           ;  取c的最右边4位
005672EB   .  8BD0          mov     edx, eax
005672ED   .  8D4D D4       lea     ecx, ss:[ebp-2C]
005672F0   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
005672F6   .  8D4D B4       lea     ecx, ss:[ebp-4C]
005672F9   .  FF15 10124000 call    near ds:[<&MSVBVM60.__vbaFreeStr>]   ;  MSVBVM60.__vbaFreeStr
005672FF   .  C745 FC 12000>mov     dword ptr ss:[ebp-4], 12
00567306   .  8B55 D4       mov     edx, ss:[ebp-2C]
00567309   .  52            push    edx
0056730A   .  68 90644400   push    unpacked.00446490
0056730F   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>]    ;  c和”0″比较
00567315   .  8BF0          mov     esi, eax
00567317   .  F7DE          neg     esi
00567319   .  1BF6          sbb     esi, esi
0056731B   .  F7DE          neg     esi
0056731D   .  8B45 D4       mov     eax, ss:[ebp-2C]
00567320   .  50            push    eax
00567321   .  68 F0614400   push    unpacked.004461F0
00567326   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>]    ;  c和””比较
0056732C   .  F7D8          neg     eax
0056732E   .  1BC0          sbb     eax, eax
00567330   .  F7D8          neg     eax
00567332   .  23F0          and     esi, eax
00567334   .  85F6          test    esi, esi
00567336   .  75 15         jnz     short unpacked.0056734D              ;  前面的两个比较取与,都不等则跳
00567338   .  C745 FC 13000>mov     dword ptr ss:[ebp-4], 13
0056733F   .  BA 8C8F4400   mov     edx, unpacked.00448F8C               ;  UNICODE “8723”
00567344   .  8D4D D4       lea     ecx, ss:[ebp-2C]
00567347   .  FF15 80114000 call    near ds:[<&MSVBVM60.__vbaStrCopy>]   ;  MSVBVM60.__vbaStrCopy
0056734D   > \C745 FC 15000>mov     dword ptr ss:[ebp-4], 15
注意这里,如果计算出来的c是”0″或者是空串则令c为”8723″。

再往下跳过一堆看不太懂的代码,来到这里:
005674D9   .  51            push    ecx
005674DA   .  6A 02         push    2
005674DC   .  8B55 B4       mov     edx, ss:[ebp-4C]
005674DF   .  52            push    edx
005674E0   .  FF15 B4104000 call    near ds:[<&MSVBVM60.#631>]           ;  取用户名第二位
005674E6   .  8BD0          mov     edx, eax
005674E8   .  8D4D B0       lea     ecx, ss:[ebp-50]
005674EB   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
005674F1   .  50            push    eax
005674F2   .  68 08694400   push    unpacked.00446908
005674F7   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>]    ;  和”4″比较
005674FD   .  8BF0          mov     esi, eax
005674FF   .  F7DE          neg     esi
00567501   .  1BF6          sbb     esi, esi
00567503   .  46            inc     esi
00567504   .  F7DE          neg     esi
00567506   .  8B45 AC       mov     eax, ss:[ebp-54]
00567509   .  50            push    eax
0056750A   .  FF15 24104000 call    near ds:[<&MSVBVM60.__vbaLenBstr>]   ;  取用户名位数
00567510   .  33C9          xor     ecx, ecx
00567512   .  83F8 07       cmp     eax, 7                               ;  用户名位数和7比较
00567515   .  0F94C1        sete    cl                                   ;  如果不等则cl=0,相等则cl=1
00567518   .  F7D9          neg     ecx
0056751A   .  66:23F1       and     si, cx
0056751D   .  8B55 A8       mov     edx, ss:[ebp-58]
00567520   .  52            push    edx
00567521   .  6A 02         push    2
00567523   .  8B45 D4       mov     eax, ss:[ebp-2C]
00567526   .  50            push    eax
00567527   .  FF15 D8114000 call    near ds:[<&MSVBVM60.#616>]           ;  取c的前两位
0056752D   .  8BD0          mov     edx, eax
0056752F   .  8D4D A4       lea     ecx, ss:[ebp-5C]
00567532   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
00567538   .  50            push    eax
00567539   .  68 9C8F4400   push    unpacked.00448F9C                    ;  UNICODE “0735”
0056753E   .  FF15 54104000 call    near ds:[<&MSVBVM60.__vbaStrCat>]    ;  c的前两位和0735连成一串
00567544   .  8BD0          mov     edx, eax
00567546   .  8D4D A0       lea     ecx, ss:[ebp-60]
00567549   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
0056754F   .  50            push    eax
00567550   .  6A 02         push    2
00567552   .  8B4D D4       mov     ecx, ss:[ebp-2C]
00567555   .  51            push    ecx
00567556   .  FF15 E4114000 call    near ds:[<&MSVBVM60.#618>]           ;  取c的后两位
0056755C   .  8BD0          mov     edx, eax
0056755E   .  8D4D 9C       lea     ecx, ss:[ebp-64]
00567561   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
00567567   .  50            push    eax
00567568   .  FF15 54104000 call    near ds:[<&MSVBVM60.__vbaStrCat>]    ;  把刚才得到的串和c的后两位再串起来
0056756E   .  8BD0          mov     edx, eax
00567570   .  8D4D 98       lea     ecx, ss:[ebp-68]
00567573   .  FF15 E8114000 call    near ds:[<&MSVBVM60.__vbaStrMove>]   ;  MSVBVM60.__vbaStrMove
00567579   .  50            push    eax
0056757A   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>]    ;  真假码比较
00567580   .  F7D8          neg     eax
00567582   .  1BC0          sbb     eax, eax
00567584   .  40            inc     eax
00567585   .  F7D8          neg     eax
00567587   .  66:23F0       and     si, ax
注意,这里真实的注册码已经计算出来,就是把0735插入到c的前两位与后两位之间,但是仅仅注册码对了还不行。再看下面:

005675DF   .  0FBF8D 60FEFF>movsx   ecx, word ptr ss:[ebp-1A0]
005675E6   .  85C9          test    ecx, ecx
005675E8   .  0F84 77090000 je      unpacked.00567F65
往前翻翻,这里其实是进行了三次判断,只有这三次判断都满足才能算注册通过,这三次分别是用户名第二位是否是4,用户名位数是否为7位,注册码是否正确,只有这三个都正确才能注册通过。当然如果想爆破都话把这里nop掉也就可以了,这个程序启动时不会验证用户名和注册码的关系,注册通过只是在注册表 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\QQPP这里加上一个jiv3a的键,键值为5,启动时只判断这个是否正确来决定是否是注册版。

顺便写上启动时候的判断,在这里:
004F2252   .  BA 84714400   mov     edx, unpacked.00447184               ;  jiv3a
004F2257   .  8D4D C8       lea     ecx, ss:[ebp-38]
004F225A   .  FF15 80114000 call    near ds:[<&MSVBVM60.__vbaStrCopy>]   ;  MSVBVM60.__vbaStrCopy
004F2260   .  BA 50714400   mov     edx, unpacked.00447150               ;  software\microsoft\qqpp
004F2265   .  8D4D CC       lea     ecx, ss:[ebp-34]
004F2268   .  FF15 80114000 call    near ds:[<&MSVBVM60.__vbaStrCopy>]   ;  MSVBVM60.__vbaStrCopy
004F226E   .  C785 E4FEFFFF>mov     dword ptr ss:[ebp-11C], 80000002
004F2278   .  8D85 1CFFFFFF lea     eax, ss:[ebp-E4]
004F227E   .  50            push    eax
004F227F   .  8D4D C8       lea     ecx, ss:[ebp-38]
004F2282   .  51            push    ecx
004F2283   .  8D55 CC       lea     edx, ss:[ebp-34]
004F2286   .  52            push    edx
004F2287   .  8D85 E4FEFFFF lea     eax, ss:[ebp-11C]
004F228D   .  50            push    eax
004F228E   .  E8 CDC60600   call    unpacked.0055E960
004F2293   .  8D4D C8       lea     ecx, ss:[ebp-38]
004F2296   .  51            push    ecx
004F2297   .  8D55 CC       lea     edx, ss:[ebp-34]
004F229A   .  52            push    edx
004F229B   .  6A 02         push    2
004F229D   .  FF15 8C114000 call    near ds:[<&MSVBVM60.__vbaFreeStrList>;  MSVBVM60.__vbaFreeStrList
004F22A3   .  83C4 0C       add     esp, 0C
004F22A6   .  C745 FC 2B000>mov     dword ptr ss:[ebp-4], 2B
004F22AD   .  8B45 D4       mov     eax, ss:[ebp-2C]
004F22B0   .  50            push    eax
004F22B1   .  68 94714400   push    unpacked.00447194                    ;  5
004F22B6   .  FF15 D8104000 call    near ds:[<&MSVBVM60.__vbaStrCmp>]    ;  MSVBVM60.__vbaStrCmp
004F22BC   .  85C0          test    eax, eax
004F22BE   .  0F85 51010000 jnz     unpacked.004F2415
当然,把这里nop掉也可以实现爆破。

————————————————————————
总结一下,程序注册的规律是:用户名必须是7位,用户名第二位必须是4。
注册码的计算方法(以下均为10进制):取用户名第一位,ascii码乘以11,再取用户名最后一位,ascii码减去78,两者求和,如果这个和大于4位则取最后4位,如果结果是0或者不存在则令其是8723,并在这个数的前两位和后两位之间插入0735,这八位数字就是注册码。

顺便说一下,这个程序作者好像花了很多功夫在防破解上面,但是最后验证程序是否注册却只是单纯地检验了一个键值是否正确,不免显得有点头重脚轻,这样做可以很容易被爆破,希望作者能够将这里改进一下。
————————————————————————
【版权声明】转载请保持文章的完整性,并注明原作者的信息,谢谢:)



发表评论

昵称:  (必须)
邮件:  (必须)
网址: 
评论: