zoukankan      html  css  js  c++  java
  • 巧用内存断点破解二元函数加密

    系统 : Windows xp

    程序 : Chafe.1

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

    要求 : 注册机编写 

    使用工具 : OD & IDA

    这个CRACKME最初是在http://www.cnblogs.com/bbdxf/p/3817880.html这篇博文里发现的,跟你看到的一样,原文只分析了算法,并没有给出注册机的写法。

      原博主笨笨D幸福是一个逆向前辈,曾在一个多月里破解了37个CrackMe,是我这种破解新手非常崇拜的大牛。然而,2014年7月18日之后他的博客就再也没有更新过,最后的动态也只是说:“最近一直出差,这两个月都没时间了。现在还在外地呢”。

      我不知道他因为什么原因突然停更,但我觉得有必要走上他曾经探索过的道路。时间不够也罢,心情不好也罢,断在中途的这条道路就由我替你延续,这个CRACKME就由我来破解!

    还是老规矩,IDA载入程序,查看字串表得到关键字串“YES! You found your serial!!”。定位字串调用位置并向上翻找到关键算法:

    0040128D  |> 3D 13010000   cmp     eax, 113
    00401292  |.  75 50         jnz     short 004012E4
    00401294  |.  E8 BA010000   call    00401453                         ;  Case 113 (WM_TIMER) of switch 0040123F
    00401299  |.  0FBE05 663140>movsx   eax, byte ptr [403166]           ;  eax值取自403166
    004012A0  |.  3A05 67314000 cmp     al, byte ptr [403167]
    004012A6  |.  75 06         jnz     short 004012AE
    004012A8  |.  33C0          xor     eax, eax
    004012AA  |.  C9            leave
    004012AB  |.  C2 1000       retn    10
    004012AE  |>  A2 67314000   mov     byte ptr [403167], al
    004012B3  |.  83F8 10       cmp     eax, 10                          ;  如果eax的值为10,则成功
    004012B6  |.  74 16         je      short 004012CE
    004012B8  |.  68 65304000   push    00403065                         ; /Text = "Your serial is not valid."
    004012BD  |.  FF35 7C314000 push    dword ptr [40317C]               ; |hWnd = 0019090C ('Your serial is not valid.',class='Edit',parent=0022092A)
    004012C3  |.  E8 66020000   call    <jmp.&USER32.SetWindowTextA>     ; SetWindowTextA
    004012C8  |.  33C0          xor     eax, eax
    004012CA  |.  C9            leave
    004012CB  |.  C2 1000       retn    10
    004012CE  |>  68 7F304000   push    0040307F                         ; /Text = "YES! You found your serial!!"
    004012D3  |.  FF35 7C314000 push    dword ptr [40317C]               ; |hWnd = 0019090C ('Your serial is not valid.',class='Edit',parent=0022092A)
    004012D9  |.  E8 50020000   call    <jmp.&USER32.SetWindowTextA>     ; SetWindowTextA
    004012DE  |.  33C0          xor     eax, eax
    004012E0  |.  C9            leave

    对403166内存下写入断点:运行程序找出4处对内存的写入操作:

    0040146F   .  8B25 A0314000 mov     esp, dword ptr [4031A0]          ;  ↓获取int值成功加4(1)
    00401475   .  6A 00         push    0                                ; /IsSigned = FALSE
    00401477   .  8D45 FC       lea     eax, dword ptr [ebp-4]           ; |
    0040147A   .  50            push    eax                              ; |pSuccess
    0040147B   .  6A 64         push    64                               ; |ControlID = 64 (100.)
    0040147D   .  FF35 70314000 push    dword ptr [403170]               ; |hWnd = 0022092A ('TEXme v1.0',class='TEXcls')
    00401483   .  E8 64000000   call    <jmp.&USER32.GetDlgItemInt>      ; GetDlgItemInt
    00401488   .  A3 88314000   mov     dword ptr [403188], eax          ;  保存序列号
    0040148D   .  837D FC 00    cmp     dword ptr [ebp-4], 0             ;  获取失败?
    00401491   .  74 07         je      short 0040149A
    00401493   .  8005 66314000>add     byte ptr [403166], 4             ;  成功数值加4,403166 = 4
    0040149A   >  C9            leave
    0040149B   .  C3            retn

    还有:

    00401069   .  6A 14         push    14                               ; /Count = 14 (20.)
    0040106B   .  68 8C314000   push    0040318C                         ; |Buffer = Chafe_1.0040318C
    00401070   .  FF35 74314000 push    dword ptr [403174]               ; |hWnd = 003D0922 (class='Edit',parent=0022092A)
    00401076   .  E8 7D040000   call    <jmp.&USER32.GetWindowTextA>     ; GetWindowTextA
    0040107B   .  B9 14000000   mov     ecx, 14                          ;  ↑返回用户名长度
    00401080   .  2BC8          sub     ecx, eax
    00401082   .  8DB8 8C314000 lea     edi, dword ptr [eax+40318C]
    00401088   >  C607 00       mov     byte ptr [edi], 0
    0040108B   .  47            inc     edi
    0040108C   .  49            dec     ecx
    0040108D   .^ 75 F9         jnz     short 00401088
    0040108F   .  85C0          test    eax, eax                         ;  用户名是0?
    00401091   .  74 10         je      short 004010A3
    00401093   .  8005 66314000>add     byte ptr [403166], 4             ;  用户名不为空则加4(2)
    0040109A   .  C605 68314000>mov     byte ptr [403168], 0
    004010A1   .  EB 06         jmp     short 004010A9
    004010A3   >  8825 66314000 mov     byte ptr [403166], ah
    004010A9   >  C9            leave
    004010AA   .  C3            retn

    以及很关键的第三处:

    00401361   .  8D3D 8C314000 lea     edi, dword ptr [40318C]          ;  取用户名(一直调用这个子程序)
    00401367   .  0FBE05 683140>movsx   eax, byte ptr [403168]           ;  取内存地址
    0040136E   .  03F8          add     edi, eax
    00401370   .  FE05 68314000 inc     byte ptr [403168]                ;  自增
    00401376   .  A1 88314000   mov     eax, dword ptr [403188]
    0040137B   .  8B25 A0314000 mov     esp, dword ptr [4031A0]
    00401381   .  40            inc     eax
    00401382   .  FF05 88314000 inc     dword ptr [403188]
    00401388   .  3307          xor     eax, dword ptr [edi]
    0040138A   .  A3 88314000   mov     dword ptr [403188], eax
    0040138F   .  803D 68314000>cmp     byte ptr [403168], 10            ;  循环到第16次,403168为10
    00401396   .  75 07         jnz     short 0040139F
    00401398   .  8005 66314000>add     byte ptr [403166], 4             ;  调用第16次时+4(3)
    0040139F   >  C9            leave
    004013A0   .  C3            retn

    最后一处:

    0040149C   .  A1 88314000   mov     eax, dword ptr [403188]          ;  当此内存的值为F6EEDB88时,
    004014A1   .  05 78241109   add     eax, 9112478
    004014A6   .  85C0          test    eax, eax                         ;  eax为0
    004014A8   .  75 09         jnz     short 004014B3                   ;  跳转+4,否则清空403166
    004014AA   .  8005 66314000>add     byte ptr [403166], 4             ;  403166 = 0x10
    004014B1   .  EB 07         jmp     short 004014BA
    004014B3   >  C605 66314000>mov     byte ptr [403166], 0
    004014BA   >  8B25 A0314000 mov     esp, dword ptr [4031A0]
    004014C0   .  C9            leave
    004014C1   .  C3            retn

    结合第三、第四个汇编代码段可知程序将用户名和序列号进行了一些操作,并判断最后得出的操作数确定是否注册成功。这是典型的采用二元函数进行加密的方式:F(用户名,序列号)= 特定值。

    这个算法比较简单,我们直接打开http://www.cnblogs.com/ZRBYYXDM/p/5115596.html中搭建的框架,并修改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 <= 19 ){                                        //格式控制。
            //模拟F(用户名,序列号)= 特定值
            /*
                char Name[20] = "";
                unsigned int Serial = 1;                                    //序列号123
            
                strcpy( Name,str );                                            //复制用户名字串
                //
                for ( int i = 0 ; i != 16 ; i++ ){
                    Serial++;
                    Serial ^= ( Name[i] + Name[i+1] * 0x100 + Name[i+2] * 0x10000 + Name[i+3] * 0x1000000 );
                }
    
                if ( Serial == 0xF6EEDB88 )
                    MessageBox( "Ok" );
                else
                    MessageBox( "Error" );
            */
            //写出F(用户名,序列号)= 特定值 的逆算法
            char Name[20] = "";
            unsigned int value = 0xF6EEDB88;
            
            strcpy( Name,str );                                            //复制用户名字串
            
            for ( int i = 15 ; i != -1 ; i-- ){
                    value ^= ( Name[i] + Name[i+1] * 0x100 + Name[i+2] * 0x10000 + Name[i+3] * 0x1000000 );
                    value--;
            }
    
            CString PassWord;
            PassWord.Format( "%u",value );
            SetDlgItemText( IDC_EDIT_PASSWORD,PassWord );
        }
        else
            MessageBox( "用户名格式错误!" );
    }

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

    运行效果:

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    eclipse集成JBPM
    一个简单的NoSQL内存数据库—Berkeley DB基本操作的例子
    Berkely DB Java Edition学习笔记
    jsp和java获取文件或路径
    【Bzoj 1835 基站选址】
    【The Time Traveller's Wife】
    【Codeforces Round #430 (Div. 2) A C D三个题】
    【AIM Tech Round 4 (Div. 2) D Prob】
    【Codeforces AIM Tech Round 4 (Div. 2) C】
    【QAQ的Minecraft】
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5130489.html
Copyright © 2011-2022 走看看