Read more about this technique HERE
Delphi
program OutputDebugString;
{$APPTYPE CONSOLE}
uses
WinAPI.Windows,
System.SysUtils;
var AErrorValue : Byte;
begin
try
randomize;
AErrorValue := Random(High(Byte));
SetLastError(AErrorValue);
OutputDebugStringW('TEST');
if (GetLastError() = AErrorValue) then
WriteLn('Debugger detected using OutputDebugString() technique.')
else
WriteLn('No debugger detected using OutputDebugString() technique.');
except
on E: Exception do
Writeln(E.ClassName, ': ', E.Message);
end;
end.
Read more...
Read more about this technique HERE
Delphi
program SuspendThread;
{$APPTYPE CONSOLE}
uses
WinAPI.Windows, System.SysUtils, Generics.Collections, tlHelp32, Classes;
type
TProcessItem = class
private
FName : String;
FProcessId : Cardinal;
FThreads : TList;
{@M}
procedure EnumThreads();
public
{@C}
constructor Create(AName : String; AProcessId : Cardinal; AEnumThreads : Boolean = True);
destructor Destroy(); override;
{@G}
property Name : String read FName;
property ProcessId : Cardinal read FProcessId;
property Threads : TList read FThreads;
end;
TEnumProcess = class
private
FItems : TObjectList;
public
{@C}
constructor Create();
destructor Destroy(); override;
{@M}
function Refresh() : Cardinal;
procedure Clear();
function Get(AProcessId : Cardinal) : TProcessItem; overload;
function Get(AName : String) : TProcessItem; overload;
{@G}
property Items : TObjectList read FItems;
end;
{
Import API's From Kernel32
}
const THREAD_SUSPEND_RESUME = $00000002;
function OpenThread(
dwDesiredAccess: DWORD;
bInheritHandle: BOOL;
dwThreadId: DWORD
) : THandle; stdcall; external kernel32 name 'OpenThread';
{
Global Vars
}
var LFindWindowSignatures : TDictionary;
LProcessNameSignatures : TStringList;
LProcesses : TEnumProcess;
{
Read more...
Read more about this technique HERE
Delphi
program FindWindowAPI;
{$APPTYPE CONSOLE}
uses
System.SysUtils, WinAPI.Windows, Generics.Collections, psAPI;
{
Read more...
Read more about this technique HERE
Delphi
unit UntPEBDebug;
interface
uses Windows;
const PROCESS_QUERY_LIMITED_INFORMATION = $1000;
PROCESS_BASIC_INFORMATION = 0;
// https://docs.microsoft.com/en-us/windows/win32/api/winternl/nf-winternl-ntqueryinformationprocess
var _NtQueryInformationProcess : function(
ProcessHandle : THandle;
ProcessInformationClass : DWORD;
ProcessInformation : Pointer;
ProcessInformationLength :
ULONG; ReturnLength : PULONG) : LongInt; stdcall;
hNTDLL : THandle;
{$IFDEF WIN64}
type
PProcessBasicInformation = ^TProcessBasicInformation;
TProcessBasicInformation = record
ExitStatus : Int64;
PebBaseAddress : Pointer;
AffinityMask : Int64;
BasePriority : Int64;
UniqueProcessId : Int64;
InheritedUniquePID : Int64;
end;
{$ELSE}
type
PProcessBasicInformation = ^TProcessBasicInformation;
TProcessBasicInformation = record
ExitStatus : DWORD;
PebBaseAddress : Pointer;
AffinityMask : DWORD;
BasePriority : DWORD;
UniqueProcessId : DWORD;
InheritedUniquePID : DWORD;
end;
{$ENDIF}
function GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;
function SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;
implementation
{-------------------------------------------------------------------------------
Open a process and retrieve the point of debug flag from PEB.
If function succeed, don't forget to call close process handle.
-------------------------------------------------------------------------------}
function GetDebugFlagPointer(AProcessID : Cardinal; var AProcessHandle : THandle) : Pointer;
var PBI : TProcessBasicInformation;
ARetLen : Cardinal;
begin
result := nil;
///
AProcessHandle := 0;
if NOT Assigned(_NtQueryInformationProcess) then
Exit();
///
AProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_WRITE or PROCESS_VM_READ, false, AProcessID);
if (AProcessHandle = 0) then
Exit;
if _NtQueryInformationProcess(AProcessHandle, PROCESS_BASIC_INFORMATION, @PBI, sizeOf(TProcessBasicInformation), @ARetLen) = ERROR_SUCCESS then
result := Pointer(NativeUInt(PBI.PebBaseAddress) + (SizeOf(Byte) * 2))
else
CloseHandle(AProcessHandle);
end;
{-------------------------------------------------------------------------------
Retrieve the target process debug status from PEB.
ADebugStatus = True : Target process debug flag is set.
ADebugStatus = False : Target process debug flag is not set.
-------------------------------------------------------------------------------}
function GetProcessDebugStatus(AProcessID : Cardinal; var ADebugStatus : boolean) : Boolean;
var hProcess : THandle;
pDebugFlagOffset : Pointer;
pDebugFlag : pByte;
ABytesRead : SIZE_T;
begin
result := false;
///
pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);
if not Assigned(pDebugFlagOffset) then
Exit();
///
try
getMem(pDebugFlag, sizeOf(Byte));
try
if NOT ReadProcessMemory(hProcess, pDebugFlagOffset, pDebugFlag, sizeOf(Byte), ABytesRead) then
Exit;
///
ADebugStatus := (pDebugFlag^ = 1);
finally
FreeMem(pDebugFlag);
end;
///
result := (ABytesRead = SizeOf(Byte));
finally
CloseHandle(hProcess);
end;
end;
{-------------------------------------------------------------------------------
Update target process debug flag.
ADebugStatus = True : Set target process debug flag.
ADebugStatus = False : Unset target process debug flag.
-------------------------------------------------------------------------------}
function SetProcessDebugStatus(AProcessID : Cardinal; ADebugStatus : Boolean) : Boolean;
var hProcess : THandle;
pDebugFlagOffset : Pointer;
ADebugFlag : Byte;
ABytesWritten : SIZE_T;
begin
result := false;
///
pDebugFlagOffset := GetDebugFlagPointer(AProcessID, hProcess);
if not Assigned(pDebugFlagOffset) then
Exit();
///
try
if ADebugStatus then
ADebugFlag := 1
else
ADebugFlag := 0;
if NOT WriteProcessMemory(hProcess, pDebugFlagOffset, @ADebugFlag, SizeOf(Byte), ABytesWritten) then
Exit;
///
result := (ABytesWritten = SizeOf(Byte));
finally
CloseHandle(hProcess);
end;
end;
initialization
{
Load NtQueryInformationProcess from NTDLL.dll
}
_NtQueryInformationProcess := nil;
hNTDLL := LoadLibrary('ntdll.dll');
if (hNTDLL <> 0) then
@_NtQueryInformationProcess := GetProcAddress(hNTDLL, 'NtQueryInformationProcess');
finalization
_NtQueryInformationProcess := nil;
if (hNTDLL <> 0) then
FreeLibrary(hNTDLL);
end.
Read more...