160个练手CrackMe-004

来源:互联网 发布:excel数据有效性日期 编辑:程序博客网 时间:2024/06/05 00:15

1、准备工作

无壳,Delphi编写,工具:DarkDe4(Delphi反汇编工具,定位事件地址)


2、OD载入运行,搜索字符串。


双击定位


0045803B为关键跳转。

[esi+0x30C] == 0x85 才提示注册成功,向上查看哪个地方有赋值操作。

在Panel1DbClick函数中发现赋值操作。

00457EFE  |.  C786 0C030000>mov dword ptr ds:[esi+0x30C],0x85



而给[esi+0x30C]赋值的条件是[esi+0x30C] == 0x3E,继续查看哪个地方写入了0x3E。

编辑框的chkcode函数中发现赋值操作。

而赋值条件是Call CKme.00403C。

到此知道了整个注册流程:

     a.输入正确的Key

     b.单击图片框

     c.双击图片框,会显示图片,提示注册成功





单步运行到00457D35时,数据窗口中跟随edx就可以看到正确的Key了:“黑头Sun Brird8dseloffc-012-OK123”

此时可以分析内存关系,可以写内存注册机了。


3、内存注册机

从[ebx + 0x318]开始,向上层函数查。

00457C56  |.  8BD8          mov ebx,eax                               ; ebx的值由eax得来,eax是上层函数传的参数
00428185   .  8B83 C4010000 mov eax,dword ptr ds:[ebx+0x1C4]          ; eax <- [ebx+0x1C4]
00428181   .  8BD8          mov ebx,eax                               ; ebx <- eax
此处省略几步。。。
004281FC   .  53            push ebx004281FD   .  56            push esi004281FE   .  8BF2          mov esi,edx00428200   .  8BD8          mov ebx,eax                               ; ebx <- eax 到这里猜想eax可能就没变化了。所以先试试。此时eax=0x0227502800428202   .  8BD6          mov edx,esi00428204   .  8BC3          mov eax,ebx                               ;  这一层相关的是eax,  eax <- ebx, 再往上看
姑且把eax的值当做基值。
内存注册机:

#include <iostream>#include <windows.h>using namespace std;int main(){    int pid;    int Base_adr = 0x02275028;                                        //基值    int Key_adr;    int tmp_adr;    char key[50] = {0};    int num = 0;    unsigned char tmp;    printf("PID:");    scanf("%d", &pid);    HANDLE hProcess = OpenProcess(2035711, false, pid);    if(hProcess == NULL)        cout << "Error!" << endl;    else{        ReadProcessMemory(hProcess, (LPCVOID)(Base_adr+0x1C4), &tmp_adr, 4, NULL);     //第一层关系        ReadProcessMemory(hProcess, (LPCVOID)(tmp_adr+0x318), &Key_adr, 4, NULL);      //正确的Key的地址        ReadProcessMemory(hProcess, (LPCVOID)Key_adr, &tmp, 1, NULL);        while(tmp != 0 && num < 50){                                                   //循环取值,取到0表示结束             key[num++] = tmp;            ReadProcessMemory(hProcess, (LPCVOID)Key_adr+num, &tmp, 1, NULL);        }    }//    printf("%X\n", Key_adr);    printf("%s\n", key);                                                               //当前name正确的key    return 0;}


尝试了一下。

输入正确的Key后,单击双击操作后显示图片。

但这个内存注册机只对分析出基值的程序有效,上面所谓的基值新开一个程序就变了。好像和下面这个模块有关。

如果这个地址显示为02230000,则上面代码中基值应该是0x02235028。        022C0000则基值为0x022C5028 。暂时不知道解决办法。有机会再解决。

补:

查了一波资料,可以吧内存注册机当做一个小的调试器,以Debug方式创建进程,在Key漏出来的地方下断点,然后读取相关寄存器的值。


源码:

