新手逆向练习与详解(1)(详解带有源文件)1-creakme

 链接 百度网盘 密码:k8p1

暑假说好集训好好学习的 但是现在感觉也没有学习多少东西  幸好的是 和一些朋友交流了很多东西 然后有个人给了我一个CrackMe  这大概是我暑假集训第一个动手做的东西吧   这个CrackMe感觉 算是比较简单的

我这里和大家声明一下 我这个是文件 是来自吾爱破解的creakme 160   导航链接  帖子里面有更厉害的思路  

本帖是编号为1的creakme  

一开始会出现一个窗口 这个窗口名称 就暴露出想让我们杀死的它动机 我们暂时叫它小K窗口 叫neg就不好玩了

然后我们点确定发现 

可以知道 两边就是让我们注册的 中间那个就是直接退出的 

我们先分析 左边的那一块 我们点开左边的那一个按钮 看见

嗯 就是输入账号和密码的  我们先 不分析算法 还有窗口(等到最后一起分析  先让他弹出来注册成功的窗口)! 

然后我用的工具是吾爱破解OD   至于虚拟机环境 感觉xp 或者win7 都行   我用的是win7 一般来说 我能用win7的系统就不会xp

首先 我们先按 F9 出现了小K窗口 我们先不管小K 然后 再按F9 就出现了 上面的页面 我们先 把他 上面的 窗口跳出来 然后点击 上面的按钮 然后按下F12 然后按下 OD 上面的K 按钮(就是我们所说的 堆栈窗口) 窗口如下

很显然 我们找的MessageBox函数就出来了 我们进去 看一看

 然后我们下断点 一步一步F8步入过  然后 到了上图  42FB18 jnz 那个语句  当跳过到那个call的时候我们发现 出现了 失败的窗口 当我们讲jnz的标志寄存器 修改使之成立之后发现 记下来的call 就是成功的call   如下图  如果再不分析算法的情况下 想爆破 直接讲jnz 改正jz就可 然后我们继续分析右边的注册窗口  

先再上边随便填写  000000

 然后我们用上面的方法确定我们所需要进入的地址 然后  下图 堆栈地址

 当我们进去F8往下走的时候发现

抱着侥幸心理试了试 结果

成功! 

然后我们再分析小k 窗口 其实这个窗口找到很简单 就是 

然后我们往下走  

是不是感觉直接把call nop掉就ok了 其实不是 你会发现我们  所有Messagebox 都是在一个地方调用的  如果你直接把小K窗口的call nop了 会导致 其他Messagebox也没办法弹出 其实我想到的办法就是打补丁 他们虽然调用的是同一个Messagebox 但是他们的参数不同 例如 上面的push eax edi  esi 判断那个都行 使之调转 然后打补丁 如果是小K 恢复现场 然后跳过  如果不是小K 只需要恢复一下现场就行了  然后这个小K也就解决了(这个只是一个思路 我具体还没有实现)

接下来就是我个人比较喜欢的 分析算法了 因为感觉爆破其实真的没什么意思 你不知道他的具体算法 感觉没有什么提升 然后我们其实算法部分上面已经有了 

其实大概就是这一部分 然后我们先随便输入账号和密码

然后我们进入我们要分析的地方 

先看左上角eax的值 然后我们再看

我们抱着试一试的心理看一看这个密码是否正确

那么 我们就大概知道是怎么做的了  下面进入算法分析部分

就是上面显示错误的messagebox上面的部分  算法部分 有两个 一个是 我们的比较长度的 一个是由name 得出密码的  我们先分析比较长度部分  

很明显的看出 这里jge指令就是比较长度的 这里是 大于等于4就跳转  然后我们进入上面的那个call 看一下具体的算法

  REPNE SCAS BYTE PTR ES:[EDI] 这个指令 其实我个人感觉也是比较好理解的  cx的值当为0的时候就停止循环 然后 当找到和al 一样值的时候也会停止循环 每次循环 cx的值减一  我们这里因为讲ecx设置为-1 那么意思就是只有当找到al的值的时候在停止循环  al的值设为0  因为字符串结束我们后面都会是 0  这里应该没有什么问题 至于后面为什么讲ecx减去2 那就更好理解了  加入我们计数的字符串长度为1 那么    我们先将ecx的值设为-1 那么  我们知道会运行2次 那么ecx的值为-3  -3-2=1 所以这就是为什么-2的原因 后面的算法分析 我是在od上一步一步的分析 因为我不想全部都写下来 其实有些东西 如果大家想学习的话 可以自己跟进去看看 我跟进去看看了看原理 但是我自己并没有打算 粘上去 其实我感觉 如果时间很紧的话 那些call进去看字符串连接 以及 16进制转换 字符串 在我们call下去就能看的出来 没必要跟进去看

