zxcasd2131s 发表于 2015-11-24 17:42

一个简单的CrackMe练习

本帖最后由 zxcasd2131s 于 2015-11-24 17:44 编辑

软件很小,通过单步也能很快找到DialogFun,然后找COMMAND消息处理,也可以通过GetDlgItemText找到关键点。
seg000:00401305 ; int __cdecl sub_401305(HWND, int, int)
seg000:00401305 sub_401305 proc near                  ; CODE XREF: AAAAAAAAAAAAAAAAAAAAA+80p
seg000:00401305
seg000:00401305 var_szFmt2= byte ptr -42Ah
seg000:00401305 var_szFmt1= byte ptr -424h
seg000:00401305 var_szFmtBuff= byte ptr -41Fh
seg000:00401305 szPassWord= byte ptr -31Fh
seg000:00401305 var_szFmtBuffLast= byte ptr -21Fh
seg000:00401305 var_szTable= byte ptr -11Fh
seg000:00401305 var_104 = byte ptr -104h
seg000:00401305 var_UserNameAddSum= dword ptr -4
seg000:00401305 arg_hDlg= dword ptr8
seg000:00401305 arg_nUserNameLength= dword ptr0Ch
seg000:00401305 arg_strUsername= dword ptr10h
seg000:00401305
seg000:00401305         push    ebp
seg000:00401306         mov   ebp, esp
seg000:00401308         sub   esp, 42Ch
seg000:0040130E         push    ebx
seg000:0040130F         push    esi
seg000:00401310         push    edi
seg000:00401311         lea   edi,
seg000:00401317         lea   esi, unk_402038
seg000:0040131D         mov   ecx, 40h
seg000:00401322         rep movsd
seg000:00401324         lea   edi,
seg000:0040132A         lea   esi, unk_402138
seg000:00401330         mov   ecx, 40h
seg000:00401335         rep movsd
seg000:00401337         lea   edi,
seg000:0040133D         lea   esi, unk_402238
seg000:00401343         mov   ecx, 40h
seg000:00401348         rep movsd
seg000:0040134A         lea   edi,
seg000:00401350         lea   esi, unk_402338
seg000:00401356         mov   ecx, 40h
seg000:0040135B         rep movsd
seg000:0040135D         lea   edi,
seg000:00401363         lea   esi, aCS                ; "%c%s"
seg000:00401369         mov   ecx, 5
seg000:0040136E         rep movsb
seg000:00401370         lea   edi,
seg000:00401376         lea   esi, aSD                ; "%s-%d"
seg000:0040137C         mov   ecx, 3
seg000:00401381         rep movsw
seg000:00401384         lea   edi,
seg000:0040138A         lea   esi, aAbcdefghijklmn    ; "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
seg000:00401390         mov   ecx, 1Bh
seg000:00401395         rep movsb
seg000:00401397         mov   , 0
seg000:0040139E         push    100h                  ; cchMax
seg000:004013A3         lea   eax,
seg000:004013A9         push    eax                     ; lpString
seg000:004013AA         push    66h                     ; nIDDlgItem
seg000:004013AC         push              ; hDlg
seg000:004013AF         call    GetDlgItemTextA
seg000:004013B4         or      eax, eax
seg000:004013B6         jz      FUN_END
seg000:004013BC         mov   eax, 11CFh
seg000:004013C1         movzx   ecx,
seg000:004013C8         cdq
seg000:004013C9         idiv    ecx                     ; 0x11CF / password的第一位 高位必须等于0x17
seg000:004013CB         cmp   edx, 17h
seg000:004013CE         jz      short loc_4013D7      ; 循环计数
seg000:004013D0         xor   eax, eax
seg000:004013D2         jmp   FUN_END
seg000:004013D7 ; ---------------------------------------------------------------------------
seg000:004013D7
seg000:004013D7 loc_4013D7:                           ; CODE XREF: sub_401305+C9j
seg000:004013D7         xor   ebx, ebx                ; 循环计数
seg000:004013D9         jmp   short loc_4013E6      ; 用户名长度
seg000:004013DB ; ---------------------------------------------------------------------------
seg000:004013DB
seg000:004013DB loc_4013DB:                           ; CODE XREF: sub_401305+E4j
seg000:004013DB         mov   eax,
seg000:004013DE         movsx   eax, byte ptr ; 循环取用户名中的1字节,带符号扩展
seg000:004013E2         add   , eax ; 用户名按位的累加和
seg000:004013E5         inc   ebx
seg000:004013E6
seg000:004013E6 loc_4013E6:                           ; CODE XREF: sub_401305+D4j
seg000:004013E6         cmp   ebx, ; 用户名长度
seg000:004013E9         jl      short loc_4013DB
seg000:004013EB         xor   ebx, ebx                ; 循环计数
seg000:004013ED         jmp   loc_401475            ; 用户名长度
seg000:004013F2 ; ---------------------------------------------------------------------------
seg000:004013F2
seg000:004013F2 loc_4013F2:                           ; CODE XREF: sub_401305+173j
seg000:004013F2         mov   edx,
seg000:004013F5         movsx   edi, byte ptr ; 循环取用户名中的1字节,带符号扩展
seg000:004013F9         mov   esi, ; 用户名累加和
seg000:004013FC         mov   ecx, ebx
seg000:004013FE         shl   ecx, 2                  ; 当前的循环计数 * 4
seg000:00401401         mov   edx, ebx
seg000:00401403         inc   edx                     ; 当前的循环计数 + 1
seg000:00401404         sub   ecx, edx
seg000:00401406         movzx   ecx, ; 结果查表,无符号扩展取1字节
seg000:0040140E         mov   edx, edi
seg000:00401410         xor   edx, ecx                ; 与当前用户名的1字节异或
seg000:00401412         mov   ecx, esi
seg000:00401414         imul    ecx, ebx
seg000:00401417         sub   ecx, esi
seg000:00401419         mov   esi, ecx                ; 用户名累加和 = 用户名累加和 * 当前的循环计数 - 用户名累加和
seg000:0040141B         xor   esi, 0FFFFFFFFh         ; 异或全f
seg000:0040141E         lea   esi,
seg000:00401425         mov   ecx, ; 用户名长度
seg000:00401428         mov   edx, ebx
seg000:0040142A         add   edx, 3                  ; 当前循环计数 + 3
seg000:0040142D         imul    ecx, edx
seg000:00401430         imul    ecx, edi                ; 用户名长度 * (当前循环计数 + 3) * 当前用户名1字节
seg000:00401433         mov   eax, esi
seg000:00401435         add   eax, ecx
seg000:00401437         mov   ecx, 0Ah
seg000:0040143C         xor   edx, edx
seg000:0040143E         div   ecx
seg000:00401440         add   edx, 30h                ; 余数 + 0x30
seg000:00401443         mov   , dl
seg000:0040144A         movzx   edi,
seg000:00401452         xor   edi, 0ADACh
seg000:00401458         mov   esi, ebx
seg000:0040145A         add   esi, 2
seg000:0040145D         mov   eax, edi
seg000:0040145F         imul    eax, esi
seg000:00401462         mov   ecx, 0Ah
seg000:00401467         cdq
seg000:00401468         idiv    ecx
seg000:0040146A         add   edx, 30h                ; ; 余数 + 0x30
seg000:0040146D         mov   , dl
seg000:00401474         inc   ebx
seg000:00401475
seg000:00401475 loc_401475:                           ; CODE XREF: sub_401305+E8j
seg000:00401475         cmp   ebx, ; 用户名长度
seg000:00401478         jl      loc_4013F2
seg000:0040147E         lea   eax,
seg000:00401484         push    eax
seg000:00401485         push    54h
seg000:00401487         lea   eax,
seg000:0040148D         push    eax                     ; LPCSTR
seg000:0040148E         lea   eax,
seg000:00401494         push    eax                     ; LPSTR
seg000:00401495         call    wsprintfA               ; Txxxxxx
seg000:0040149A         mov   edi,
seg000:0040149D         mov   eax, edi
seg000:0040149F         imul    eax,
seg000:004014A3         mov   ecx, 64h
seg000:004014A8         cdq
seg000:004014A9         idiv    ecx
seg000:004014AB         mov   edi, edx
seg000:004014AD         add   edi, 30h
seg000:004014B0         push    edi
seg000:004014B1         lea   edi,
seg000:004014B7         push    edi
seg000:004014B8         lea   edi,
seg000:004014BE         push    edi                     ; LPCSTR
seg000:004014BF         lea   edi,
seg000:004014C5         push    edi                     ; LPSTR
seg000:004014C6         call    wsprintfA
seg000:004014CB         add   esp, 20h
seg000:004014CE         lea   ecx,
seg000:004014D4         or      eax, 0FFFFFFFFh
seg000:004014D7
seg000:004014D7 loc_4014D7:                           ; CODE XREF: sub_401305+1D7j
seg000:004014D7         inc   eax
seg000:004014D8         cmp   byte ptr , 0
seg000:004014DC         jnz   short loc_4014D7
seg000:004014DE         push    eax                     ; 长度
seg000:004014DF         lea   eax,    ; 用户输入的密码
seg000:004014E5         push    eax
seg000:004014E6         lea   eax, ; 算法算出的字符串
seg000:004014EC         push    eax
seg000:004014ED         call    sub_4012C2            ; 最后一层
seg000:004014F2         add   esp, 0Ch
seg000:004014F5         cmp   eax, 0
seg000:004014F8         jnz   short loc_401501
seg000:004014FA         mov   eax, 0
seg000:004014FF         jmp   short FUN_END
seg000:00401501 ; ---------------------------------------------------------------------------
seg000:00401501
seg000:00401501 loc_401501:                           ; CODE XREF: sub_401305+1F3j
seg000:00401501         xor   eax, eax
seg000:00401503         inc   eax
seg000:00401504
seg000:00401504 FUN_END:                              ; CODE XREF: sub_401305+B1j
seg000:00401504                                       ; sub_401305+CDj ...
seg000:00401504         pop   edi
seg000:00401505         pop   esi
seg000:00401506         pop   ebx
seg000:00401507         leave
seg000:00401508         retn
seg000:00401508 sub_401305 endp

