- UID
- 21061
注册时间2006-9-10
阅读权限10
最后登录1970-1-1
周游历练
该用户从未签到
|
标 题: DCG_3_7算法分析
作 者: lelfei
时 间: 2006-09-12,13:27
链 接: http://bbs.pediy.com/showthread.php?threadid=31823
【破解作者】 lelfei
【使用工具】 OD
【破解平台】 Win9x/NT/2000/XP
【软件名称】 DCG_3_7
【下载地址】 DCG里找吧
【软件简介】 在3系列里好像就剩这一个没人写算法了,我就献丑了
【软件大小】 40K
【加壳方式】 无
【破解声明】 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【破解内容】
费话少说,直接进入正题~~
运行程序,输入用户名:lelfei注册码:12341234后确定,出现提示框:"Good Job ..."以及"... You have the wrong serial!... Try again"。就从这提示入手了!
先用PEiD看一下:LCC Win32 1.x -> Jacob Navia [Overlay]不像壳,用OD载入,没有任何提示,那就先试一下用Ultra String Reference进行字符串搜索吧,居然上面的字符串都出来了?那就直接双击进入吧:
代码:--------------------------------------------------------------------------------
00403254 push 20 ; /Count = 20 (32.)
00403256 push dword ptr [ebp-8] ; |Buffer
00403259 push 66 ; |ControlID = 66 (102.)
0040325B push dword ptr [ebp+8] ; |hWnd
0040325E call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA …………………………取用户名
00403263 push 29 ; /Count = 29 (41.)
00403265 push dword ptr [ebp-C] ; |Buffer
00403268 push 67 ; |ControlID = 67 (103.)
0040326A push dword ptr [ebp+8] ; |hWnd
0040326D call <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA ……………………………取注册码
00403272 lea edi, [ebp-A8]
00403278 push edi ; /Arg1
00403279 call 0040129C ; \DCG_3_7.0040129C
0040327E add esp, 4
00403281 push dword ptr [ebp-8] ; /s
00403284 call <jmp.&CRTDLL.strlen> ; \strlen ………………………………………判断用户名的长度
00403289 add esp, 4
0040328C push eax
0040328D push dword ptr [ebp-8]
00403290 lea edi, [ebp-A8]
00403296 push edi
00403297 call 00402E41 ;………………………………………………………检查用户名
0040329C add esp, 0C
0040329F lea edi, [ebp-20]
004032A2 push edi
004032A3 lea edi, [ebp-A8]
004032A9 push edi
004032AA call 00402F1A ;………………………………………………………计算注册码,关键点,跟入
004032AF add esp, 8
004032B2 mov dword ptr [ebp-4], 0
004032B9 /mov edi, [ebp-4]
004032BC |movzx esi, byte ptr [ebp+edi-20]
004032C1 |push esi ; /Arg3
004032C2 |push 0040B148 ; |%02x
004032C7 |shl edi, 1 ; |
004032C9 |lea edi, [ebp+edi-49] ; |
004032CD |push edi ; |Arg1
004032CE |call 00405FC5 ; \DCG_3_7.00405FC5
004032D3 |add esp, 0C
004032D6 |inc dword ptr [ebp-4]
004032D9 |cmp dword ptr [ebp-4], 14
004032DD \jl short 004032B9 ;………………………………………………………这个循环将16进制转换成字符
004032DF push dword ptr [ebp-C] ; /String2
004032E2 lea edi, [ebp-49] ; |
004032E5 push edi ; |String1
004032E6 call <jmp.&KERNEL32.lstrcmpA> ; \lstrcmpA ………………………………………比较真假注册码
004032EB cmp eax, 0
004032EE jnz short 00403305 ;………………………………………………………跳就错了
004032F0 push 0 ; /Style = MB_OK|MB_APPLMODAL
004032F2 push 0040B119 ; |make teh tut!
004032F7 push 0040B127 ; |shit. your really good at crypto
004032FC push 0 ; |hOwner = NULL
004032FE call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00403303 jmp short 0040332B
00403305 push 0 ; /Style = MB_OK|MB_APPLMODAL
00403307 push 0040B108 ; |yay
0040330C push 0040B10C ; |good job ...
00403311 push 0 ; |hOwner = NULL
00403313 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00403318 push 0 ; /Style = MB_OK|MB_APPLMODAL
0040331A push 0040B0D4 ; |sucker
0040331F push 0040B0DB ; |... you have the wrong serial!\n... try again
00403324 push 0 ; |hOwner = NULL
00403326 call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
--------------------------------------------------------------------------------
程序流程很清晰,先用GetDlgItemTextA获得文本框中的用户名和注册码,再根据用户名计算真注册码,再用lstrcmpA与假注册码比较,最后弹出"good job ..."
试着在004032E6 call <jmp.&KERNEL32.lstrcmpA> ; \lstrcmpA处下断,运行程序输入刚才的试炼码,点"Register",果然断下来了,再看堆栈:
0012F9A4 0012FA17 |String1 = "bd18dadc2d9a43a9f66fd6d4458b464b7c9e63a6"
0012F9A8 0014E0A8 \String2 = "12341234"
晕!这就出来了?试着再运行一遍,将上面的"bd18dadc2d9a43a9f66fd6d4458b464b7c9e63a6"输入,果然弹出"your really good at crypto"了!
看来004032AA处的call即为关键call了:
代码:--------------------------------------------------------------------------------
……
00402F93 mov edi, [ebp+8]
00402F96 mov edi, [edi] ;取用户名长度
00402F98 and edi, 3F ;屏蔽超长位数
00402F9B mov [ebp-14], edi
00402F9E cmp dword ptr [ebp-14], 38 ;判断长度
00402FA2 jnb short 00402FB0
00402FA4 mov edi, 38
00402FA9 mov ebx, edi
00402FAB sub ebx, [ebp-14]
00402FAE jmp short 00402FBA
00402FB0 mov edi, 78
00402FB5 mov ebx, edi
00402FB7 sub ebx, [ebp-14]
00402FBA mov [ebp-18], ebx
00402FBD push dword ptr [ebp-18]
00402FC0 push 0040B094
00402FC5 push dword ptr [ebp+8]
00402FC8 call 00402E41 ;第一次没有计算
00402FCD add esp, 0C
00402FD0 push 8
00402FD2 lea edi, [ebp-8]
00402FD5 push edi
00402FD6 push dword ptr [ebp+8]
00402FD9 call 00402E41 ;通过用户名和一固定值进行计算
00402FDE add esp, 0C
00402FE1 mov edi, [ebp+C]
00402FE4 mov esi, [ebp+8]
00402FE7 mov esi, [esi+8]
00402FEA shr esi, 18 ;以下为将计算出的值重新排序
00402FED mov ebx, esi
00402FEF mov [edi], bl
00402FF1 mov edi, [ebp+C]
00402FF4 mov esi, [ebp+8]
00402FF7 mov esi, [esi+8]
00402FFA shr esi, 10
--------------------------------------------------------------------------------
再看00402FD9处:
代码:--------------------------------------------------------------------------------
00402E41 push ebp
00402E42 mov ebp, esp
00402E44 push ecx
00402E45 push eax
00402E46 push esi
00402E47 push edi
00402E48 cmp dword ptr [ebp+10], 0
00402E4C jnz short 00402E53
00402E4E jmp 00402F16
00402E53 mov edi, [ebp+8]
00402E56 mov edi, [edi]
00402E58 and edi, 3F
00402E5B mov [ebp-4], edi
00402E5E mov edi, 40
00402E63 sub edi, [ebp-4]
00402E66 mov [ebp-8], edi
00402E69 mov edi, [ebp+8]
00402E6C mov esi, [ebp+10]
00402E6F add [edi], esi
00402E71 mov edi, [ebp+8]
00402E74 mov esi, [edi]
00402E76 mov [edi], esi
00402E78 mov edi, [ebp+8]
00402E7B mov esi, [ebp+10]
00402E7E cmp [edi], esi
00402E80 jnb short 00402E8A
00402E82 mov edi, [ebp+8]
00402E85 add edi, 4
00402E88 inc dword ptr [edi]
00402E8A cmp dword ptr [ebp-4], 0
00402E8E je short 00402EF1
00402E90 mov edi, [ebp-8]
00402E93 cmp [ebp+10], edi
00402E96 jb short 00402EF1
00402E98 push dword ptr [ebp-8] ; /n
00402E9B push dword ptr [ebp+C] ; |src
00402E9E mov edi, [ebp-4] ; |
00402EA1 mov esi, [ebp+8] ; |
00402EA4 lea edi, [edi+esi+1C] ; |
00402EA8 push edi ; |dest
00402EA9 call <jmp.&CRTDLL.memcpy> ; \memcpy
00402EAE add esp, 0C
00402EB1 mov edi, [ebp+8]
00402EB4 mov esi, edi
00402EB6 add esi, 1C
00402EB9 push esi
00402EBA push edi
00402EBB call 004012E8 ;关键,跟进
00402EC0 add esp, 8
00402EC3 mov edi, [ebp-8]
00402EC6 sub [ebp+10], edi
00402EC9 mov edi, [ebp-8]
00402ECC add edi, [ebp+C]
00402ECF mov [ebp+C], edi
00402ED2 mov dword ptr [ebp-4], 0
00402ED9 jmp short 00402EF1
00402EDB /push dword ptr [ebp+C]
00402EDE |push dword ptr [ebp+8]
00402EE1 |call 004012E8
00402EE6 |add esp, 8
00402EE9 |sub dword ptr [ebp+10], 40
00402EED |add dword ptr [ebp+C], 40
00402EF1 cmp dword ptr [ebp+10], 40 ;当长度大于40H时再来一遍
00402EF5 \jnb short 00402EDB
00402EF7 cmp dword ptr [ebp+10], 0
00402EFB je short 00402F16
00402EFD push dword ptr [ebp+10] ; /n
00402F00 push dword ptr [ebp+C] ; |src
00402F03 mov edi, [ebp-4] ; |
00402F06 mov esi, [ebp+8] ; |
00402F09 lea edi, [edi+esi+1C] ; |
00402F0D push edi ; |dest
00402F0E call <jmp.&CRTDLL.memcpy> ; \memcpy
00402F13 add esp, 0C
00402F16 pop edi
00402F17 pop esi
00402F18 leave
00402F19 retn
--------------------------------------------------------------------------------
再跟进到00402EBB的call,计算方法终于现形了:
代码:--------------------------------------------------------------------------------
004012E8 push ebp
004012E9 mov ebp, esp
004012EB sub esp, 58
004012EE push ebx
004012EF push esi
004012F0 push edi
004012F1 mov edi, [ebp+C]
004012F4 movzx esi, byte ptr [edi] ;用户名ASC码接起来,共40H位,不足位补0,最后位为80
004012F7 shl esi, 18
004012FA movzx ebx, byte ptr [edi+1]
004012FE shl ebx, 10
00401301 or esi, ebx
………………
0040152E movzx ebx, byte ptr [edi+3E]
00401532 shl ebx, 8
00401535 or esi, ebx
00401537 movzx edi, byte ptr [edi+3F]
0040153B or esi, edi
0040153D mov [ebp-4], esi ;将固定值复制0023 4567 89AB CDEF FEDC BA98 7654 3210 EFE1 D2C3
00401540 mov edi, [ebp+8]
00401543 mov edi, [edi+8]
00401546 mov [ebp-48], edi
00401549 mov edi, [ebp+8]
0040154C mov edi, [edi+C]
0040154F mov [ebp-4C], edi
00401552 mov edi, [ebp+8]
00401555 mov edi, [edi+10]
00401558 mov [ebp-50], edi
0040155B mov edi, [ebp+8]
0040155E mov edi, [edi+14]
00401561 mov [ebp-54], edi
00401564 mov edi, [ebp+8]
00401567 mov edi, [edi+18]
0040156A mov [ebp-58], edi
0040156D mov edi, [ebp-48]
00401570 mov esi, [ebp-54]
00401573 mov ebx, edi
00401575 shl ebx, 5
00401578 shr edi, 1B
0040157B or ebx, edi
0040157D mov edi, [ebp-4C] ;将用户名ASC码与固定值进行计算
00401580 mov edx, [ebp-50] ;计算过程太麻烦,没用循环,都是一句一句写的
00401583 xor edx, esi
00401585 and edi, edx
00401587 xor esi, edi
00401589 lea edi, [ebx+esi+5C27C99]
00401590 add edi, [ebp-40]
00401593 add [ebp-58], edi
00401596 mov edi, [ebp-4C]
………………
00402E02 mov [ebp-50], esi ;将计算出的值分别加上一些固定值并保存
00402E05 mov edi, [ebp+8]
00402E08 add edi, 8
00402E0B mov esi, [ebp-48]
00402E0E add [edi], esi
00402E10 mov edi, [ebp+8]
00402E13 add edi, 0C
00402E16 mov esi, [ebp-4C]
00402E19 add [edi], esi
00402E1B mov edi, [ebp+8]
00402E1E add edi, 10
00402E21 mov esi, [ebp-50]
00402E24 add [edi], esi
00402E26 mov edi, [ebp+8]
00402E29 add edi, 14
00402E2C mov esi, [ebp-54]
00402E2F add [edi], esi
00402E31 mov edi, [ebp+8]
00402E34 add edi, 18
00402E37 mov esi, [ebp-58]
00402E3A add [edi], esi
00402E3C pop edi
00402E3D pop esi
00402E3E pop ebx
00402E3F leave
00402E40 retn
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
【破解总结】
通过用户名ASC码与一固定值进行计算,将计算结果直接转化为字符串即为注册码。
这个Crackme流程很清晰,算法也不难,但是比较复杂。。。还好可以直接把计算过程COPY出来计算。。。
要做KeyGen的话可以把004012E8到00402E3A处的直接复制出来做计算就OK了,keygen就不写了……
-------------------------------------------------------------------------------- |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入我们
x
|