首页
社区
课程
招聘
[原创]crackme算法详细分析(我写的第一篇文章,大家支持一下啊)
发表于: 2006-3-5 15:57 6583

[原创]crackme算法详细分析(我写的第一篇文章,大家支持一下啊)

2006-3-5 15:57
6583

CRACKME1.0 算法分析(下载地址:http://www.fradfire.com/crackme1.0.exe)

这个是我在看雪论坛发的第一个破文,因为技术比较菜,所以写的不是很好,希望大侠们不要见笑,实际上这个CRACKME是《加密与解密第2版》中的一
个练习题,后面有答案,但是答案上是用SOFTICE 来破解的,提示的很简短,在这里我主要对这个CRACKME的算法做详细的分析,好了不说废话了
开始吧
****************************************************************************************************************************
1)运行PEID探测无壳
2)运行这个CRACKME,输入任意的注册码和序列号后有错误提示----Wrong Serial Number !
3) 用IDA载入这个程序,搜索这个错误提示字符串,很快就找到了这个错误提示的入口
CODE:00427B44 ; 〓〓〓〓〓〓〓〓〓〓〓〓 S U B R O U T I N E  〓〓〓〓〓〓〓〓〓〓〓〓〓〓〓
CODE:00427B44
CODE:00427B44 ; Attributes: bp-based frame
CODE:00427B44
CODE:00427B44 sub_427B44      proc near               ; DATA XREF: CODE:004279A1o
CODE:00427B44
CODE:00427B44 var_8           = dword ptr -8
CODE:00427B44 var_4           = dword ptr -4
CODE:00427B44
CODE:00427B44                 push    ebp
CODE:00427B45                 mov     ebp, esp
CODE:00427B47                 push    0
CODE:00427B49                 push    0
CODE:00427B4B                 push    ebx
CODE:00427B4C                 mov     ebx, eax
CODE:00427B4E                 xor     eax, eax
CODE:00427B50                 push    ebp
CODE:00427B51                 push    offset loc_427BFA
CODE:00427B56                 push    dword ptr fs:[eax]
CODE:00427B59                 mov     fs:[eax], esp
CODE:00427B5C                 lea     edx, [ebp+var_4]
CODE:00427B5F                 mov     eax, [ebx+1DCh]
CODE:00427B65                 call    sub_415D90
CODE:00427B6A                 mov     eax, [ebp+var_4]  ;在这个地方ebp+var_4这个局部变量保存了我们输入的UserName,并将其值传送到EAX中
CODE:00427B6D                 call    sub_4037B0
CODE:00427B72                 dec     eax
CODE:00427B73                 jl      short loc_427BA5
CODE:00427B75                 lea     edx, [ebp+var_4]
CODE:00427B78                 mov     eax, [ebx+1ECh]
CODE:00427B7E                 call    sub_415D90
CODE:00427B83                 mov     eax, [ebp+var_4] ;此处[ebp+var_4]这个局部变量保存了我们输入的Serial

