0%

crackme42

本题要求在不修改源程序的情况下要去除开始的那个对话框

我们使用了调试的方法控制程序的执行,大概hook也可以用这种原理实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
//调试器原理大概就是这样了吧 
#include <windows.h>
#include <iostream>

using namespace std;

//断点地址
DWORD dwBreakPoint = 0x401000;
//新的执行地址
DWORD dwNewEip = 0x401013;

int main() {
cout << "请确保本注册机与程序在同一个目录下面!" << endl;
cout << "按任意键继续..." << endl;
//该结构用于指定新进程的主窗口特性
STARTUPINFO si = { 0} ;
//.应用程序必须将cb初始化为sizeof(STARTUPINFO)
si.cb = sizeof(STARTUPINFO);
//在创建进程时相关的数据结构之一,该结构返回有关新进程及其主线程的信息。
PROCESS_INFORMATION pi = { 0 };
//创建一个调试进程
CreateProcess("defiler.2.exe",NULL,NULL,NULL,FALSE,DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,NULL,NULL,&si,&pi);
//调试信息结构体
DEBUG_EVENT dbg;
//每个线程内核对象都维护着一个CONTEXT结构,里面保存了线程运行的状态,
//该结构里有各种信息,寄存器这些的,我们可以修改里面的内容达到控制程序运行的目的。
CONTEXT ct;
//线程的Handle
HANDLE h;
//设置标记
ct.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS;
//开始调试
while (WaitForDebugEvent(&dbg,INFINITE)) {
if (dbg.dwThreadId != pi.dwThreadId) {
ContinueDebugEvent(dbg.dwProcessId,dbg.dwThreadId,DBG_CONTINUE);
cout << "跳过其他线程" << endl;
continue;
}
switch (dbg.dwDebugEventCode) {
case CREATE_PROCESS_DEBUG_EVENT://调试进程的创建
//获取线程的句柄
h = OpenThread(THREAD_ALL_ACCESS,FALSE,dbg.dwThreadId);
GetThreadContext(h,&ct);
ct.Dr0 = dwBreakPoint; //设置断点地址
ct.Dr7 = 0x101;
SetThreadContext(h,&ct);
CloseHandle(h);
ContinueDebugEvent(dbg.dwProcessId,dbg.dwThreadId,DBG_CONTINUE);
break;
case EXCEPTION_DEBUG_EVENT://接收到调试事件
//断点事件
if (0x4000001e == dbg.u.Exception.ExceptionRecord.ExceptionCode) {
cout << "捕捉到断点" << endl;
HANDLE h = OpenThread(THREAD_ALL_ACCESS,FALSE,dbg.dwThreadId);
DWORD dwPid = GetProcessId(pi.hProcess);
MessageBox(NULL,"这是注入的对话框!","hello",0x40);
GetThreadContext(h,&ct);
//修改相关寄存器,达到对程序的控制
ct.Rip = dwNewEip;
SetThreadContext(h,&ct);
CloseHandle(h);
}
ContinueDebugEvent(dbg.dwProcessId,dbg.dwThreadId,DBG_CONTINUE);
break;
case EXIT_PROCESS_DEBUG_EVENT://调试进程结束
ContinueDebugEvent(dbg.dwProcessId,dbg.dwThreadId,DBG_CONTINUE);
ExitProcess(0);
break;
default:
ContinueDebugEvent(dbg.dwProcessId,dbg.dwThreadId,DBG_CONTINUE);
break;
}
}
return 0;
}