0042FA8A  |.  0FB600        movzx eax,byte ptr ds:[eax]                      ;  把我们输进去的字符串首地址给了eax
0042FA8D  |.  F72D 50174300 imul dword ptr ds:[0x431750]                     ;  eax *0x29
0042FA93  |.  A3 50174300   mov dword ptr ds:[0x431750],eax
0042FA98  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]
0042FA9D  |.  0105 50174300 add dword ptr ds:[0x431750],eax                  ;  将eax*2 放进地址为0x431750的内存中
0042FAA3  |.  8D45 FC       lea eax,[local.1]                                ;  下面这个 call 这个call就是 将edx的值给eax
0042FAA6  |.  BA ACFB4200   mov edx,Acid_bur.0042FBAC                        ;  0x42fbac 是 CW的首地址
0042FAAB  |.  E8 583CFDFF   call Acid_bur.00403708                           ;  将 0x42fbb8 的首地址给12f938
0042FAB0  |.  8D45 F8       lea eax,[local.2]                                ;  eax 是12f934
0042FAB3  |.  BA B8FB4200   mov edx,Acid_bur.0042FBB8                        ;  0x42fbb8 是 CEACKED 的首地址
0042FAB8  |.  E8 4B3CFDFF   call Acid_bur.00403708
0042FABD  |.  FF75 FC       push [local.1]                                   ;  CW的首地址
0042FAC0  |.  68 C8FB4200   push Acid_bur.0042FBC8                           ;  UNICODE "-"
0042FAC5  |.  8D55 E8       lea edx,[local.6]                                ;  我们上面求出的eax的值
0042FAC8  |.  A1 50174300   mov eax,dword ptr ds:[0x431750]                  ;  这个是我们上面的0x431750值的首地址
0042FACD  |.  E8 466CFDFF   call Acid_bur.00406718                           ;  将上面求出eax的16进制转换成字符串 存储在12e87d
0042FAD2  |.  FF75 E8       push [local.6]
0042FAD5  |.  68 C8FB4200   push Acid_bur.0042FBC8                           ;  UNICODE "-"
0042FADA  |.  FF75 F8       push [local.2]                                   ;  Acid_bur.0042FBB8
0042FADD  |.  8D45 F4       lea eax,[local.3]
0042FAE0  |.  BA 05000000   mov edx,0x5
0042FAE5  |.  E8 C23EFDFF   call Acid_bur.004039AC                           ;  字符串连接 最后放进 地址为1247efc
0042FAEA  |.  8D55 F0       lea edx,[local.4]
0042FAED  |.  8B83 E0010000 mov eax,dword ptr ds:[ebx+0x1E0]
0042FAF3  |.  E8 60AFFEFF   call Acid_bur.0041AA58
0042FAF8  |.  8B55 F0       mov edx,[local.4]                                ;  这个是我们输入密码的首地址
0042FAFB      8B45 F4       mov eax,dword ptr ss:[ebp-0xC]                   ;  这个是我们最后得出的密码
0042FAFE  |.  E8 F93EFDFF   call Acid_bur.004039FC                           ;  比较函数不相等则跳转
0042FB03      75 1A         jnz short Acid_bur.0042FB1F
0042FB05  |.  6A 00         push 0x0

所以这个算法我们就分析出来了 如果用C语言来表示的话 应该是这样子的 

#include <cstdio>
#include <windows.h>
#include <iostream>
using namespace std;
char name[256];
char password[256];
char szBuff[256];
void slove()
{
     int sum=0;
     long int date=(long int )name[0];
     date*=0x29;
     date*=2;
     sprintf(szBuff, "CW-%d-CRACKED", date);
}
//CW-3936-CRACKED
int main()
{
    while(1)
    {
         printf("请输入账号:\n");
         scanf("%s",name);
         printf("请输入密码:\n");
         scanf("%s",password);
         slove();
        if(strcmp(szBuff,password)==0)
        {
             MessageBox(NULL,TEXT("您答对了"),TEXT("恭喜"),MB_OK);
        }
        else
        {
             MessageBox(NULL,TEXT("您答错了"),TEXT("抱歉"),MB_OK);
        }
    }

    return 0;
}

有哪里不对的 还请指出 多多包涵  也很欢迎大家留言或者私信讨论!!!

猜你喜欢

转载自blog.csdn.net/qq_41071646/article/details/81206704