#include <iostream>#include <windows.h>using namespace std;int main() {    char exePath[100] = {"C:\\CKme.exe"};    int int3_adr = 0x00457D35;      // 设置断点的地方    unsigned char CC = 0xCC;    unsigned char E8 = 0xE8;    STARTUPINFO si;    PROCESS_INFORMATION pi;    DEBUG_EVENT devent;    CONTEXT context;    char key[50] = {0};    char tmp = 0;    int num = 0;//    LPCONTEXT lpContext;    ZeroMemory( &si, sizeof(si));    si.cb = sizeof(STARTUPINFO);    si.dwFlags = STARTF_USESHOWWINDOW;//    si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);    si.wShowWindow = SW_SHOW;    ZeroMemory( &pi, sizeof(pi) );//    cout << "File Path:";//    scanf("%s", exePath);    if(CreateProcess(exePath,                     NULL, NULL, NULL,                     FALSE,                     DEBUG_PROCESS,                     NULL, NULL, &si, &pi)){// 以Debug方式创建进程         cout << "OK" << endl;        while(TRUE){            if(WaitForDebugEvent(&devent, INFINITE)){//等待Debug事件 //                cout << "Lai MI" << endl;                switch(devent.dwDebugEventCode){// 过滤事件                     case CREATE_PROCESS_DEBUG_EVENT://                        cout << pi.dwProcessId << endl;                        WriteProcessMemory(pi.hProcess, (LPVOID)int3_adr, &CC, 1, NULL);//进程被创建时下断点                         break;                    case EXCEPTION_DEBUG_EVENT://                        SuspendThread(pi.hThread);if(devent.u.Exception.ExceptionRecord.ExceptionCode == EXCEPTION_BREAKPOINT){// 判断异常信息(int 3 断点信息为0x80000003)                               SuspendThread(pi.hThread);// 暂停线程                             context.ContextFlags = CONTEXT_CONTROL;// 此Flags表示get或set Eip,Ebp...等寄存器                             if(GetThreadContext(pi.hThread, &context)){                                cout << "Eip:" << hex << context.Eip << endl;                                if(context.Eip != int3_adr + 1){// 判断异常的地方是否是我们想要的地方 //                                cout << hex << devent.u.Exception.ExceptionRecord.ExceptionCode << endl;                                ResumeThread(pi.hThread);// 其他地方的断点直接恢复线程 }else{context.ContextFlags = CONTEXT_INTEGER;// 此Flags表示get或set Eax,Ebx...等寄存器 if(GetThreadContext(pi.hThread, &context)){// 这里我们要get Edx的值,Edx指向了注册码 cout << "Edx:" << hex << context.Edx << endl;ReadProcessMemory(pi.hProcess, (LPCVOID)context.Edx, &tmp, 1, NULL);while(tmp != 0 && num < 50){key[num++] = tmp;ReadProcessMemory(pi.hProcess, (LPCVOID)(context.Edx+num), &tmp, 1, NULL);}cout << "This is the registration code:"; cout << key << endl;//输出注册码 }WriteProcessMemory(pi.hProcess, (LPVOID)int3_adr, &E8, 1, NULL);// 还原断点 context.ContextFlags = CONTEXT_CONTROL;context.Eip -= 1;SetThreadContext(pi.hThread, &context);// 还原 Eip ResumeThread(pi.hThread);// 恢复线程 }                                                            }                   }                        break;                }                ContinueDebugEvent(devent.dwProcessId, devent.dwThreadId, DBG_CONTINUE);// 继续Debug事件             }else{                cout << "Error";                cout << GetLastError();                return 0;            }        }    }else{        cout << "Error";        cout << GetLastError();    }    return 0;}


效果图:程序运行起来后先随便几个字符。



4、追码

