首页
社区
课程
招聘
[原创]Bispoo's KeygenMe#3.EXE
发表于: 2008-11-27 22:10 4927

[原创]Bispoo's KeygenMe#3.EXE

2008-11-27 22:10
4927
crackmes.de上下载的  能搞出来纯属运气
相关文件见附件
Difficulty: 2 - Needs a little brain (or luck)
Platform: Windows
Language: Assembler

分析如下:
004021EA    6A 20           PUSH 20
004021EC    68 E2114000     PUSH KeygenMe.004011E2
004021F1    68 2E010000     PUSH 12E
004021F6    FF75 08         PUSH DWORD PTR SS:[EBP+8]
004021F9    FF15 60024100   CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>]         ; USER32.GetDlgItemTextA
004021FF    83F8 1B         CMP EAX,1B                                            ;取得serial 长度小于等于0x1B
00402202    0F87 69010000   JA KeygenMe.00402371
00402208    6A 29           PUSH 29
0040220A    68 04104000     PUSH KeygenMe.00401004
0040220F    68 2D010000     PUSH 12D
00402214    FF75 08         PUSH DWORD PTR SS:[EBP+8]
00402217    FF15 60024100   CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>]         ; USER32.GetDlgItemTextA
0040221D    83F8 01         CMP EAX,1                                             ;取得name 长度大于等于1
00402220    72 74           JB SHORT KeygenMe.00402296
00402222    83F8 1E         CMP EAX,1E
00402225    77 6F           JA SHORT KeygenMe.00402296                            ;name长度小于等于0x1e
00402227    A0 04104000     MOV AL,BYTE PTR DS:[401004]
0040222C    3C 20           CMP AL,20                                             ;name[0]不能为'-'
0040222E    74 38           JE SHORT KeygenMe.00402268
00402230    E9 F5000000     JMP KeygenMe.0040232A                                 ;这里跳走
================================================================================================================
0040232A    90              NOP
0040232B    90              NOP
0040232C    90              NOP
0040232D    90              NOP
0040232E    90              NOP
0040232F    55              PUSH EBP
00402330    81EC 00100000   SUB ESP,1000
00402336    50              PUSH EAX
00402337    51              PUSH ECX
00402338    52              PUSH EDX
00402339    B8 04104000     MOV EAX,KeygenMe.00401004                             ; ASCII "dalixux"
0040233E    B9 5E104000     MOV ECX,KeygenMe.0040105E
00402343    8A10            MOV DL,BYTE PTR DS:[EAX]
00402345    84D2            TEST DL,DL
00402347    74 06           JE SHORT KeygenMe.0040234F
00402349    8811            MOV BYTE PTR DS:[ECX],DL
0040234B    40              INC EAX
0040234C    41              INC ECX
0040234D  ^ EB F4           JMP SHORT KeygenMe.00402343                           ;这个循环复制name到40105E
0040234F    5A              POP EDX
00402350    59              POP ECX
00402351    58              POP EAX
00402352    BB 5E104000     MOV EBX,KeygenMe.0040105E
00402357    BD 55104000     MOV EBP,KeygenMe.00401055                             ; ASCII "12345678"
0040235C    E8 85000000     CALL KeygenMe.004023E6                                ;关键CALL
00402361    81C4 00100000   ADD ESP,1000
00402367    5D              POP EBP
00402368    803D 01124000 F>CMP BYTE PTR DS:[401201],0FF
0040236F    E7 CA           OUT 0CA,EAX                                           ; I/O 命令
注意40326f的指令   在执行完关键call后 会变成 jb short 4023A5  这里就是爆破点了
==============================================================================================================
004023E6    68 04104000     PUSH KeygenMe.00401004                                ; ASCII "dalixux"
004023EB    E8 A0030000     CALL KeygenMe.00402790                                ; 把name中的小写字母变大写 存放地址不变
004023F0    A0 04104000     MOV AL,BYTE PTR DS:[401004]
004023F5    84C0            TEST AL,AL
004023F7    8D35 04104000   LEA ESI,DWORD PTR DS:[401004]
004023FD    8D3D 04104000   LEA EDI,DWORD PTR DS:[401004]
00402403    74 29           JE SHORT KeygenMe.0040242E
00402405    C70424 00000000 MOV DWORD PTR SS:[ESP],0                              ;返回地址清0
==============================================================================================================
0040240C    0FBE0E          MOVSX ECX,BYTE PTR DS:[ESI]                           
0040240F    51              PUSH ECX
00402410    68 2D104000     PUSH KeygenMe.0040102D                                ; ASCII "KYPZAXSFCSNGRQTNWD8592VQWRKH"
                      ;常量串const_string出现
