-
Notifications
You must be signed in to change notification settings - Fork 60
/
main.c
216 lines (188 loc) · 4.98 KB
/
main.c
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
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
#define _CRT_SECURE_NO_WARNINGS
#include <Windows.h>
#include <DbgHelp.h>
#include <stdio.h>
LONG
WINAPI
NtSetInformationProcess(
_In_ HANDLE hProcess,
_In_ PROCESS_INFORMATION_CLASS ProcessInformationClass,
_In_reads_bytes_(ProcessInformationSize) LPVOID ProcessInformation,
_In_ DWORD ProcessInformationSize
);
VOID
DbgPrintEx (
_In_ ULONG ErrorSource,
_In_ ULONG ErrorLevel,
_In_ PCHAR Format,
...
);
typedef struct _PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION
{
ULONG Version;
ULONG Reserved;
PVOID Callback;
} PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION, *PPROCESS_INSTRUMENTATION_CALLBACK_INFORMATION;
#define ProcessInstrumentationCallback 40
extern VOID InstrumentationHook(VOID);
extern VOID CfgHook(VOID);
VOID
InstrumentationCHook (
_In_ DWORD64 Function,
_In_ DWORD64 ReturnValue
)
{
static BOOLEAN g_Recurse = 0;
//
// Don't recurse, since we may be doing indirect calls here
//
if (g_Recurse == 0)
{
BOOL bRes;
DWORD64 dwDisplacement = 0;
DWORD64 dwAddress = Function;
CHAR buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME] = { 0 };
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
//
// In the recurse path now
//
g_Recurse = 1;
//
// The return address may be in some known symbol -- look it up
//
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
bRes = SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement, pSymbol);
if (!bRes)
{
//
// Arbitrary memory
//
printf("CFG Hook to: %p\n", Function);
}
else
{
//
// Some symbol and displacement. Print return address too
//
printf("Instrumentation Hook from: %p (%s+%lx) [EAX = %08lX]\n", Function, pSymbol->Name, dwDisplacement, ReturnValue);
}
//
// Recursion ended
//
g_Recurse = 0;
}
}
VOID
CfgCHook (
_In_ DWORD64 Function
)
{
static BOOLEAN g_RecurseCfg = 0;
//
// Don't recurse, since we may be doing indirect calls here
//
if (g_RecurseCfg == 0)
{
BOOL bRes;
DWORD64 dwDisplacement = 0;
DWORD64 dwAddress = Function;
CHAR buffer[sizeof(SYMBOL_INFO) + MAX_SYM_NAME] = {0};
PSYMBOL_INFO pSymbol = (PSYMBOL_INFO)buffer;
//
// In the recurse path now
//
g_RecurseCfg = 1;
//
// The return address may be in some known symbol -- look it up
//
pSymbol->SizeOfStruct = sizeof(SYMBOL_INFO);
pSymbol->MaxNameLen = MAX_SYM_NAME;
bRes = SymFromAddr(GetCurrentProcess(), dwAddress, &dwDisplacement, pSymbol);
if (!bRes)
{
//
// Arbitrary memory
//
printf("CFG Hook to: %p\n", Function);
}
else
{
//
// Some symbol and displacement
//
printf("CFG Hook to: %p (%s+%lx)\n", Function, pSymbol->Name, dwDisplacement);
}
//
// Recursion ended
//
g_RecurseCfg = 0;
}
}
VOID
Dummy (
VOID
)
{
PVOID Base;
ULONG size;
PIMAGE_LOAD_CONFIG_DIRECTORY loadConfig;
DWORD old;
PIMAGE_NT_HEADERS64 ntHeaders;
//
// Hardcoded for notepad -- get its base address
//
Base = GetModuleHandle("notepad.exe");
//
// Get the NT headers
//
ntHeaders = ImageNtHeader(Base);
//
// Get the load config directory
//
loadConfig = ImageDirectoryEntryToData(Base, TRUE, IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG, &size);
//
// Make the CFG pointer writeable
//
VirtualProtect((PVOID)loadConfig->GuardCFCheckFunctionPointer, sizeof(PVOID), PAGE_READWRITE, &old);
//
// Take over it
//
*(PVOID*)loadConfig->GuardCFCheckFunctionPointer = (PVOID)(ULONG_PTR)CfgHook;
//
// Restore protection
//
VirtualProtect((PVOID)loadConfig->GuardCFCheckFunctionPointer, sizeof(PVOID), old, &old);
}
DWORD
WINAPI
DllMain (IN PVOID hInstance, IN ULONG Reason, IN PVOID Reserved)
{
UNREFERENCED_PARAMETER(hInstance);
UNREFERENCED_PARAMETER(Reserved);
if (Reason == DLL_PROCESS_ATTACH)
{
PROCESS_INSTRUMENTATION_CALLBACK_INFORMATION nirvana;
//
// Create a console for debugging
//
AllocConsole();
freopen("CONOUT$", "w", stdout);
//
// Setup the debugger engine
//
SymSetOptions(SYMOPT_UNDNAME);
SymInitialize(GetCurrentProcess(), NULL, TRUE);
//
// Setup the instrumentation hook
//
nirvana.Callback = (PVOID)(ULONG_PTR)InstrumentationHook;
nirvana.Version = 0;
nirvana.Reserved = 0;
NtSetInformationProcess(GetCurrentProcess(), ProcessInstrumentationCallback, &nirvana, sizeof(nirvana));
}
//
// All good
//
return TRUE;
}