00457C40  /.  55            push ebp                                 ;  chkcode 真正判断函数00457C41  |.  8BEC          mov ebp,esp00457C43  |.  51            push ecx00457C44  |.  B9 05000000   mov ecx,0x500457C49  |>  6A 00         /push 0x000457C4B  |.  6A 00         |push 0x000457C4D  |.  49            |dec ecx00457C4E  |.^ 75 F9         \jnz XCKme.00457C4900457C50  |.  51            push ecx00457C51  |.  874D FC       xchg [local.1],ecx00457C54  |.  53            push ebx00457C55  |.  56            push esi00457C56  |.  8BD8          mov ebx,eax00457C58  |.  33C0          xor eax,eax00457C5A  |.  55            push ebp00457C5B  |.  68 3D7E4500   push CKme.00457E3D00457C60  |.  64:FF30       push dword ptr fs:[eax]00457C63  |.  64:8920       mov dword ptr fs:[eax],esp00457C66  |.  8BB3 F8020000 mov esi,dword ptr ds:[ebx+0x2F8]         ;  name的长度?00457C6C  |.  83C6 05       add esi,0x500457C6F  |.  FFB3 10030000 push dword ptr ds:[ebx+0x310]00457C75  |.  8D55 F8       lea edx,[local.2]00457C78  |.  8BC6          mov eax,esi00457C7A  |.  E8 85FEFAFF   call CKme.00407B0400457C7F  |.  FF75 F8       push [local.2]                           ;  参数1:str(len(name)+5)00457C82  |.  FFB3 14030000 push dword ptr ds:[ebx+0x314]            ;  参数2:'dseloffc-012-OK'00457C88  |.  8D55 F4       lea edx,[local.3]00457C8B  |.  8B83 D4020000 mov eax,dword ptr ds:[ebx+0x2D4]00457C91  |.  E8 B2B6FCFF   call CKme.00423348                       ;  获取name00457C96  |.  FF75 F4       push [local.3]                           ;  参数3:name00457C99  |.  8D83 18030000 lea eax,dword ptr ds:[ebx+0x318]         ;  参数4:目标地址00457C9F  |.  BA 04000000   mov edx,0x4                              ;  参数5:400457CA4  |.  E8 93BFFAFF   call CKme.00403C3C                       ;  连接字符串00457CA9  |.  33D2          xor edx,edx00457CAB  |.  8B83 F4020000 mov eax,dword ptr ds:[ebx+0x2F4]

这一段还不是太明白,只知道大致效果是这样。


写注册机:

name = input("Name:")key = '黑头Sun Bird' + str(len(name)+5) + 'dseloffc-012-OK' + nameprint('Key:', key, sep='')




原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 手表玻璃面花了怎么办 有个窝囊的父母怎么办 苹果7p玩游戏卡怎么办 三星玩游戏很卡怎么办 三星打游戏很卡怎么办 香水喷到眼睛里怎么办 萍果平板锁机怎么办? 苹果6开机卡死怎么办 辐射4发夹用完了怎么办 辐射4多的武器怎么办 大姨妈恶心想吐怎么办 玩完游戏想吐怎么办 玩完了海盗船想吐怎么办 戴眼镜恶心想吐怎么办 玩电脑恶心想吐怎么办 玩游戏玩的头疼怎么办 玩游戏头疼想吐怎么办 游戏玩久了头疼怎么办 有3d眩晕症怎么办 玩游戏晕3d怎么办 梦幻西游亏的钱怎么办 普惠卡销户了钱存进去了怎么办 梦幻西游现金变储备了怎么办 孩子挣了钱存不下怎么办 电脑显示副本不是正版怎么办 斗战神师徒一个人删除角色怎么办 起业kx5防盗器不响怎么办 灌浆记录仪存盘满了怎么办 自首后发现无罪证据怎么办 中国劲酒过期了怎么办 玻尿酸流到眼皮怎么办 手指被胶带缠紫了怎么办 打玻尿酸不平整怎么办 孩子被老师体罚我该怎么办 孩子妈妈入狱了我该怎么办 机顶盒电视收不到台怎么办 跳芭蕾舞下面硬起来了怎么办 深情密码结局赵深深怎么办 宝宝头着地摔了怎么办 小孩头着地摔了怎么办 头朝下墩了脖子怎么办