4
4
using System . Threading ;
5
5
using System . Diagnostics ;
6
6
using System . Runtime . InteropServices ;
7
+ using System . Windows . Forms ;
8
+ using System . Net ;
9
+ using System . Security . Cryptography ;
7
10
8
11
namespace AntiCrack_DotNet
9
12
{
@@ -62,8 +65,8 @@ internal sealed class AntiDebug
62
65
[ DllImport ( "kernelbase.dll" , SetLastError = true ) ]
63
66
private static extern int QueryFullProcessImageNameA ( SafeHandle hProcess , uint Flags , byte [ ] lpExeName , Int32 [ ] lpdwSize ) ;
64
67
65
- [ DllImport ( "user32 .dll" , SetLastError = true ) ]
66
- private static extern IntPtr GetForegroundWindow ( ) ;
68
+ [ DllImport ( "win32u .dll" , SetLastError = true ) ]
69
+ private static extern IntPtr NtUserGetForegroundWindow ( ) ;
67
70
68
71
[ DllImport ( "user32.dll" , SetLastError = true ) ]
69
72
private static extern int GetWindowTextLengthA ( IntPtr HWND ) ;
@@ -93,13 +96,19 @@ internal sealed class AntiDebug
93
96
94
97
/// <summary>
95
98
/// Attempts to close an invalid handle to detect debugger presence.
99
+ /// <param name="Syscall">specifies if we should use syscall to call the WinAPI functions.</param>
96
100
/// </summary>
97
101
/// <returns>Returns true if an exception is caught, indicating no debugger, otherwise false.</returns>
98
- public static bool NtCloseAntiDebug_InvalidHandle ( )
102
+ public static bool NtCloseAntiDebug_InvalidHandle ( bool Syscall )
99
103
{
100
104
try
101
105
{
102
- NtClose ( ( IntPtr ) 0x1231222L ) ;
106
+ int RandomInt = new Random ( ) . Next ( int . MinValue , int . MaxValue ) ;
107
+ IntPtr RandomIntPtr = new IntPtr ( RandomInt ) ;
108
+ if ( Syscall )
109
+ Syscalls . SyscallNtClose ( RandomIntPtr ) ;
110
+ else
111
+ NtClose ( RandomIntPtr ) ;
103
112
return false ;
104
113
}
105
114
catch
@@ -110,17 +119,22 @@ public static bool NtCloseAntiDebug_InvalidHandle()
110
119
111
120
/// <summary>
112
121
/// Attempts to close a protected handle to detect debugger presence.
122
+ /// <param name="Syscall">specifies if we should use syscall to call the WinAPI functions.</param>
113
123
/// </summary>
114
124
/// <returns>Returns true if an exception is caught, indicating no debugger, otherwise false.</returns>
115
- public static bool NtCloseAntiDebug_ProtectedHandle ( )
125
+ public static bool NtCloseAntiDebug_ProtectedHandle ( bool Syscall )
116
126
{
117
- IntPtr hMutex = CreateMutexA ( IntPtr . Zero , false , new Random ( ) . Next ( 0 , 9999999 ) . ToString ( ) ) ;
127
+ string RandomMutexName = new Random ( ) . Next ( int . MinValue , int . MaxValue ) . ToString ( ) ;
128
+ IntPtr hMutex = CreateMutexA ( IntPtr . Zero , false , RandomMutexName ) ;
118
129
uint HANDLE_FLAG_PROTECT_FROM_CLOSE = 0x00000002 ;
119
130
SetHandleInformation ( hMutex , HANDLE_FLAG_PROTECT_FROM_CLOSE , HANDLE_FLAG_PROTECT_FROM_CLOSE ) ;
120
131
bool Result = false ;
121
132
try
122
133
{
123
- NtClose ( hMutex ) ;
134
+ if ( Syscall )
135
+ Syscalls . SyscallNtClose ( hMutex ) ;
136
+ else
137
+ NtClose ( hMutex ) ;
124
138
Result = false ;
125
139
}
126
140
catch
@@ -153,45 +167,62 @@ public static bool IsDebuggerPresentCheck()
153
167
}
154
168
155
169
/// <summary>
156
- /// Checks if the process has debug flags set using NtQueryInformationProcess.
170
+ /// Checks if the process has debug flags set using NtQueryInformationProcess
171
+ /// <param name="Syscall">specifies if we should use syscall to call the WinAPI functions.</param>
157
172
/// </summary>
158
173
/// <returns>Returns true if debug flags are set, otherwise false.</returns>
159
- public static bool NtQueryInformationProcessCheck_ProcessDebugFlags ( )
174
+ public static bool NtQueryInformationProcessCheck_ProcessDebugFlags ( bool Syscall )
160
175
{
161
176
uint ProcessDebugFlags = 0 ;
162
- NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 0x1F , out ProcessDebugFlags , sizeof ( uint ) , 0 ) ;
177
+ uint Class = 0x1F ;
178
+ uint Size = sizeof ( uint ) ;
179
+ uint Result = 0 ;
180
+ if ( Syscall )
181
+ Syscalls . SyscallNtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , Class , out ProcessDebugFlags , Size , out Result ) ;
182
+ else
183
+ NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 0x1F , out ProcessDebugFlags , sizeof ( uint ) , 0 ) ;
163
184
if ( ProcessDebugFlags == 0 )
164
185
return true ;
165
186
return false ;
166
187
}
167
188
168
189
/// <summary>
169
190
/// Checks if the process has a debug port using NtQueryInformationProcess.
191
+ /// <param name="Syscall">specifies if we should use syscalls to call the WinAPI functions.</param>.
170
192
/// </summary>
171
193
/// <returns>Returns true if a debug port is detected, otherwise false.</returns>
172
- public static bool NtQueryInformationProcessCheck_ProcessDebugPort ( )
194
+ public static bool NtQueryInformationProcessCheck_ProcessDebugPort ( bool Syscall )
173
195
{
174
196
uint DebuggerPresent = 0 ;
175
197
uint Size = sizeof ( uint ) ;
176
198
if ( Environment . Is64BitProcess )
177
199
Size = sizeof ( uint ) * 2 ;
178
- NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 7 , out DebuggerPresent , Size , 0 ) ;
200
+ uint Result = 0 ;
201
+ if ( Syscall )
202
+ Syscalls . SyscallNtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 7 , out DebuggerPresent , Size , out Result ) ;
203
+ else
204
+ NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 7 , out DebuggerPresent , Size , 0 ) ;
179
205
if ( DebuggerPresent != 0 )
180
206
return true ;
181
207
return false ;
182
208
}
183
209
184
210
/// <summary>
185
211
/// Checks if the process has a debug object handle using NtQueryInformationProcess.
212
+ /// <param name="Syscall">specifies if we should use syscall to call the WinAPI functions.</param>
186
213
/// </summary>
187
214
/// <returns>Returns true if a debug object handle is detected, otherwise false.</returns>
188
- public static bool NtQueryInformationProcessCheck_ProcessDebugObjectHandle ( )
215
+ public static bool NtQueryInformationProcessCheck_ProcessDebugObjectHandle ( bool Syscall )
189
216
{
190
217
IntPtr hDebugObject = IntPtr . Zero ;
191
218
uint Size = sizeof ( uint ) ;
192
219
if ( Environment . Is64BitProcess )
193
220
Size = sizeof ( uint ) * 2 ;
194
- NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 0x1E , out hDebugObject , Size , 0 ) ;
221
+
222
+ if ( Syscall )
223
+ Syscalls . SyscallNtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 0x1E , out hDebugObject , Size , 0 ) ;
224
+ else
225
+ NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , 0x1E , out hDebugObject , Size , 0 ) ;
195
226
if ( hDebugObject != IntPtr . Zero )
196
227
return true ;
197
228
return false ;
@@ -221,18 +252,31 @@ public static string AntiDebugAttach()
221
252
/// <returns>Returns true if a known debugger window is detected, otherwise false.</returns>
222
253
public static bool FindWindowAntiDebug ( )
223
254
{
255
+ string [ ] BadWindowNames = { "x32dbg" , "x64dbg" , "windbg" , "ollydbg" , "dnspy" , "immunity debugger" , "hyperdbg" , "cheat engine" , "cheatengine" , "ida" } ;
224
256
Process [ ] GetProcesses = Process . GetProcesses ( ) ;
225
257
foreach ( Process GetWindow in GetProcesses )
226
258
{
227
- string [ ] BadWindowNames = { "x32dbg" , "x64dbg" , "windbg" , "ollydbg" , "dnspy" , "immunity debugger" , "hyperdbg" , "cheat engine" , "cheatengine" , "ida" } ;
228
- foreach ( string BadWindows in BadWindowNames )
259
+ try
229
260
{
230
- if ( GetWindow . MainWindowTitle . ToLower ( ) . Contains ( BadWindows ) )
261
+ if ( GetWindow . MainWindowHandle != IntPtr . Zero )
231
262
{
232
- GetWindow . Close ( ) ;
233
- return true ;
263
+ string title = GetWindow . MainWindowTitle ;
264
+ if ( string . IsNullOrEmpty ( title ) ) continue ;
265
+
266
+ foreach ( string BadWindows in BadWindowNames )
267
+ {
268
+ if ( title . IndexOf ( BadWindows , StringComparison . OrdinalIgnoreCase ) >= 0 )
269
+ {
270
+ GetWindow . Close ( ) ;
271
+ return true ;
272
+ }
273
+ }
234
274
}
235
275
}
276
+ catch
277
+ {
278
+ continue ;
279
+ }
236
280
}
237
281
return false ;
238
282
}
@@ -241,10 +285,10 @@ public static bool FindWindowAntiDebug()
241
285
/// Checks if the foreground window belongs to a known debugger.
242
286
/// </summary>
243
287
/// <returns>Returns true if a known debugger window is detected, otherwise false.</returns>
244
- public static bool GetForegroundWindowAntiDebug ( )
288
+ public static bool NtUserGetForegroundWindowAntiDebug ( )
245
289
{
246
290
string [ ] BadWindowNames = { "x32dbg" , "x64dbg" , "windbg" , "ollydbg" , "dnspy" , "immunity debugger" , "hyperdbg" , "debug" , "debugger" , "cheat engine" , "cheatengine" , "ida" } ;
247
- IntPtr HWND = GetForegroundWindow ( ) ;
291
+ IntPtr HWND = NtUserGetForegroundWindow ( ) ;
248
292
if ( HWND != IntPtr . Zero )
249
293
{
250
294
int WindowLength = GetWindowTextLengthA ( HWND ) ;
@@ -254,7 +298,7 @@ public static bool GetForegroundWindowAntiDebug()
254
298
GetWindowTextA ( HWND , WindowName , WindowLength + 1 ) ;
255
299
foreach ( string BadWindows in BadWindowNames )
256
300
{
257
- if ( WindowName . ToString ( ) . ToLower ( ) . Contains ( BadWindows ) )
301
+ if ( Utils . Contains ( WindowName . ToString ( ) . ToLower ( ) , BadWindows ) )
258
302
{
259
303
return true ;
260
304
}
@@ -353,16 +397,21 @@ public static bool HardwareRegistersBreakpointsDetection()
353
397
{
354
398
Structs . CONTEXT Context = new Structs . CONTEXT ( ) ;
355
399
Context . ContextFlags = CONTEXT_DEBUG_REGISTERS ;
356
- IntPtr CurrentThread = GetCurrentThread ( ) ;
357
- if ( GetThreadContext ( CurrentThread , ref Context ) )
400
+ foreach ( ProcessThread Threads in Process . GetCurrentProcess ( ) . Threads )
358
401
{
359
- if ( ( Context . Dr1 != 0x00 || Context . Dr2 != 0x00 || Context . Dr3 != 0x00 || Context . Dr4 != 0x00 || Context . Dr5 != 0x00 || Context . Dr6 != 0x00 || Context . Dr7 != 0x00 ) )
402
+ uint THREAD_GET_CONTEXT = 0x0008 ;
403
+ uint THREAD_QUERY_INFORMATION = 0x0040 ;
404
+ IntPtr hThread = OpenThread ( THREAD_GET_CONTEXT | THREAD_QUERY_INFORMATION , false , Threads . Id ) ;
405
+ if ( GetThreadContext ( hThread , ref Context ) )
360
406
{
361
- NtClose ( CurrentThread ) ;
362
- return true ;
407
+ if ( ( Context . Dr1 != 0x00 || Context . Dr2 != 0x00 || Context . Dr3 != 0x00 || Context . Dr6 != 0x00 || Context . Dr7 != 0x00 ) )
408
+ {
409
+ NtClose ( hThread ) ;
410
+ return true ;
411
+ }
363
412
}
413
+ NtClose ( hThread ) ;
364
414
}
365
- NtClose ( CurrentThread ) ;
366
415
return false ;
367
416
}
368
417
@@ -386,15 +435,17 @@ private static string CleanPath(string Path)
386
435
387
436
/// <summary>
388
437
/// Checks if the parent process is a debugger by querying process information.
438
+ /// <param name="Syscall">specifies if we should use syscall to call the WinAPI functions.</param>
389
439
/// </summary>
390
440
/// <returns>Returns true if the parent process is a debugger, otherwise false.</returns>
391
- public static bool ParentProcessAntiDebug ( )
441
+ public static bool ParentProcessAntiDebug ( bool Syscall )
392
442
{
393
443
try
394
444
{
395
445
Structs . PROCESS_BASIC_INFORMATION PBI = new Structs . PROCESS_BASIC_INFORMATION ( ) ;
396
446
uint ProcessBasicInformation = 0 ;
397
- if ( NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , ProcessBasicInformation , ref PBI , ( uint ) Marshal . SizeOf ( typeof ( Structs . PROCESS_BASIC_INFORMATION ) ) , 0 ) == 0 )
447
+ uint Result = Syscall ? Syscalls . SyscallNtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , ProcessBasicInformation , ref PBI , ( uint ) Marshal . SizeOf ( typeof ( Structs . PROCESS_BASIC_INFORMATION ) ) , 0 ) : NtQueryInformationProcess ( Process . GetCurrentProcess ( ) . SafeHandle , ProcessBasicInformation , ref PBI , ( uint ) Marshal . SizeOf ( typeof ( Structs . PROCESS_BASIC_INFORMATION ) ) , 0 ) ;
448
+ if ( Result == 0 )
398
449
{
399
450
int ParentPID = PBI . InheritedFromUniqueProcessId . ToInt32 ( ) ;
400
451
if ( ParentPID != 0 )
@@ -432,7 +483,8 @@ public static bool NtSetDebugFilterStateAntiDebug()
432
483
return true ;
433
484
}
434
485
435
- delegate int ExecutionDelegate ( ) ;
486
+ [ UnmanagedFunctionPointer ( CallingConvention . StdCall ) ]
487
+ private delegate int ExecutionDelegate ( ) ;
436
488
437
489
/// <summary>
438
490
/// Uses page guard to detect debugger presence by executing a function pointer.
@@ -471,5 +523,4 @@ public static bool PageGuardAntiDebug()
471
523
return false ;
472
524
}
473
525
}
474
-
475
- }
526
+ }
0 commit comments