zoukankan      html  css  js  c++  java
  • 一个有趣的CM

    系统 : Windows xp

    程序 : Crackme#3 - Self Destructed

    程序下载地址 :http://pan.baidu.com/s/1kVxwlaZ

    要求 : 注册机编写 

    使用工具 : OD

    可在“PEDIY CrackMe 2007”中查找关于此程序的讨论,标题为“适合新手的D4ph1_-_Crackme#3的破解”。

    利用超级字符串插件看下程序内的文本:

    Ultra String Reference
    Address    Disassembly                               Text String
    00401000   mov     esi, dword ptr [esp]              (initial cpu selection)
    00401068   push    0040313A                          kernel32.dll
    00401229   push    00403147                          eraser.bat
    00401255   push    00403147                          eraser.bat
    0040125C   push    00403153                          :loop
    
    del "%s"
    
    if exist "%s" goto loop
    
    del "%s"
    00401289   push    00403000                          crackme#3 by d4ph1
    0040128E   push    00403186                          debugger found...i think im gonna kill myself!:(
    004012A0   push    00403147                          eraser.bat
    00401346   push    00403000                          crackme#3 by d4ph1
    0040134B   push    00403013                          *======== your target is to create a valid keygenerator.contact : fistiks16@hotmail.com ========*
    004014AB   push    00403000                          crackme#3 by d4ph1
    004014B0   push    004030E0                          great work!hope this is coming from your keygenerator!:)
    004014C0   push    00403000                          crackme#3 by d4ph1
    004014C5   push    00403119                          this is not the right serial...
    004014D5   push    00403000                          crackme#3 by d4ph1
    004014DA   push    004030BB                          you have to write a serial first...!
    004014F3   push    00403000                          crackme#3 by d4ph1
    004014F8   push    00403098                          you have to write a name first...!
    00401508   push    00403000                          crackme#3 by d4ph1
    0040150D   push    00403075                          the name you write is not correct!

    好像检索出了什么不得了的内容,双击debugger found...i think im gonna kill myself!:( 查看引用位置:

    004011F3  /$  68 D1314000   push    004031D1                         ; /isdebuggerpresent
    004011F8  |.  FF35 F0344000 push    dword ptr [4034F0]               ; |hModule = NULL
    004011FE  |.  E8 8B030000   call    <jmp.&kernel32.GetProcAddress>   ; GetProcAddress
    00401203  |.  FFD0          call    eax
    00401205  |.  0BC0          or      eax, eax
    00401207  |.  75 0C         jnz     short 00401215
    00401209  |.  8A1D 07124000 mov     bl, byte ptr [401207]
    0040120F  |.  80FB 75       cmp     bl, 75
    00401212  |.  75 03         jnz     short 00401217
    00401214  |.  C3            retn
    00401215  |>  EB 00         jmp     short 00401217
    00401217  |>  6A 00         push    0                                ; /hTemplateFile = NULL
    00401219  |.  68 80000000   push    80                               ; |Attributes = NORMAL
    0040121E  |.  6A 02         push    2                                ; |Mode = CREATE_ALWAYS
    00401220  |.  6A 00         push    0                                ; |pSecurity = NULL
    00401222  |.  6A 00         push    0                                ; |ShareMode = 0
    00401224  |.  68 00000040   push    40000000                         ; |Access = GENERIC_WRITE
    00401229  |.  68 47314000   push    00403147                         ; |eraser.bat
    0040122E  |.  E8 37030000   call    <jmp.&kernel32.CreateFileA>      ; CreateFileA
    00401233  |.  8BD8          mov     ebx, eax
    00401235  |.  8D35 0A394000 lea     esi, dword ptr [40390A]
    0040123B  |.  68 04010000   push    104                              ; /BufSize = 104 (260.)
    00401240  |.  56            push    esi                              ; |PathBuffer => Crackme#.0040390A
    00401241  |.  6A 00         push    0                                ; |hModule = NULL
    00401243  |.  E8 3A030000   call    <jmp.&kernel32.GetModuleFileName>; GetModuleFileNameA
    00401248  |.  56            push    esi                              ; /pDest => Crackme#.0040390A
    00401249  |.  56            push    esi                              ; |pSrc => ""
    0040124A  |.  E8 E5020000   call    <jmp.&user32.CharToOemA>         ; CharToOemA
    0040124F  |.  8D3D 0A354000 lea     edi, dword ptr [40350A]
    00401255  |.  68 47314000   push    00403147                         ; /eraser.bat
    0040125A  |.  56            push    esi                              ; |<%s> => ""
    0040125B  |.  56            push    esi                              ; |<%s> => ""
    0040125C  |.  68 53314000   push    00403153                         ; |:loop
    
    del "%s"
    
    if exist "%s" goto loop
    
    del "%s"
    00401261  |.  57            push    edi                              ; |s => Crackme#.0040350A
    00401262  |.  E8 C7020000   call    <jmp.&user32.wsprintfA>          ; wsprintfA
    00401267  |.  83C4 14       add     esp, 14
    0040126A  |.  57            push    edi                              ; /String
    0040126B  |.  E8 3C030000   call    <jmp.&kernel32.lstrlenA>         ; lstrlenA
    00401270  |.  8D15 0E3A4000 lea     edx, dword ptr [403A0E]
    00401276  |.  6A 00         push    0                                ; /pOverlapped = NULL
    00401278  |.  52            push    edx                              ; |pBytesWritten => Crackme#.00403A0E
    00401279  |.  50            push    eax                              ; |nBytesToWrite
    0040127A  |.  57            push    edi                              ; |Buffer
    0040127B  |.  53            push    ebx                              ; |hFile
    0040127C  |.  E8 25030000   call    <jmp.&kernel32.WriteFile>        ; WriteFile
    00401281  |.  53            push    ebx                              ; /hObject
    00401282  |.  E8 DD020000   call    <jmp.&kernel32.CloseHandle>      ; CloseHandle
    00401287  |.  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
    00401289  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    0040128E  |.  68 86314000   push    00403186                         ; |debugger found...i think im gonna kill myself!:(
    00401293  |.  6A 00         push    0                                ; |hOwner = NULL
    00401295  |.  E8 B2020000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    0040129A  |.  6A 00         push    0                                ; /IsShown = 0
    0040129C  |.  6A 00         push    0                                ; |DefDir = NULL
    0040129E  |.  6A 00         push    0                                ; |Parameters = NULL
    004012A0  |.  68 47314000   push    00403147                         ; |eraser.bat
    004012A5  |.  6A 00         push    0                                ; |Operation = NULL
    004012A7  |.  6A 00         push    0                                ; |hWnd = NULL
    004012A9  |.  E8 04030000   call    <jmp.&shell32.ShellExecuteA>     ; ShellExecuteA
    004012AE  |.  6A 00         push    0                                ; /ExitCode = 0
    004012B0  .  E8 BB020000   call    <jmp.&kernel32.ExitProcess>      ; ExitProcess

    程序启动时利用WINAPI 查看是否被调试,如果被调试则创建批处理文件:

    :LOOP
    DEL "D:IT逆向工程CrackMecrackme3selfdestructedCrackme#3 - Self Destructed.exe"
    IF EXIST "D:IT逆向工程CrackMecrackme3selfdestructedCrackme#3 - Self Destructed.exe" GOTO LOOP
    DEL "ERASER.BAT"

    启动批处理开始循环删除之后,退出程序。批处理删除源程序之后,再删除自身。很有想法的一个反调试机制。

    再来看看算法部分:

    00401366  |.  68 EC314000   push    004031EC                         ; /123
    0040136B  |.  68 80000000   push    80                               ; |wParam = 80
    00401370  |.  6A 0D         push    0D                               ; |Message = WM_GETTEXT
    00401372  |.  68 EA030000   push    3EA                              ; |ControlID = 3EA (1002.)
    00401377  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
    0040137A  |.  E8 D9010000   call    <jmp.&user32.SendDlgItemMessageA>; SendDlgItemMessageA
    0040137F  |.  A3 6C324000   mov     dword ptr [40326C], eax
    00401384  |.  83F8 04       cmp     eax, 4                           ;  长度低于等于4?
    00401387  |.  0F86 60010000 jbe     004014ED                         ;  是则报错
    0040138D  |.  83F8 14       cmp     eax, 14                          ;  长度高于等于14?
    00401390  |.  0F83 57010000 jnb     004014ED                         ;  是则报错
    00401396  |.  68 70324000   push    00403270                         ; /lParam = 403270
    0040139B  |.  68 00010000   push    100                              ; |wParam = 100
    004013A0  |.  6A 0D         push    0D                               ; |Message = WM_GETTEXT
    004013A2  |.  68 EB030000   push    3EB                              ; |ControlID = 3EB (1003.)
    004013A7  |.  FF75 08       push    dword ptr [ebp+8]                ; |hWnd
    004013AA  |.  E8 A9010000   call    <jmp.&user32.SendDlgItemMessageA>; SendDlgItemMessageA
    004013AF  |.  83F8 00       cmp     eax, 0                           ;  长度为0则报错
    004013B2  |.  0F84 1B010000 je      004014D3
    004013B8  |.  33C9          xor     ecx, ecx                         ;  开始初始化
    004013BA  |.  49            dec     ecx
    004013BB  |.  33D2          xor     edx, edx
    004013BD  |.  4A            dec     edx
    004013BE  |.  33F6          xor     esi, esi
    004013C0  |.  4E            dec     esi
    004013C1  |.  33C0          xor     eax, eax
    004013C3  |.  A1 6C324000   mov     eax, dword ptr [40326C]          ;  载入用户名长度
    004013C8  |.  48            dec     eax
    004013C9  |.  50            push    eax
    004013CA  |>  46            /inc     esi
    004013CB  |.  41            |inc     ecx
    004013CC  |.  0FBE81 F03440>|movsx   eax, byte ptr [ecx+4034F0]      ;  遍历一个特定字符串
    004013D3  |.  0FBE9E EC3140>|movsx   ebx, byte ptr [esi+4031EC]      ;  遍历用户名字符串
    004013DA  |.  83F0 12       |xor     eax, 12
    004013DD  |.  83C0 34       |add     eax, 34
    004013E0  |.  C1E3 03       |shl     ebx, 3
    004013E3  |.  83EB 20       |sub     ebx, 20
    004013E6  |.  83F3 66       |xor     ebx, 66
    004013E9  |.  32C3          |xor     al, bl
    004013EB  |.  03C3          |add     eax, ebx
    004013ED  |.  E8 5CFDFFFF   |call    0040114E                        ;  根据eax的值算出一个对应的值,并保存
    004013F2  |.  58            |pop     eax
    004013F3  |.  3BF0          |cmp     esi, eax                        ;  是否已经遍历结束?
    004013F5  |.  50            |push    eax
    004013F6  |.  74 0A         |je      short 00401402
    004013F8  |.  83F9 03       |cmp     ecx, 3                          ;  第4次循环的时候,重置ecx为-1
    004013FB  |.  75 03         |jnz     short 00401400
    004013FD  |.  33C9          |xor     ecx, ecx
    004013FF  |.  49            |dec     ecx
    00401400  |>^ EB C8         jmp     short 004013CA
    00401402  |>  58            pop     eax
    00401403  |.  42            inc     edx
    00401404  |.  C682 70334000>mov     byte ptr [edx+403370], 2D        ;  添加连字符-
    0040140B  |.  33C9          xor     ecx, ecx
    0040140D  |.  49            dec     ecx
    0040140E  |.  BB 13000000   mov     ebx, 13
    00401413  |.  33C0          xor     eax, eax
    00401415  |>  41            /inc     ecx
    00401416  |.  0FBEB1 F43440>|movsx   esi, byte ptr [ecx+4034F4]      ;  遍历一个特定字符串
    0040141D  |.  0FBEBB B73140>|movsx   edi, byte ptr [ebx+4031B7]      ;  遍历一个特定字符串
    00401424  |.  2BFE          |sub     edi, esi
    00401426  |.  03C7          |add     eax, edi
    00401428  |.  2BC6          |sub     eax, esi
    0040142A  |.  C1E0 04       |shl     eax, 4
    0040142D  |.  83F9 01       |cmp     ecx, 1                          ;  循环两次了?
    00401430  |.^ 75 E3         jnz     short 00401415
    00401432  |.  C1E8 04       shr     eax, 4
    00401435  |.  33C9          xor     ecx, ecx
    00401437  |.  49            dec     ecx
    00401438  |>  41            /inc     ecx
    00401439  |.  E8 10FDFFFF   |call    0040114E                        ;  根据eax的值算出一个对应的值,并保存
    0040143E  |.  8AC4          |mov     al, ah
    00401440  |.  83F9 01       |cmp     ecx, 1                          ;  循环两次了?
    00401443  |.^ 75 F3         jnz     short 00401438
    00401445  |.  42            inc     edx
    00401446  |.  C682 70334000>mov     byte ptr [edx+403370], 2D        ;  添加连字符-
    0040144D  |.  33C9          xor     ecx, ecx
    0040144F  |.  49            dec     ecx
    00401450  |.  33FF          xor     edi, edi
    00401452  |.  0FBE35 063540>movsx   esi, byte ptr [403506]
    00401459  |>  41            /inc     ecx
    0040145A  |.  0FBE81 F63440>|movsx   eax, byte ptr [ecx+4034F6]      ;  遍历一个特定字符串
    00401461  |.  8B9F 07124000 |mov     ebx, dword ptr [edi+401207]     ;  遍历一个代码区段
    00401467  |.  33C3          |xor     eax, ebx
    00401469  |.  331D 06354000 |xor     ebx, dword ptr [403506]
    0040146F  |.  2BD8          |sub     ebx, eax
    00401471  |.  2B1D 06354000 |sub     ebx, dword ptr [403506]
    00401477  |.  03C3          |add     eax, ebx
    00401479  |.  E8 D0FCFFFF   |call    0040114E                        ;  根据eax的值算出一个对应的值,并保存
    0040147E  |.  83C7 04       |add     edi, 4
    00401481  |.  4E            |dec     esi                             ;  循环结束?
    00401482  |.^ 75 D5         jnz     short 00401459
    00401484  |.  68 70334000   push    00403370                         ; /String = ""
    00401489  |.  E8 1E010000   call    <jmp.&kernel32.lstrlenA>         ; lstrlenA
    0040148E  |.  8BC8          mov     ecx, eax
    00401490  |.  41            inc     ecx
    00401491  |>  49            /dec     ecx                             ;  密码和序列号是否一致?
    00401492  |.  0FBE81 703240>|movsx   eax, byte ptr [ecx+403270]
    00401499  |.  0FBE99 703340>|movsx   ebx, byte ptr [ecx+403370]
    004014A0  |.  3BC3          |cmp     eax, ebx
    004014A2  |.  75 1A         |jnz     short 004014BE
    004014A4  |.  83F9 00       |cmp     ecx, 0
    004014A7  |.^ 75 E8         jnz     short 00401491
    004014A9  |.  6A 00         push    0                                ; /Style = MB_OK|MB_APPLMODAL
    004014AB  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    004014B0  |.  68 E0304000   push    004030E0                         ; |great work!hope this is coming from your keygenerator!:)
    004014B5  |.  6A 00         push    0                                ; |hOwner = NULL
    004014B7  |.  E8 90000000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    004014BC  |.  EB 28         jmp     short 004014E6
    004014BE  |>  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
    004014C0  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    004014C5  |.  68 19314000   push    00403119                         ; |this is not the right serial...
    004014CA  |.  6A 00         push    0                                ; |hOwner = NULL
    004014CC  |.  E8 7B000000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    004014D1  |.  EB 13         jmp     short 004014E6
    004014D3  |>  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
    004014D5  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    004014DA  |.  68 BB304000   push    004030BB                         ; |you have to write a serial first...!
    004014DF  |.  6A 00         push    0                                ; |hOwner = NULL
    004014E1  |.  E8 66000000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    004014E6  |>  E8 93FCFFFF   call    0040117E
    004014EB  |.  EB 2C         jmp     short 00401519
    004014ED  |>  0BC0          or      eax, eax
    004014EF  |.  75 15         jnz     short 00401506
    004014F1  |.  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
    004014F3  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    004014F8  |.  68 98304000   push    00403098                         ; |you have to write a name first...!
    004014FD  |.  6A 00         push    0                                ; |hOwner = NULL
    004014FF  |.  E8 48000000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    00401504  |.  EB 13         jmp     short 00401519
    00401506  |>  6A 10         push    10                               ; /Style = MB_OK|MB_ICONHAND|MB_APPLMODAL
    00401508  |.  68 00304000   push    00403000                         ; |crackme#3 by d4ph1
    0040150D  |.  68 75304000   push    00403075                         ; |the name you write is not correct!
    00401512  |.  6A 00         push    0                                ; |hOwner = NULL
    00401514  |.  E8 33000000   call    <jmp.&user32.MessageBoxA>        ; MessageBoxA
    00401519  |>  EB 09         jmp     short 00401524
    0040151B  |>  B8 00000000   mov     eax, 0
    00401520  |.  C9            leave
    00401521  |.  C2 1000       retn    10
    00401524  |>  B8 01000000   mov     eax, 1
    00401529  |.  C9            leave
    0040152A  .  C2 1000       retn    10

    中间的子程序:

    0040114E  /$  66:50         push    ax
    00401150  |.  C0E8 04       shr     al, 4
    00401153  |.  24 0F         and     al, 0F
    00401155  |.  04 30         add     al, 30
    00401157  |.  3C 39         cmp     al, 39
    00401159  |.  7E 02         jle     short 0040115D
    0040115B  |.  04 07         add     al, 7
    0040115D  |>  42            inc     edx
    0040115E  |.  8882 70334000 mov     byte ptr [edx+403370], al
    00401164  |.  66:58         pop     ax
    00401166  |.  C0E0 04       shl     al, 4
    00401169  |.  C0E8 04       shr     al, 4
    0040116C  |.  24 0F         and     al, 0F
    0040116E  |.  04 30         add     al, 30
    00401170  |.  3C 39         cmp     al, 39
    00401172  |.  7E 02         jle     short 00401176
    00401174  |.  04 07         add     al, 7
    00401176  |>  42            inc     edx
    00401177  |.  8882 70334000 mov     byte ptr [edx+403370], al
    0040117D  .  C3            retn

    整体算法不困难,就是稍微有点复杂,有点耐心就可以搞定啦。

    打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,新增类函数如下:

    void CKengen_TemplateDlg::CreateStr(CString &str, DWORD num)
    {
        BYTE Temp = 0;
    
        __asm{
            push eax
    
            mov eax,num
            shr al,4
            and al,0x0F
            add al,0x30
            cmp al,0x39
            jle NotAdd
            add al,7
    NotAdd:    mov Temp,al
    
            pop eax
        }
    
        str += (char)Temp;
    
        __asm{
            push eax
    
            mov eax,num
            shl al,4
            shr al,4
            and al,0x0F
            add al,0x30
            cmp al,0x39
            jle NotAdd2
            add al,7
    NotAdd2:mov Temp,al
    
            pop eax
        }
    
        str += (char)Temp;
    
        return ;
    }

    再将OnBtnDecrypt函数编辑如下:

    void CKengen_TemplateDlg::OnBtnDecrypt() 
    {
        // TODO: Add your control notification handler code here
        CString str;
        GetDlgItemText( IDC_EDIT_NAME,str );                    //获取用户名字串基本信息。
        int len = str.GetLength();
    
        if ( len > 4 && len < 14 ){                                        //格式控制。
            char CharArr[] = { 0x58,0x50,0x80,0x7C,0x05,0x01 };
            char ComputerName[] = { 0x32,0x30,0x31,0x36,0x30,0x34,0x30,0x35,0x2D,0x32,0x30,0x30,0x37,0x00 };
            DWORD CodeSegment[] = { 0x1D8A0C75,    0x00401207,    0x7575FB80,    0x00EBC303,
                                    0x8068006A,    0x6A000000,    0x6A006A02,    0x00006800,
                                    0x47684000,    0xE8004031,    0x00000337,    0x358DD88B,
                                    0x0040390A,    0x00010468,    0x006A5600,    0x00033AE8,
            };
    
            CString Serial = "";
    
            int i = 0,j = 0 ;
            for ( ; i != str.GetLength() ; i++,j++ ){
                DWORD Char = CharArr[j];
                DWORD Temp = str.GetAt( i );
                DWORD Res = 0;
    
                Char = ( Char^0x12 ) + 0x34;
                Temp = ( ((Temp<<3) - 0x20) ^ 0x66 );
                __asm{
                    push eax
                    push ebx
    
                    mov eax,Char
                    mov ebx,Temp
    
                    xor al,bl
                    add eax,ebx
                    mov Res,eax
    
                    pop eax
                    pop ebx
                }
                CreateStr( Serial,Res );
    
                if ( j == 3 )
                    j = -1;
            }
    
            Serial += "-";
            CreateStr( Serial,0x536 );
            CreateStr( Serial,0x505 );
            Serial += "-";
    
            for ( i = 0 ; i != 0x0D ; i++ ){
                DWORD EAX = ( ComputerName[i] ^ CodeSegment[i] );
                DWORD EBX = ( CodeSegment[i] ^ 0x0D ) - EAX - 0x0D;
                DWORD Res = EAX + EBX;
    
                CreateStr( Serial,Res );
            }
    
            SetDlgItemText( IDC_EDIT_PASSWORD,Serial );
        }
        else
            MessageBox( "用户名格式错误!" );
    }

    再在OnInitDialog中添加此代码修改标题:SetWindowText(_T("CRACKME_Keygen"));

    运行效果:

  • 相关阅读:
    python之os模块
    python之字符串
    python之爬虫(beautifulsoup)
    python之常见算法
    python之装饰器(类装饰器,函数装饰器)
    python之mock使用,基于unittest
    python之定时器
    python基础语法随记
    redis基础
    移动端页面开发(二)
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5737239.html
Copyright © 2011-2022 走看看