View difference between Paste ID: CCqQ7Rj7 and 3GEE5PJc
SHOW: | | - or go back to the newest paste.
1
/* 
2
Antidebugging Breakpoints IDC script for IDA PRO by JSacco v0.2
3
How to use? Open IDA Pro, press shift+F2 paste the code and run.
4
Last modification date: 2021216
5
*/
6
#include <idc.idc>
7
8
static main() 
9
{
10
    // Trace everything in the cosmos? ( Not recommended )
11
    auto trace_kernel32 = 1; // (1) Enabled
12
    auto trace_ntdll = 0;    // (0) Disabled
13
    auto trace_user32 = 0;   // (0) Disabled
14
    
15
    // Autorun ?
16
    // RunTo(BeginEA());
17
    // GetDebuggerEvent(WFNE_SUSP, -1);
18
    
19
    if (get_process_state() == 0){
20
        warning("Ooops! Antidebugging breakpoints cannot be configured\n\nNo process is currently debugged..");
21
        return;
22
    }
23
    if (get_process_state() != -1){
24
        warning("Ooops! Antidebugging breakpoints cannot be configured\n\nPlease suspend the debugger first..");
25
        return;
26
    }
27
    
28
    Message("[?] API - Antidebugging Breakpoints for IDA PRO by jSacco <jsacco@exploitpack.com>\n");
29
    Message("[?] Based on the \"Ultimate\" Antidebugging-Reference by Peter Ferrie\n");
30
    Message("[?] Breakpoints properties: Trace on - enabled [ No-Break ]\n\n");
31
    
32
    if (trace_kernel32){
33
        kernel32_brk();
34
    }
35
    
36
    if (trace_ntdll){
37
        ntdll_brk();
38
    }
39
40
    if (trace_user32){
41
        user32_brk();
42
    }  
43
}
44
45
static kernel32_brk()
46
{
47
    // KERNEL32
48
    auto addr1 = LocByName("kernel32_CheckRemoteDebuggerPresent");
49
    auto addr2 = LocByName("kernel32_CreateToolhelp32Snapshot");
50
    auto addr3 = LocByName("kernel32_IsDebuggerPresent");
51
    auto addr4 = LocByName("kernel32_SuspendThread");
52
    auto addr5 = LocByName("kernel32_QueueUserAPC");
53
    auto addr6 = LocByName("kernel32_CreateProcessA");
54
    auto addr7 = LocByName("kernel32_CreateThread");
55
    auto addr8 = LocByName("kernel32_DebugActiveProcess");
56
    auto addr9 = LocByName("kernel32_RaiseException");
57
    auto addr10 = LocByName("kernel32_WriteProcessMemory");
58
    auto addr11 = LocByName("kernel32_CloseHandle");
59
    auto addr12 = LocByName("kernel32_LoadLibraryA");
60
    auto addr13 = LocByName("kernel32_LoadLibraryExA");
61
    auto addr14 = LocByName("kernel32_ReadFile");
62
    auto addr15 = LocByName("kernel32_GetLocalTime");
63
    auto addr16 = LocByName("kernel32_GetSystemTime");
64
    auto addr17 = LocByName("kernel32_GetTickCount");
65
    auto addr18 = LocByName("kernel32_timeGetTime");
66
    auto addr19 = LocByName("kernel32_QueryPerformanceCounter");
67
    auto addr20 = LocByName("kernel32_SwitchToThread");
68
    auto addr21 = LocByName("kernel32_Toolhelp32ReadProcessMemory");
69
    auto addr22 = LocByName("kernel32_UnhandledExceptionFilter");
70
    auto addr23 = LocByName("kernel32_VirtualProtect");
71
    auto addr24 = LocByName("kernel32_VirtualProtectEx");
72
73
	if (addr1 != BADADDR){
74
		Message("[*] Kernel32 CheckRemoteDebuggerPresent at address, breakpoint set %x\n", addr1);
75
		AddBpt(addr1);
76
		SetBptAttr(addr1, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
77
		SetBptCnd(addr1, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_CheckRemoteDebuggerPresent: The kernel32 CheckRemoteDebuggerPresent function was introduced in Windows XP SP1 to query a value that has existed since Windows NT. Remote in this sense refers to a separate process on the same machine.\\n\")");
78
79
		// Add runtime patching here if necessary
80
		// PatchDword(addr1, 0x8B55FF8B);
81
		// PatchDword(addr1 + 4, 0x0C458BEC);
82
		// PatchDword(addr1 + 8, 0x008F006A);
83
		// PatchDword(addr1 + 12, 0xC25DC033);
84
		// PatchWord(addr1 + 16, 0x0008); 
85
	}
86
	
87
    if (addr2 != BADADDR){
88
		Message("[*] Kernel32 CreateToolhelp32Snapshot at address, breakpoint set %x\n", addr2);
89
		AddBpt(addr2);
90
		SetBptAttr(addr2, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
91
		SetBptCnd(addr2, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_CreateToolhelp32Snapshot: The process ID of both Explorer.exe and the parent process of the current process, and the name of that parent process, can be obtained by the kernel32 CreateToolhelp32Snapshot() function and a kernel32 Process32Next() function enumeration.\\n\")");
92
93
		// Add runtime patching here if necessary
94
	}
95
96
	if (addr3 != BADADDR){
97
		Message("[*] Kernel32 IsDebuggerPresent at address, breakpoint set %x\n", addr3);
98
		AddBpt(addr3);
99
		SetBptAttr(addr3, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
100
		SetBptCnd(addr3, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_IsDebuggerPresent: The kernel32 IsDebuggerPresent() function was introduced in Windows 95. It returns a non-zero value if a debugger is present.\\n\")");
101
102
		// Add runtime patching here if necessary
103
	}
104
105
	if (addr4 != BADADDR){
106
		Message("[*] Kernel32 SuspendThread at address, breakpoint set %x\n", addr4);
107
		AddBpt(addr4);
108
		SetBptAttr(addr4, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
109
		SetBptCnd(addr4, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_SuspendThread: The kernel32 SuspendThread() function can be another very effective way to disable user-mode debuggers. This can be achieved by enumerating the threads of a given process, or searching for a named window and opening its owner thread, and then suspending that thread.\\n\")");
110
111
		// Add runtime patching here if necessary
112
	}
113
114
	if (addr5 != BADADDR){
115
		Message("[*] Kernel32 QueueUserAPC at address, breakpoint set %x\n", addr5);
116
		AddBpt(addr5);
117
		SetBptAttr(addr5, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
118
		SetBptCnd(addr5, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_QueueUserAPC: The kernel32 QueueUserAPC() function can be used to register Asynchronous Procedure Calls (APCs). Asynchronous Procedure Calls are functions that are called when the associated thread enters an alertable state, such as by calling the kernel32 Sleep() function. \\n\")");
119
120
		// Add runtime patching here if necessary
121
	}
122
123
	if (addr6 != BADADDR){
124
		Message("[*] Kernel32 CreateProcessA at address, breakpoint set %x\n", addr6);
125
		AddBpt(addr6);
126
		SetBptAttr(addr6, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
127
		SetBptCnd(addr6, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_CreateProcessA: Creates a new process and its primary thread. The new process runs in the security context of the calling process.\\n\")");
128
129
		// Add runtime patching here if necessary
130
	}
131
132
	if (addr7 != BADADDR){
133
		Message("[*] Kernel32 CreateThread at address, breakpoint set %x\n", addr7);
134
		AddBpt(addr7);
135
		SetBptAttr(addr7, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
136
		SetBptCnd(addr7, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_CreateThread: Threads are a simple way for the debuggee to transfer control to a memory location where execution can resume freely, unless a breakpoint is placed at the appropriate location. They can also be used to interfere with the execution of the other threads (including the main thread), and thus interfere with debugging. \\n\")");
137
138
		// Add runtime patching here if necessary
139
	}
140
141
	if (addr8 != BADADDR){
142
		Message("[*] Kernel32 DebugActiveProcess at address, breakpoint set %x\n", addr8);
143
		AddBpt(addr8);
144
		SetBptAttr(addr8, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
145
		SetBptCnd(addr8, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_DebugActiveProcess: The kernel32 DebugActiveProcess() function can be used to attach as a debugger to an already running process. Since only one debugger can be attached to a process at a time, a failure to attach to the process might indicate the presence of anotherdebugger. \\n\")");
146
147
		// Add runtime patching here if necessary
148
	}
149
150
	if (addr9 != BADADDR){
151
		Message("[*] Kernel32 RaiseException at address, breakpoint set %x\n", addr9);
152
		AddBpt(addr9);
153
		SetBptAttr(addr9, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
154
		SetBptCnd(addr9, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_RaiseException: The kernel32 RaiseException() function can be used to force certain exceptions to occur, which includes exceptions that a debugger would normally consume.\\n\")");
155
156
		// Add runtime patching here if necessary
157
	}
158
159
	if (addr10 != BADADDR){
160
		Message("[*] Kernel32 WriteProcessMemory at address, breakpoint set %x\n", addr10);
161
		AddBpt(addr10);
162
		SetBptAttr(addr10, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
163
		SetBptCnd(addr10, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_WriteProcessMemory: The kernel32 WriteProcessMemory() function can be used to perform self-modification of the code stream, by reading file content to a location after the call to the function.\\n\")");
164
165
		// Add runtime patching here if necessary
166
	}
167
168
	if (addr11 != BADADDR){
169
		Message("[*] Kernel32 CloseHandle at address, breakpoint set %x\n", addr11);
170
		AddBpt(addr11);
171
		SetBptAttr(addr11, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
172
		SetBptCnd(addr11, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_CloseHandle: One well-known technique for detecting a debugger involves the kernel32 CloseHandle() function. If an invalid handle is passed to the kernel32 CloseHandle() function and a debugger is present, then an EXCEPTION_INVALID_HANDLE (0xC0000008) exception will be raised.\\n\")");
173
174
		// Add runtime patching here if necessary
175
	}
176
177
	if (addr12 != BADADDR){
178
		Message("[*] Kernel32 LoadLibraryA at address, breakpoint set %x\n", addr12);
179
		AddBpt(addr12);
180
		SetBptAttr(addr12, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
181
		SetBptCnd(addr12, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_LoadLibraryA: The kernel32 LoadLibrary() function is a surprisingly simple and effective way to detect a debugger. When a file is loaded in the presence of a debugger, using the kernel32 LoadLibrary() function, a handle to the file is opened. This allows the debugger to read the debug information from the file (assuming that it is present).\\n\")");
182
183
		// Add runtime patching here if necessary
184
	}
185
186
	if (addr13 != BADADDR){
187
		Message("[*] Kernel32 LoadLibraryExA at address, breakpoint set %x\n", addr13);
188
		AddBpt(addr13);
189
		SetBptAttr(addr13, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
190
		SetBptCnd(addr13, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_LoadLibraryExA: The kernel32 LoadLibraryExA() function is a surprisingly simple and effective way to detect a debugger. When a file is loaded in the presence of a debugger, using the kernel32 LoadLibrary() function, a handle to the file is opened. This allows the debugger to read the debug information from the file (assuming that it is present).\\n\")");
191
192
		// Add runtime patching here if necessary
193
	}
194
195
	if (addr14 != BADADDR){
196
		Message("[*] Kernel32 ReadFile at address, breakpoint set %x\n", addr14);
197
		AddBpt(addr14);
198
		SetBptAttr(addr14, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
199
		SetBptCnd(addr14, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_ReadFile: The kernel32 ReadFile() function can be used to perform self-modification of the code stream, by reading file content to a location after the call to the function.\\n\")");
200
201
		// Add runtime patching here if necessary
202
	}
203
204
	if (addr15 != BADADDR){
205
		Message("[*] Kernel32 GetLocalTime at address, breakpoint set %x\n", addr15);
206
		AddBpt(addr15);
207
		SetBptAttr(addr15, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
208
		SetBptCnd(addr15, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_GetLocalTime: When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution. This delay can be measured using one of several possible time sources.\\n\")");
209
210
		// Add runtime patching here if necessary
211
	}
212
213
	if (addr16 != BADADDR){
214
		Message("[*] Kernel32 GetSystemTime at address, breakpoint set %x\n", addr16);
215
		AddBpt(addr16);
216
		SetBptAttr(addr16, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
217
		SetBptCnd(addr16, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_GetSystemTime: When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution. This delay can be measured using one of several possible time sources.\\n\")");
218
219
		// Add runtime patching here if necessary
220
	}
221
222
	if (addr17 != BADADDR){
223
		Message("[*] Kernel32 GetTickCount at address, breakpoint set %x\n", addr17);
224
		AddBpt(addr17);
225
		SetBptAttr(addr17, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
226
		SetBptCnd(addr17, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_GetTickCount: When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution. This delay can be measured using one of several possible time sources.\\n\")");
227
228
		// Add runtime patching here if necessary
229
	}
230
231
	if (addr18 != BADADDR){
232
		Message("[*] Kernel32 timeGetTime at address, breakpoint set %x\n", addr18);
233
		AddBpt(addr18);
234
		SetBptAttr(addr18, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
235
		SetBptCnd(addr18, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_timeGetTime: When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution. This delay can be measured using one of several possible time sources.\\n\")");
236
237
		// Add runtime patching here if necessary
238
	}
239
240
	if (addr19 != BADADDR){
241
		Message("[*] Kernel32 QueryPerformanceCounter at address, breakpoint set %x\n", addr19);
242
		AddBpt(addr19);
243
		SetBptAttr(addr19, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
244
		SetBptCnd(addr19, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_QueryPerformanceCounter: When a debugger is present, and used to single-step through the code, there is a significant delay between the executions of the individual instructions, when compared to native execution. This delay can be measured using one of several possible time sources.\\n\")");
245
246
		// Add runtime patching here if necessary
247
	}
248
249
	if (addr20 != BADADDR){
250
		Message("[*] Kernel32 SwitchToThread at address, breakpoint set %x\n", addr20);
251
		AddBpt(addr20);
252
		SetBptAttr(addr20, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
253
		SetBptCnd(addr20, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_SwitchToThread: The kernel32 SwitchToThread() function allows the current thread to offer to give up the rest of its time slice. When an application is being debugged, the act of single-stepping through the code causes debug events and often results in no yield being allowed.\\n\")");
254
255
		// Add runtime patching here if necessary
256
	}
257
258
	if (addr21 != BADADDR){
259
		Message("[*] Kernel32 Toolhelp32ReadProcessMemory at address, breakpoint set %x\n", addr21);
260
		AddBpt(addr21);
261
		SetBptAttr(addr21, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
262
		SetBptCnd(addr21, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_Toolhelp32ReadProcessMemory: The kernel32 Toolhelp32ReadProcessMemory() allows one process to open and read the memory of another process.  This function can be used as another way to detect a step-over condition, by checking for a breakpoint after the function call.\\n\")");
263
264
		// Add runtime patching here if necessary
265
	}
266
267
	if (addr22 != BADADDR){
268
		Message("[*] Kernel32 UnhandledExceptionFilter at address, breakpoint set %x\n", addr22);
269
		AddBpt(addr22);
270
		SetBptAttr(addr22, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
271
		SetBptCnd(addr22, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_UnhandledExceptionFilter: When an exception occurs, and no registered Exception Handlers exist (neither Structured nor Vectored), or if none of the registered handlers handles the exception, then the kernel32 UnhandledExceptionFilter() function will be called as a last resort. If a debugger is present, then that call will not be reached.\\n\")");
272
273
		// Add runtime patching here if necessary
274
	}
275
276
	if (addr23 != BADADDR){
277
		Message("[*] Kernel32 VirtualProtect at address, breakpoint set %x\n", addr23);
278
		AddBpt(addr23);
279
		SetBptAttr(addr23, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
280
		SetBptCnd(addr23, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_VirtualProtect: The kernel32 VirtualProtect() can be used to allocate guard pages. Guard pages are pages that trigger an exception the first time that they are accessed. Guard pages can also be used to detect a debugger. \\n\")");
281
282
		// Add runtime patching here if necessary
283
	}
284
285
	if (addr24 != BADADDR){
286
		Message("[*] Kernel32 VirtualProtectEx at address, breakpoint set %x\n", addr24);
287
		AddBpt(addr24);
288
		SetBptAttr(addr24, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
289
		SetBptCnd(addr24, "Message(\"[!] ANTI-DBG TRIGGERED - kernel32_Vkernel32_VirtualProtectEx: The kernel32 VirtualProtectEx() can be used to allocate guard pages. Guard pages are pages that trigger an exception the first time that they are accessed. Guard pages can also be used to detect a debugger.\\n\")");
290
291
		// Add runtime patching here if necessary
292
	}
293
}
294
295
static ntdll_brk()
296
{
297
    // NTDLL
298
    auto addr25 = LocByName("ntdll_NtQueryInformationProcess");
299
    auto addr26 = LocByName("ntdll_RtlQueryProcessHeapInformation");
300
    auto addr27 = LocByName("ntdll_RtlQueryProcessDebugInformation");
301
    auto addr28 = LocByName("ntdll_NtYieldExecution");
302
    auto addr29 = LocByName("ntdll_NtProtectVirtualMemory");
303
    auto addr30 = LocByName("ntdll_NtSetInformationThread");
304
    auto addr31 = LocByName("ntdll_DbgUiDebugActiveProcess");
305
    auto addr32 = LocByName("ntdll_NtDebugActiveProcess");
306
    auto addr33 = LocByName("ntdll_NtSetInformationProcess");
307
    auto addr34 = LocByName("ntdll_NtQueryObject");
308
    auto addr35 = LocByName("ntdll_NtQuerySystemInformation");
309
    auto addr36 = LocByName("ntdll_NtSetLdtEntries");
310
    auto addr37 = LocByName("ntdll_NtQueueApcThread");
311
    auto addr38 = LocByName("ntdll_NtRaiseException");
312
    auto addr39 = LocByName("ntdll_RtlRaiseException");
313
    auto addr40 = LocByName("ntdll_RtlProcessFlsData");
314
    auto addr41 = LocByName("ntdll_DbgPrint");
315
    auto addr42 = LocByName("ntdll_DbgSetDebugFilterState");
316
    auto addr43 = LocByName("ntdll_DbgBreakPoint");
317
    auto addr44 = LocByName("ntdll_NtSuspendThread");
318
    auto addr45 = LocByName("ntdll_NtWriteVirtualMemory");
319
    auto addr46 = LocByName("ntdll_NtClose");
320
    auto addr47 = LocByName("ntdll_LdrLoadDll");
321
    
322
	if (addr25 != BADADDR){
323
		Message("[*] NTDLL NtQueryInformationProcess at address, breakpoint set %x\n", addr25);
324
		AddBpt(addr25);
325
		SetBptAttr(addr25, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
326
		SetBptCnd(addr25, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtQueryInformationProcess: The ntdll NtQueryInformationProcess() function accepts a parameter which is the class of information to query. The return value is 0xffffffff if the process is being debugged. \\n\")");
327
328
		// Add runtime patching here if necessary
329
	}
330
331
	if (addr26 != BADADDR){
332
		Message("[*] NTDLL RtlQueryProcessHeapInformation at address, breakpoint set %x\n", addr26);
333
		AddBpt(addr26);
334
		SetBptAttr(addr26, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
335
		SetBptCnd(addr26, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_RtlQueryProcessHeapInformation: The ntdll RtlQueryProcessHeapInformation() function can be used to read the heap flags from the process memory of the current process.\\n\")");
336
337
		// Add runtime patching here if necessary
338
	}
339
340
	if (addr27 != BADADDR){
341
		Message("[*] NTDLL RtlQueryProcessDebugInformation at address, breakpoint set %x\n", addr27);
342
		AddBpt(addr27);
343
		SetBptAttr(addr27, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
344
		SetBptCnd(addr27, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_RtlQueryProcessDebugInformation: The ntdll RtlQueryProcessDebugInformation() function can be used to read certain fields from the process memory of the requested process, including the heap flags. \\n\")");
345
346
		// Add runtime patching here if necessary
347
	}
348
349
	if (addr28 != BADADDR){
350
		Message("[*] NTDLL NtYieldExecution at address, breakpoint set %x\n", addr28);
351
		AddBpt(addr28);
352
		SetBptAttr(addr28, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
353
		SetBptCnd(addr28, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtYieldExecution: The NTDLL NtYieldExecution() function allows the current thread to offer to give up the rest of its time slice. When an application is being debugged, the act of single-stepping through the code causes debug events and often results in no yield being allowed.\\n\")");
354
355
		// Add runtime patching here if necessary
356
	}
357
358
	if (addr29 != BADADDR){
359
		Message("[*] NTDLL NtProtectVirtualMemory at address, breakpoint set %x\n", addr29);
360
		AddBpt(addr29);
361
		SetBptAttr(addr29, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
362
		SetBptCnd(addr29, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtProtectVirtualMemory: The kernel32 NtProtectVirtualMemory() can be used to allocate guard pages. Guard pages are pages that trigger an exception the first time that they are accessed. Guard pages can also be used to detect a debugger.\\n\")");
363
364
		// Add runtime patching here if necessary
365
	}
366
367
	if (addr30 != BADADDR){
368
		Message("[*] NTDLL NtSetInformationThread at address, breakpoint set %x\n", addr30);
369
		AddBpt(addr30);
370
		SetBptAttr(addr30, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
371
		SetBptCnd(addr30, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtSetInformationThread: Windows 2000 introduced a function extension which, at first glance, might appear to exist only for anti-debugging purposes. It is the ThreadHideFromDebugger (0x11) member of the ThreadInformationClass class. It can be set on a per-thread basis by calling the ntdll NtSetInformationThread() function.\\n\")");
372
373
		// Add runtime patching here if necessary
374
	}
375
376
	if (addr31 != BADADDR){
377
		Message("[*] NTDLL DbgUiDebugActiveProcess at address, breakpoint set %x\n", addr31);
378
		AddBpt(addr31);
379
		SetBptAttr(addr31, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
380
		SetBptCnd(addr31, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_DbgUiDebugActiveProcess: The kernel32 DbgUiDebugActiveProcess() can be used to attach as a debugger to an already running process. Since only one debugger can be attached to a process at a time, a failure to attach to the process might indicate the presence of anotherdebugger. \\n\")");
381
382
		// Add runtime patching here if necessary
383
	}
384
385
	if (addr32 != BADADDR){
386
		Message("[*] NTDLL NtDebugActiveProcess at address, breakpoint set %x\n", addr32);
387
		AddBpt(addr32);
388
		SetBptAttr(addr32, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
389
		SetBptCnd(addr32, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtDebugActiveProcess: The kernel32 NtDebugActiveProcess() can be used to attach as a debugger to an already running process. Since only one debugger can be attached to a process at a time, a failure to attach to the process might indicate the presence of anotherdebugger. \\n\")");
390
391
		// Add runtime patching here if necessary
392
	}
393
394
	if (addr33 != BADADDR){
395
		Message("[*] NTDLL NtSetInformationProcess at address, breakpoint set %x\n", addr33);
396
		AddBpt(addr33);
397
		SetBptAttr(addr33, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
398
		SetBptCnd(addr33, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtSetInformationProcess: Perhaps because the value of the Local Descriptor Table (LDT) register is zero in user-mode in a physical (as opposed to a virtual) Windows environment, it is generally not supported properly (or at all) by debuggers. As a result, it can be used as a simple anti-debugger technique.\\n\")");
399
400
		// Add runtime patching here if necessary
401
	}
402
403
	if (addr34 != BADADDR){
404
		Message("[*] NTDLL NtQueryObject at address, breakpoint set %x\n", addr34);
405
		AddBpt(addr34);
406
		SetBptAttr(addr34, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
407
		SetBptCnd(addr34, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtQueryObject: Windows XP introduced a debug object. When a debugging session begins, a debug object is created, and a handle is associated with it. Using the ntdll NtQueryObject() function, it is possible to query for the list of existing objects, and check the number of handles associated with any debug objectthat exists.\\n\")");
408
409
		// Add runtime patching here if necessary
410
	}
411
412
	if (addr35 != BADADDR){
413
		Message("[*] NTDLL NtQuerySystemInformation at address, breakpoint set %x\n", addr35);
414
		AddBpt(addr35);
415
		SetBptAttr(addr35, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
416
		SetBptCnd(addr35, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtQuerySystemInformation: The ntdll NtQuerySystemInformation() function accepts a parameter which is the class of information to query. Most of the classes are not documented. This includes the SystemKernelDebuggerInformation (0x23) class, which has existed since Windows NT. The SystemKernelDebuggerInformation class returns the value of two flags: KdDebuggerEnabled in al, and KdDebuggerNotPresent in ah. Thus, the return value in ah is zero if a debugger is present. \\n\")");
417
418
		// Add runtime patching here if necessary
419
	}
420
421
	if (addr36 != BADADDR){
422
		Message("[*] NTDLL NtSetLdtEntries at address, breakpoint set %x\n", addr36);
423
		AddBpt(addr36);
424
		SetBptAttr(addr36, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
425
		SetBptCnd(addr36, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtSetLdtEntries: The ntdll NtSetLdtEntries() function also allows setting the Local Descriptor Table values directly, but only for the current process. It is an entirely separate function with a slightly different parameter format compared to the ProcessLdtInformation technique.\\n\")");
426
427
		// Add runtime patching here if necessary
428
	}
429
430
	if (addr37 != BADADDR){
431
		Message("[*] NTDLL NtQueueApcThread at address, breakpoint set %x\n", addr37);
432
		AddBpt(addr37);
433
		SetBptAttr(addr37, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
434
		SetBptCnd(addr37, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtQueueApcThread: The ntdll NtQueueApcThread() function can be used to register Asynchronous Procedure Calls (APCs). Asynchronous Procedure Calls are functions that are called when the associated thread enters an alertable state, such as by calling the kernel32 Sleep() function. \\n\")");
435
436
		// Add runtime patching here if necessary
437
	}
438
439
	if (addr38 != BADADDR){
440
		Message("[*] NTDLL NtRaiseException at address, breakpoint set %x\n", addr38);
441
		AddBpt(addr38);
442
		SetBptAttr(addr38, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
443
		SetBptCnd(addr38, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtRaiseException: The ntdll NtRaiseException() function can be used to force certain exceptions to occur, which includes exceptions that a debugger would normally consume. \\n\")");
444
445
		// Add runtime patching here if necessary
446
	}
447
448
	if (addr39 != BADADDR){
449
		Message("[*] NTDLL RtlRaiseException at address, breakpoint set %x\n", addr39);
450
		AddBpt(addr39);
451
		SetBptAttr(addr39, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
452
		SetBptCnd(addr39, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_RtlRaiseException: The ntdll RtlRaiseException() function can be used to force certain exceptions to occur, which includes exceptions that a debugger would normally consume. \\n\")");
453
454
		// Add runtime patching here if necessary
455
	}
456
457
	if (addr40 != BADADDR){
458
		Message("[*] NTDLL RtlProcessFlsData at address, breakpoint set %x\n", addr40);
459
		AddBpt(addr40);
460
		SetBptAttr(addr40, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
461
		SetBptCnd(addr40, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_RtlProcessFlsData: The ntdll RtlProcessFlsData() function is an undocumented function When called with the appropriate parameter and memory values, the function will execute code at a user-specified pointer in memory. If a debugger is unaware of this fact, then execution control might be lost.\\n\")");
462
463
		// Add runtime patching here if necessary
464
	}
465
466
	if (addr41 != BADADDR){
467
		Message("[*] Ntdll DbgPrint at address, breakpoint set %x\n", addr41);
468
		AddBpt(addr41);
469
		SetBptAttr(addr41, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
470
		SetBptCnd(addr41, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_DbgPrint: Normally, the ntdll DbgPrint() function raises an exception, but a registered Structured Exception Handler will not see it.\\n\")");
471
472
		// Add runtime patching here if necessary
473
	}
474
475
	if (addr42 != BADADDR){
476
		Message("[*] Ntdll DbgSetDebugFilterState at address, breakpoint set %x\n", addr42);
477
		AddBpt(addr42);
478
		SetBptAttr(addr42, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
479
		SetBptCnd(addr42, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_DbgSetDebugFilterState: The ntdll DbgSetDebugFilterState() function (or the ntdll NtSetDebugFilterState() function, both introduced in Windows XP) cannot be used to detect the presence of a debugger.\\n\")");
480
481
		// Add runtime patching here if necessary
482
	}
483
484
	if (addr43 != BADADDR){
485
		Message("[*] Ntdll DbgBreakPoint at address, breakpoint set %x\n", addr43);
486
		AddBpt(addr43);
487
		SetBptAttr(addr43, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
488
		SetBptCnd(addr43, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_DbgBreakPoint: The ntdll DbgBreakPoint() function is called when a debugger attaches to an already-running process. The function allows the debugger to gain control because an exception is raised that the debugger can intercept.\\n\")");
489
490
		// Add runtime patching here if necessary
491
	}
492
493
	if (addr44 != BADADDR){
494
		Message("[*] NTDLL NtSuspendThread at address, breakpoint set %x\n", addr44);
495
		AddBpt(addr44);
496
		SetBptAttr(addr44, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
497
		SetBptCnd(addr44, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtSuspendThread:  The ntdll NtSuspendThread() function can be another very effective way to disable user-mode debuggers. This can be achieved by enumerating the threads of a given process, or searching for a named window and opening its owner thread, and then suspending that thread.\\n\")");
498
499
		// Add runtime patching here if necessary
500
	}
501
502
	if (addr45 != BADADDR){
503
		Message("[*] NTDLL NtWriteVirtualMemory at address, breakpoint set %x\n", addr45);
504
		AddBpt(addr45);
505
		SetBptAttr(addr45, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
506
		SetBptCnd(addr45, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtWriteVirtualMemory: The ntdll NtWriteVirtualMemory() function can be used to perform self-modification of the code stream, by reading file content to a location after the call to the function.\\n\")");
507
508
		// Add runtime patching here if necessary
509
	}
510
511
	if (addr46 != BADADDR){
512
		Message("[*] NTDLL NtClose at address, breakpoint set %x\n", addr46);
513
		AddBpt(addr46);
514
		SetBptAttr(addr46, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
515
		SetBptCnd(addr46, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_NtClose: If an invalid handle is passed to the CloseHandle() function and a debugger is present, then an EXCEPTION_INVALID_HANDLE (0xC0000008) exception will be raised. \\n\")");
516
517
		// Add runtime patching here if necessary
518
	}
519
520
	if (addr47 != BADADDR){
521
		Message("[*] NTDLL LdrLoadDll at address, breakpoint set %x\n", addr47);
522
		AddBpt(addr47);
523
		SetBptAttr(addr47, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
524
		SetBptCnd(addr47, "Message(\"[!] ANTI-DBG TRIGGERED - ntdll_LdrLoadDll: The ntdll LdrLoadDll() function is a surprisingly simple and effective way to detect a debugger. When a file is loaded in the presence of a debugger, using the kernel32 LoadLibrary() function, a handle to the file is opened. This allows the debugger to read the debug information from the file (assuming that it is present).\\n\")");
525
526
		// Add runtime patching here if necessary
527
	}
528
}
529
530
static user32_brk()
531
{
532
    // USER32
533
    auto addr48 = LocByName("user32_FindWindowA");
534
    auto addr49 = LocByName("user32_BlockInput");
535
536
	if (addr48 != BADADDR){
537
		Message("[*] Kernel32 FindWindowA at address, breakpoint set %x\n", addr48);
538
		AddBpt(addr48);
539
		SetBptAttr(addr48, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
540
		SetBptCnd(addr48, "Message(\"[!] ANTI-DBG TRIGGERED - user32_FindWindowA: The user32 FindWindow() function can be used to search for windows by name or class. This is an easy way to detect the presence of a debugger, if the debugger has a graphical user interface. \\n\")");
541
542
		// Add runtime patching here if necessary
543
	}
544
545
	if (addr49 != BADADDR){
546
		Message("[*] Kernel32 BlockInput at address, breakpoint set %x\n", addr49);
547
		AddBpt(addr49);
548
		SetBptAttr(addr49, BPTATTR_FLAGS, BPT_TRACEON | BPT_TRACE | BPT_ENABLED);
549
		SetBptCnd(addr49, "Message(\"[!] ANTI-DBG TRIGGERED - user32_BlockInput: The user32 BlockInput() function can block or unblock all mouse and keyboard events (apart from the ctrl-alt-delete key sequence). The effect remains until either the process exits or the function is called again with the opposite parameter. It is a very effective way to disable debuggers.\\n\")");
550
551
		// Add runtime patching here if necessary
552
	}
553
}