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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
|
/********************************************//**
* 内存补丁技术学习笔记--Debug API 机制
*
* MinGW gcc 4.7.1 编译通过
* 2013.11.17
* by skiyer
***********************************************/
#include <windows.h>
#define BREAK_POINT 0x004A0824 //需要下断点处的地址
#define PATCH_POINT 0x0040119E //需要打补丁处地址
#define SZFILENAME ".\\第一集.exe" //目标程序文件名
int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR szCmdLine, int iCmdShow)
{
STARTUPINFO si ;
PROCESS_INFORMATION pi ;
ZeroMemory(&si, sizeof(STARTUPINFO)) ;
ZeroMemory(&pi, sizeof(PROCESS_INFORMATION)) ;
si.cb = sizeof(STARTUPINFO) ;
BOOL WhileDoFlag = TRUE;
BYTE dwINT3code[1] = {0xCC}; //INT3指令
BYTE dwOldbyte[1] = {0}; //用于保存BREAK_POINT处原指令
BYTE dwPatchcode[] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90}; //补丁指令
unsigned int nPatchSize = 6; //补丁字节数
//调试载入目标程序
if( !CreateProcess(SZFILENAME, NULL, NULL, NULL, FALSE,
DEBUG_PROCESS | DEBUG_ONLY_THIS_PROCESS,
NULL, NULL, &si, &pi ) )
{
MessageBox(NULL, "程序载入失败!", "ERROR", MB_OK);
return FALSE;
}
DEBUG_EVENT DBEvent ;
CONTEXT Regs ;
DWORD dwState, Oldpp;
Regs.ContextFlags = CONTEXT_FULL | CONTEXT_DEBUG_REGISTERS ;
while (WhileDoFlag)
{
//等待调试事件发生
WaitForDebugEvent (&DBEvent, INFINITE);
dwState = DBG_EXCEPTION_NOT_HANDLED ;
switch (DBEvent.dwDebugEventCode)
{
case CREATE_PROCESS_DEBUG_EVENT:
//如果进程开始
//备份BREAK_POINT处原指令
ReadProcessMemory(pi.hProcess, (LPCVOID)(BREAK_POINT), &dwOldbyte, sizeof(dwOldbyte), NULL) ;
//修改内存属性,使之可写
VirtualProtectEx(pi.hProcess, (LPVOID)BREAK_POINT, 1, PAGE_EXECUTE_READWRITE, &Oldpp);
//写入INT3指令
WriteProcessMemory(pi.hProcess, (LPVOID)BREAK_POINT, &dwINT3code, 1, NULL);
dwState = DBG_CONTINUE ;
break;
case EXCEPTION_DEBUG_EVENT:
switch (DBEvent.u.Exception.ExceptionRecord.ExceptionCode)
{
case EXCEPTION_BREAKPOINT:
//如果触发断点异常
{
GetThreadContext(pi.hThread, &Regs) ;
if(Regs.Eip == BREAK_POINT + 1)
//如果在BREAK_POINT处中断
{
//在PATCH_POINT处写入补丁
WriteProcessMemory(pi.hProcess, (LPVOID)PATCH_POINT, &dwPatchcode, nPatchSize, NULL);
//恢复BREAK_POINT处原指令
WriteProcessMemory(pi.hProcess, (LPVOID)BREAK_POINT, &dwOldbyte, 1, NULL);
//重新执行原指令
Regs.Eip--;
SetThreadContext(pi.hThread, &Regs) ;
}
dwState = DBG_CONTINUE ;
break;
}
}
break;
case EXIT_PROCESS_DEBUG_EVENT :
//进程退出
WhileDoFlag = FALSE;
break ;
}
ContinueDebugEvent(pi.dwProcessId, pi.dwThreadId, dwState) ;
}
CloseHandle(pi.hProcess) ;
CloseHandle(pi.hThread) ;
return TRUE;
}
|