检测系统是否有调试器存在
{ Process database constants }
const
fDebugSingle = $00000001;
{ Process database types }
type
PProcessDatabase = ^TProcessDatabase;
TProcessDatabase = packed record
DontCare1: array[0..7] of Integer;
Flags: Integer;
DontCare2: array[0..11] of Integer;
DebugeeCB: Integer;
DontCare3: array[0..22] of Integer;
DontCare4: Word;
end;
function IsDebuggerPresentForWindows: Boolean;
var
PDB: PProcessDatabase;
TID: Integer;
Obsfucator: ULONG;
begin
Result := False;
Obsfucator := 0;
TID := GetCurrentThreadID;
// Calculate Obsfucator
asm
MOV EAX, FS:[18h]
SUB EAX, 10h
XOR EAX, [TID]
MOV [Obsfucator], EAX
// Obsfucator := (@TIB - $10) xor GetCurrentThreadID
end;
if Obsfucator <> 0 then
begin
// Retriece pointer to the PDB
PDB := Pointer(GetCurrentProcessID xor Obsfucator);
// Return True if process is being debugged
Result := (PDB^.Flags and fDebugSingle) <> 0;
end;
end;
{ Check for debugger under NT }
{ NT IsDebuggerPresent prototype }
type
TIsDebuggerPresent = function: BOOL; stdcall;
function IsDebuggerPresentForNT: Boolean;
var
Kernel32: THandle;
FIsDebuggerPresent: TIsDebuggerPresent;
begin
Result := False;
// Attempt to load KERNEL32
Kernel32 := LoadLibrary('KERNEL32.DLL');
if Kernel32 <> 0 then
begin
// Retrieve address of IsDebuggerPresent
FIsDebuggerPresent := GetProcAddress(Kernel32,
'IsDebuggerPresent');
// Return True if a debugger is present
if Assigned(FIsDebuggerPresent) then
Result := FIsDebuggerPresent;
// Release KERNEL32
FreeLibrary(Kernel32);
end;
end;
function IsDebuggerPresent: Boolean;
begin
// If Windows 95, use PDB. Otherwise, use NT's IsDebuggerPresent
if (Win32Platform = VER_PLATFORM_WIN32_NT) or
((Win32Platform = VER_PLATFORM_WIN32_WINDOWS) and
((Win32MajorVersion > 4) or
((Win32MajorVersion = 4) and (Win32MinorVersion > 0)))) then
Result := IsDebuggerPresentForNT else
Result := IsDebuggerPresentForWindows;
end;