首页
社区
课程
招聘
[原创][邀请码已发]分析昨天xiaojiam的crackme
发表于: 2010-4-10 19:25 5162

[原创][邀请码已发]分析昨天xiaojiam的crackme

2010-4-10 19:25
5162

昨天逛论坛看到的一个crackmehttp://bbs.pediy.com/showthread.php?t=110534&highlight=KeyGen+%E8%B6%85%E5%B0%8F+%E5%B0%8F,分析完了,花时间写了个注册机...在此总结一下,跟大伙交流交流了。嗯,顺便看能不能跟管理员讨个邀请码

没壳,原帖LZ也说了没Anti...运行看了下界面,然后直接OD载入,在主模块中查找当前模块中的名称,发现USER32.GetDlgItemTextA(),先尝试在它上面下断啰。然后F9运行,随便输入name和password值,点crack键后果然断了下来,alt+F9来到0040133B,这里连续调用了两次上面这个API,分别取输入的name和password了。

然后是00401367这个地方的call crackme.004013c8,上面取得的字符串作为参数传给它的,在这F7跟入。接着004013c8~00401417是判断了strlen(name)和strlen(password)是否为5和10,不是的话就game over啦。00401430~004014f7是一个循环,嗯,应该是这个算法的主体了,唉,想写注册机,慢慢分析一下吧。

 
check(handle var,
 char* name,                                    //0240f8f4,len=5
 char* password){                            //0240f7f4,len=10
    int j=1;
    int k=2;                                      //汇编中为strlen(name)-3
    int mid1,mid2;
    for(int i=0,i<=6,i++){
 if(name[i]>0x7a||name[i]<=0x60       //要求name全为小写字母,对应汇编地址40~5c
  ||password[i]>0x5a||password[i]<=0x40 //要求password全为大写字母,对应汇编地址62~7e
  ||password[j]-password[j-1]!=i){       //password要满足的另一个条件,对应汇编地址80~9f
  k-=0x19;                                      //jmp 004014f0,不满足条件时循环仍继续,
  continue;                                   //但后面验证就不会通过吧?没跟下去,累啊...
 }
     mid1=name[i]-password[j-1];      //对应汇编地址a1~bf
     mid2=0x1d/(j+2)+0x1e;              //对应汇编地址c2~d6
     if(mid1==mid2){
         j+=2;
  k*=2;
 }
    }
    ...
}
 