CODE:00427B86                 push    eax              ;输入的Serial入栈
CODE:00427B87                 lea     edx, [ebp+var_8]
CODE:00427B8A                 mov     eax, [ebx+1DCh]
CODE:00427B90                 call    sub_415D90
CODE:00427B95                 mov     eax, [ebp+var_8]
CODE:00427B98                 pop     edx
CODE:00427B99                 call    sub_427A20       ;此处是关键CALL 跟进去就是算法的核心
CODE:00427B9E                 cmp     eax, 0BC614Eh
CODE:00427BA3                 jge     short loc_427BC3    >=就跳转到成功
CODE:00427BA5
CODE:00427BA5 loc_427BA5:                             ; CODE XREF: sub_427B44+2Fj
CODE:00427BA5                 push    0
CODE:00427BA7                 push    offset aError_0 ; "ERROR"
CODE:00427BAC                 push    offset aWrongSerialNum ; "Wrong Serial Number !"   注册错误的提示
CODE:00427BB1                 mov     eax, ds:dword_429744
CODE:00427BB6                 call    sub_4199FC
CODE:00427BBB                 push    eax
CODE:00427BBC                 call    MessageBoxA_0            ;调用此函数之后将产生错误提示
CODE:00427BC1                 jmp     short loc_427BDF
CODE:00427BC3 ; ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
CODE:00427BC3
CODE:00427BC3 loc_427BC3:                             ; CODE XREF: sub_427B44+5Fj
CODE:00427BC3                 push    0
CODE:00427BC5                 push    offset aSuccess ; "Success"
CODE:00427BCA                 push    offset aCongratulation ; "Congratulation ! You've Did It.\rMail Us"... 注册成功的提示
CODE:00427BCF                 mov     eax, ds:dword_429744
CODE:00427BD4                 call    sub_4199FC
CODE:00427BD9                 push    eax
CODE:00427BDA                 call    MessageBoxA_0         

