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
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
| # include "windows.h"
# include "stdio.h"
LPVOID g_pfWriteFile = NULL;
CREATE_PROCESS_DEBUG_INFO g_cpdi;
BYTE g_chINT3 = 0xCC;
BYTE g_ch0rgByte = 0;
BOOL OnCreateProcessDebugEvent(LPDEBUG_EVENT pde)
{
// 获取WriteFile() API的地址
g_pfWriteFile = GetProcAddress(GetModuleHandle("kernel32.dll"), "WriteFile");
printf("g_pfWriteFile:%d\n", g_pfWriteFile);
// API钩子 WriteFile()
memcpy(&g_cpdi, &pde->u.CreateProcessInfo, sizeof(CREATE_PROCESS_DEBUG_EVENT));
ReadProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_ch0rgByte, sizeof(BYTE), NULL);
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_chINT3, sizeof(BYTE), NULL);
return TRUE;
}
BOOL OnExceptionDebugEvent(LPDEBUG_EVENT pde)
{
CONTEXT ctx;
PBYTE lpBuffer = NULL;
DWORD dwNumOfBytesToWrite, dwAddrOfBuffer, i;
PEXCEPTION_RECORD per = &pde->u.Exception.ExceptionRecord;
if (EXCEPTION_BREAKPOINT == per->ExceptionCode)
{
if (g_pfWriteFile == per->ExceptionAddress)
{
// 将0xcc恢复为original byte
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile,
&g_ch0rgByte, sizeof(BYTE), NULL);
// 获取线程上下文
ctx.ContextFlags = CONTEXT_CONTROL;
GetThreadContext(g_cpdi.hThread, &ctx);
// 获取WriteFile的第2,3个参数
ReadProcessMemory(g_cpdi.hProcess, (LPCVOID)(ctx.Esp + 8),
&dwAddrOfBuffer, sizeof(DWORD), NULL);
ReadProcessMemory(g_cpdi.hProcess, (LPCVOID)(ctx.Esp + 0xc),
&dwNumOfBytesToWrite, sizeof(DWORD), NULL);
/*dwAddrOfBuffer = ctx.Rsi;
dwNumOfBytesToWrite = ctx.Rdx;*/
printf("size: %d\n", dwNumOfBytesToWrite);
// 分配临时缓冲区
lpBuffer = (PBYTE)malloc(dwNumOfBytesToWrite + 1);
memset(lpBuffer, 0, dwNumOfBytesToWrite + 1);
// 复制WriteFile缓冲区到临时缓冲区
ReadProcessMemory(g_cpdi.hProcess, (LPCVOID)dwAddrOfBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);
printf("\n original string: %s\n", lpBuffer);
// 小写字母转大写字母
for (i = 0; i < dwNumOfBytesToWrite; i++)
{
if (0x61 <= lpBuffer[i] && lpBuffer[i] <= 0x7A)
{
lpBuffer[i] = lpBuffer[i] - 0x20;
}
}
printf("\n converted string: %s\n", lpBuffer);
// 将变换后的缓冲区换到WriteFile中
WriteProcessMemory(g_cpdi.hThread, (LPVOID)dwAddrOfBuffer,
lpBuffer, dwNumOfBytesToWrite, NULL);
free(lpBuffer);
// 将线程上下文的EIP更改为WriteFile的首地址
ctx.Eip = (DWORD)g_pfWriteFile;
SetThreadContext(g_cpdi.hThread, &ctx);
ContinueDebugEvent(pde->dwProcessId, pde->dwThreadId, DBG_CONTINUE);
Sleep(0);
WriteProcessMemory(g_cpdi.hProcess, g_pfWriteFile, &g_chINT3,
sizeof(BYTE), NULL);
return TRUE;
}
}
return FALSE;
}
void DebugLoop()
{
DEBUG_EVENT de;
DWORD dwContinueStatus;
while (WaitForDebugEvent(&de, INFINITE))
{
dwContinueStatus = DBG_CONTINUE;
// 被调试进程生成或附加
if (CREATE_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
OnCreateProcessDebugEvent(&de);
// 异常
else if (EXCEPTION_DEBUG_EVENT == de.dwDebugEventCode)
{
if (OnExceptionDebugEvent(&de))
continue;
}
// 中止
else if (EXIT_PROCESS_DEBUG_EVENT == de.dwDebugEventCode)
break;
ContinueDebugEvent(de.dwProcessId, de.dwThreadId, dwContinueStatus);
}
}
int main(int argc, char* argv[])
{
DWORD dwPID;
dwPID = atoi(argv[1]);
// 使调试器附加到一个活动进程并且调试它
if (!DebugActiveProcess(dwPID))
{
printf("DebugActiveProcess failed\n");
return 1;
}
DebugLoop();
return 0;
}
|