00402415    E8 87010000     CALL KeygenMe.004025A1                                ;这个call是查找字符是否在const_string出现
如出现则返回地址  未出现则返回0  功能近似于 strchr
0040241A    83C4 08         ADD ESP,8                                             ;平衡堆栈
0040241D    85C0            TEST EAX,EAX
0040241F    74 05           JE SHORT KeygenMe.00402426                            
00402421    8A16            MOV DL,BYTE PTR DS:[ESI]
00402423    8817            MOV BYTE PTR DS:[EDI],DL
00402425    47              INC EDI
00402426    8A46 01         MOV AL,BYTE PTR DS:[ESI+1]
00402429    46              INC ESI
0040242A    84C0            TEST AL,AL
0040242C  ^ 75 DE           JNZ SHORT KeygenMe.0040240C
0040242E    8D05 04104000   LEA EAX,DWORD PTR DS:[401004]
00402434    C607 00         MOV BYTE PTR DS:[EDI],0                               ;name变换后的字符串name2  存放的地址不变
这段代码  是把name中 不属于常量串的 字符删除  并用后面首个 属于常量串的字符覆盖 
比如 我输入的用户名dalixux  大写后为DALIXUX 执行上面的代码后 为DAXX
==============================================================================================================
00402437    8D50 01         LEA EDX,DWORD PTR DS:[EAX+1]                          ;name2+1
0040243A    8D2424          LEA ESP,DWORD PTR SS:[ESP]                            
0040243D    8A08            MOV CL,BYTE PTR DS:[EAX]                              ;name2[i]
0040243F    40              INC EAX
00402440    84C9            TEST CL,CL
00402442  ^ 75 F9           JNZ SHORT KeygenMe.0040243D
00402444    29D0            SUB EAX,EDX                                           ;计算出name2的长度
00402446    83F8 18         CMP EAX,18 
00402449    7D 27           JGE SHORT KeygenMe.00402472                           ;长度大于0x18跳走
0040244B    B9 18000000     MOV ECX,18
00402450    29C1            SUB ECX,EAX                                           ;计数器
00402452    8DB8 04104000   LEA EDI,DWORD PTR DS:[EAX+401004]                     
00402458    89C8            MOV EAX,ECX
0040245A    C1E9 02         SHR ECX,2
0040245D    BE 2D104000     MOV ESI,KeygenMe.0040102D                             ; ASCII "KYPZAXSFCSNGRQTNWD8592VQWRKH"
00402462    F3:A5           REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]        ;以双字的形式复制
00402464    89C1            MOV ECX,EAX
00402466    83E1 03         AND ECX,3
00402469    F3:A4           REP MOVS BYTE PTR ES:[EDI],BYTE PTR DS:[ESI]          ;继续复制
0040246B    C605 1C104000 C>MOV BYTE PTR DS:[40101C],0C0                          ;填充问号   记为newname
这段代码的作用 检查name2的长度  如大于等于0x18则不变  小于0x18的部分 用const_string填充 直到长度为0x18 
===============================================================================================================
00402472    B8 2D104000     MOV EAX,KeygenMe.0040102D                             ; ASCII "KYPZAXSFCSNGRQTNWD8592VQWRKH"
00402477    C64424 39 00    MOV BYTE PTR SS:[ESP+39],0
0040247C    C68424 84000000>MOV BYTE PTR SS:[ESP+84],0
00402484    31ED            XOR EBP,EBP
00402486    8D48 01         LEA ECX,DWORD PTR DS:[EAX+1]
00402489    8A10            MOV DL,BYTE PTR DS:[EAX]
0040248B    40              INC EAX
0040248C    84D2            TEST DL,DL
0040248E  ^ 75 F9           JNZ SHORT KeygenMe.00402489
00402490    29C8            SUB EAX,ECX                                           ;计算const_string的长度
00402492    894424 10       MOV DWORD PTR SS:[ESP+10],EAX
00402496    B8 01000000     MOV EAX,1
0040249B    2D 78F44800     SUB EAX,48F478                                        ;1-0x48f478
004024A0    894424 18       MOV DWORD PTR SS:[ESP+18],EAX
004024A4    31DB            XOR EBX,EBX
004024A6    C74424 14 77F44>MOV DWORD PTR SS:[ESP+14],48F477
004024AE    8D05 04104000   LEA EAX,DWORD PTR DS:[401004]                         
004024B4    48              DEC EAX
004024B5    8DBC24 84000000 LEA EDI,DWORD PTR SS:[ESP+84]
004024BC    894424 1C       MOV DWORD PTR SS:[ESP+1C],EAX                         ;eax为newname[-1]
004024C0    EB 04           JMP SHORT KeygenMe.004024C6
004024C2    8B4424 1C       MOV EAX,DWORD PTR SS:[ESP+1C]                         ;newname[-1]                        
004024C6    0FBE4C18 01     MOVSX ECX,BYTE PTR DS:[EAX+EBX+1]                     ;ecx为newname[i] i从0-0x18
004024CB    8D73 01         LEA ESI,DWORD PTR DS:[EBX+1]                          ;esi为i+1
004024CE    51              PUSH ECX
004024CF    68 2D104000     PUSH KeygenMe.0040102D                                ; ASCII "KYPZAXSFCSNGRQTNWD8592VQWRKH"
004024D4    E8 C8000000     CALL KeygenMe.004025A1                                ;类似strchr 肯定会返回一个地址&const_string[j]
004024D9    BA 890BB7FF     MOV EDX,FFB70B89                                      ;1-0x48f478就是FFB70B89
004024DE    89C1            MOV ECX,EAX                                           
004024E0    01D1            ADD ECX,EDX
004024E2    81C1 4BE40800   ADD ECX,8E44B                                         ; ASCII ".4.42"
执行完这句 ECX的值为j+1,我们看下计算过程: &const_string[j] - 0x48f478 + 0x8E44B + 1
注意下const_string的首地址为0x40102d  计算下会发现0x40102d + 0x8E44B - 0x48f478 = 0 就是const_string首个字符的索引j
再加1  就变为 j+1。。。
004024E8    8D41 FF         LEA EAX,DWORD PTR DS:[ECX-1]                          ;EAX为j
004024EB    0FAFC1          IMUL EAX,ECX                                          ;此时EAX = j * (j + 1)
004024EE    01E8            ADD EAX,EBP                                           ;EBP首次计算为0 
004024F0    99              CDQ
004024F1    F77C24 18       IDIV DWORD PTR SS:[ESP+18]                            ;const_string.length
004024F5    83C4 08         ADD ESP,8
004024F8    B9 06000000     MOV ECX,6
004024FD    42              INC EDX                                              
004024FE    89D5            MOV EBP,EDX                                           ;EBP为(EAX % const_length.length) + 1
00402500    BA 2C104000     MOV EDX,KeygenMe.0040102C                             ;&const_string[-1]                               
00402505    8A042A          MOV AL,BYTE PTR DS:[EDX+EBP]                          ;const_string[x]                
00402508    8807            MOV BYTE PTR DS:[EDI],AL                              ;这里的AL的值已经是正确的serial了只需要每                                                                                     六位添加一个'-'就行了 注意观察EDI
0040250A    51              PUSH ECX
0040250B    31C9            XOR ECX,ECX
0040250D    8A0D 01124000   MOV CL,BYTE PTR DS:[401201]
00402513    80B9 E2114000 2>CMP BYTE PTR DS:[ECX+4011E2],2D
0040251A    75 0C           JNZ SHORT KeygenMe.00402528
0040251C    FE05 01124000   INC BYTE PTR DS:[401201]
00402522    8A0D 01124000   MOV CL,BYTE PTR DS:[401201]
00402528    2A81 E2114000   SUB AL,BYTE PTR DS:[ECX+4011E2]                        ;与填入的伪码比较
0040252E    59              POP ECX
0040252F    E8 A5FEFFFF     CALL KeygenMe.004023D9                                 ;相等则[401201]不变 不等值为-2
00402534    FE05 01124000   INC BYTE PTR DS:[401201]                               ; [401201]++                            
0040253A    89F0            MOV EAX,ESI
0040253C    99              CDQ
0040253D    F7F9            IDIV ECX                                               
0040253F    47              INC EDI
00402540    85D2            TEST EDX,EDX                                           ;检测 (i+1) %6 == 0  
00402542    75 09           JNZ SHORT KeygenMe.0040254D
00402544    83FB 17         CMP EBX,17
00402547    7D 04           JGE SHORT KeygenMe.0040254D
00402549    C607 2D         MOV BYTE PTR DS:[EDI],2D                                ;填充'-'
0040254C    47              INC EDI
0040254D    89F3            MOV EBX,ESI
0040254F    803D 01124000 F>CMP BYTE PTR DS:[401201],0FF
00402556    74 2B           JE SHORT KeygenMe.00402583
00402558    83FB 18         CMP EBX,18
0040255B  ^ 0F8C 61FFFFFF   JL KeygenMe.004024C2
00402561    8B8424 F0000000 MOV EAX,DWORD PTR SS:[ESP+F0]
00402568    C607 00         MOV BYTE PTR DS:[EDI],0
0040256B    8DB424 84000000 LEA ESI,DWORD PTR SS:[ESP+84]
00402572    B8 80104000     MOV EAX,KeygenMe.00401080
00402577    8A16            MOV DL,BYTE PTR DS:[ESI]
00402579    84D2            TEST DL,DL
0040257B    74 06           JE SHORT KeygenMe.00402583
0040257D    8810            MOV BYTE PTR DS:[EAX],DL
0040257F    40              INC EAX
00402580    46              INC ESI
00402581  ^ EB F4           JMP SHORT KeygenMe.00402577
00402583    89F0            MOV EAX,ESI
00402585    56              PUSH ESI
00402586    E8 8C010000     CALL KeygenMe.00402717                                  ;这个CALL是个小ANTI
它会计算原来被清0的返回地址 如果40236c-40257c中被下了断点计算出的 返回地址就是错的  同时还检验serial中'-'位置
0040258B    812D 31124000 A>SUB DWORD PTR DS:[401231],75AB46AE
00402595    8B35 31124000   MOV ESI,DWORD PTR DS:[401231]
0040259B    897424 04       MOV DWORD PTR SS:[ESP+4],ESI
0040259F    5E              POP ESI
004025A0    C3              RETN

