【软件名称】openCanvas V4.0.6e plus 汉化绿色版
【应用平台】Win2000
【作者邮箱】chubing6143@sina.com
【使用工具】 peid, OllyDbg1.10
【软件限制】序列号
【破解工具】OllyDbg v1.10
【软件简介】OpenCanvas 是一款小巧的 CG 手绘软件,让用户在使用数位板在电脑上绘图时,就像是在纸上手绘一样,可以画出极为细致的图像。
【破解过程】
写在前面的:好久没有破解了,想着找个简单的练下手吧,没想到这个软件对我来说可不简单了。我基本是在马上准备放弃时,破解了该软件的。好累好累。写这个破文更累了。希望给我等菜鸟一点帮助。由于有很多地方叙述起来比较麻烦,我就省略了(有可能是很关键的,例如版本检查详细过程)。我想如果你自己做一遍会发现其中的。重点讲述思想了。
该软件破解过程基本上是不停的修改不停的重新加载调试了。写注册机到不是很难,但是太麻烦,我就不费这力了。
首先利用FI知道该程序是DELPHI的,利用DEDE可以发现“解锁软件”按钮对应函数如下:
00514254 . 8A90 E8020000 mov dl,byte ptr ds:[eax+2E8]
0051425A . FECA dec dl ; Switch (cases 1..4)
0051425C . 74 0E je short oC4PE.0051426C
0051425E . FECA dec dl
00514260 . 74 10 je short oC4PE.00514272
00514262 . FECA dec dl
00514264 . 74 12 je short oC4PE.00514278
00514266 . FECA dec dl
00514268 . 74 14 je short oC4PE.0051427E
0051426A . EB 17 jmp short oC4PE.00514283
0051426C > E8 13F8FFFF call oC4PE.00513A84 ; Case 1 of switch 0051425A
00514271 . C3 retn
00514272 > E8 C5F9FFFF call oC4PE.00513C3C ; Case 2 of switch 0051425A
00514277 . C3 retn
00514278 > E8 EFFBFFFF call oC4PE.00513E6C ; Case 3 of switch 0051425A
0051427D . C3 retn
0051427E > E8 A1FDFFFF call oC4PE.00514024 ; Case 4 of switch 0051425A
00514283 > C3 retn ; Default case of switch 0051425A
00514284 . C780 34020000 0>mov dword ptr ds:[eax+234],2
0051428E . C3 retn
输入任意的解锁序列号“1234”,然后进行分析:在0051427E > E8 A1FDFFFF call oC4PE.00514024处F7跟进来到:
00514024 /$ 55 push ebp
00514025 |. 8BEC mov ebp,esp
00514027 |. 83C4 C8 add esp,-38
0051402A |. 53 push ebx
0051402B |. 56 push esi
0051402C |. 57 push edi
0051402D |. 33D2 xor edx,edx
0051402F |. 8955 C8 mov dword ptr ss:[ebp-38],edx
00514032 |. 8955 CC mov dword ptr ss:[ebp-34],edx
00514035 |. 8955 D0 mov dword ptr ss:[ebp-30],edx
00514038 |. 8955 D4 mov dword ptr ss:[ebp-2C],edx
0051403B |. 8955 D8 mov dword ptr ss:[ebp-28],edx
0051403E |. 8955 DC mov dword ptr ss:[ebp-24],edx
00514041 |. 8955 E0 mov dword ptr ss:[ebp-20],edx
00514044 |. 8BD8 mov ebx,eax
00514046 |. 33C0 xor eax,eax
00514048 |. 55 push ebp
00514049 |. 68 45425100 push oC4PE.00514245
0051404E |. 64:FF30 push dword ptr fs:[eax]
00514051 |. 64:8920 mov dword ptr fs:[eax],esp
00514054 |. 8D75 E4 lea esi,dword ptr ss:[ebp-1C]
00514057 |. B9 18000000 mov ecx,18
0051405C |. 33D2 xor edx,edx
0051405E |. 8BC6 mov eax,esi
00514060 |. E8 D791F6FF call oC4PE.0047D23C
00514065 |. 8D55 E0 lea edx,dword ptr ss:[ebp-20]
00514068 |. 8B83 DC020000 mov eax,dword ptr ds:[ebx+2DC]
0051406E |. E8 C19DF2FF call oC4PE.0043DE34
00514073 |. 8B45 E0 mov eax,dword ptr ss:[ebp-20] ; 输入的序列号
00514076 |. E8 0DFEEEFF call oC4PE.00403E88 ; 求得序列号长度
0051407B |. BA 16000000 mov edx,16 ; 序列号长度必须为0x16
00514080 |. E8 4BD0F0FF call oC4PE.004210D0
00514085 |. 50 push eax
00514086 |. 8D55 DC lea edx,dword ptr ss:[ebp-24]
00514089 |. 8B83 DC020000 mov eax,dword ptr ds:[ebx+2DC]
0051408F |. E8 A09DF2FF call oC4PE.0043DE34
00514094 |. 8B45 DC mov eax,dword ptr ss:[ebp-24]
00514097 |. E8 B0FFEEFF call oC4PE.0040404C
0051409C |. 8BD0 mov edx,eax
0051409E |. 8BC6 mov eax,esi
005140A0 |. 59 pop ecx
005140A1 |. E8 EE91F6FF call oC4PE.0047D294
005140A6 |. 8BC6 mov eax,esi
005140A8 |. E8 5F03F7FF call oC4PE.0048440C ; 关键函数
005140AD |. 8BF8 mov edi,eax
005140AF |. 89BB E0020000 mov dword ptr ds:[ebx+2E0],edi
005140B5 |. 83C7 F3 add edi,-0D ; Switch (cases D..13)
005140B8 |. 83FF 06 cmp edi,6
005140BB |. 77 3F ja short oC4PE.005140FC ; 不能跳
005140BD |. 0FB6BF CB405100 movzx edi,byte ptr ds:[edi+5140CB]
005140C4 |. FF24BD D2405100 jmp dword ptr ds:[edi*4+5140D2]
其中005140A8 |. E8 5F03F7FF call oC4PE.0048440C 为关键函数,F7跟进去:
0048440C /$ 53 push ebx
0048440D |. 56 push esi
0048440E |. 8BF0 mov esi,eax
00484410 |. 56 push esi
00484411 |. E8 D4130000 call oC4PE.004857EA ; 序列号检查函数一
00484416 |. 59 pop ecx
00484417 |. 8BD8 mov ebx,eax
00484419 |. 83FB FF cmp ebx,-1
0048441C |. 74 20 je short oC4PE.0048443E
0048441E |. 8BC3 mov eax,ebx
00484420 |. E8 1F000000 call oC4PE.00484444 ; 序列号检查函数二
00484425 |. 84C0 test al,al
00484427 |. 74 07 je short oC4PE.00484430
00484429 |. 56 push esi
0048442A |. E8 ED0C0000 call oC4PE.0048511C ; 将注册码后8位倒序排列
0048442F |. 59 pop ecx
00484430 |> 56 push esi
00484431 |. E8 F6120000 call oC4PE.0048572C ; 序列号检查函数三
00484436 |. 59 pop ecx
00484437 |. 84C0 test al,al
00484439 |. 75 03 jnz short oC4PE.0048443E ; 关键跳转
0048443B |. 83CB FF or ebx,FFFFFFFF
0048443E |> 8BC3 mov eax,ebx
00484440 |. 5E pop esi
00484441 |. 5B pop ebx
00484442 \. C3 retn
其中“序列号检查函数一”具体如下:
004857EA /$ 8B4C24 04 mov ecx,dword ptr ss:[esp+4]
004857EE |. B2 53 mov dl,53
004857F0 |. 8A41 01 mov al,byte ptr ds:[ecx+1]
004857F3 |. 3C 34 cmp al,34
004857F5 |. 75 0B jnz short oC4PE.00485802
004857F7 |. 3851 03 cmp byte ptr ds:[ecx+3],dl
004857FA |. 75 06 jnz short oC4PE.00485802
004857FC |. B8 0D000000 mov eax,0D
00485801 |. C3 retn
00485802 |> 3C 50 cmp al,50
00485804 |. 75 0C jnz short oC4PE.00485812
00485806 |. 8079 03 34 cmp byte ptr ds:[ecx+3],34
0048580A |. 75 06 jnz short oC4PE.00485812
0048580C |. B8 0E000000 mov eax,0E
00485811 |. C3 retn
00485812 |> 3C 45 cmp al,45
00485814 |. 75 0B jnz short oC4PE.00485821
00485816 |. 3851 03 cmp byte ptr ds:[ecx+3],dl
00485819 |. 75 06 jnz short oC4PE.00485821
0048581B |. B8 0F000000 mov eax,0F
00485820 |. C3 retn
00485821 |> 3C 50 cmp al,50
00485823 |. 75 0C jnz short oC4PE.00485831
00485825 |. 8079 03 45 cmp byte ptr ds:[ecx+3],45
00485829 |. 75 06 jnz short oC4PE.00485831
0048582B |. B8 10000000 mov eax,10
00485830 |. C3 retn
00485831 |> 3C 47 cmp al,47
00485833 |. 75 1C jnz short oC4PE.00485851
00485835 |. 8079 03 34 cmp byte ptr ds:[ecx+3],34
00485839 |. 75 06 jnz short oC4PE.00485841
0048583B |. B8 11000000 mov eax,11
00485840 |. C3 retn
00485841 |> 3C 47 cmp al,47
00485843 |. 75 0C jnz short oC4PE.00485851
00485845 |. 8079 03 50 cmp byte ptr ds:[ecx+3],50
00485849 |. 75 06 jnz short oC4PE.00485851
0048584B |. B8 12000000 mov eax,12
00485850 |. C3 retn
00485851 |> 83C8 FF or eax,FFFFFFFF
00485854 \. C3 retn
而“序列号检查函数二”具体如下:
00484444 /$ 83E8 0E sub eax,0E ; eax为序列号检查函数一的返回值
00484447 |. 74 0A je short oC4PE.00484453
00484449 |. 83E8 02 sub eax,2
0048444C |. 74 05 je short oC4PE.00484453
0048444E |. 83E8 02 sub eax,2
00484451 |. 75 03 jnz short oC4PE.00484456
00484453 |> B0 01 mov al,1
00484455 |. C3 retn
00484456 |> 33C0 xor eax,eax
00484458 \. C3 retn
可以知道要想使得序列号满足检查函数一、二的要求可以取下面的情况:
00485821 |> 3C 50 cmp al,50
00485823 |. 75 0C jnz short oC4PE.00485831
00485825 |. 8079 03 45 cmp byte ptr ds:[ecx+3],45
00485829 |. 75 06 jnz short oC4PE.00485831
0048582B |. B8 10000000 mov eax,10
00485830 |. C3 retn
即序列号的第二位为0x50(P),第四位为0x45(E)
而“序列号检查函数三”具体如下:
0048572C /$ 56 push esi
0048572D |. 8B7424 08 mov esi,dword ptr ss:[esp+8]
00485731 |. B0 2D mov al,2D
00485733 |. 3846 08 cmp byte ptr ds:[esi+8],al ; 序列号的第9位必须为-
00485736 |. 75 54 jnz short oC4PE.0048578C
00485738 |. 3846 0D cmp byte ptr ds:[esi+D],al ; 序列号的第14位必须为-
0048573B |. 75 4F jnz short oC4PE.0048578C
0048573D |. 0FBE06 movsx eax,byte ptr ds:[esi] ; 序列号的第一位
00485740 |. 50 push eax
00485741 |. E8 91FAFFFF call oC4PE.004851D7 ; 序列号检查函数3-1
00485746 |. 83C4 04 add esp,4
00485749 |. 84C0 test al,al
0048574B |. 74 3F je short oC4PE.0048578C
0048574D |. 0FBE4E 0E movsx ecx,byte ptr ds:[esi+E] ; 序列号后8位的最后一位
00485751 |. 51 push ecx
00485752 |. E8 80FAFFFF call oC4PE.004851D7 ; 序列号检查函数3-1
00485757 |. 83C4 04 add esp,4
0048575A |. 84C0 test al,al
0048575C |. 74 2E je short oC4PE.0048578C
0048575E |. 0FBE56 13 movsx edx,byte ptr ds:[esi+13] ; 序列号后8位的第3位
00485762 |. 52 push edx
00485763 |. E8 6FFAFFFF call oC4PE.004851D7 ; 序列号检查函数3-1
00485768 |. 83C4 04 add esp,4
0048576B |. 84C0 test al,al
0048576D |. 74 1D je short oC4PE.0048578C
0048576F |. 56 push esi
00485770 |. E8 1B000000 call oC4PE.00485790 ; 序列号检查函数3-2
00485775 |. 0FBE4E 04 movsx ecx,byte ptr ds:[esi+4] ; 序列号的第5位
00485779 |. 25 FF000000 and eax,0FF
0048577E |. 83C4 04 add esp,4
00485781 |. 33D2 xor edx,edx
00485783 |. 3BC8 cmp ecx,eax ; 序列号第5位必须与序列号检查函数3-2结果相等
00485785 |. 0F94C2 sete dl
00485788 |. 8AC2 mov al,dl
0048578A |. 5E pop esi
0048578B |. C3 retn
0048578C |> 32C0 xor al,al
0048578E |. 5E pop esi
0048578F \. C3 retn
由上面可以简单知道正确序列号格式为
********-****-********
且序列号的第二位为0x50(P),第四位为0x45(E)
令序列号为1P3E5678-1234-12345678,重新加载程序,在0048572C 处断下接着分析:
其中“序列号检查函数3-1”分析如下:
004851D7 /$ 8B4424 04 mov eax,dword ptr ss:[esp+4]
004851DB |. 83F8 41 cmp eax,41
004851DE |. 7C 12 jl short oC4PE.004851F2
004851E0 |. 83F8 5A cmp eax,5A
004851E3 |. 7F 0D jg short oC4PE.004851F2
004851E5 |. 83F8 49 cmp eax,49
004851E8 |. 74 08 je short oC4PE.004851F2
004851EA |. 83F8 4F cmp eax,4F
004851ED |. 74 03 je short oC4PE.004851F2
004851EF |. B0 01 mov al,1
004851F1 |. C3 retn
004851F2 |> 32C0 xor al,al
004851F4 \. C3 retn
简单分析可以知道要求检查的序列号某位必须满足:必须为大写字母且不为I, O;因此上面分析知道 序列号的第一位,序列号后8位的最后一位,序列号后8位的第3位都必须满足为大写字母且不为I, O。取序列号为GP3E5678-1234-12B4567A;接着分析“序列号检查函数3-2”,其具体如下:
00485790 /$ 83EC 08 sub esp,8
00485793 |. 8D4424 04 lea eax,dword ptr ss:[esp+4]
00485797 |. 56 push esi
00485798 |. 8B7424 10 mov esi,dword ptr ss:[esp+10]
0048579C |. 50 push eax
0048579D |. 0FBE0E movsx ecx,byte ptr ds:[esi]
004857A0 |. 51 push ecx
004857A1 |. E8 72FAFFFF call oC4PE.00485218 ; 序列号第一位在已知KEY中的位置
004857A6 |. 0FBE46 0E movsx eax,byte ptr ds:[esi+E] ; 序列号的后8位的最后一位
004857AA |. 8D5424 18 lea edx,dword ptr ss:[esp+18]
004857AE |. 52 push edx
004857AF |. 50 push eax
004857B0 |. E8 63FAFFFF call oC4PE.00485218
004857B5 |. 0FBE56 13 movsx edx,byte ptr ds:[esi+13] ; 序列号的后8位的第3位
004857B9 |. 8D4C24 14 lea ecx,dword ptr ss:[esp+14]
004857BD |. 51 push ecx
004857BE |. 52 push edx
004857BF |. E8 54FAFFFF call oC4PE.00485218
004857C4 |. 8B4424 28 mov eax,dword ptr ss:[esp+28] ; 序列号最后一位在KEY中的位置
004857C8 |. 8B4C24 1C mov ecx,dword ptr ss:[esp+1C] ; 序列号后8位中的第3位在KEY中的位置
004857CC |. 03C1 add eax,ecx
004857CE |. 8B4C24 20 mov ecx,dword ptr ss:[esp+20] ; 序列号第一位在KEY中的位置
004857D2 |. 03C1 add eax,ecx
004857D4 |. B9 17000000 mov ecx,17
004857D9 |. 99 cdq
004857DA |. F7F9 idiv ecx
004857DC |. 52 push edx ; (序列号第一位在KEY中的位置+序列号后8位中的第3位在KEY中的位置+序列号最后一位在KEY中的位置)%0x17
004857DD |. E8 79F9FFFF call oC4PE.0048515B
004857E2 |. 83C4 1C add esp,1C
004857E5 |. 5E pop esi
004857E6 |. 83C4 08 add esp,8
004857E9 \. C3 retn
其实可以简单概括如下:序列号检查函数3-2为将序列号的第1位、后8位的第3位以及序列号最后一位进行简单运算得到一个结果存储在EAX中
下面可以看到00485783 |. 3BC8 cmp ecx,eax ; 序列号第5位必须与序列号检查函数3-2结果相等
因此,根据调试过程可以取序列号第5位为0x48(H),这样序列号修改为:
GP3EH678-1234-12B4567A,然后重新加载程序,在484436处断下接着分析,前面过程可以直接F8过去,来到下面代码处:
00514106 |> \83BB E0020000 F>cmp dword ptr ds:[ebx+2E0],-1 ; Cases E,10 of switch 005140B5
0051410D |. /0F84 D6000000 je oC4PE.005141E9
00514113 |. |6A FF push -1
00514115 |. |8D45 FC lea eax,dword ptr ss:[ebp-4]
00514118 |. |50 push eax
00514119 |. |56 push esi
0051411A |. |E8 3617F7FF call oC4PE.00485855 ; 序列号检查函数四
其中“序列号检查函数四”分析如下:
00485855 /$ 51 push ecx
00485856 |. 56 push esi
00485857 |. 57 push edi
00485858 |. 8B7C24 10 mov edi,dword ptr ss:[esp+10]
0048585C |. 8D4424 08 lea eax,dword ptr ss:[esp+8]
00485860 |. 50 push eax
00485861 |. 0FBE4F 0A movsx ecx,byte ptr ds:[edi+A] ; 序列号中间4位的第2位
00485865 |. 51 push ecx
00485866 |. E8 39F9FFFF call oC4PE.004851A4 ; 序列号检查函数4-1
0048586B |. 83C4 08 add esp,8
0048586E |. 84C0 test al,al
00485870 |. 74 6D je short oC4PE.004858DF
00485872 |. 0FBE47 05 movsx eax,byte ptr ds:[edi+5] ; 序列号第6位
00485876 |. 8D5424 10 lea edx,dword ptr ss:[esp+10]
0048587A |. 52 push edx
0048587B |. 50 push eax
0048587C |. E8 23F9FFFF call oC4PE.004851A4 ; 序列号检查函数4-1
00485881 |. 83C4 08 add esp,8
00485884 |. 84C0 test al,al
00485886 |. 74 57 je short oC4PE.004858DF
00485888 |. 8B7424 10 mov esi,dword ptr ss:[esp+10] ; 序列号第6位前面运算结果
0048588C |. 8B5424 08 mov edx,dword ptr ss:[esp+8] ; 序列号中间4位的第2位前面运算结果
00485890 |. C1E6 04 shl esi,4
00485893 |. 03F2 add esi,edx
00485895 |. 56 push esi
00485896 |. 57 push edi
00485897 |. E8 77000000 call oC4PE.00485913 ; 序列号检查函数4-2
0048589C |. 0FBE4F 10 movsx ecx,byte ptr ds:[edi+10] ; 序列号后8位的第6位
004858A0 |. 25 FF000000 and eax,0FF
004858A5 |. 83C4 08 add esp,8
004858A8 |. 3BC8 cmp ecx,eax ; 序列号后8位的第6位必须与序列号检查函数4-2结果相等
004858AA |. 75 33 jnz short oC4PE.004858DF
004858AC |. 81C6 38010000 add esi,138
004858B2 |. 56 push esi
004858B3 |. E8 2D000000 call oC4PE.004858E5 ; 序列号检查函数4-3
004858B8 |. 83C4 04 add esp,4
004858BB |. 84C0 test al,al
004858BD |. 74 20 je short oC4PE.004858DF
004858BF |. 8B4424 18 mov eax,dword ptr ss:[esp+18]
004858C3 |. 85C0 test eax,eax
004858C5 |. 7E 0C jle short oC4PE.004858D3
004858C7 |. 81FE 90010000 cmp esi,190
004858CD |. 7C 10 jl short oC4PE.004858DF
004858CF |. 3BF0 cmp esi,eax
004858D1 |. 7F 0C jg short oC4PE.004858DF
004858D3 |> 8B5424 14 mov edx,dword ptr ss:[esp+14]
004858D7 |. 5F pop edi
004858D8 |. B0 01 mov al,1
004858DA |. 8932 mov dword ptr ds:[edx],esi
004858DC |. 5E pop esi
004858DD |. 59 pop ecx
004858DE |. C3 retn
004858DF |> 5F pop edi
004858E0 |. 32C0 xor al,al
004858E2 |. 5E pop esi
004858E3 |. 59 pop ecx
004858E4 \. C3 retn
其中“序列号检查函数4-1”分析如下:
004851A4 /$ 8B4424 04 mov eax,dword ptr ss:[esp+4]
004851A8 |. 83F8 32 cmp eax,32
004851AB |. 7C 11 jl short oC4PE.004851BE
004851AD |. 83F8 39 cmp eax,39
004851B0 |. 7F 0C jg short oC4PE.004851BE
004851B2 |. 8B4C24 08 mov ecx,dword ptr ss:[esp+8]
004851B6 |. 83C0 CE add eax,-32
004851B9 |. 8901 mov dword ptr ds:[ecx],eax
004851BB |. B0 01 mov al,1
004851BD |. C3 retn
004851BE |> 83F8 41 cmp eax,41
004851C1 |. 7C 11 jl short oC4PE.004851D4
004851C3 |. 83F8 48 cmp eax,48
004851C6 |. 7F 0C jg short oC4PE.004851D4
004851C8 |. 8B5424 08 mov edx,dword ptr ss:[esp+8]
004851CC |. 83C0 C7 add eax,-39
004851CF |. 8902 mov dword ptr ds:[edx],eax
004851D1 |. B0 01 mov al,1
004851D3 |. C3 retn
004851D4 |> 32C0 xor al,al
004851D6 \. C3 retn
可以看出要求被检查的序列号必须满足在0x32到0x39之间或0x41到0x48之间,并将之间取0x32或0x39;
为了方便取注册码中间4位的第2位以及注册码第6位都为0x41(A),在004858A8 处可以确定序列号后8位的第6位为0x4E(N),
这样注册码修改为GP3EHA78-1A34-12B45N7A;由于注册码中间4位的第2位以及注册码第6位取得比较合理,序列号检查函数4-3能够满足条件,
(说明:其实这里我费了很多功夫的,但要说明很麻烦,我就省略了,有兴趣的可以试一试了)
下面接着分析:
0051411F |. 83C4 0C add esp,0C
00514122 |. 84C0 test al,al
00514124 |. 0F84 BF000000 je oC4PE.005141E9
0051412A |. 56 push esi
0051412B |. E8 331AF7FF call oC4PE.00485B63 ; 序列号检查函数五
其中“序列号检查函数五”分析如下:
00485B63 /$ 51 push ecx
00485B64 |. 56 push esi
00485B65 |. 8B7424 0C mov esi,dword ptr ss:[esp+C]
00485B69 |. 8D4424 04 lea eax,dword ptr ss:[esp+4]
00485B6D |. 0FBE4E 0B movsx ecx,byte ptr ds:[esi+B] ; 序列号中间4位的第3位
00485B71 |. 50 push eax
00485B72 |. 51 push ecx
00485B73 |. E8 2CF6FFFF call oC4PE.004851A4 ; 序列号检查函数4-1
00485B78 |. 83C4 08 add esp,8
00485B7B |. 84C0 test al,al
00485B7D |. 0F84 82000000 je oC4PE.00485C05
00485B83 |. 0FBE46 12 movsx eax,byte ptr ds:[esi+12] ; 序列号后8位的第4位
00485B87 |. 8D5424 0C lea edx,dword ptr ss:[esp+C]
00485B8B |. 52 push edx
00485B8C |. 50 push eax
00485B8D |. E8 12F6FFFF call oC4PE.004851A4 ; 序列号检查函数4-1
00485B92 |. 83C4 08 add esp,8
00485B95 |. 84C0 test al,al
00485B97 |. 74 6C je short oC4PE.00485C05
00485B99 |. 56 push esi
00485B9A |. E8 6B000000 call oC4PE.00485C0A
00485B9F |. 0FBE4E 07 movsx ecx,byte ptr ds:[esi+7] ; 序列号的第8位
00485BA3 |. 25 FF000000 and eax,0FF
00485BA8 |. 83C4 04 add esp,4
00485BAB |. 3BC8 cmp ecx,eax ; 序列号第8位必须与前面运算结果相等
00485BAD |. 75 56 jnz short oC4PE.00485C05
00485BAF |. 8B4C24 0C mov ecx,dword ptr ss:[esp+C] ; 序列号后8位的第4位运算结果
00485BB3 |. 8B5424 04 mov edx,dword ptr ss:[esp+4] ; 序列号中间4位的第3位运算结果
00485BB7 |. C1E1 04 shl ecx,4
00485BBA |. 03CA add ecx,edx
00485BBC |. BE 13000000 mov esi,13
00485BC1 |. 8BC1 mov eax,ecx
00485BC3 |. 99 cdq
00485BC4 |. F7FE idiv esi
00485BC6 |. 85D2 test edx,edx
00485BC8 |. 75 3B jnz short oC4PE.00485C05
00485BCA |. B8 F31ACA6B mov eax,6BCA1AF3
00485BCF |. F7E9 imul ecx
00485BD1 |. C1FA 03 sar edx,3
00485BD4 |. 8BC2 mov eax,edx
00485BD6 |. C1E8 1F shr eax,1F
00485BD9 |. 03D0 add edx,eax
00485BDB |. 83FA 03 cmp edx,3
00485BDE |. 7C 16 jl short oC4PE.00485BF6
00485BE0 |. 83FA 08 cmp edx,8
00485BE3 |. 7F 11 jg short oC4PE.00485BF6
00485BE5 |. B8 01000000 mov eax,1
00485BEA |. 33C9 xor ecx,ecx
00485BEC |. 3BC0 cmp eax,eax
00485BEE |. 5E pop esi
00485BEF |. 0F94C1 sete cl
00485BF2 |. 8AC1 mov al,cl
00485BF4 |. 59 pop ecx
00485BF5 |. C3 retn
00485BF6 |> 33C0 xor eax,eax
00485BF8 |. 33C9 xor ecx,ecx
00485BFA |. 83F8 01 cmp eax,1
00485BFD |. 5E pop esi
00485BFE |. 0F94C1 sete cl
00485C01 |. 8AC1 mov al,cl
00485C03 |. 59 pop ecx
00485C04 |. C3 retn
00485C05 |> 32C0 xor al,al
00485C07 |. 5E pop esi
00485C08 |. 59 pop ecx
00485C09 \. C3 retn
在00485BAB可以确定序列号第8位为0x39(9),从00485BAD到retn其实要求“序列号后8位的第4位”与“序列号中间4位的第3位”构成的数据等于0x13*3即0x39,根据序列号检查函数4-1算法,可以确定“序列号后8位的第4位”与“序列号中间4位的第3位”为5,B
这样注册码修改为GP3EHA79-1AB4-12B55N7A
下面接着分析:
00514130 |. 59 pop ecx
00514131 |. 84C0 test al,al
00514133 |. 0F84 B0000000 je oC4PE.005141E9
00514139 |. 8B83 E0020000 mov eax,dword ptr ds:[ebx+2E0]
0051413F |. E8 0003F7FF call oC4PE.00484444
00514144 |. 84C0 test al,al
00514146 |. 74 34 je short oC4PE.0051417C
00514148 |. B9 DF010000 mov ecx,1DF
0051414D |. BA B8010000 mov edx,1B8
00514152 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00514155 |. E8 3686F6FF call oC4PE.0047C790 ; 版本检查函数
0051415A |. 84C0 test al,al
0051415C |. 75 4F jnz short oC4PE.005141AD
0051415E |. 8D55 D4 lea edx,dword ptr ss:[ebp-2C]
00514161 |. A1 98D05D00 mov eax,dword ptr ds:[5DD098]
00514166 |. E8 9117EFFF call oC4PE.004058FC
0051416B |. 8B45 D4 mov eax,dword ptr ss:[ebp-2C]
0051416E |. 33C9 xor ecx,ecx
00514170 |. 33D2 xor edx,edx
00514172 |. E8 4DF00700 call oC4PE.005931C4
00514177 |. E9 A1000000 jmp oC4PE.0051421D
0051417C |> B9 B7010000 mov ecx,1B7
00514181 |. BA 90010000 mov edx,190
00514186 |. 8B45 FC mov eax,dword ptr ss:[ebp-4]
00514189 |. E8 0286F6FF call oC4PE.0047C790
0051418E |. 84C0 test al,al
00514190 |. 74 1B je short oC4PE.005141AD
00514192 |. 8D55 D0 lea edx,dword ptr ss:[ebp-30]
00514195 |. A1 98D05D00 mov eax,dword ptr ds:[5DD098]
0051419A |. E8 5D17EFFF call oC4PE.004058FC
0051419F |. 8B45 D0 mov eax,dword ptr ss:[ebp-30]
005141A2 |. 33C9 xor ecx,ecx
005141A4 |. 33D2 xor edx,edx
005141A6 |. E8 19F00700 call oC4PE.005931C4
005141AB |. EB 70 jmp short oC4PE.0051421D
005141AD |> 8B83 E0020000 mov eax,dword ptr ds:[ebx+2E0]
005141B3 |. 83F8 0F cmp eax,0F
005141B6 |. 74 25 je short oC4PE.005141DD
005141B8 |. 83F8 10 cmp eax,10
005141BB |. 74 20 je short oC4PE.005141DD
005141BD |. 83F8 13 cmp eax,13
005141C0 |. 74 1B je short oC4PE.005141DD
005141C2 |. 8D55 CC lea edx,dword ptr ss:[ebp-34]
005141C5 |. A1 64D25D00 mov eax,dword ptr ds:[5DD264]
005141CA |. E8 2D17EFFF call oC4PE.004058FC
005141CF |. 8B45 CC mov eax,dword ptr ss:[ebp-34]
005141D2 |. 33C9 xor ecx,ecx
005141D4 |. 33D2 xor edx,edx
005141D6 |. E8 E9EF0700 call oC4PE.005931C4
005141DB |. EB 40 jmp short oC4PE.0051421D
005141DD |> C783 34020000 0>mov dword ptr ds:[ebx+234],1
005141E7 |. EB 34 jmp short oC4PE.0051421D
005141E9 |> FF83 E4020000 inc dword ptr ds:[ebx+2E4]
005141EF |. 8D55 C8 lea edx,dword ptr ss:[ebp-38]
005141F2 |. A1 10D55D00 mov eax,dword ptr ds:[5DD510]
005141F7 |. E8 0017EFFF call oC4PE.004058FC
005141FC |. 8B45 C8 mov eax,dword ptr ss:[ebp-38]
005141FF |. 33C9 xor ecx,ecx
00514201 |. 33D2 xor edx,edx
00514203 |. E8 BCEF0700 call oC4PE.005931C4
00514208 |. 8BC3 mov eax,ebx
0051420A |. E8 69F8FFFF call oC4PE.00513A78
0051420F |. 84C0 test al,al
00514211 |. 74 0A je short oC4PE.0051421D
00514213 |. C783 34020000 0>mov dword ptr ds:[ebx+234],2
0051421D |> 33C0 xor eax,eax
0051421F |. 5A pop edx
00514220 |. 59 pop ecx
00514221 |. 59 pop ecx
00514222 |. 64:8910 mov dword ptr fs:[eax],edx
00514225 |. 68 4C425100 push oC4PE.0051424C
0051422A |> 8D45 C8 lea eax,dword ptr ss:[ebp-38]
0051422D |. BA 05000000 mov edx,5
00514232 |. E8 F5F9EEFF call oC4PE.00403C2C
00514237 |. 8D45 DC lea eax,dword ptr ss:[ebp-24]
0051423A |. BA 02000000 mov edx,2
0051423F |. E8 E8F9EEFF call oC4PE.00403C2C
00514244 \. C3 retn
到此分析完成了一部分,这时如果你利用得到的序列号"GP3EHA79-1AB4-12B55N7A"输入,程序会提示"感谢注册,重启......",但是一旦重启就会显示仍然是试用版。很明显有重启验证了。
下面来对付重启验证了。
首先做点准备工作,利用对注册表操作函数下断点可以发现程序将序列号存储在:HKEY_CLASSES_ROOT\CLSID\{D81EDBF9-D167-4011-B77D-211DF920EB80}\Version下的id及idx中
简单说来,重启验证后有功能限制,那么我们就利用功能限制(呵呵,我本来想利用程序初始化话阶段的处理函数,但失败了,因为程序是读取了id和idx后,利用SendMessage来判断的,我没有找到下手地方,菜鸟嘛可以理解了)了,非注册版不能保存文件,这样利用“文件保存”按钮对应的函数可以定位到下面关键代码:
00530CC2 > \8D45 E8 lea eax,dword ptr ss:[ebp-18]
00530CC5 . 50 push eax
00530CC6 . 8D45 EC lea eax,dword ptr ss:[ebp-14]
00530CC9 . 50 push eax
00530CCA . 8D45 F0 lea eax,dword ptr ss:[ebp-10]
00530CCD . 50 push eax
00530CCE . 56 push esi
00530CCF . E8 554CF5FF call oC4PE.00485929 ; 验证函数1
00530CD4 . 83C4 10 add esp,10
00530CD7 . 83E0 7F and eax,7F
00530CDA . 03F8 add edi,eax
00530CDC . 8D45 DA lea eax,dword ptr ss:[ebp-26]
00530CDF . 50 push eax
00530CE0 . 8D45 DB lea eax,dword ptr ss:[ebp-25]
00530CE3 . 50 push eax
00530CE4 . 56 push esi
00530CE5 . E8 874DF5FF call oC4PE.00485A71 ; 验证函数2
00530CEA . 83C4 0C add esp,0C
00530CED . 83E0 7F and eax,7F
00530CF0 . 03F8 add edi,eax
00530CF2 . 56 push esi
00530CF3 . E8 6B4EF5FF call oC4PE.00485B63 ; 验证函数3
00530CF8 . 59 pop ecx
00530CF9 . 83E0 7F and eax,7F
00530CFC . 03F8 add edi,eax
00530CFE . B9 1E000000 mov ecx,1E
00530D03 . 33D2 xor edx,edx
00530D05 . 8B45 E0 mov eax,dword ptr ss:[ebp-20]
00530D08 . E8 83BAF4FF call oC4PE.0047C790 ; 验证函4
00530D0D . 83E0 7F and eax,7F
00530D10 . 03D8 add ebx,eax
00530D12 . 8B4D E8 mov ecx,dword ptr ss:[ebp-18]
00530D15 . 8B55 EC mov edx,dword ptr ss:[ebp-14]
00530D18 . 8B45 F0 mov eax,dword ptr ss:[ebp-10]
00530D1B . E8 CC37F5FF call oC4PE.004844EC ; 验证函数5
00530D20 . B9 1E000000 mov ecx,1E
00530D25 . 33D2 xor edx,edx
00530D27 . E8 64BAF4FF call oC4PE.0047C790 ; 验证函数6
00530D2C . 83E0 7F and eax,7F
00530D2F . 03D8 add ebx,eax
00530D31 . 837D DC 02 cmp dword ptr ss:[ebp-24],2
00530D35 . 74 18 je short oC4PE.00530D4F ;
00530D37 . B9 9C0E5300 mov ecx,oC4PE.00530E9C
00530D3C . B2 01 mov dl,1
00530D3E . A1 7C414800 mov eax,dword ptr ds:[48417C]
00530D43 . E8 8093EDFF call oC4PE.0040A0C8
00530D48 . E8 8B29EDFF call oC4PE.004036D8
00530D4D . EB 38 jmp short oC4PE.00530D87
00530D4F > 83FF 05 cmp edi,5
00530D52 . 74 05 je short oC4PE.00530D59 ;
00530D54 . 83FB 02 cmp ebx,2
00530D57 . 75 15 jnz short oC4PE.00530D6E
00530D59 > 33C9 xor ecx,ecx
00530D5B . B2 01 mov dl,1
00530D5D . A1 9C424800 mov eax,dword ptr ds:[48429C]
00530D62 . E8 6193EDFF call oC4PE.0040A0C8
00530D67 . E8 6C29EDFF call oC4PE.004036D8
由于过程与前面基本一样,我就不再赘述了。
根据验证函数1,将序列号修改为GP3EHA79-1ABB-12B55N7A,
根据验证函数2,将序列号修改为GP3EHA79-2ABB-E2B55N7A,
此时利用此序列号可以发现程序已经真正完成注册了。算是大功告成了!!!好累啊,休息了。
【破解后话】这个软件的破解其实从算法来说,并不复杂,但是需要耐心,而且需要不停的修改序列号,不停的调试。我就是准备放弃的时候,试了一下居然成功了。呵呵,那么在生活中其他事情也很有可能是“山穷水尽疑无路,柳暗花明又一村”。希望我的生活能够如此,看到这的看官们也能这样哦!!!
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)