首页
社区
课程
招聘
[原创]eKH-CrackMe算法分析
发表于: 2007-4-7 17:32 7734

[原创]eKH-CrackMe算法分析

2007-4-7 17:32
7734

└文章标题┐:eKH-CrackMe算法分析
└破文作者┐:-=>大菜一号<=-
└破解对象┐:CrackMe(附件)
└下载地址┐:附件
└对象大小┐:193k
└加壳方式┐:没有耶
└保护方式┐:普通算法
└编写语言┐:Delphi
└使用工具┐:OD
└破解平台┐:D版XP
└破解声明┐:无话可说!!!!!!!!
----------------------------------------------------------------------------------
└破解过程┐:
呃~~~这个CrackMe偶也是从附件上下载下来滴!不过破解者并没有分析算法,所以偶就拿来试试咧!
找字符串,很容易断下了:
"Wrong Serial number!"

00427B99  |.  E8 82FEFFFF   call    00427A20
00427B9E  |.  3D 4E61BC00   cmp     eax, 0BC614E
00427BA3  |.  7D 1E         jge     short 00427BC3
00427BA5  |>  6A 00         push    0
00427BA7  |.  68 087C4200   push    00427C08        ;  error
00427BAC  |.  68 107C4200   push    00427C10        ;  wrong serial number !

向上看,00427b99处,一个call,一个cmp,一个jge可以跳过错误信息的跳转,呵,经典..
断在00427b99处了!

