简单算法-韩语小词典2004算法分析
———————————————————————————————————————————
【软件名称】:韩语小词典2004 
【文章作者】:仙剑太郎
【网站地址】:中国X黑客小组 www.CnXHacker.com
【软件简介】:类似金山词霸式的查询韩语的词典软件.
【软件限制】:注册码方式
【破解声明】:初学Crack,只是感兴趣,没有其它目的。失误之处敬请诸位大侠赐教!
【破解工具】:Ollydbg
———————————————————————————————————————————
【破解过程】:
 
应该是比较旧的软件了,现在也停止升级了.新手来看看怎么分析算法,老鸟来个鼓励呵呵~
打开软件有要求注册的提示,我们进去后,在设置那里点注册,弹出的输入注册码的框框中随便输入,确定后有出错提示....-_-
本机机器码:NNRK-81E2-5NMN
试炼注册码:123456
由于是多语言的,所以不好依据提示的内容来确定位置,可以直接下断MessageBoxA,中断后返回来到如下:

0041B706  |.  68 00E00000   push 0E000                                   ; /Arg1 = 0000E000
0041B70B  |.  8D4C24 08     lea ecx,dword ptr ss:[esp+8]                 ; |
0041B70F  |.  C74424 14 000>mov dword ptr ss:[esp+14],0                  ; |
0041B717  |.  E8 35670300   call MultiDic.00451E51                       ; \MultiDic.00451E51
0041B71C  |.  A1 18ED4700   mov eax,dword ptr ds:[47ED18]
0041B721  |.  894424 00     mov dword ptr ss:[esp],eax
0041B725  |.  8B4C24 18     mov ecx,dword ptr ss:[esp+18]
0041B729  |.  C64424 10 01  mov byte ptr ss:[esp+10],1
0041B72E  |.  51            push ecx                                     ; /Arg1
0041B72F  |.  8D4C24 04     lea ecx,dword ptr ss:[esp+4]                 ; |
0041B733  |.  E8 19670300   call MultiDic.00451E51                       ; \MultiDic.00451E51
0041B738  |.  8B5424 04     mov edx,dword ptr ss:[esp+4]
0041B73C  |.  8B4424 00     mov eax,dword ptr ss:[esp]
0041B740  |.  6A 00         push 0                                       ; /Style = 