4)用OD载入来到00427B44这个地址,并在此处设断.然后F9运行,并在UserName处输入123456789,在Serial处输入123456 点击OK后便中断在00427B44这个地方
然后取消断点,单步向下运行,注意观察寄存器窗口各个寄存器的值,看看哪一句代码,读入了我们输入的UserName和Serial,不久便会发现
00427B6A  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]   在这个地方EBP-4这个局部变量保存了我们输入的UserName,并将其值传送到EAX中
00427B83  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]   此处EBP-4这个局部变量保存了我们输入的Serial
一直向下跟直到
CODE:00427B99                 call    sub_427A20 很明显此处是关键CALL 必须跟进去
****************************************************************************************************************************
5)核心算法分析
00427A20  /$  55            PUSH EBP                    ;此时EAX和EDX中分别保存的是UserName和123456
00427A21  |.  8BEC          MOV EBP,ESP
00427A23  |.  83C4 F0       ADD ESP,-10                  ;为变量和参数分配空间
00427A26  |.  53            PUSH EBX
00427A27  |.  56            PUSH ESI
00427A28  |.  33C9          XOR ECX,ECX                  ;ECX寄存器清0
00427A2A  |.  894D F0       MOV DWORD PTR SS:[EBP-10],ECX ;EBP-10 这个局部变量被赋值为0
00427A2D  |.  894D F4       MOV DWORD PTR SS:[EBP-C],ECX  ;EBP-C  这个局部变量也被赋值为0
00427A30  |.  8955 F8       MOV DWORD PTR SS:[EBP-8],EDX  ;EBP-8  这个局部变量保存了我们输入的SERIAL
00427A33  |.  8945 FC       MOV DWORD PTR SS:[EBP-4],EAX  ;EBP-4  这个局部变量保存了我们输入的USERNMAE
00427A36  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]  ;USENAME 再次写入到EAX中 EAX的值为123456789
00427A39  |.  E8 26BFFDFF   CALL crackme1.00403964        ;这个函数我没有跟进去,有兴趣的可以跟进去看看
00427A3E  |.  8B45 F8       MOV EAX,DWORD PTR SS:[EBP-8]  ;SERIAL写入到EAX中 EAX的值为123456
00427A41  |.  E8 1EBFFDFF   CALL crackme1.00403964        ;再次调用这个函数
00427A46  |.  33C0          XOR EAX,EAX                   ;EAX清0
00427A48  |.  55            PUSH EBP                     
00427A49  |.  68 2A7B4200   PUSH crackme1.00427B2A        
00427A4E  |.  64:FF30       PUSH DWORD PTR FS:[EAX]
00427A51  |.  64:8920       MOV DWORD PTR FS:[EAX],ESP
00427A54  |.  33DB          XOR EBX,EBX                   ;EBX清0
00427A56  |.  8B45 FC       MOV EAX,DWORD PTR SS:[EBP-4]  ;USERNAME送入EAX EAX=123456789
00427A59  |.  E8 52BDFDFF   CALL crackme1.004037B0        ;调用这个函数后,返回的是我们输入的USERNAME的位数,其值放在EAX中,此时EAX=9
00427A5E  |.  8BF0          MOV ESI,EAX                  
00427A60  |.  85F6          TEST ESI,ESI
00427A62  |.  7E 3C         JLE SHORT crackme1.00427AA0    ;<=则跳,很显然跳转不成功
00427A64  |.  B8 01000000   MOV EAX,1                      ;EAX置1
----------------------------第一个循环-------------------------------------------------------------------------------------
00427A69  |>  8BD0          /MOV EDX,EAX                   ;EDX置1
00427A6B  |.  8B4D FC       |MOV ECX,DWORD PTR SS:[EBP-4]  ;ECX保存了USERNAME
00427A6E  |.  0FB64C11 FF   |MOVZX ECX,BYTE PTR DS:[ECX+EDX-1];传送USERNAME中的第一个位到ECX中,因为是字节传送,此时ECX=00000031(1的16进制ASCLL码)
00427A73  |.  03D9          |ADD EBX,ECX                      ;EBX+ECX=00000031
00427A75  |.  71 05         |JNO SHORT crackme1.00427A7C      ;OF标志位为0就跳(未溢出就跳)
00427A77  |.  E8 B4AFFDFF   |CALL crackme1.00402A30           
00427A7C  |>  C1E3 08       |SHL EBX,8                        ;逻辑左移,EBX=00003100
00427A7F  |.  8B0D 80884200 |MOV ECX,DWORD PTR DS:[428880]    ;ECX保存了428880这个存储单元的值--LANNYDIBANDINGINANAKEKHYANGNGENT
00427A85  |.  0FB65411 FF   |MOVZX EDX,BYTE PTR DS:[ECX+EDX-1] ;将ECX中的第一位4C(L的16进制ASCII)送入EDX中
00427A8A  |.  0BDA          |OR EBX,EDX                        ;EBX和EDX进行OR运算 EBX=0000314C                  
00427A8C  |.  85DB          |TEST EBX,EBX
00427A8E  |.  7D 0C         |JGE SHORT crackme1.00427A9C       ;>=则跳 第五次循环和最后一次这个条件将不会满足
00427A90  |.  6BD3 FF       |IMUL EDX,EBX,-1
00427A93  |.  71 05         |JNO SHORT crackme1.00427A9A
00427A95  |.  E8 96AFFDFF   |CALL crackme1.00402A30
00427A9A  |>  8BDA          |MOV EBX,EDX
00427A9C  |>  40            |INC EAX                            ;EAX+1
00427A9D  |.  4E            |DEC ESI                            :ESI-1
00427A9E  |.^ 75 C9         \JNZ SHORT crackme1.00427A69        ;循环的条件(很明显将循环9次)每次的循环将会导致EAX的值的变化--EDX将变化....每次都产生不同的结果
经过9次循环后 EBX的值将是本次循环的结果EBX=0C7E84BF
----------------------------------------------------------------------------------------------------------------------------
00427AA0  |>  81F3 78563412 XOR EBX,12345678                    ;OR运算后 EBX=1E4AD27C   
00427AA6  |.  8D55 F0       LEA EDX,DWORD PTR SS:[EBP-10]
00427AA9  |.  8BC3          MOV EAX,EBX
00427AAB  |.  E8 44E9FDFF   CALL crackme1.004063F4
00427AB0  |.  8B45 F0       MOV EAX,DWORD PTR SS:[EBP-10]
00427AB3  |.  E8 F8BCFDFF   CALL crackme1.004037B0                  
00427AB8  |.  8BF0          MOV ESI,EAX
00427ABA  |.  85F6          TEST ESI,ESI
00427ABC  |.  7E 38         JLE SHORT crackme1.00427AF6
----------------------------第2个循环---------------------------------------------------------------------------------------
00427ABE  |>  8BC3          /MOV EAX,EBX
00427AC0  |.  B9 0A000000   |MOV ECX,0A
00427AC5  |.  99            |CDQ                                 ;将EAX寄存器中的双字+0扩展成为4字 并保存在EDX:EAX中
00427AC6  |.  F7F9          |IDIV ECX                            ;EAX:EDX/ECX  商保存在EAX中 余数保存在EDX中
00427AC8  |.  6215 3C7B4200 |BOUND EDX,QWORD PTR DS:[427B3C]         
00427ACE  |.  8A92 84884200 |MOV DL,BYTE PTR DS:[EDX+428884]     ;用DD 00428884查看会看到LANNY5646521这个字符串,取该字符串的一位到DL中,取哪一位和所的的余数有关
00427AD4  |.  8D45 F0       |LEA EAX,DWORD PTR SS:[EBP-10]      
00427AD7  |.  E8 FCBBFDFF   |CALL crackme1.004036D8
00427ADC  |.  8B55 F0       |MOV EDX,DWORD PTR SS:[EBP-10]
00427ADF  |.  8D45 F4       |LEA EAX,DWORD PTR SS:[EBP-C]
00427AE2  |.  E8 D1BCFDFF   |CALL crackme1.004037B8
00427AE7  |.  8BC3          |MOV EAX,EBX
00427AE9  |.  B9 0A000000   |MOV ECX,0A
00427AEE  |.  99            |CDQ
00427AEF  |.  F7F9          |IDIV ECX                            ;再次做除法运算
00427AF1  |.  8BD8          |MOV EBX,EAX
00427AF3  |.  4E            |DEC ESI                             ;ESI-1 第一次ESI中保存的仍然是USERNAME的位数9
00427AF4  |.^ 75 C8         \JNZ SHORT crackme1.00427ABE         ;很明显将循环9次                                
----------------------------------------------------------------------------------------------------------------------------
00427AF6  |>  8B45 F4       MOV EAX,DWORD PTR SS:[EBP-C]     ;送入EAX中的值就是正确的Serial  
00427AF9  |.  8B55 F8       MOV EDX,DWORD PTR SS:[EBP-8]     ;错误的serial
00427AFC  |.  E8 BFBDFDFF   CALL crackme1.004038C0            ;对两个serial进行一系列的运算
00427B01  |.  75 07         JNZ SHORT crackme1.00427B0A       ;要想注册成功就必须让这个条件不成立   
00427B03  |.  BB 4E61BC00   MOV EBX,0BC614E                   ;如果能运行到此处 那么 那么他将最终跳向成功
00427B08  |.  EB 05         JMP SHORT crackme1.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 crackme1.00427B31
00427B1C  |>  8D45 F0       LEA EAX,DWORD PTR SS:[EBP-10]
00427B1F  |.  BA 04000000   MOV EDX,4
00427B24  |.  E8 2FBAFDFF   CALL crackme1.00403558
00427B29  \.  C3            RETN                            ;返回到00427B31
00427B2A   .^ E9 A9B4FDFF   JMP crackme1.00402FD8
00427B2F   .^ EB EB         JMP SHORT crackme1.00427B1C
00427B31   .  8BC3          MOV EAX,EBX
00427B33   .  5E            POP ESI
00427B34   .  5B            POP EBX
00427B35   .  8BE5          MOV ESP,EBP
00427B37   .  5D            POP EBP
00427B38   .  C3            RETN                           ;返回到00427B9E 因为EAX被赋予了错误的值,所以注册失败
好了,不说了,不好意思说了很多的废话,主要是为了让象我一样的菜鸟都能看懂,下面看下这个算法的运算过程
****************************************************************************************************************************
运算过程:
  username:         1     2         3        4         5          6            7          8            9
  16进制ASCII形式:31    32        33        34        35         36           37         38           39
  M 字符串:       LANNYDIBANDINGINANAKEKHYANGNGENT
  16进制ASCII形式:4C 41 4E 4E 59 44 49 42 41 4E 44 49 4E 47 49 4E 41 4E 41 4B 45 4B 48 59 41 4E 47 4E 47 45 4E 54
  N 字符串:LANNY5646521
