• 破解 Rith's CrackMe #1(对比IDA查看动态分析中的MFC函数名)


    系统 : Windows xp

    程序 : Rith's CrackMe #1

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

    要求 : 注册机编写 

    使用工具 : IDA Pro & OD

    可在“PEDIY CrackMe 2007”中查找关于此程序的破文,标题为“WAKU的第二个破文----Rith's CrackMe #1(非常简单)”。

    使用IDA载入程序,在字串表中找出正确注册的提示“Well done cracker!”,并双击交叉参考来到关键代码处:

    00401582   .  68 B81B4000   push    00401BB8                         ;  SE handler installation
    00401587   .  64:A1 0000000>mov     eax, dword ptr fs:[0]
    0040158D   .  50            push    eax
    0040158E   .  64:8925 00000>mov     dword ptr fs:[0], esp
    00401595   .  83EC 0C       sub     esp, 0C
    00401598   .  53            push    ebx
    00401599   .  55            push    ebp
    0040159A   .  56            push    esi
    0040159B   .  8BF1          mov     esi, ecx
    0040159D   .  57            push    edi
    0040159E   .  68 48304000   push    00403048                         ;  ASCII "31415926535897932384"
    004015A3   .  8D4C24 14     lea     ecx, dword ptr [esp+14]
    004015A7   .  897424 1C     mov     dword ptr [esp+1C], esi
    004015AB   .  E8 FA020000   call    <jmp.&MFC42.#537>
    004015B0   .  6A 01         push    1
    004015B2   .  8BCE          mov     ecx, esi
    004015B4   .  C74424 28 000>mov     dword ptr [esp+28], 0
    004015BC   .  E8 E3020000   call    <jmp.&MFC42.#6334>               ;  MFC函数,此时,函数正在获取对话框的数据
    004015C1   .  8B7E 60       mov     edi, dword ptr [esi+60]          ;  执行完此指令,edi存着用户名地址
    004015C4   .  8B5F F8       mov     ebx, dword ptr [edi-8]           ;  用户名长度
    004015C7   .  83FB 05       cmp     ebx, 5                           ;  长度不能小于5
    004015CA   .  7C 7E         jl      short 0040164A
    004015CC   .  8B46 64       mov     eax, dword ptr [esi+64]          ;  eax存着序列号地址
    004015CF   .  894424 14     mov     dword ptr [esp+14], eax
    004015D3   .  3958 F8       cmp     dword ptr [eax-8], ebx           ;  用户名序列号长度是否相同?
    004015D6   .  75 72         jnz     short 0040164A
    004015D8   .  83FB 14       cmp     ebx, 14                          ;  用户名长度大于0x14?
    004015DB   .  7F 6D         jg      short 0040164A
    004015DD   .  33C9          xor     ecx, ecx
    004015DF   .  85DB          test    ebx, ebx                         ;  长度为0,则跳转。并没有用的一条指令
    004015E1   .  7E 54         jle     short 00401637
    004015E3   .  8B7424 10     mov     esi, dword ptr [esp+10]          ;  取密钥
    004015E7   >  8A040F        mov     al, byte ptr [edi+ecx]           ;  迭代用户名字串
    004015EA   .  0FBE2C31      movsx   ebp, byte ptr [ecx+esi]          ;  迭代密钥
    004015EE   .  0FBEC0        movsx   eax, al
    004015F1   .  99            cdq                                      ;  扩展指令
    004015F2   .  F7FD          idiv    ebp                              ;  用户名字符除以密钥字符
    004015F4   .  8BC2          mov     eax, edx                         ;  保留余数
    004015F6   .  D1E0          shl     eax, 1                           ;  左移1位
    004015F8   .  83F8 7B       cmp     eax, 7B                          ;  小于等于7B?
    004015FB   .  7E 03         jle     short 00401600
    004015FD   .  83E8 1A       sub     eax, 1A                          ;  大于7B则减去-1A
    00401600   >  83F8 41       cmp     eax, 41                          ;  大于等于41?
    00401603   .  7D 09         jge     short 0040160E                   ;  是则进入下一cmp
    00401605   .  BA 82000000   mov     edx, 82
    0040160A   .  2BD0          sub     edx, eax                         ;  edx-=eax
    0040160C   .  8BC2          mov     eax, edx                         ;  保留edx
    0040160E   >  83F8 5B       cmp     eax, 5B                          ;  小于等于5B?
    00401611   .  7E 12         jle     short 00401625                   ;  是则直接去序列号进行对比
    00401613   .  83F8 61       cmp     eax, 61                          ;  大于等于61?
    00401616   .  7D 0D         jge     short 00401625                   ;  是则直接去序列号进行对比
    00401618   .  99            cdq                                      ;  否则eax除以10
    00401619   .  BD 0A000000   mov     ebp, 0A
    0040161E   .  F7FD          idiv    ebp
    00401620   .  83C2 30       add     edx, 30                          ;  余数+30
    00401623   .  8BC2          mov     eax, edx                         ;  存入eax
    00401625   >  8B5424 14     mov     edx, dword ptr [esp+14]          ;  取序列号
    00401629   .  38040A        cmp     byte ptr [edx+ecx], al           ;  序列号与处理结果是否相同?
    0040162C   .  75 1C         jnz     short 0040164A
    0040162E   .  41            inc     ecx                              ;  循环变量自增
    0040162F   .  3BCB          cmp     ecx, ebx                         ;  迭代结束?
    00401631   .^ 7C B4         jl      short 004015E7
    00401633   .  8B7424 18     mov     esi, dword ptr [esp+18]
    00401637   >  6A 00         push    0
    00401639   .  68 34304000   push    00403034                         ;  ASCII "Congratulations!"
    0040163E   .  68 20304000   push    00403020                         ;  ASCII "Well done cracker!"
    00401643   .  8BCE          mov     ecx, esi
    00401645   .  E8 54020000   call    <jmp.&MFC42.#4224>               ;  MessageBox函数

    以上就是注册的关键代码了,发现该程序调用了MFC函数,函数名并没有在OD中显示,不要紧,对比IDA中相同的地址就可以看到具体用了什么函数。快速破解这个程序需要对MFC有一定的了解。好了,仔细跟踪代码,发现程序采用了F(用户名)=序列号的判断形势,我们用高级语言实现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 >= 5 && len <= 0x14 ){                                        //格式控制。
            CString Serial = "31415926535897932384";                        //密钥
            CString PassWord = str;                                            //序列号
            
            for ( int i = 0 ; i != len ; i++ ){
                PassWord.SetAt( i,( PassWord[i] % Serial[i] ) << 1 );
                if ( PassWord[i] > 0x7B )
                    PassWord.SetAt( i,PassWord[i] - 0x1A );
                if ( PassWord[i] < 0x41 )
                    PassWord.SetAt( i,0x82 - PassWord[i] );
    
                if ( PassWord[i] > 0x5B && PassWord[i] < 0x61 )
                    PassWord.SetAt( i,PassWord[i] % 10 + 0x30 );
            }
    
            SetDlgItemText( IDC_EDIT_PASSWORD,PassWord );
        }
        else
            MessageBox( "用户名格式错误!" );
    }

    再在OnInitDialog中添加此代码修改标题:SetWindowText(_T("Rith's CrackMe #1_Keygen"));

    运行效果:

    我们一路奋战,不是为了改变世界,而是不让世界改变我们 ——《熔炉》
  • 相关阅读:
    SpringBoot非官方教程 | 第九篇: springboot整合Redis
    SpringBoot非官方教程 | 第八篇:springboot整合mongodb
    SpringBoot非官方教程 | 第七篇:springboot开启声明式事务
    SpringBoot非官方教程 | 第六篇:springboot整合mybatis
    SpringBoot非官方教程 | 第五篇:springboot整合 beatlsql
    SpringBoot非官方教程 | 第四篇:SpringBoot 整合JPA
    SpringBoot非官方教程 | 第三篇:SpringBoot用JdbcTemplates访问Mysql
    SpringBoot非官方教程 | 第二篇:Spring Boot配置文件详解
    SpringBoot非官方教程 | 终章:文章汇总
    SpringBoot非官方教程 | 第一篇:构建第一个SpringBoot工程
  • 原文地址:https://www.cnblogs.com/ZRBYYXDM/p/5120411.html
Copyright © 2020-2023  润新知