F7跟进去,来到这里:
00427A20  /$  55            push    ebp
00427A21  |.  8BEC          mov     ebp, esp
00427A23  |.  83C4 F0       add     esp, -10
00427A26  |.  53            push    ebx
00427A27  |.  56            push    esi
00427A28  |.  33C9          xor     ecx, ecx
00427A2A  |.  894D F0       mov     dword ptr [ebp-10], ecx
00427A2D  |.  894D F4       mov     dword ptr [ebp-C], ecx
00427A30  |.  8955 F8       mov     dword ptr [ebp-8], edx
00427A33  |.  8945 FC       mov     dword ptr [ebp-4], eax
00427A36  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00427A39  |.  E8 26BFFDFF   call    00403964
00427A3E  |.  8B45 F8       mov     eax, dword ptr [ebp-8]
00427A41  |.  E8 1EBFFDFF   call    00403964
00427A46  |.  33C0          xor     eax, eax
00427A48  |.  55            push    ebp
00427A49  |.  68 2A7B4200   push    00427B2A
00427A4E  |.  64:FF30       push    dword ptr fs:[eax]
00427A51  |.  64:8920       mov     dword ptr fs:[eax], esp
00427A54  |.  33DB          xor     ebx, ebx
00427A56  |.  8B45 FC       mov     eax, dword ptr [ebp-4]
00427A59  |.  E8 52BDFDFF   call    004037B0                         ;  取name长度
00427A5E  |.  8BF0          mov     esi, eax
00427A60  |.  85F6          test    esi, esi
00427A62  |.  7E 3C         jle     short 00427AA0                   ;  name长度为空就出错
00427A64  |.  B8 01000000   mov     eax, 1
00427A69  |>  8BD0          /mov     edx, eax
00427A6B  |.  8B4D FC       |mov     ecx, dword ptr [ebp-4]          ;  name传到ecx
00427A6E  |.  0FB64C11 FF   |movzx   ecx, byte ptr [ecx+edx-1]       ;  取name字符
00427A73  |.  03D9          |add     ebx, ecx                        ;  累加上上一次循环结果
00427A75  |.  71 05         |jno     short 00427A7C
00427A77  |.  E8 B4AFFDFF   |call    00402A30
00427A7C  |>  C1E3 08       |shl     ebx, 8                          ;  累加结果左移8位
00427A7F  |.  8B0D 80884200 |mov     ecx, dword ptr [428880]         ;  字符串a("LANNYDIBANDINGINANAKEKHYANGNGENTOT")传到ecx
00427A85  |.  0FB65411 FF   |movzx   edx, byte ptr [ecx+edx-1]       ;  每次循环取字符串a的字符
00427A8A  |.  0BDA          |or      ebx, edx                        ;  每次循环取出的字符串a的字符与左移后的结果做“或”运算
00427A8C  |.  85DB          |test    ebx, ebx
00427A8E  |.  7D 0C         |jge     short 00427A9C                  ;  结果是否大于0
00427A90  |.  6BD3 FF       |imul    edx, ebx, -1                    ;  结果小于0则*-1
00427A93  |.  71 05         |jno     short 00427A9A
00427A95  |.  E8 96AFFDFF   |call    00402A30
00427A9A  |>  8BDA          |mov     ebx, edx
00427A9C  |>  40            |inc     eax                             ;  eax+1
00427A9D  |.  4E            |dec     esi                             ;  计数减一
00427A9E  |.^ 75 C9         \jnz     short 00427A69                  ;  没算法跳上去
00427AA0  |>  81F3 78563412 xor     ebx, 12345678                    ;  循环结果与0x12345678异或
00427AA6  |.  8D55 F0       lea     edx, dword ptr [ebp-10]
00427AA9  |.  8BC3          mov     eax, ebx
00427AAB  |.  E8 44E9FDFF   call    004063F4                         ;  把最后结果转换成十进制并格式化为字符串->
00427AB0  |.  8B45 F0       mov     eax, dword ptr [ebp-10]          ;  结果字符串到eax
00427AB3  |.  E8 F8BCFDFF   call    004037B0                         ;  取结果字符串长度
00427AB8  |.  8BF0          mov     esi, eax                         ;  长度到esi
00427ABA  |.  85F6          test    esi, esi
00427ABC  |.  7E 38         jle     short 00427AF6                   ;  长度为空就出错
00427ABE  |>  8BC3          /mov     eax, ebx
00427AC0  |.  B9 0A000000   |mov     ecx, 0A                         ;  0xa传到ecx
00427AC5  |.  99            |cdq                                     ;  双字扩展
00427AC6  |.  F7F9          |idiv    ecx                             ;  这个循环共用了两个idiv,这个主要是取余->取余到edx;
00427AC8  |.  6215 3C7B4200 |bound   edx, qword ptr [427B3C]
00427ACE  |.  8A92 84884200 |mov     dl, byte ptr [edx+428884]       ;  根据余数从"LANNY5646521"里取相应的字符
00427AD4  |.  8D45 F0       |lea     eax, dword ptr [ebp-10]
00427AD7  |.  E8 FCBBFDFF   |call    004036D8
00427ADC  |.  8B55 F0       |mov     edx, dword ptr [ebp-10]
00427ADF  |.  8D45 F4       |lea     eax, dword ptr [ebp-C]
00427AE2  |.  E8 D1BCFDFF   |call    004037B8
00427AE7  |.  8BC3          |mov     eax, ebx
00427AE9  |.  B9 0A000000   |mov     ecx, 0A                         ;  0xa到ecx
00427AEE  |.  99            |cdq                                     ;  双字扩展(根据上一次循环idiv的商的符号填充edx)
00427AEF  |.  F7F9          |idiv    ecx                             ;  有符号除
00427AF1  |.  8BD8          |mov     ebx, eax                        ;  商传到ebx
00427AF3  |.  4E            |dec     esi                             ;  计数器减一
00427AF4  |.^ 75 C8         \jnz     short 00427ABE
00427AF6  |>  8B45 F4       mov     eax, dword ptr [ebp-C]           ;ebp-c里是真码
00427AF9  |.  8B55 F8       mov     edx, dword ptr [ebp-8]           ;ebp-8里是假码
00427AFC  |.  E8 BFBDFDFF   call    004038C0                         ;对比的call,里面跳转太多,偶就不跟了!有兴趣可以进去看一下
00427B01  |.  75 07         jnz     short 00427B0A                   ;对比的call出来后,这里如果跳就错了
00427B03  |.  BB 4E61BC00   mov     ebx, 0BC614E                     ;把0xbc614e传到ebx->0xbc614e是个注册成功的标记,算法call出去以后,会根据这个判断是否注册成功,当然,上面跳了之后这个标记就不在ebx里了,所以要爆破的话把427b01处的jnz,nop掉或改为je就行,当然也可以手动给ebx赋一个0x0bc614e
00427B08  |.  EB 05         jmp     short 00427B0F
00427B0A  |>  BB 91D61200   mov     ebx, 12D691
00427B0F  |>  33C0          xor     eax, eax
00427B11  |.  5A            pop     edx
00427B12  |.  59            pop     ecx
00427B13  |.  59            pop     ecx
00427B14  |.  64:8910       mov     dword ptr fs:[eax], edx
00427B17  |.  68 317B4200   push    00427B31
00427B1C  |>  8D45 F0       lea     eax, dword ptr [ebp-10]
00427B1F  |.  BA 04000000   mov     edx, 4
00427B24  |.  E8 2FBAFDFF   call    00403558
00427B29  \.  C3            retn

