首页
社区
课程
招聘
[原创]CrackMe.happytown.VC.0019 算法分析
发表于: 2006-11-20 15:42 5851

[原创]CrackMe.happytown.VC.0019 算法分析

2006-11-20 15:42
5851

【文章标题】: CrackMe.happytown.VC.0019 简单算法分析
【文章作者】: 红尘岁月
【作者邮箱】: butter9999@21cn.com
【软件名称】: CrackMe.happytown.VC.0019
【软件大小】: 56K
【下载地址】: http://bbs.pediy.com/showthread.php?s=&threadid=35158
【加壳方式】: 无
【编写语言】: VC
【使用工具】: OD
【操作平台】: Win9x/NT/2000/XP
【作者声明】: 只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【详细过程】
  0040106D     PUSH 3E9                                           ; /ControlID = 3E9 (1001.)
  00401072     PUSH ESI                                           ; |hWnd
  00401073     CALL DWORD PTR DS:[<&USER32.GetDlgItem>]           ; \GetDlgItem
  00401079     PUSH EAX                                           ; /hWnd
  0040107A     CALL DWORD PTR DS:[<&USER32.SetFocus>]             ; \SetFocus
  00401080     PUSH ESI
  00401081     CALL CrackMe_.00401130                             ;  关键call计算
  00401086     ADD ESP,4
  00401089     TEST EAX,EAX
  0040108B     POP ESI
  0040108C     JE CrackMe_.0040111F                               ;  爆破点
  00401092     PUSH 40                                            ; /Style = MB_OK|MB_ICONASTERISK|MB_APPLMODAL
  00401094     PUSH CrackMe_.004060C4                             ; |Title = "Congratulations"
  00401099     PUSH CrackMe_.004060B4                             ; |Text = "Good job, man!"
  0040109E     PUSH 0                                             ; |hOwner = NULL
  004010A0     CALL DWORD PTR DS:[<&USER32.MessageBoxA>]          ; \MessageBoxA
  004010A6     XOR EAX,EAX
  004010A8     RETN 10
  
  /////////////////////////////////////////////////////////////////////////
  跟进算法Call
  /////////////////////////////////////////////////////////////////////////
  
  
  00401130     SUB ESP,51C
  00401136     PUSH EBX
  00401137     PUSH EBP
  00401138     PUSH ESI
  00401139     PUSH EDI
  0040113A     MOV ECX,7
  0040113F     MOV ESI,CrackMe_.004060D4                          ; mstr1= ASCII "TRADECANMAKEEVERYONEBETTEROFF"
  00401144     LEA EDI,DWORD PTR SS:[ESP+10]
  00401148     XOR EAX,EAX
  0040114A     REP MOVS DWORD PTR ES:[EDI],DWORD PTR DS:[ESI]
  0040114C     MOVS WORD PTR ES:[EDI],WORD PTR DS:[ESI]
  0040114E     MOV ECX,31
  00401153     LEA EDI,DWORD PTR SS:[ESP+F9]
  0040115A     MOV BYTE PTR SS:[ESP+F8],0
  00401162     MOV BYTE PTR SS:[ESP+1C0],0
  0040116A     REP STOS DWORD PTR ES:[EDI]
  0040116C     STOS WORD PTR ES:[EDI]
  0040116E     STOS BYTE PTR ES:[EDI]
  0040116F     MOV ECX,31
  00401174     XOR EAX,EAX
  00401176     LEA EDI,DWORD PTR SS:[ESP+1C1]
  0040117D     MOV BYTE PTR SS:[ESP+288],0
  00401185     REP STOS DWORD PTR ES:[EDI]
  00401187     STOS WORD PTR ES:[EDI]
  00401189     STOS BYTE PTR ES:[EDI]
  0040118A     MOV ECX,0A8
  0040118F     XOR EAX,EAX
  00401191     LEA EDI,DWORD PTR SS:[ESP+289]
  00401198     MOV BYTE PTR SS:[ESP+30],0
  0040119D     REP STOS DWORD PTR ES:[EDI]
  0040119F     STOS WORD PTR ES:[EDI]
  004011A1     STOS BYTE PTR ES:[EDI]
  004011A2     MOV ECX,31
  004011A7     XOR EAX,EAX
  004011A9     LEA EDI,DWORD PTR SS:[ESP+31]
  004011AD     XOR ESI,ESI
  004011AF     REP STOS DWORD PTR ES:[EDI]
  004011B1     STOS WORD PTR ES:[EDI]
  004011B3     STOS BYTE PTR ES:[EDI]
  004011B4     LEA EDI,DWORD PTR SS:[ESP+288]
  004011BB     /XOR ECX,ECX
  004011BD     |/LEA EAX,DWORD PTR DS:[ECX+ESI]
  004011C0     ||MOV EBX,1A
  004011C5     ||CDQ
  004011C6     ||IDIV EBX
  004011C8     ||ADD DL,41
  004011CB     ||MOV BYTE PTR DS:[EDI+ECX],DL
  004011CE     ||INC ECX
  004011CF     ||CMP ECX,EBX
  004011D1     |\JL SHORT CrackMe_.004011BD
  004011D3     |INC ESI
  004011D4     |ADD EDI,EBX
  004011D6     |CMP ESI,EBX
  004011D8     \JL SHORT CrackMe_.004011BB
  004011DA     MOV EBP,DWORD PTR SS:[ESP+530]
  004011E1     LEA EAX,DWORD PTR SS:[ESP+F8]
  
  上面是这些是为计算做准备,初始化一些内存
  
  004011E8     PUSH 0C9                                           ; /Count = C9 (201.)
  004011ED     PUSH EAX                                           ; |Buffer
  004011EE     PUSH 3E8                                           ; |ControlID = 3E8 (1000.)
  004011F3     PUSH EBP                                           ; |hWnd
  004011F4     CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>]      ; \GetDlgItemTextA
  004011FA     MOV ESI,EAX
  004011FC     CMP ESI,4                                          ;  用户名长度必须nlen>=4
  004011FF     JL CrackMe_.00401305
  00401205     CMP ESI,0F
  00401208     JG CrackMe_.00401305                               ;  用户名长度必须nlen<16
  0040120E     LEA ECX,DWORD PTR SS:[ESP+F8]                      ;  name
  00401215     PUSH ESI                                           ;  nlen
  00401216     PUSH ECX
  00401217     CALL CrackMe_.00401320                             ;  算法call2:必须为字符且做小写转为大写
  0040121C     ADD ESP,8
  0040121F     TEST EAX,EAX
  00401221     JE CrackMe_.00401305
  00401227     MOV EAX,1D
  0040122C     CDQ
  0040122D     IDIV ESI
  0040122F     TEST EAX,EAX                                       ;  A=0x1d/nlen,B=0x1d%nlen
  00401231     JLE SHORT CrackMe_.0040124D
  00401233     MOV EDI,DWORD PTR DS:[<&KERNEL32.lstrcatA>]        ;  kernel32.lstrcatA
  00401239     MOV ESI,EAX
  0040123B     /LEA EDX,DWORD PTR SS:[ESP+F8]                     ;  新的用户名newname=重复name字符串A次
  00401242     |LEA EAX,DWORD PTR SS:[ESP+30]
  00401246     |PUSH EDX
  00401247     |PUSH EAX
  00401248     |CALL EDI
  0040124A     |DEC ESI
  0040124B     \JNZ SHORT CrackMe_.0040123B
  0040124D     MOV EBX,DWORD PTR DS:[<&KERNEL32.lstrlenA>]        ;  kernel32.lstrlenA
  00401253     LEA ECX,DWORD PTR SS:[ESP+30]
  00401257     PUSH ECX                                           ; /String
  00401258     CALL EBX                                           ; \lstrlenA
  0040125A     MOV ESI,1D
  0040125F     XOR EDI,EDI
  00401261     SUB ESI,EAX
  00401263     TEST ESI,ESI
  00401265     JLE SHORT CrackMe_.0040127E
  00401267     /LEA EDX,DWORD PTR SS:[ESP+30]                     ;  newname后再加上name前B个字符
  0040126B     |PUSH EDX
  0040126C     |CALL EBX                                          ;  lstrlenA
  0040126E     |MOV CL,BYTE PTR SS:[ESP+EDI+F8]
  00401275     |INC EDI
  00401276     |CMP EDI,ESI
  00401278     |MOV BYTE PTR SS:[ESP+EAX+30],CL
  0040127C     \JL SHORT CrackMe_.00401267
  0040127E     LEA EDX,DWORD PTR SS:[ESP+1C0]
  00401285     PUSH 0C9                                           ; /Count = C9 (201.)
  0040128A     PUSH EDX                                           ; |Buffer
  0040128B     PUSH 3E9                                           ; |ControlID = 3E9 (1001.)
  00401290     PUSH EBP                                           ; |hWnd
  00401291     CALL DWORD PTR DS:[<&USER32.GetDlgItemTextA>]      ; \GetDlgItemTextA
  00401297     CMP EAX,1D
  0040129A     JNZ SHORT CrackMe_.00401305                        ;  注册码长度klen=29
  0040129C     PUSH EAX
  0040129D     LEA EAX,DWORD PTR SS:[ESP+1C4]
  004012A4     PUSH EAX
  004012A5     CALL CrackMe_.00401320                             ;  算法call2:必须为字符且做小写转为大写
  004012AA     ADD ESP,8
  004012AD     TEST EAX,EAX
  004012AF     JE SHORT CrackMe_.00401305
  004012B1     XOR EDX,EDX
  004012B3     /MOV AL,BYTE PTR SS:[ESP+EDX+30]                   ;  newname[i]
  004012B7     |SUB AL,41                                         ;  A=newname[i]-0x41
  004012B9     |XOR ECX,ECX                                       ;  ione=0
  004012BB     |MOVSX EAX,AL
  004012BE     |LEA ESI,DWORD PTR DS:[EAX+EAX*2]                  ;  B=3A
  004012C1     |LEA EAX,DWORD PTR DS:[EAX+ESI*4]                  ;  C=13A
  004012C4     |LEA ESI,DWORD PTR SS:[ESP+EAX*2+288]              ;  D=esp+26A+0x288  ,在esp+0x288处有大量字符串,设为mstr3
  004012CB     |MOV AL,BYTE PTR SS:[ESP+EDX+1C0]                  ;  key[i] ,key为用户输入的注册码
  004012D2     |/CMP AL,BYTE PTR DS:[ESI+ECX]                     ;  用key[i]与mstr3[D+ione]比较
  004012D5     ||JNZ SHORT CrackMe_.004012E9
  004012D7     ||MOV BL,BYTE PTR SS:[ESP+EDX+10]                  ;  mstr1[i] ,mstr1= ASCII "TRADECANMAKEEVERYONEBETTEROFF"
  004012DB     ||CMP BL,BYTE PTR SS:[ESP+ECX+288]                 ;  mstr3[ione],实际只用了前26个字母,可新设mstr2[30]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
  004012E2     ||JNZ SHORT CrackMe_.00401305                      ;必须相等
  004012E4     ||MOV ECX,1D
  004012E9     ||INC ECX                                          ;ione++
  004012EA     ||CMP ECX,1D                                       ;ione是否小于29
  004012ED     |\JL SHORT CrackMe_.004012D2
  004012EF     |INC EDX
  004012F0     |CMP EDX,1D
  004012F3     \JL SHORT CrackMe_.004012B3
  004012F5     POP EDI
  004012F6     POP ESI
  004012F7     POP EBP
  004012F8     MOV EAX,1
  004012FD     POP EBX
  004012FE     ADD ESP,51C
  00401304     RETN
  
  
  /////////////////////////////////////////////////////////////////////////
  算法call2:必须为字符且做小写转为大写
  /////////////////////////////////////////////////////////////////////////
  00401320     PUSH EBX
  00401321     MOV EBX,DWORD PTR SS:[ESP+C]
  00401325     PUSH ESI
  00401326     XOR ESI,ESI                                        ;  参数2
  00401328     TEST EBX,EBX
  0040132A     PUSH EDI
  0040132B     JLE SHORT CrackMe_.0040137A
  0040132D     MOV EDI,DWORD PTR SS:[ESP+10]                      ;  参数1
  00401331     /CMP DWORD PTR DS:[406300],1
  00401338     |JLE SHORT CrackMe_.0040134E
  0040133A     |MOVSX EAX,BYTE PTR DS:[ESI+EDI]                   ;  
  0040133E     |PUSH 103
  00401343     |PUSH EAX
  00401344     |CALL CrackMe_.0040145C
  00401349     |ADD ESP,8
  0040134C     |JMP SHORT CrackMe_.00401361
  0040134E     |MOVSX ECX,BYTE PTR DS:[ESI+EDI]                   ;  
  00401352     |MOV EDX,DWORD PTR DS:[4060F4]                     ;  CrackMe_.004060FE
  00401358     |MOV AX,WORD PTR DS:[EDX+ECX*2]
  0040135C     |AND EAX,103
  00401361     |TEST EAX,EAX
  00401363     |JE SHORT CrackMe_.00401383                        ;  不能为数字
  00401365     |MOVSX EAX,BYTE PTR DS:[ESI+EDI]
  00401369     |PUSH EAX
  0040136A     |CALL CrackMe_.00401390                            ;  小写转为大写
  0040136F     |ADD ESP,4
  00401372     |MOV BYTE PTR DS:[ESI+EDI],AL
  00401375     |INC ESI
  00401376     |CMP ESI,EBX
  00401378     \JL SHORT CrackMe_.00401331
  0040137A     POP EDI
  0040137B     POP ESI
  0040137C     MOV EAX,1
  00401381     POP EBX
  00401382     RETN
  
  
  /////////////////////////////////////////////////////////////////////////
  /////////////////////////////////////////////////////////////////////////
  
  算法总结:
  
  1) 用户名必须大于3小于16,注册码必须为29位,注册码应该不能为数字吧.
  
  2) 用户名循环填充到29位
  
  3) 先用[newname[i]-0x41]*26算去基地址D
  
  4) 再用mstr1[i]在mstr2中找到第二个地址ione
  
  5) D+ione就是key[i]在mstr3中的位置
  
  
  代码如下:
  
  void CCrackme_hxd001Dlg::OnOK()
  {
          // TODO: Add extra validation here
          char name[20];
          int nlen;
          nlen=GetDlgItemText(IDC_EDIT1,name,20);
          if(nlen<4||nlen>16)
          {
                  MessageBox("用户名大于4小于16!");
                  return ;
          }
  
  //初始化
          char key[30]="";
          char newname[30];
          char mstr1[30]="TRADECANMAKEEVERYONEBETTEROFF";
          char mstr2[30]="ABCDEFGHIJKLMNOPQRSTUVWXYZ";
          char mstr3[677]="ABCDEFGHIJKLMNOPQRSTUVWXYZBCDEFGHIJKLMNOPQRSTUVWXY\
  ZACDEFGHIJKLMNOPQRSTUVWXYZABDEFGHIJKLMNOPQRSTUVWXY\
  ZABCEFGHIJKLMNOPQRSTUVWXYZABCDFGHIJKLMNOPQRSTUVWXY\
  ZABCDEGHIJKLMNOPQRSTUVWXYZABCDEFHIJKLMNOPQRSTUVWXY\
  ZABCDEFGIJKLMNOPQRSTUVWXYZABCDEFGHJKLMNOPQRSTUVWXY\
  ZABCDEFGHIKLMNOPQRSTUVWXYZABCDEFGHIJLMNOPQRSTUVWXY\
  ZABCDEFGHIJKMNOPQRSTUVWXYZABCDEFGHIJKLNOPQRSTUVWXY\
  ZABCDEFGHIJKLMOPQRSTUVWXYZABCDEFGHIJKLMNPQRSTUVWXY\
  ZABCDEFGHIJKLMNOQRSTUVWXYZABCDEFGHIJKLMNOPRSTUVWXY\
  ZABCDEFGHIJKLMNOPQSTUVWXYZABCDEFGHIJKLMNOPQRTUVWXY\
  ZABCDEFGHIJKLMNOPQRSUVWXYZABCDEFGHIJKLMNOPQRSTVWXY\
  ZABCDEFGHIJKLMNOPQRSTUWXYZABCDEFGHIJKLMNOPQRSTUVXY\
  ZABCDEFGHIJKLMNOPQRSTUVWYZABCDEFGHIJKLMNOPQRSTUVWX\
  ZABCDEFGHIJKLMNOPQRSTUVWXY";
  
          int i,m,ione;
          for(i=0;i<29;i++)
          {
                  m=i%nlen;
                  newname[i]=name[m];
          }
          newname[29]='\0';
          strupr(newname);
  
          for(i=0;i<29;i++)
          {
                  m=newname[i]-0x41;
                  ione=0;
                  while(mstr1[i]!=mstr2[ione])ione++;
                  ione=26*m+ione;
                  key[i]=mstr3[ione];
          }
  
          key[i]='\0';
  
          SetDlgItemText(IDC_EDIT2,key);
  
  }
  
例如:
用户名:ccbhcsy
注册码:VTBKGUYPOBRGWTGTZVPWZGVULTGDH
  
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!

                                                       2006年11月20日 15:40:49


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

收藏
免费 7
支持
分享
最新回复 (1)
雪    币: 200
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
/*
//
2006-11-23 18:13
0
游客
登录 | 注册 方可回帖
返回
//