第一个循环:
第1次循环:1)取 username的第一位31和0想加    00000031+0=00000031
            2)00000031 逻辑左移一个单位  =====00003100
            3)00003100与字符串M的第一位做OR运算 //00003100  OR 0000004C=0000314C

      
第2次循环:1)取usename 的第2位和0000314C想加   0000314C+00000032=0000317E
           2)0000317E 逻辑左移一个单位  =====00317E00
           3)00317E00与字符串M的第2位做OR运算  //00317E00 OR 00000041=00317E41
..........................中间的过程省略(注意第5次循环和最后一次的时候.00427A8E 这个条件将不会满足,他将会去做乘法运算).....................................
经过第一个循环:得到结果EBX=0C7E84BF
在进行这样一次运算:0C7E84BF XOR 12345678=1E4AD2C7
第二个循环:
第1次循环:1)1E4AD2C7 扩展为000000001E4AD2C7
            2)000000001E4AD2C7除以0A======03077B7A(商).......00000003(余数)
            4)取N字符串LANNY5646521的第4(00000003+1)个字符 该字符是正确serial的第一位
第2次循环:1)03077B7A扩展为0000000003077B7A
           2)0000000003077B7A除以0A=======004D8C59(商)........00000000(余数)
           3)取N字符串LANNY5646521的第1(0000000+1)个字符 该字符是正确serial的第二位