算法call出来就到这:
00427B99  |.  E8 82FEFFFF   call    00427A20                         ;算法call
00427B9E  |.  3D 4E61BC00   cmp     eax, 0BC614E                     ;这里就判断eax地址里的内容是否为0xbc614e
00427BA3  |.  7D 1E         jge     short 00427BC3                   ;爆破点
00427BA5  |>  6A 00         push    0
00427BA7  |.  68 087C4200   push    00427C08                         ;  error
00427BAC  |.  68 107C4200   push    00427C10                         ;  wrong serial number !
00427BB1  |.  A1 44974200   mov     eax, dword ptr [429744]
00427BB6  |.  E8 411EFFFF   call    004199FC
00427BBB  |.  50            push    eax                              ; |hOwner
00427BBC  |.  E8 4FD9FDFF   call    <jmp.&user32.MessageBoxA>        ; \MessageBoxA
00427BC1  |.  EB 1C         jmp     short 00427BDF
00427BC3  |>  6A 00         push    0
00427BC5  |.  68 287C4200   push    00427C28                         ;  success
00427BCA  |.  68 307C4200   push    00427C30                         ;  congratulation ! you've did it.\nmail us : ekhmail@egroups.com

算法总结:
1、依次取name字符循环,累加(加上上次的循环结果),也依次"LANNYDIBANDINGINANAKEKHYANGNGENTOT"
里取出与循环计数器相应位置的字符,将其与累加后的结果相"或",或后的结果如果小于0,结果就乘以-1!大于0啥也不做;
然后,把最后的结果转换成十进制并格式化成新的字符串;

2、根据新的字符串长度开始循环,将上面循环的结果(十六进制整数)先与0xA取余,根据余数从"LANNY5646521"里取相应的字符,再用上面循环结果除以0xA,得出商(向后面几次循环提供取余的被除数)
之后得出的字符串就是注册码了;

下面是c++的注册机:
#include <iostream.h>
#include <stdio.h>
#include <string.h>
#include <windows.h>
void main()
{
        char name[100],lscode[100];
        char lpChar1[]="LANNYDIBANDINGINANAKEKHYANGNGENTOT",
                 lpChar2[]="LANNY5646521";
        int i,yu,len;
        unsigned long  ls1=0,ls2=0;
        cout<<"Your name:";
        cin>>name;
        len=strlen(name);
        for(i=0;i<len;i++)
        {
                ls1=ls1+name[i];
                ls2=ls1<<8;
                ls1=abs(ls2 | lpChar1[i]);
        }
        ls1^=0x12345678;
        len=sprintf(lscode,"%i",ls1);
        for(i=0;i<len;i++)
        {
                yu=ls1 % 0xA;
                name[i]=lpChar2[yu];
                ls1/=0xA;
        }
        name[i]='\0';
        cout<<"Your code:"<<name<<endl;
}
很简单,不加注释了!
----------------------------------------------------------------------------------
└经验总结┐:
这个CrackMe难度不高,适合新手!

呵呵,其实注册码就在"LANNY5646521"这串里面!!
----------------------------------------------------------------------------------
└版权声明┐ 本文原创于看雪软件安全论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                           2007年4月7日  11:59:5


[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)

上传的附件:
收藏
免费 7
支持
分享
最新回复 (7)
雪    币: 112
活跃值: (16)
能力值: ( LV9,RANK:290 )
在线值:
发帖
回帖
粉丝
2
支持一下!!!强!!!
2007-4-7 17:36
0
雪    币: 110
活跃值: (13)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
牛 X ,佩服
2007-4-7 20:47
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
很深奥   只是部分还是看不很懂
继续努力学习
2007-4-10 10:33
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
5
看来我是非常非常非常非常有必要去学习一下子表格算法了
2007-8-14 00:26
0
雪    币: 498
活跃值: (1552)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
wxq
6
支持一下。下来学习学习哈
2007-9-4 19:39
0
雪    币: 177
活跃值: (12)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
学习~~
2007-10-3 12:08
0
雪    币: 347
活跃值: (30)
能力值: ( LV9,RANK:420 )
在线值:
发帖
回帖
粉丝
8
今天才发现,原来我也分析过这个Crack Me

声明:当时我可不知道这个Crack Me有人发过算法分析的,我属于看过就忘记的那种
2007-10-3 22:02
0
游客
登录 | 注册 方可回帖
返回
//