seg000:004012C2 sub_4012C2 proc near                  ; CODE XREF: sub_401305+1E8p
seg000:004012C2
seg000:004012C2 arg_Pass1= dword ptr8
seg000:004012C2 arg_Pass2= dword ptr0Ch
seg000:004012C2 arg_Pass1Length= dword ptr10h
seg000:004012C2
seg000:004012C2         push    ebp
seg000:004012C3         mov   ebp, esp
seg000:004012C5         push    ebx
seg000:004012C6         push    esi
seg000:004012C7         push    edi
seg000:004012C8         mov   ebx,
seg000:004012CB         xor   esi, esi
seg000:004012CD         inc   esi                     ; 循环基址
seg000:004012CE         jmp   short loc_4012F9
seg000:004012D0 ; ---------------------------------------------------------------------------
seg000:004012D0
seg000:004012D0 loc_4012D0:                           ; CODE XREF: sub_4012C2+39j
seg000:004012D0         mov   edx,
seg000:004012D3         movsx   edi, byte ptr
seg000:004012D7         mov   eax, edi
seg000:004012D9         xor   eax, 20h
seg000:004012DC         mov   ecx, 0Ah
seg000:004012E1         cdq
seg000:004012E2         idiv    ecx
seg000:004012E4         mov   edi, edx
seg000:004012E6         add   edi, 30h
seg000:004012E9         mov   edx,
seg000:004012EC         movsx   edx, byte ptr
seg000:004012F0         cmp   edi, edx                ; 用户输入的密码与算法算出的字符串
seg000:004012F2         jz      short loc_4012F8      ; 按位异或0x20然后 % 0xA,余数 + 0x30比较是否相等
seg000:004012F4         xor   eax, eax                ; 不相等,eax清0返回
seg000:004012F6         jmp   short loc_401300
seg000:004012F8 ; ---------------------------------------------------------------------------
seg000:004012F8
seg000:004012F8 loc_4012F8:                           ; CODE XREF: sub_4012C2+30j
seg000:004012F8         inc   esi
seg000:004012F9
seg000:004012F9 loc_4012F9:                           ; CODE XREF: sub_4012C2+Cj
seg000:004012F9         cmp   esi, ebx
seg000:004012FB         jl      short loc_4012D0
seg000:004012FD         xor   eax, eax
seg000:004012FF         inc   eax
seg000:00401300
seg000:00401300 loc_401300:                           ; CODE XREF: sub_4012C2+34j
seg000:00401300         pop   edi
seg000:00401301         pop   esi
seg000:00401302         pop   ebx
seg000:00401303         pop   ebp
seg000:00401304         retn
seg000:00401304 sub_4012C2 endp

