DCG_3_7算法分析
标 题: 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 不像壳,用OD载入,没有任何提示,那就先试一下用Ultra String Reference进行字符串搜索吧,居然上面的字符串都出来了?那就直接双击进入吧:
代码:--------------------------------------------------------------------------------
00403254push 20 ; /Count = 20 (32.)
00403256push dword ptr ; |Buffer
00403259push 66 ; |ControlID = 66 (102.)
0040325Bpush dword ptr ; |hWnd
0040325Ecall <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA …………………………取用户名
00403263push 29 ; /Count = 29 (41.)
00403265push dword ptr ; |Buffer
00403268push 67 ; |ControlID = 67 (103.)
0040326Apush dword ptr ; |hWnd
0040326Dcall <jmp.&USER32.GetDlgItemTextA> ; \GetDlgItemTextA……………………………取注册码
00403272lea edi,
00403278push edi ; /Arg1
00403279call 0040129C ; \DCG_3_7.0040129C
0040327Eadd esp, 4
00403281push dword ptr ; /s
00403284call <jmp.&CRTDLL.strlen> ; \strlen ………………………………………判断用户名的长度
00403289add esp, 4
0040328Cpush eax
0040328Dpush dword ptr
00403290lea edi,
00403296push edi
00403297call 00402E41 ;………………………………………………………检查用户名
0040329Cadd esp, 0C
0040329Flea edi,
004032A2push edi
004032A3lea edi,
004032A9push edi
004032AAcall 00402F1A ;………………………………………………………计算注册码,关键点,跟入
004032AFadd esp, 8
004032B2mov dword ptr , 0
004032B9/mov edi,
004032BC|movzx esi, byte ptr
004032C1|push esi ; /Arg3
004032C2|push 0040B148 ; |%02x
004032C7|shl edi, 1 ; |
004032C9|lea edi, ; |
004032CD|push edi ; |Arg1
004032CE|call 00405FC5 ; \DCG_3_7.00405FC5
004032D3|add esp, 0C
004032D6|inc dword ptr
004032D9|cmp dword ptr , 14
004032DD\jl short 004032B9 ;………………………………………………………这个循环将16进制转换成字符
004032DFpush dword ptr ; /String2
004032E2lea edi, ; |
004032E5push edi ; |String1
004032E6call <jmp.&KERNEL32.lstrcmpA> ; \lstrcmpA………………………………………比较真假注册码
004032EBcmp eax, 0
004032EEjnz short 00403305 ;………………………………………………………跳就错了
004032F0push 0 ; /Style = MB_OK|MB_APPLMODAL
004032F2push 0040B119 ; |make teh tut!
004032F7push 0040B127 ; |shit. your really good at crypto
004032FCpush 0 ; |hOwner = NULL
004032FEcall <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00403303jmp short 0040332B
00403305push 0 ; /Style = MB_OK|MB_APPLMODAL
00403307push 0040B108 ; |yay
0040330Cpush 0040B10C ; |good job ...
00403311push 0 ; |hOwner = NULL
00403313call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
00403318push 0 ; /Style = MB_OK|MB_APPLMODAL
0040331Apush 0040B0D4 ; |sucker
0040331Fpush 0040B0DB ; |... you have the wrong serial!\n... try again
00403324push 0 ; |hOwner = NULL
00403326call <jmp.&USER32.MessageBoxA> ; \MessageBoxA
--------------------------------------------------------------------------------
程序流程很清晰,先用GetDlgItemTextA获得文本框中的用户名和注册码,再根据用户名计算真注册码,再用lstrcmpA与假注册码比较,最后弹出"good job ..."
试着在004032E6call <jmp.&KERNEL32.lstrcmpA> ; \lstrcmpA处下断,运行程序输入刚才的试炼码,点"Register",果然断下来了,再看堆栈:
0012F9A4 0012FA17|String1 = "bd18dadc2d9a43a9f66fd6d4458b464b7c9e63a6"
0012F9A8 0014E0A8\String2 = "12341234"
晕!这就出来了?试着再运行一遍,将上面的"bd18dadc2d9a43a9f66fd6d4458b464b7c9e63a6"输入,果然弹出"your really good at crypto"了!
看来004032AA处的call即为关键call了:
代码:--------------------------------------------------------------------------------
……
00402F93mov edi,
00402F96mov edi, ;取用户名长度
00402F98and edi, 3F ;屏蔽超长位数
00402F9Bmov , edi
00402F9Ecmp dword ptr , 38 ;判断长度
00402FA2jnb short 00402FB0
00402FA4mov edi, 38
00402FA9mov ebx, edi
00402FABsub ebx,
00402FAEjmp short 00402FBA
00402FB0mov edi, 78
00402FB5mov ebx, edi
00402FB7sub ebx,
00402FBAmov , ebx
00402FBDpush dword ptr
00402FC0push 0040B094
00402FC5push dword ptr
00402FC8call 00402E41 ;第一次没有计算
00402FCDadd esp, 0C
00402FD0push 8
00402FD2lea edi,
00402FD5push edi
00402FD6push dword ptr
00402FD9call 00402E41 ;通过用户名和一固定值进行计算
00402FDEadd esp, 0C
00402FE1mov edi,
00402FE4mov esi,
00402FE7mov esi,
00402FEAshr esi, 18 ;以下为将计算出的值重新排序
00402FEDmov ebx, esi
00402FEFmov , bl
00402FF1mov edi,
00402FF4mov esi,
00402FF7mov esi,
00402FFAshr esi, 10
--------------------------------------------------------------------------------
再看00402FD9处:
代码:--------------------------------------------------------------------------------
00402E41push ebp
00402E42mov ebp, esp
00402E44push ecx
00402E45push eax
00402E46push esi
00402E47push edi
00402E48cmp dword ptr , 0
00402E4Cjnz short 00402E53
00402E4Ejmp 00402F16
00402E53mov edi,
00402E56mov edi,
00402E58and edi, 3F
00402E5Bmov , edi
00402E5Emov edi, 40
00402E63sub edi,
00402E66mov , edi
00402E69mov edi,
00402E6Cmov esi,
00402E6Fadd , esi
00402E71mov edi,
00402E74mov esi,
00402E76mov , esi
00402E78mov edi,
00402E7Bmov esi,
00402E7Ecmp , esi
00402E80jnb short 00402E8A
00402E82mov edi,
00402E85add edi, 4
00402E88inc dword ptr
00402E8Acmp dword ptr , 0
00402E8Eje short 00402EF1
00402E90mov edi,
00402E93cmp , edi
00402E96jb short 00402EF1
00402E98push dword ptr ; /n
00402E9Bpush dword ptr ; |src
00402E9Emov edi, ; |
00402EA1mov esi, ; |
00402EA4lea edi, ; |
00402EA8push edi ; |dest
00402EA9call <jmp.&CRTDLL.memcpy> ; \memcpy
00402EAEadd esp, 0C
00402EB1mov edi,
00402EB4mov esi, edi
00402EB6add esi, 1C
00402EB9push esi
00402EBApush edi
00402EBBcall 004012E8 ;关键,跟进
00402EC0add esp, 8
00402EC3mov edi,
00402EC6sub , edi
00402EC9mov edi,
00402ECCadd edi,
00402ECFmov , edi
00402ED2mov dword ptr , 0
00402ED9jmp short 00402EF1
00402EDB/push dword ptr
00402EDE|push dword ptr
00402EE1|call 004012E8
00402EE6|add esp, 8
00402EE9|sub dword ptr , 40
00402EED|add dword ptr , 40
00402EF1 cmp dword ptr , 40 ;当长度大于40H时再来一遍
00402EF5\jnb short 00402EDB
00402EF7cmp dword ptr , 0
00402EFBje short 00402F16
00402EFDpush dword ptr ; /n
00402F00push dword ptr ; |src
00402F03mov edi, ; |
00402F06mov esi, ; |
00402F09lea edi, ; |
00402F0Dpush edi ; |dest
00402F0Ecall <jmp.&CRTDLL.memcpy> ; \memcpy
00402F13add esp, 0C
00402F16pop edi
00402F17pop esi
00402F18leave
00402F19retn
--------------------------------------------------------------------------------
再跟进到00402EBB的call,计算方法终于现形了:
代码:--------------------------------------------------------------------------------
004012E8push ebp
004012E9mov ebp, esp
004012EBsub esp, 58
004012EEpush ebx
004012EFpush esi
004012F0push edi
004012F1mov edi,
004012F4movzx esi, byte ptr ;用户名ASC码接起来,共40H位,不足位补0,最后位为80
004012F7shl esi, 18
004012FAmovzx ebx, byte ptr
004012FEshl ebx, 10
00401301or esi, ebx
………………
0040152Emovzx ebx, byte ptr
00401532shl ebx, 8
00401535or esi, ebx
00401537movzx edi, byte ptr
0040153Bor esi, edi
0040153Dmov , esi ;将固定值复制0023 4567 89AB CDEF FEDC BA98 7654 3210 EFE1 D2C3
00401540mov edi,
00401543mov edi,
00401546mov , edi
00401549mov edi,
0040154Cmov edi,
0040154Fmov , edi
00401552mov edi,
00401555mov edi,
00401558mov , edi
0040155Bmov edi,
0040155Emov edi,
00401561mov , edi
00401564mov edi,
00401567mov edi,
0040156Amov , edi
0040156Dmov edi,
00401570mov esi,
00401573mov ebx, edi
00401575shl ebx, 5
00401578shr edi, 1B
0040157Bor ebx, edi
0040157Dmov edi, ;将用户名ASC码与固定值进行计算
00401580mov edx, ;计算过程太麻烦,没用循环,都是一句一句写的
00401583xor edx, esi
00401585and edi, edx
00401587xor esi, edi
00401589lea edi,
00401590add edi,
00401593add , edi
00401596mov edi,
………………
00402E02 mov , esi ;将计算出的值分别加上一些固定值并保存
00402E05 mov edi,
00402E08 add edi, 8
00402E0B mov esi,
00402E0E add , esi
00402E10 mov edi,
00402E13 add edi, 0C
00402E16 mov esi,
00402E19 add , esi
00402E1B mov edi,
00402E1E add edi, 10
00402E21 mov esi,
00402E24 add , esi
00402E26 mov edi,
00402E29 add edi, 14
00402E2C mov esi,
00402E2F add , esi
00402E31 mov edi,
00402E34 add edi, 18
00402E37 mov esi,
00402E3A add , esi
00402E3C pop edi
00402E3D pop esi
00402E3E pop ebx
00402E3F leave
00402E40 retn
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
【破解总结】
通过用户名ASC码与一固定值进行计算,将计算结果直接转化为字符串即为注册码。
这个Crackme流程很清晰,算法也不难,但是比较复杂。。。还好可以直接把计算过程COPY出来计算。。。
要做keygen的话可以把004012E8到00402E3A处的直接复制出来做计算就OK了,keygen就不写了……
--------------------------------------------------------------------------------
页:
[1]