microshupi 发表于 2006-9-12 22:28:24

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]
查看完整版本: DCG_3_7算法分析