-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuAntiDebug.pas
More file actions
204 lines (175 loc) · 4.45 KB
/
uAntiDebug.pas
File metadata and controls
204 lines (175 loc) · 4.45 KB
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
unit uAntiDebug;
{
反调试保护模块
功能:
1. 检测调试器存在
2. 检测远程调试器
3. 检测时间异常(反单步调试)
4. 检测硬件断点
5. 保护进程(可选)
使用方法:
1. 在程序启动时调用 TAntiDebug.CheckAll
2. 如果返回True,表示检测到调试器,应终止程序
编译指令:
- 在Release配置中定义RELEASE符号以启用反调试保护
}
{$IFDEF RELEASE}
{$DEFINE ENABLE_ANTI_DEBUG} // 生产环境启用反调试
{$ENDIF}
interface
uses
Winapi.Windows, System.SysUtils;
type
TAntiDebug = class
private
class function GetTickCountDiff(StartTick: DWORD): DWORD;
public
// 检测调试器
class function IsDebuggerPresent: Boolean;
class function CheckRemoteDebugger: Boolean;
class function DetectTimingAnomaly: Boolean;
class function DetectHardwareBreakpoints: Boolean;
// 综合检测
class function CheckAll: Boolean;
// 保护进程(需要管理员权限)
class procedure ProtectProcess;
end;
implementation
// 检测本地调试器
class function TAntiDebug.IsDebuggerPresent: Boolean;
begin
{$IFDEF ENABLE_ANTI_DEBUG}
Result := Winapi.Windows.IsDebuggerPresent;
{$ELSE}
Result := False;
{$ENDIF}
end;
// 检测远程调试器
class function TAntiDebug.CheckRemoteDebugger: Boolean;
var
IsPresent: BOOL;
ProcessHandle: THandle;
begin
Result := False;
{$IFDEF ENABLE_ANTI_DEBUG}
ProcessHandle := GetCurrentProcess;
IsPresent := False;
if CheckRemoteDebuggerPresent(ProcessHandle, IsPresent) then
Result := IsPresent;
{$ENDIF}
end;
// 计算时间差
class function TAntiDebug.GetTickCountDiff(StartTick: DWORD): DWORD;
var
CurrentTick: DWORD;
begin
CurrentTick := GetTickCount;
if CurrentTick >= StartTick then
Result := CurrentTick - StartTick
else
// 处理溢出情况
Result := (High(DWORD) - StartTick) + CurrentTick + 1;
end;
// 检测时间异常(反单步调试)
class function TAntiDebug.DetectTimingAnomaly: Boolean;
var
StartTick: DWORD;
TimeDiff: DWORD;
const
THRESHOLD_MS = 100; // 100毫秒阈值
begin
Result := False;
{$IFDEF ENABLE_ANTI_DEBUG}
StartTick := GetTickCount;
// 执行一些简单操作
Sleep(10);
TimeDiff := GetTickCountDiff(StartTick);
// 如果时间差异过大,可能存在调试器
if TimeDiff > THRESHOLD_MS then
Result := True;
{$ENDIF}
end;
// 检测硬件断点
class function TAntiDebug.DetectHardwareBreakpoints: Boolean;
var
Context: TContext;
ThreadHandle: THandle;
begin
Result := False;
{$IFDEF ENABLE_ANTI_DEBUG}
ThreadHandle := GetCurrentThread;
FillChar(Context, SizeOf(Context), 0);
Context.ContextFlags := CONTEXT_DEBUG_REGISTERS;
if GetThreadContext(ThreadHandle, Context) then
begin
// 检查调试寄存器DR0-DR3
if (Context.Dr0 <> 0) or (Context.Dr1 <> 0) or
(Context.Dr2 <> 0) or (Context.Dr3 <> 0) then
Result := True;
end;
{$ENDIF}
end;
// 综合检测所有反调试方法
class function TAntiDebug.CheckAll: Boolean;
begin
Result := False;
{$IFDEF ENABLE_ANTI_DEBUG}
// 检测本地调试器
if IsDebuggerPresent then
begin
Result := True;
Exit;
end;
// 检测远程调试器
if CheckRemoteDebugger then
begin
Result := True;
Exit;
end;
// 检测时间异常
if DetectTimingAnomaly then
begin
Result := True;
Exit;
end;
// 检测硬件断点
if DetectHardwareBreakpoints then
begin
Result := True;
Exit;
end;
{$ENDIF}
end;
// 保护进程(使调试器崩溃)
class procedure TAntiDebug.ProtectProcess;
type
TNtSetInformationProcess = function(
ProcessHandle: THandle;
ProcessInformationClass: DWORD;
ProcessInformation: Pointer;
ProcessInformationLength: ULONG
): DWORD; stdcall;
var
NtSetInformationProcess: TNtSetInformationProcess;
ProcessInformation: DWORD;
NtDllHandle: THandle;
begin
{$IFDEF ENABLE_ANTI_DEBUG}
try
NtDllHandle := GetModuleHandle('ntdll.dll');
if NtDllHandle <> 0 then
begin
@NtSetInformationProcess := GetProcAddress(NtDllHandle, 'NtSetInformationProcess');
if Assigned(NtSetInformationProcess) then
begin
ProcessInformation := 1;
// ProcessBreakOnTermination = 29
NtSetInformationProcess(GetCurrentProcess, 29, @ProcessInformation, SizeOf(ProcessInformation));
end;
end;
except
// 忽略错误(可能没有管理员权限)
end;
{$ENDIF}
end;
end.