第3次循环:1)004D8C59扩展为00000000004D8C59
           2)00000000004D8C59除以0A======0007C13C(商).......00000001(余数)
           3)取N字符串LANNY5646521的第2(00000001+1)个字符 该字符是正确serial的第三位
...........就这样经过9次循环后便得到正确的serial为(NLALNN6L5)...................
*************************************************************************************************************************
总结:其实,这个CRACKME 要得到他的serial并不难,因为它是明码保存的,保护机制很弱,经过这两个循环之后在OD的堆栈窗口就看到
正确的serial,所以要单纯的找到他的 serial其实是很简单的,当然我在这里也只是分析他的算法.
由于第一次 写破文,加之水平有限,错误之处,请大家见谅,欢迎大家指出.
最后祝愿大家都能在看雪学到更高的解密技术...

                                                                                                      
                        
              
                                                   
                                                                                                        jipo400
                                                                                                        2006.3.5


[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

收藏
免费 7
支持
分享
最新回复 (10)
雪    币: 234
活跃值: (370)
能力值: ( LV9,RANK:530 )
在线值:
发帖
回帖
粉丝
2
支持一下
2006-3-5 17:12
0
雪    币: 2256
活跃值: (941)
能力值: (RANK:2210 )
在线值:
发帖
回帖
粉丝
3
呵呵~不错不错。这个CRACKME我也写过
2006-3-5 17:27
0
雪    币: 214
活跃值: (70)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
为什么现在很多的 CRACKME 大家都写过了啊 ,哎看来 要自己学会写一些crackme 了
2006-3-5 18:50
0
雪    币: 203
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错不错
2006-3-5 21:18
0
雪    币: 204
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
支持,学习
2006-3-6 09:25
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
最初由 byh9999 发布
支持,学习


2006-3-6 23:28
0
雪    币: 201
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
好东西,顶一下!!
2006-3-8 00:38
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
9
还是这个方便啊,支持+感谢!
2006-3-8 23:41
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
10
好好学习学习
2006-3-9 15:26
0
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
11
我来顶一个
linwen42
Y454NY6A4
2006-3-10 19:02
0
游客
登录 | 注册 方可回帖
返回
//