[FONT=Verdana][COLOR=#333333][COLOR=#333333][FONT=Verdana]#include <stdio.h>[/FONT]
[FONT=Verdana][COLOR=#333333]#include <stdlib.h>[/FONT]
[FONT=Verdana][COLOR=#333333]#include <time.h>[/FONT]
 
[COLOR=#333333][FONT=Verdana]int main(){[/FONT]
[FONT=Verdana][COLOR=#333333] char name[6]={0};[/FONT]
[FONT=Verdana][COLOR=#333333] char password[11]={0};[/FONT]
[FONT=Verdana][COLOR=#333333] int i=0,j=1,mid=0;[/FONT]
 
[COLOR=#333333][FONT=Verdana] srand((unsigned)time(0));[/FONT]
[FONT=Verdana][COLOR=#333333] for(i=0;i<5;i++){[/FONT]
[FONT=Verdana][COLOR=#333333]  mid=0x1d/(j+2)+0x1e;[/FONT]
[FONT=Verdana][COLOR=#333333]  while(0x41>password[j-1]||password[j-1]>0x5A-i){[/FONT]
[FONT=Verdana][COLOR=#333333]     name[i]=0x61+rand()%26;[/FONT]
[FONT=Verdana][COLOR=#333333]     password[j-1]=name[i]-mid;[/FONT]
[FONT=Verdana][COLOR=#333333]  }[/FONT]
[FONT=Verdana][COLOR=#333333]  password[j]=i+password[j-1];[/FONT]
[FONT=Verdana][COLOR=#333333]  j+=2;[/FONT]
[FONT=Verdana][COLOR=#333333] }[/FONT]
[FONT=Verdana][COLOR=#333333] [/FONT]
[FONT=Verdana][COLOR=#333333] printf("name:%s\n",name);[/FONT]
[FONT=Verdana][COLOR=#333333] printf("password:%s",password);[/FONT]
[FONT=Verdana][COLOR=#333333] [/FONT]
[FONT=Verdana][COLOR=#333333] return 0;[/FONT]
[FONT=Verdana][COLOR=#333333]}[/FONT]
[/FONT]

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

收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 267
活跃值: (24)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
2
支持lz,希望以后多分享共同进步~
2010-4-10 20:00
0
雪    币: 5
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
楼主厉害!!!
2010-4-10 20:10
0
雪    币: 261
活跃值: (10)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
4
算法都说到了,要是补点认证提示那就更好了。重点就在那!
2010-4-11 12:51
0
雪    币: 57
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
不错,希望自己能有这个水平啊
2010-4-11 22:45
0
雪    币: 224
活跃值: (55)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
6
看了xiaojiamd在4楼的提示,我继续跟了一下这个crackme的认证过程。嗯,这里的检验提示方式确实很有启发作用,xiaojiam真是费心了,嘿...

是这样的,验证通过的话提示对话框标题为“正确”,错误时提示对话框标题为“错误”。调用的MessageBox API达到这种效果需要有参数传入,但是我们在OD中搜参考字符串的话是搜不到这两个字符串的,它们是放在哪的呢?我是分析了过后再回过去看从而有这些问题的,我想如果有分析者习惯于在参考字符串上下断的话,一开始在这会有这样的疑惑吧?

验证代码是这样的:
//正确与否的提示部分
00401548   $ 55             PUSH EBP
00401549   . 89E5           MOV EBP,ESP
0040154B   . 81EC 34010000  SUB ESP,134
00401551   . 53             PUSH EBX
00401552   . 837D 0C 05     CMP DWORD PTR SS:[EBP+C],5
00401556   . 0F8E A4000000  JLE crackme.00401600
0040155C   . 837D 0C 13     CMP DWORD PTR SS:[EBP+C],13
00401560   . 0F8F 9A000000  JG crackme.00401600		
;要求传入的参数(5,13],上一个函数调用这个函数时传入的值为2*(k-9)
00401566   . 83C4 FC        ADD ESP,-4
00401569   . 6A 00          PUSH 0                            ; /Arguments = NULL
0040156B   . 6A 00          PUSH 0                            ; |BufSize = 0
0040156D   . 8D45 FC        LEA EAX,DWORD PTR SS:[EBP-4]      ; |
00401570   . 50             PUSH EAX                          ; |Buffer
00401571   . 68 00040000    PUSH 400                          ; |LanguageId = 400 (LANG_NEUTRAL)
00401576   . 8B45 0C        MOV EAX,DWORD PTR SS:[EBP+C]      ; |
00401579   . 50             PUSH EAX                          ; |MessageId
0040157A   . 6A 00          PUSH 0                            ; |pSource = NULL
0040157C   . 68 00130000    PUSH 1300                         ; |Flags = ALLOCATE_BUFFER|IGNORE_INSERTS|FROM_SYSTEM|0
00401581   . E8 DA020000    CALL <JMP.&KERNEL32.FormatMessage>; \FormatMessageA
;生成的消息为“环境不正确。”,这个API会分配空间保存这个字符串(因为LLOCATE_BUFFER标志)
00401586   . 83C4 04        ADD ESP,4
00401589   . 83C4 F8        ADD ESP,-8
0040158C   . 8B45 FC        MOV EAX,DWORD PTR SS:[EBP-4]
0040158F   . 50             PUSH EAX                          ; /src
00401590   . 8D85 F0FEFFFF  LEA EAX,DWORD PTR SS:[EBP-110]    ; |
00401596   . 50             PUSH EAX                          ; |dest
00401597   . E8 54020000    CALL <JMP.&msvcrt.strcpy>         ; \strcpy
;将“环境不正确。”拷入指定栈地址备用
0040159C   . 83C4 10        ADD ESP,10
0040159F   . C785 ECFEFFFF >MOV DWORD PTR SS:[EBP-114],0
004015A9   . 8DB426 0000000>LEA ESI,DWORD PTR DS:[ESI]
004015B0   > 83BD ECFEFFFF >CMP DWORD PTR SS:[EBP-114],3      
;这到004015e4这一个循环,从上面的字符串中拷出“正确”作为下面验证对话框的题目
004015B7   . 7E 07          JLE SHORT crackme.004015C0
004015B9   . EB 2B          JMP SHORT crackme.004015E6
004015BB     90             NOP
004015BC     8D7426 00      LEA ESI,DWORD PTR DS:[ESI]
004015C0   > 8B85 ECFEFFFF  MOV EAX,DWORD PTR SS:[EBP-114]
004015C6   . 8D55 F0        LEA EDX,DWORD PTR SS:[EBP-10]
004015C9   . 8B8D ECFEFFFF  MOV ECX,DWORD PTR SS:[EBP-114]
004015CF   . 83C1 06        ADD ECX,6
004015D2   . 8D9D F0FEFFFF  LEA EBX,DWORD PTR SS:[EBP-110]
004015D8   . 8A0C19         MOV CL,BYTE PTR DS:[ECX+EBX]
004015DB   . 880C10         MOV BYTE PTR DS:[EAX+EDX],CL
004015DE   . FF85 ECFEFFFF  INC DWORD PTR SS:[EBP-114]
004015E4   .^EB CA          JMP SHORT crackme.004015B0
004015E6   > 6A 20          PUSH 20                           ; /Style = MB_OK|MB_ICONQUESTION|MB_APPLMODAL
004015E8   . 8D45 F0        LEA EAX,DWORD PTR SS:[EBP-10]     ; |
004015EB   . 50             PUSH EAX                          ; |Title = "正确"
004015EC   . 68 08134000    PUSH crackme.00401308             ; |Text = ""
004015F1   . 6A 00          PUSH 0                            ; |hOwner = NULL
004015F3   . E8 48020000    CALL <JMP.&USER32.MessageBoxA>    ; \MessageBoxA
004015F8   . EB 20          JMP SHORT crackme.0040161A
004015FA     8DB6 00000000  LEA ESI,DWORD PTR DS:[ESI]
00401600   > 83C4 F4        ADD ESP,-0C
00401603   . 6A 02          PUSH 2                            ; /LanguageID = 2 (LANG_BULGARIAN)
00401605   . 6A 10          PUSH 10                           ; |Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
00401607   . 6A 00          PUSH 0                            ; |Title = NULL
00401609   . 68 08134000    PUSH crackme.00401308             ; |Text = ""
;这里传入NULL,就会弹出系统默认的“错误”对话框
0040160E   . 8B45 08        MOV EAX,DWORD PTR SS:[EBP+8]      ; |
00401611   . 50             PUSH EAX                          ; |hOwner
00401612   . E8 21020000    CALL <JMP.&USER32.MessageBoxExA>  ; \MessageBoxExA
00401617   . 83C4 0C        ADD ESP,0C


就是这样了,传入参数(2*(k-9))属于(5,13]则通过验证,此时要用的“正确”字符串是从FormatMessage的的返回参数中提取出来的了,对验证不通过提示时,给MessageBoxExA传入的对话框标题字符串的地址为NULL,些时该API会调用系统默认的错误提示框了。

嗯,就是这些了,也不知道xiaojiam的回复是不是指这个地方
另外谢谢大伙的支持。3、5楼的朋友,我也是菜鸟一只,大家相互讨论,共同进步吧...
2010-4-12 20:58
0
雪    币: 181
活跃值: (27)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
膜拜楼主大神
2010-4-13 09:19
0
游客
登录 | 注册 方可回帖
返回
//