SCSC注册分析
【破解作者】 winndy
【作者邮箱】 CNwinndy@hotmail.com
【使用工具】 PEID v0.93 OllyDbg v1.10 fly修改版
【破解平台】 Winxp SP2
【软件名称】 SCSC - Source Code SpellChecker V1.10
【官方网址】 HTTP://www.parasitesoft.com
【编写语言】 VC6
【软件介绍】 SCSC - Source Code SpellChecker facilitates spelling check and correction for user interface
that is exposed by your C/C++ source code.
【破解声明】 For study ,For Fun,
【破解说明】 无壳,采用MD5算法,失误之处还望指出
【破解过程】PEID查壳,无壳,Microsoft Visual C++ 6.0编写.
先运行Scsc,打开注册窗口,输入Name:CNwinndy,Code:1234567890
点"OK",弹出messagebox(不一定,也许是一个form,猜测),显示警告消息为"Invalid registration code",
标题为"Source Code Spell Checker".
OllyDbg载入Scsc.exe.右键,"搜索"--"所有参考字符串".
找到这里:
0040319D push Scsc.0045C034 ASCII "Invalid registration code"
光标落在这一行,F2,下断点.
再多下些断点,Command命令行输入:bpx messageboxex,打开了Intermodular calls,
点目标,按照字母顺序排序,找到messageboxA,
00432C32 call dword ptr ds:[<&USER32.MessageBoxA>] USER32.MessageBoxA
再下断点.
Scsc是用getdlgitem还是GetWindowTextA来获得用户名和假注册码呢?
把GetWindowTextA下断,顺便把GetWindowTextLengthA也下断点,
往上找,call USER32.GetDlgItem处也下断点.
然后F9运行程序,由于刚才在所有GetWindowTextA和getdlgitem处都下了断点,
因此会有一些不必要的中断,通过观察寄存器,可以取消不必要的断点.
进入主程序以后,打开输入注册码的窗口,输入Name:CNwinndy,Code:1234567890.
点"OK",程序会中断在00432A7C :
00432A62 /$ 55 push ebp
00432A63 |. 8BEC mov ebp,esp
00432A65 |. 56 push esi
00432A66 |. 57 push edi
00432A67 |. 8B7D 08 mov edi,dword ptr ss:[ebp+8]
00432A6A |. FF75 0C push dword ptr ss:[ebp+C]
00432A6D |. 8BCF mov ecx,edi
00432A6F |. E8 A8FFFFFF call Scsc.00432A1C
00432A74 |. 833F 00 cmp dword ptr ds:[edi],0
00432A77 |. 8BF0 mov esi,eax
00432A79 |. 74 28 je short Scsc.00432AA3
00432A7B |. 56 push esi ; /hWnd
00432A7C |. FF15 00964400 call dword ptr ds:[<&USER32.GetWind>; \GetWindowTextLengthA
;F8跳过,发现EAX=0000000A,这是注册码"1234567890"的长度.
;第二次进入,F8跳过,发现EAX=00000008,这是用户名"CNwinndy"的长度.
00432A82 |. 8D48 01 lea ecx,dword ptr ds:[eax+1]
00432A85 |. 51 push ecx
00432A86 |. 8B4D 10 mov ecx,dword ptr ss:[ebp+10]
00432A89 |. 50 push eax
00432A8A |. E8 A689FFFF call Scsc.0042B435 ;F8先跳过再说,有问题再进去看
00432A8F |. 50 push eax ; |Buffer
00432A90 |. 56 push esi ; |hWnd
00432A91 |. FF15 E0944400 call dword ptr ds:[<&USER32.GetWind>; \GetWindowTextA ;F8跳过,
00432A97 |. 8B4D 10 mov ecx,dword ptr ss:[ebp+10] ;
;Ecx=0012FBD8 D ECX 查看内存:58 3B BC 00 再D [ECX] (或D 00BC3B58),查看:
;00BC3B58 31 32 33 34 35 36 37 38 12345678 ===>这里是假key
;00BC3B60 39 30 00 90.
;第二次进入,D [ECX],
;00BC3BA8 43 4E 77 69 6E 6E 64 79 CNwinndy ===>这里是用户名
00432A9A |. 6A FF push -1
00432A9C |. E8 6C89FFFF call Scsc.0042B40D ;F8先跳过再说,有问题再进去看
00432AA1 |. EB 0B jmp short Scsc.00432AAE
00432AA3 |> \8B45 10 mov eax,dword ptr ss:[ebp+10]
00432AA6 |. FF30 push dword ptr ds:[eax] ; /Arg2
00432AA8 |. 56 push esi ; |Arg1
00432AA9 |. E8 EEE8FFFF call Scsc.0043139C ; \Scsc.0043139C
00432AAE |> 5F pop edi ; 0012F6CC
00432AAF |. 5E pop esi
00432AB0 |. 5D pop ebp
00432AB1 \. C2 0C00 retn 0C
返回到:004030D7
004030C0 . 56 push esi
004030C1 . 8BF1 mov esi,ecx
004030C3 . 57 push edi
004030C4 . 8B7C24 0C mov edi,dword ptr ss:[esp+C]
004030C8 . 8D46 60 lea eax,dword ptr ds:[esi+60]
004030CB . 50 push eax ; /Arg3
004030CC . 68 EF030000 push 3EF ; |Arg2 = 000003EF
004030D1 . 57 push edi ; |Arg1
004030D2 . E8 8BF90200 call Scsc.00432A62 ; \Scsc.00432A62 ;取注册码
回到这里,再去取用户名
004030D7 . 83C6 5C add esi,5C
004030DA . 56 push esi ; /Arg3
004030DB . 68 F0030000 push 3F0 ; |Arg2 = 000003F0
004030E0 . 57 push edi ; |Arg1
004030E1 . E8 7CF90200 call Scsc.00432A62 ; \Scsc.00432A62;取用户名
004030E6 . 5F pop edi
004030E7 . 5E pop esi
004030E8 . C2 0400 retn 4
回到这里:
004299AB . C745 08 01000000 mov dword ptr ss:[ebp+8],1
004299B2 . EB 27 jmp short Scsc.004299DB
004299DB > \8B45 E8 mov eax,dword ptr ss:[ebp-18]
004299DE . 8B4D F4 mov ecx,dword ptr ss:[ebp-C]
004299E1 . 8987 B8000000 mov dword ptr ds:[edi+B8],eax
004299E7 . 8B45 08 mov eax,dword ptr ss:[ebp+8]
004299EA . 5F pop edi
004299EB . 5E pop esi
004299EC . 64:890D 00000000 mov dword ptr fs:[0],ecx
004299F3 . 5B pop ebx
004299F4 . C9 leave
004299F5 . C2 0400 retn 4
回到0040310A:
00403100 . 56 push esi
00403101 . 8BF1 mov esi,ecx
00403103 . 6A 01 push 1
00403105 . E8 4C680200 call Scsc.00429956
0040310A . 8B46 60 mov eax,dword ptr ds:[esi+60] ;
;注意观察寄存器:EAX 00BC3B58 ASCII "1234567890"
0040310D . B9 30154600 mov ecx,Scsc.00461530
00403112 . 50 push eax ;将注册码压入堆栈,下面这个Call不可跳过,需单步进入
00403113 . 68 90C14500 push Scsc.0045C190 ; ASCII "scsc"
00403118 . E8 03070000 call Scsc.00403820 ; *****************,F7进入,见下面的[分析一]
0040311D . 83F8 02 cmp eax,2 ; Switch (cases 0..10000)
00403120 . 77 4B ja short Scsc.0040316D
00403122 . 74 39 je short Scsc.0040315D
00403124 . 83E8 00 sub eax,0
00403127 . 74 13 je short Scsc.0040313C
00403129 . 48 dec eax
0040312A . 75 4D jnz short Scsc.00403179
0040312C . 6A 00 push 0 ; /Arg3 = 00000000; Case 1 of switch 0040311D
0040312E . 6A 00 push 0 ; |Arg2 = 00000000
00403130 . 68 48C14500 push Scsc.0045C148 ; |Arg1 = 0045C148 ASCII "Registration Code specified for
ParasiteSoft product other then SCSC"
00403135 . E8 2DFB0200 call Scsc.00432C67 ; \Scsc.00432C67
0040313A . 5E pop esi
0040313B . C3 retn
0040313C > 8B46 5C mov eax,dword ptr ds:[esi+5C] ; Case 0 of switch 0040311D
0040313F . B9 30154600 mov ecx,Scsc.00461530
00403144 . 50 push eax ; /Arg3
00403145 . 68 1CA14500 push Scsc.0045A11C ; |Arg2 = 0045A11C ASCII "UserName"
0040314A . 68 28154600 push Scsc.00461528 ; |Arg1 = 00461528
0040314F . E8 28F80200 call Scsc.0043297C ; \Scsc.0043297C
00403154 . 8BCE mov ecx,esi
00403156 . E8 633E0200 call Scsc.00426FBE
0040315B . 5E pop esi
0040315C . C3 retn
0040315D > 6A 00 push 0 ; /Arg3 = 00000000; Case 2 of switch 0040311D
0040315F . 6A 00 push 0 ; |Arg2 = 00000000
00403161 . 68 28C14500 push Scsc.0045C128 ; |Arg1 = 0045C128 ASCII "Indecent user name specified"
00403166 . E8 FCFA0200 call Scsc.00432C67 ; \Scsc.00432C67
0040316B . 5E pop esi
0040316C . C3 retn
//查词典:Indecent:无礼的,下流的;不适当的,不合理的
//对用户名还有限制?要重新跟,看EAX是怎么生成的.
0040316D > 83F8 03 cmp eax,3
00403170 . 74 27 je short Scsc.00403199
00403172 . 3D 00000100 cmp eax,10000 ; UNICODE "=::=::\"
00403177 . 74 10 je short Scsc.00403189
00403179 > 6A 00 push 0 ; /Arg3 = 00000000; Default case of switch 0040311D
0040317B . 6A 00 push 0 ; |Arg2 = 00000000
0040317D . 68 E4C04500 push Scsc.0045C0E4 ; |Arg1 = 0045C0E4 ASCII "Internal software error. Please
contact ParasiteSoft representative"
00403182 . E8 E0FA0200 call Scsc.00432C67 ; \Scsc.00432C67
00403187 . 5E pop esi
00403188 . C3 retn
00403189 > 6A 00 push 0 ; /Arg3 = 00000000; Case 10000 of switch 0040311D
0040318B . 6A 00 push 0 ; |Arg2 = 00000000
0040318D . 68 50C04500 push Scsc.0045C050 ; |Arg1 = 0045C050 ASCII "This serial number is for upgrade
license only.
Please enter your original serial number for limited license first and then apply upgrade license"
00403192 . E8 D0FA0200 call Scsc.00432C67 ; \Scsc.00432C67
00403197 . 5E pop esi
00403198 . C3 retn
///说明:当输入ESI=1时的注册码时,会弹出此对话框.
00403199 > 6A 00 push 0 ; /Arg3 = 00000000; Case 3 of switch 0040311D
0040319B . 6A 00 push 0 ; |Arg2 = 00000000
0040319D . 68 34C04500 push Scsc.0045C034 ; |Arg1 = 0045C034 ASCII "Invalid registration code"
004031A2 . E8 C0FA0200 call Scsc.00432C67 ; \Scsc.00432C67
004031A7 . 5E pop esi
004031A8 . C3 retn
可以注意到这段根据EAX的返回值来确定分支:
EAX=0时注册成功,调用了两个call:call Scsc.0043297C 和call Scsc.00426FBE,.
EAX为其他值(1,2,3,10000,Default case )的处理函数都相同:call Scsc.00432C67 ,弹出错误的对话框.
对于EAX=1,2,从程序分析来看,好像是不可能的(有误之处还请多指教),从该公司网站来看,
目前它只有一种产品,所以EAX=1时的报错不可能,可能是为以后扩展用的吧.
至于EX=2时的错误信息是"Indecent user name specified",可能也是为扩展所用.
###########################################################################################
[分析一]
00403820 /$ 53 push ebx
00403821 |. 55 push ebp
00403822 |. 56 push esi
00403823 |. 57 push edi
00403824 |. E8 C7FFFFFF call Scsc.004037F0 ;F8先跳过再说,先从宏观上有个认识
;跳过后,EAX=FFFFFFFF,可能是个标志,如有需要,再跟进去看
;后来追踪EAX时回到了这个call里面,看来还是得进去看,见后面的代码[分析二]
00403829 |. 8B7C24 18 mov edi,dword ptr ss:[esp+18] ; 我们输入的注册码
0040382D |. 8B5C24 14 mov ebx,dword ptr ss:[esp+14] ; scsc,注意了,这是一个常数
00403831 |. 8BE8 mov ebp,eax ; FFFFFFFF
00403833 |. BE 0A000000 mov esi,0A ;注意了,这是一个常数
00403838 |> 57 /push edi
00403839 |. 53 |push ebx
0040383A |. 56 |push esi ; ESI的值为注册码的序号index
0040383B |. 68 FA000000 |push 0FA ; 注意了,这是一个常数
00403840 |. E8 5B7E0000 |call Scsc.0040B6A0 ; ###################
;山雨欲来风满楼啊,一下子压入了这么多参数,这个call当然不可放过,进入!见下面的[分析三]
00403845 |. 83C4 10 |add esp,10
00403848 |. 85C0 |test eax,eax
0040384A |. 75 0F |jnz short Scsc.0040385B ;注册成功就跳
0040384C |. 4E |dec esi
0040384D |.^ 79 E9 \jns short Scsc.00403838 ;循环依次与11个注册码相比较
0040384F |. 5F pop edi
00403850 |. 5E pop esi ;ESI的值为注册码的序号index
00403851 |. 5D pop ebp
00403852 |. B8 03000000 mov eax,3 ;设置注册码错误标志
00403857 |. 5B pop ebx
00403858 |. C2 0800 retn 8 ;跳去messageboxexa...记起来了吧
==================
比较完注册码之后从
00403858 |. C2 0800 retn 8
返回到
0040311D . 83F8 02 cmp eax,2 ; Switch (cases 0..10000)
========================
0040385B |> 85F6 test esi,esi
0040385D |. 7D 0C jge short Scsc.0040386B
0040385F |. 5F pop edi
00403860 |. 5E pop esi
00403861 |. 5D pop ebp
00403862 |. B8 03000000 mov eax,3 ;设置注册码错误标志
00403867 |. 5B pop ebx
00403868 |. C2 0800 retn 8
0040386B |> 3BF5 cmp esi,ebp
0040386D |. 7D 09 jge short Scsc.00403878
0040386F |. 5F pop edi
00403870 |. 5E pop esi
00403871 |. 5D pop ebp
00403872 |. 33C0 xor eax,eax
00403874 |. 5B pop ebx
00403875 |. C2 0800 retn 8
00403878 |> 85ED test ebp,ebp
0040387A |. 7D 11 jge short Scsc.0040388D
0040387C |. 83FE 01 cmp esi,1 ;若注册码对应的序号为1,则设置"upgrade license"标志
0040387F |. 75 0C jnz short Scsc.0040388D
00403881 |. 5F pop edi
00403882 |. 5E pop esi
00403883 |. 5D pop ebp
00403884 |. B8 00000100 mov eax,10000 ; UNICODE "=::=::\"
/////这里设置注册码为"upgrade license"标志,确定以后的Switch分支,
00403889 |. 5B pop ebx
0040388A |. C2 0800 retn 8
0040388D |> 57 push edi
0040388E |. 53 push ebx
0040388F |. 56 push esi
00403890 |. 68 FA000000 push 0FA
00403895 |. E8 E67E0000 call Scsc.0040B780
;;跟进后发现是将用户名和注册码写入注册表
;查看注册表:HKEY_CURRENT_USER\Software\ParasiteSoft\ProductData\Product011
;这个项目下面会生成"code000"-"code010"(注册码)以及"data000-data010"(用户名)的键,
;但值是二进制的,不是明码.
0040389A |. 83C4 10 add esp,10
0040389D |. 5F pop edi
0040389E |. 5E pop esi
0040389F |. 5D pop ebp
004038A0 |. 5B pop ebx
004038A1 \. C2 0800 retn 8
###########################################################################################
[分析三]
0040B6A0 /$ 81EC 00010000 sub esp,100
0040B6A6 |. 8B9424 08010000 mov edx,dword ptr ss:[esp+108]
0040B6AD |. B9 40000000 mov ecx,40 ;这是个计数器,为rep stos服务
0040B6B2 |. 33C0 xor eax,eax
0040B6B4 |. 57 push edi
0040B6B5 |. 8D7C24 04 lea edi,dword ptr ss:[esp+4]
0040B6B9 |. F3:AB rep stos dword ptr es:[edi] ;
0040B6BB |. 8B8C24 10010000 mov ecx,dword ptr ss:[esp+110] ;ECX 0045C190 ASCII "scsc"
0040B6C2 |. 8D4424 04 lea eax,dword ptr ss:[esp+4] ;EAX=0012F5D4
0040B6C6 |. 50 push eax
0040B6C7 |. 8B8424 0C010000 mov eax,dword ptr ss:[esp+10C]
0040B6CE |. 51 push ecx ; scsc,Const
0040B6CF |. 52 push edx ; 00A-000,计数器
0040B6D0 |. 50 push eax ; 00FA,Const
0040B6D1 |. E8 9AFEFFFF call Scsc.0040B570 ;这个call也要跟进,见核心call[分析四]
0040B6D6 |. 8B8C24 24010000 mov ecx,dword ptr ss:[esp+124] ; 我们输入的码
0040B6DD |. 8D5424 14 lea edx,dword ptr ss:[esp+14] ; 真正的注册码
0040B6E1 |. 51 push ecx
0040B6E2 |. 52 push edx
0040B6E3 |. E8 48FFFFFF call Scsc.0040B630 ;这是干嘛用的?^_^见下面的核心[分析五].
0040B6E8 |. 83C4 18 add esp,18
0040B6EB |. 5F pop edi
0040B6EC |. 81C4 00010000 add esp,100
0040B6F2 \. C3 retn
###########################################################################################
核心:
[分析四]
0040B570 /$ 8B4424 0C mov eax,dword ptr ss:[esp+C] ; scsc
0040B574 |. 8B4C24 08 mov ecx,dword ptr ss:[esp+8] ; 00a-000,counter
0040B578 |. 8B5424 04 mov edx,dword ptr ss:[esp+4] ; 00FA 这是刚才压入的三个参数
0040B57C |. 81EC 6C010000 sub esp,16C
0040B582 |. 53 push ebx
0040B583 |. 55 push ebp
0040B584 |. 56 push esi
0040B585 |. 57 push edi
0040B586 |. 50 push eax
0040B587 |. 51 push ecx
0040B588 |. 52 push edx
0040B589 |. 8D8424 88000000 lea eax,dword ptr ss:[esp+88] ; EAX 0012F2EC ASCII "580b1cc08479915b2aeccdb9aed0af93"
0040B590 |. 68 8CCF4500 push Scsc.0045CF8C ; ASCII "%08X%08X%s"
0040B595 |. 50 push eax ; 20."000000FA00000009scsc"的长度
0040B596 |. E8 9D990000 call Scsc.00414F38
0040B59B |. 8D8C24 90000000 lea ecx,dword ptr ss:[esp+90] ; ECX 0012F2EC ASCII "000000FA0000000Ascsc"
0040B5A2 |. 51 push ecx ;
0040B5A3 |. E8 2A7D0100 call Scsc.004232D2
;不用跟进,执行完后,EAX 0012F4BC ASCII "000000fa0000000ascsc",可以推测
; 这个call的功能是把"000000FA00000009scsc"变成小写"000000fa00000009scsc"
0040B5A8 |. 83C4 18 add esp,18
0040B5AB |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
0040B5AF |. E8 EC050000 call Scsc.0040BBA0
;这个call是MD5::initialize,执行完后,EAX=0012F450,D EAX,
;0012F450 01 23 45 67 89 AB CD EF #Eg壂惋 ==>很熟悉吧,不用想了,就是MD5
;0012F458 FE DC BA 98 76 54 32 10 簶vT2
0040B5B4 |. 8D7C24 7C lea edi,dword ptr ss:[esp+7C]
0040B5B8 |. 83C9 FF or ecx,FFFFFFFF
0040B5BB |. 33C0 xor eax,eax
0040B5BD |. 8D5424 7C lea edx,dword ptr ss:[esp+7C]
0040B5C1 |. F2:AE repne scas byte ptr es:[edi] ;用来测试用来Hash的MD5字符串长度
0040B5C3 |. F7D1 not ecx
0040B5C5 |. 49 dec ecx ;ECX=0014,长度20,
0040B5C6 |. 51 push ecx
0040B5C7 |. 52 push edx
;EDX 0012F4BC ASCII "000000fa0000000ascsc"
0040B5C8 |. 8D4C24 18 lea ecx,dword ptr ss:[esp+18]
;ECX=0012F450, D ECX,
0012F450 01 23 45 67 89 AB CD EF #Eg壂惋
0012F458 FE DC BA 98 76 54 32 10 簶vT2
0040B5CC |. E8 DF050000 call Scsc.0040BBB0 ; unpdate
;进入,看到很醒目的一串:
;0045D020=Scsc.0045D020 (ASCII "MD5::update: Can't update a finalized digest!")
;作者已经告诉我们是什么算法了
0040B5D1 |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10] ;ECX=0012F450,
0040B5D5 |. E8 B6060000 call Scsc.0040BC90 ; finalize
;进入,看到很醒目的一串:
;0045D050=Scsc.0045D050 (ASCII "MD5::finalize: Already finalized this digest!")
;这个call之后,观察内存
;012F450 58 0B 1C C0 84 79 91 5B X绖y慬 =>MD5Hash后的值
;0012F458 2A EC CD B9 AE D0 AF 93 *焱巩携
0040B5DA |. 8D4424 7C lea eax,dword ptr ss:[esp+7C]
0040B5DE |. 8D4C24 10 lea ecx,dword ptr ss:[esp+10]
;EAX 0012F4BC ASCII "000000fa0000000ascsc"
;ECX 0012F450
0040B5E2 |. 50 push eax
0040B5E3 |. E8 58070000 call Scsc.0040BD40 ; get md5 ,lower case
;进入,看到很醒目的一串:
;0045D098=Scsc.0045D098 (ASCII "MD5::hex_digest: Can't get digest if you haven't ")
;出来后:EAX 0012F4BC ASCII "580b1cc08479915b2aeccdb9aed0af93"
0040B5E8 |. 8BBC24 8C010000 mov edi,dword ptr ss:[esp+18C]
0040B5EF |. 33C9 xor ecx,ecx
0040B5F1 |. 8BD7 mov edx,edi
0040B5F3 |. 8D7424 7C lea esi,dword ptr ss:[esp+7C]
0040B5F7 |> 8BC6 /mov eax,esi
0040B5F9 |. 8BDA |mov ebx,edx
0040B5FB |. 8B28 |mov ebp,dword ptr ds:[eax]
0040B5FD |. 892B |mov dword ptr ds:[ebx],ebp
0040B5FF |. 8A40 04 |mov al,byte ptr ds:[eax+4]
0040B602 |. 8843 04 |mov byte ptr ds:[ebx+4],al
0040B605 |. 8BC1 |mov eax,ecx
0040B607 |. 83E8 05 |sub eax,5
0040B60A |. F7D8 |neg eax
0040B60C |. 1AC0 |sbb al,al
0040B60E |. 83C6 05 |add esi,5
0040B611 |. 83E0 2D |and eax,2D ;EAX=002D, '-'的AScii码
0040B614 |. 41 |inc ecx
0040B615 |. 8842 05 |mov byte ptr ds:[edx+5],al
0040B618 |. 83C2 06 |add edx,6
0040B61B |. 83F9 06 |cmp ecx,6
0040B61E |.^ 7C D7 \jl short Scsc.0040B5F7
0040B620 |. 8BC7 mov eax,edi
//上面的循环用来格式化注册码;
//ESI 0012F4DA ASCII "93"
//EDI 0012F5D4 ASCII "580b1-cc084-79915-b2aec-cdb9a-ed0af";这就是注册码了,呵呵
0040B622 |. 5F pop edi
0040B623 |. 5E pop esi
0040B624 |. 5D pop ebp
0040B625 |. 5B pop ebx
0040B626 |. 81C4 6C010000 add esp,16C
0040B62C \. C3 retn
回到:0040B6D6 ,见上面的代码.
###########################################################################################
核心[分析五]
进行注册码校验的过程:
0040B630 /$ 53 push ebx ; Scsc.00409DB0
0040B631 |. 8B5C24 08 mov ebx,dword ptr ss:[esp+8]
0040B635 |. 56 push esi
0040B636 |. 57 push edi
0040B637 |. 53 push ebx
0040B638 |. E8 C97D0100 call Scsc.00423406 ;
0040B63D |. 8B7424 18 mov esi,dword ptr ss:[esp+18]
0040B641 |. 56 push esi
0040B642 |. E8 BF7D0100 call Scsc.00423406
0040B647 |. 8BFB mov edi,ebx
0040B649 |. 83C9 FF or ecx,FFFFFFFF
0040B64C |. 33C0 xor eax,eax
0040B64E |. 83C4 08 add esp,8
0040B651 |. F2:AE repne scas byte ptr es:[edi]
0040B653 |. F7D1 not ecx
0040B655 |. 49 dec ecx
0040B656 |. 83F9 23 cmp ecx,23 ;验证真码的长度
0040B659 |. 74 04 je short Scsc.0040B65F
0040B65B |. 5F pop edi
0040B65C |. 5E pop esi
0040B65D |. 5B pop ebx
0040B65E |. C3 retn
0040B65F |> 8BFE mov edi,esi
0040B661 |. 83C9 FF or ecx,FFFFFFFF
0040B664 |. 33C0 xor eax,eax
0040B666 |. F2:AE repne scas byte ptr es:[edi]
0040B668 |. F7D1 not ecx
0040B66A |. 49 dec ecx
0040B66B |. 83F9 23 cmp ecx,23 ;;验证假码的长度
0040B66E |. 74 06 je short Scsc.0040B676
0040B670 |> 5F pop edi
0040B671 |. 5E pop esi
0040B672 |. 33C0 xor eax,eax
0040B674 |. 5B pop ebx
0040B675 |. C3 retn
0040B676 |> 8BFB mov edi,ebx
0040B678 |. 33C9 xor ecx,ecx
0040B67A |. 8BC6 mov eax,esi
0040B67C |. 2BFE sub edi,esi
0040B67E |> 8A1407 mov dl,byte ptr ds:[edi+eax]
0040B681 |. 8A18 mov bl,byte ptr ds:[eax]
0040B683 |. 3AD3 cmp dl,bl
0040B685 |.^ 75 E9 jnz short Scsc.0040B670 //真码和假码的奇数个字符不等就跳回去
0040B687 |. 83C1 02 add ecx,2 //每次递增为2个字符,只校验奇数位
0040B68A |. 83C0 02 add eax,2
0040B68D |. 83F9 23 cmp ecx,23
0040B690 |.^ 72 EC jb short Scsc.0040B67E
0040B692 |. 5F pop edi
0040B693 |. 5E pop esi
0040B694 |. B8 01000000 mov eax,1
//校验成功,设置标志,在下面检验标志,决定是否需要继续校验后面的注册码
//00403804 |. 85C0 |test eax,eax
0040B699 |. 5B pop ebx
0040B69A \. C3 retn
###########################################################################################
[分析二]
004037F0 /$ 56 push esi
004037F1 |. BE 0A000000 mov esi,0A
004037F6 |> 56 /push esi
004037F7 |. 68 FA000000 |push 0FA
004037FC |. E8 0F830000 |call Scsc.0040BB10
00403801 |. 83C4 08 |add esp,8
00403804 |. 85C0 |test eax,eax
00403806 |. 75 08 |jnz short Scsc.0040381>
00403808 |. 4E |dec esi
00403809 |.^ 79 EB \jns short Scsc.004037F>
0040380B |. 83C8 FF or eax,FFFFFFFF
0040380E |. 5E pop esi
0040380F |. C3 retn
00403810 |> 8BC6 mov eax,esi //设置标志
00403812 |. 5E pop esi ; 00BC51C8
00403813 \. C3 retn
返回到这里:004037DB
004037B0 /$ 8B4424 04 mov eax,dword ptr ss:[e>
004037B4 |. 85C0 test eax,eax
004037B6 |. 74 1E je short Scsc.004037D6
004037B8 |. 7E 17 jle short Scsc.004037D1
004037BA |. 83F8 02 cmp eax,2
004037BD |. 7F 12 jg short Scsc.004037D1
004037BF |. E8 2C000000 call Scsc.004037F0
004037C4 |. 33C9 xor ecx,ecx
004037C6 |. 83F8 01 cmp eax,1
004037C9 |. 0F9DC1 setge cl
004037CC |. 8BC1 mov eax,ecx
004037CE |. C2 0400 retn 4
004037D1 |> 33C0 xor eax,eax
004037D3 |. C2 0400 retn 4
004037D6 |> E8 15000000 call Scsc.004037F0
004037DB |. 33D2 xor edx,edx
004037DD |. 85C0 test eax,eax //00403810处设置了标志,这里检验
004037DF |. 0F9DC2 setge dl
004037E2 |. 8BC2 mov eax,edx //set flag
004037E4 \. C2 0400 retn 4
回到这里:
00409E72 . 85C0 test eax,eax
00409E74 . 75 0E jnz short Scsc.00409E84
跟踪下面的call,最后到了系统程序领空,不动了,
点击一下Scsc窗口后程序又一次中断在0040B6CE,
走下去,再回到这里,看来不取消断点就要转圈了.
我还想保留我设置的断点,于是重新运行程序,删除注册表中的值后,继续调试.
【破解总结】 注册码与用户名无关,即使用户名为空,也可以注册,基本注册码仅有10个,升级注册码一个,
注册码为字符串000000fa0000000<X>scsc 的MD5串的前30个字符,每五个字符串用'-'分隔,
(说明<X>取值为a,9,8,7,6,5,4,3,2,0;都为小写,<X>=1时是升级密码).
程序似乎有些BUG,升级密码不能输入,弹出的信息是"只有输入其他密码后才能输升级密码",
但是当输入其他密码后,注册窗口消失了,怎么输入升级密码?
由于程序进行校验的部分(见分析五)只检验注册码的奇数位,因此偶数为可以位任意字符,因而
可以从基本注册码扩展为任意个注册码.注册码不区分大小写.
基本注册码为:
000000fa0000000ascsc--- 580b1-cc084-79915-b2aec-cdb9a-ed0af
000000fa00000009scsc----c504e-55a67-da3c5-c8b36-6fb68-afb8b
000000fa00000008scsc-----524bf-35c2f-41abf-006fe-a8807-ea77e
000000fa00000007scsc-----07f3f-08424-13cc7-3adfd-73a46-05b4f
000000fa00000006scsc----0C2CA-8A062-61C5F-1A21C-48A04-A8926
000000fa00000005scsc-----3dc2b-29164-f7aff-16767-d6822-a5cfc
000000fa00000004scsc-----0E581-13C66-1CA2A-CB1E3-4B384-ABDA3
000000fa00000003scsc-----CDAF1-63AFE-6531F-4DE8C-87660-010E4
000000fa00000002scsc----39F45-4367B-42F88-1974D-391FA-65B7C
000000fa00000001scsc-----6CDFC-C1CE8-8AEDF-191A2-5E672-EDE20 [Upgrade licence,bug?]
000000fa00000000scsc-----44EFB-47117-782CC-F990E-02C7C-1E94C
【Greetings】 看雪论坛,FCG论坛,DFCG论坛等
【完稿时间等】2005.04.27,天气:小雨,广州