=========================================================================================================================
注册机
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>

#define SERIAL_LENGTH 0x18
#define MAX_NAMELENGTH 0x1e+10

void main(int argc, char **argv)
{
  char serial[SERIAL_LENGTH] = {0};
  char name[MAX_NAMELENGTH];
  const char const_string[] = "KYPZAXSFCSNGRQTNWD8592VQWRKH";
  int name_length;
  int cosnt_string_length;
  int i, j;
  int sum = 0;
  printf("please input your name: \n");
  scanf("%s", name);
  fflush(stdout);
  name_length = strlen(name);
  if(name_length > 0x1e)
  {
    printf(" name's length must be less then 0x1e\n");
    goto end;
  }
  cosnt_string_length = strlen(const_string);
  for(i = 0, j = 0; i < name_length; i++)
  {
    name[i] = toupper(name[i]);
    if(NULL != strchr(const_string, name[i]))
    {
      serial[j++] = name[i]; 
    }
  
  }
  memcpy(&serial[j], const_string, SERIAL_LENGTH - strlen(serial));
  for(i = 0; i < SERIAL_LENGTH; i++)
  {
    j = strchr(const_string, serial[i]) - const_string;
    j = (j * (j + 1) + sum)% cosnt_string_length ;
    sum = j + 1;
    serial[i] = const_string[j];
    if(0 == i % 6 && 0 != i)
      printf("-");
    printf("%C", serial[i]);
  }
  printf("\n");
end:  
  getchar();
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (2)
雪    币: 2316
活跃值: (129)
能力值: (RANK:410 )
在线值:
发帖
回帖
粉丝
2
收藏,以后学习。
2008-11-30 19:20
0
雪    币: 2110
活跃值: (21)
能力值: (RANK:260 )
在线值:
发帖
回帖
粉丝
3
楼主过谦了,这个难度还是不低的。
2008-11-30 21:56
0
游客
登录 | 注册 方可回帖
返回
//