MB_OK|MB_APPLMODAL
0041B742  |.  52            push edx                                     ; |Title
0041B743  |.  50            push eax                                     ; |Text
0041B744  |.  FF15 60754600 call dword ptr ds:[<&USER32.GetFocus>]       ; |[GetFocus
0041B74A  |.  50            push eax                                     ; |hOwner
0041B74B  |.  FF15 64754600 call dword ptr ds:[<&USER32.MessageBoxA>]    ; \MessageBoxA
0041B751  |.  8D4C24 00     lea ecx,dword ptr ss:[esp]                   ;返回到这里

向上看,OD有个黑色的框连着这段,看开头,如下:

0041B6E0  /$  6A FF         push -1
0041B6E2  |.  68 50274600   push MultiDic.00462750                     ;  SE handler installation
0041B6E7  |.  64:A1 0000000>mov eax,dword ptr fs:[0]
0041B6ED  |.  50            push eax
0041B6EE  |.  64:8925 00000>mov dword ptr fs:[0],esp

显示这是一个CALL的入口,在0041B6E0下断,F9运行,看堆栈窗口

=====================================
0012B18C   0040F2B9  返回到 MultiDic.0040F2B9 来自 MultiDic.0041B6E0
=====================================

说明了有个CALL来自0040F2B9,取消断点后,CTRL+G ,0040F2B9,来到如下:

0040F2A8   . /EB 0F         jmp short MultiDic.0040F2B9
0040F2AA   > |68 30E00000   push 0E030                                   ; /Arg1 = 0000E030
0040F2AF   . |B9 C0104800   mov ecx,MultiDic.004810C0                    ; |
0040F2B4   . |E8 27C40000   call MultiDic.0041B6E0                       ; \MultiDic.0041B6E0
0040F2B9   > \8D4C24 10     lea ecx,dword ptr ss:[esp+10]                ;来到这里

通过0040F2AA前面的>可以看到,有跳转到这里调用出错提示0040F2B4 ,鼠标点一下0040F2AA所在行,沿着红色的

线条向上找,来到这里

0040F230   > \1BC0          sbb eax,eax
0040F232   .  83D8 FF       sbb eax,-1
0040F235   >  85C0          test eax,eax
0040F237      75 71         jnz short MultiDic.0040F2AA

很经典的比较方式.在0040F237下断,运行,中断后修改jnzje,呵,暴破了吧.我们现在要找算法,所以还得继续.

继续向上番,看到有几个CALL,呵有眉目了.

0040F1BF   .  50            push eax                                     ; /Arg1
0040F1C0 > .  C68424 3C0300>mov byte ptr ss:[esp+33C],1          
0040F1C8   .  E8 43620000   call MultiDic.00415410                       ; \MultiDic.00415410
0040F1CD   .  8D8C24 300100>lea ecx,dword ptr ss:[esp+130]
0040F1D4   .  8D5424 18     lea edx,dword ptr ss:[esp+18]
0040F1D8   .  51            push ecx
0040F1D9   .  8D4424 34     lea eax,dword ptr ss:[esp+34]
0040F1DD   .  52            push edx
0040F1DE   .  50            push eax
0040F1DF   .  8D4C24 1C     lea ecx,dword ptr ss:[esp+1C]
0040F1E3   .  E8 C8620000   call MultiDic.004154B0
0040F1E8   .  8D8C24 300200>lea ecx,dword ptr ss:[esp+230]
0040F1EF   .  8D9424 300100>lea edx,dword ptr ss:[esp+130]
0040F1F6   .  51            push ecx                                     ; /Arg2
0040F1F7   .  52            push edx                                     ; |Arg1
0040F1F8   .  8D4C24 18     lea ecx,dword ptr ss:[esp+18]                ; |
0040F1FC   .  E8 5F630000   call MultiDic.00415560                       ; \MultiDic.00415560

首先从0040F1C8 的CALL开始,粗跟,大致看到这是机器码的生成,0040F1E3的CALL也是.到第三个CALL

了,0040F1FC,看到push的两个参数了吗呵呵,F2下断,运行后中断看到寄存器显示

================================
EAX 00000001
ECX 0012B1A4
EDX 0012B2C4 ASCII "NNRK-81E2-5NMN"
EBX 00000001
ESP 0012B18C
=================================

呵看到自己的机器码了吧?F7跟进,来到下面:

00415560  /$  81EC 14020000 sub esp,214
00415566  |.  8BD1          mov edx,ecx
00415568  |.  B9 41000000   mov ecx,41
0041556D  |.  33C0          xor eax,eax
0041556F  |.  53            push ebx
00415570  |.  57            push edi
00415571  |.  8DBC24 140100>lea edi,dword ptr ss:[esp+114]
00415578  |.  8B9C24 200200>mov ebx,dword ptr ss:[esp+220]
0041557F  |.  F3:AB         rep stos dword ptr es:[edi]
00415581  |.  B9 41000000   mov ecx,41
00415586  |.  8D7C24 0C     lea edi,dword ptr ss:[esp+C]
0041558A  |.  F3:AB         rep stos dword ptr es:[edi]
0041558C  |.  8D4424 0B     lea eax,dword ptr ss:[esp+B]
00415590  |.  8D4C24 0A     lea ecx,dword ptr ss:[esp+A]
00415594  |.  50            push eax                                     ; /Arg5
00415595  |.  51            push ecx                                     ; |Arg4
00415596  |.  8D4424 14     lea eax,dword ptr ss:[esp+14]                ; |
0041559A  |.  8D8C24 1C0100>lea ecx,dword ptr ss:[esp+11C]               ; |
004155A1  |.  50            push eax                                     ; |Arg3
004155A2  |.  51            push ecx                                     ; |Arg2
004155A3  |.  53            push ebx                                     ; |Arg1
004155A4  |.  8BCA          mov ecx,edx                                  ; |
004155A6  |.  E8 E5020000   call MultiDic.00415890                       ; \MultiDic.00415890
004155AB  |.  84C0          test al,al

上面004155A6是对机器码的处理,对机器码运算生成一个6位小表,但这个表是没作用的。
继续向下看:

004155BD  |.  83C9 FF       or ecx,FFFFFFFF
004155C0  |.  33C0          xor eax,eax
004155C2  |.  33F6          xor esi,esi
004155C4  |.  F2:AE         repne scas byte ptr es:[edi]
004155C6  |.  F7D1          not ecx
004155C8  |.  49            dec ecx
004155C9  |.  74 46         je short MultiDic.00415611
004155CB  |.  55            push ebp
004155CC  |.  8BAC24 2C0200>mov ebp,dword ptr ss:[esp+22C]      ;算法核心
004155D3  |>  0FBE441E 01   /movsx eax,byte ptr ds:[esi+ebx+1]  ;取机器码偶位数ASCII
004155D8  |.  0FBE141E      |movsx edx,byte ptr ds:[esi+ebx]
;取机器码奇位数ASCII
004155DC  |.  33C2          |xor eax,edx                        ;偶位 xor 奇位
004155DE  |.  B9 1A000000   |mov ecx,1A                         ;常量0x1A
004155E3  |.  99            |cdq
004155E4  |.  F7F9          |idiv ecx                           ;ecx余eax
004155E6  |.  6A 01         |push 1      
004155E8  |.  80C2 41       |add dl,41                          ;常数0x41累加
004155EB  |.  885424 15     |mov byte ptr ss:[esp+15],dl        ;保存1位结果到表的指针
004155EF  |.  8D5424 15     |lea edx,dword ptr ss:[esp+15]      ;取出新表(这个表没用到,汗!)
004155F3  |.  52            |push edx
004155F4  |.  55            |push ebp
004155F5  |.  E8 A6810200   |call MultiDic.0043D7A0             ;连接字符
004155FA  |.  8BFB          |mov edi,ebx                        ;机器码先保存起来
004155FC  |.  83C9 FF       |or ecx,FFFFFFFF     
004155FF  |.  33C0          |xor eax,eax                        ;清零
00415601  |.  83C4 0C       |add esp,0C
00415604  |.  83C6 02       |add esi,2                          ;step=2
00415607  |.  F2:AE         |repne scas byte ptr es:[edi]       ;偶菜不知道这是什么
00415609  |.  F7D1          |not ecx
0041560B  |.  49            |dec ecx                            ;记数器-1
0041560C  |.  3BF1          |cmp esi,ecx                        ;循环完了吗?
0041560E  |.^ 72 C3         \jb short MultiDic.004155D3
00415610  |.  5D            pop ebp                             ;这里可以做内存注册机
00415611  |>  5E            pop esi
00415612  |.  5F            pop edi
00415613  |.  B0 01         mov al,1
00415615  |.  5B            pop ebx
00415616  |.  81C4 14020000 add esp,214
0041561C  \.  C2 0800       retn 8

好了,基本上算法大概就在上面的
下面用高级语言描述一下算法(顺便复习一下C ^_^),注册机如下:

#include <stdio.h>
void main()
{
/* KeyGen By XJTL   www.CnXHacker.com */
  int j,k,t=0,l=0,s[20];
  char n[20];
  printf("******** KeyGen For KCDICT2004 ********\n");
  printf("Please Input Your Serial Num:");
  scanf("%s",n);
  while(n[l]!='\0') l++;
  printf("\n Your License Num is : ");
  for(k=0;k<l;k+=2)
  {
    s[t]=n[k+1]^n[k];
    s[t]%=0x1A;
    s[t]+=0x41;
    printf("%c",s[t]);
    t++;
  }
    printf("\n");
}

———————————————————————————————————————————

【最后总结】:

这里介绍了如何找到算法核心,方便我等菜鸟们步入算法分析时代。希望各位小鸟们加油哟~