最后算法注册机:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <windows.h>

int main(int argc, char* argv[])
{
      char szUserName = {0};
      int nLength = 0;
      char szTable[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
      char szPassWord = {0};

      printf("Input UserName: ");
      scanf("%63s", szUserName);
      nLength = strlen(szUserName);
      if (nLength == 0)
      {
                return 0;
      }

      int nEsi = 0x30 - (0x48 / nLength);
      nEsi = nEsi + nEsi * 4;

      int nEdi = ((0x2BC - nEsi) * 0x6B) - 0x0CF6C;
      if ((nEdi <= 0x2300) && (nEdi >= 0x190))
      {
                int nUserNameSum = 0;
                int nTempNameSum = 0;
                int i = 0;
                //char ch = 0;
                int nIndex = 0;
                //BYTE bData = 0;
                char szBuff = {0};

                for (i = 0; i < nLength; i++)
                {
                        nUserNameSum += szUserName;
                }

                for (i = 0; i < nLength; i++)
                {
                        nTempNameSum = nUserNameSum;
                        //ch = szUserName;
                        nIndex = i * 4 - (i + 1);
                        //bData = szTable;
                        nTempNameSum = static_cast<DWORD>((nTempNameSum * i - nTempNameSum) ^ 0x0FFFFFFFF) + 0x14D + (szUserName ^ (nIndex == -1 ? 0 : szTable));
                        szBuff = static_cast<char>(static_cast<DWORD>((((nLength * (i + 3)) * szUserName) + nTempNameSum)) % 0x0A) + 0x30;
                        szBuff = static_cast<char>(((static_cast<DWORD>(szBuff)) ^ 0x0ADAC) * (i + 2) % 0x0A) + 0x30;
                }

                wsprintf(szPassWord, "%c%s", 'T', szBuff);
                wsprintf(szPassWord, "%s-%d", szPassWord, ((nLength * nUserNameSum) % 0x64) + 0x30);

                for (i = 0; i < static_cast<int>(strlen(szPassWord)); i++)
                {
                        szPassWord = ((szPassWord ^ 0x20) % 0x0A) + 0x30;
                }

                printf("PassWord: %s\r\n", szPassWord);
      }
      else
      {
                printf("Input UserName Error!\r\n");
      }

      system("pause");
      return 0;
}


附件传上来,方便新手朋友练手。

2909094965 发表于 2015-11-24 18:15

看不懂,谢谢分享

laozhangty 发表于 2015-11-24 18:49

多谢分享

Wings_翅膀 发表于 2015-12-2 14:55

下载试试,谢谢楼主分享

Wings_翅膀 发表于 2015-12-2 16:38

试了试,注册名的算法没有跟完,就没有做注册机。直接根据注册名,把注册码跟出来了,跟到明码需要转换一下,我就跟到这里了。提供一组注册码
注册名:82345
注册码:T49012314
效果图:
页: [1]
查看完整版本: 一个简单的CrackMe练习