unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls, uallProtect, uallHook;
type
TForm1 =
class(TForm)
Button1: TButton;
Memo1: TMemo;
Edit1: TEdit;
procedure Button1Click(Sender: TObject);
private
{ Private-Deklarationen }
public
{ Public-Deklarationen }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
type
PDebugModule = ^TDebugModule;
TDebugModule =
packed record
Reserved:
array [0..1]
of Cardinal;
Base: Cardinal;
Size: Cardinal;
Flags: Cardinal;
Index: Word;
Unknown: Word;
LoadCount: Word;
ModuleNameOffset: Word;
ImageName:
array [0..$FF]
of Char;
end;
type
PDebugModuleInformation = ^TDebugModuleInformation;
TDebugModuleInformation =
record
Count: Cardinal;
Modules:
array [0..0]
of TDebugModule;
end;
PDebugBuffer = ^TDebugBuffer;
TDebugBuffer =
record
SectionHandle: THandle;
SectionBase: Pointer;
RemoteSectionBase: Pointer;
SectionBaseDelta: Cardinal;
EventPairHandle: THandle;
Unknown:
array [0..1]
of Cardinal;
RemoteThreadHandle: THandle;
InfoClassMask: Cardinal;
SizeOfInfo: Cardinal;
AllocatedSize: Cardinal;
SectionSize: Cardinal;
ModuleInformation: PDebugModuleInformation;
BackTraceInformation: Pointer;
HeapInformation: Pointer;
LockInformation: Pointer;
Reserved:
array [0..7]
of Pointer;
end;
const
PDI_MODULES = $01;
ntdll = '
ntdll.dll';
var
HNtDll: HMODULE;
HNtDll2: HMODULE;
type
TFNRtlCreateQueryDebugBuffer =
function(Size: Cardinal;
EventPair: Boolean): PDebugBuffer;
stdcall;
TFNRtlQueryProcessDebugInformation =
function(ProcessId,
DebugInfoClassMask: Cardinal;
var DebugBuffer: TDebugBuffer): Integer;
stdcall;
TFNRtlDestroyQueryDebugBuffer =
function(DebugBuffer: PDebugBuffer): Integer;
stdcall;
TFNRtlCreateUserThread =
procedure(ProcessHandle: THANDLE;
SecurityDescriptor: PSECURITY_DESCRIPTOR;
CreateSuspended: Boolean;
StackZeroBits: ULONG;
StackReserved: PULONG; StackCommit: PULONG;
StartAddress: Pointer;
StartParameter: Pointer;
ThreadHandle: PHANDLE;
ClientID: Pointer);
stdcall;
var
RtlCreateQueryDebugBuffer: TFNRtlCreateQueryDebugBuffer;
RtlQueryProcessDebugInformation: TFNRtlQueryProcessDebugInformation;
RtlDestroyQueryDebugBuffer: TFNRtlDestroyQueryDebugBuffer;
RtlCreateUserThread: TFNRtlCreateUserThread;
nextRtlCreateUserThread: TFNRtlCreateUserThread;
procedure myRtlCreateUserThread(ProcessHandle: THANDLE;
SecurityDescriptor: PSECURITY_DESCRIPTOR;
CreateSuspended: Boolean;
StackZeroBits: ULONG;
StackReserved: PULONG;
StackCommit: PULONG;
StartAddress: Pointer;
StartParameter: Pointer;
ThreadHandle: PHANDLE;
ClientID: Pointer);
stdcall;
begin
StartAddress := Pointer(dword(StartAddress)-dword(HNtDll2)+dword(HNtDll));
nextRtlCreateUSerThread(ProcessHandle, SecurityDescriptor,
CreateSuspended,StackZeroBits, StackReserved, StackCommit,
StartAddress, StartParameter, ThreadHandle ,ClientID);
end;
function LoadRtlQueryDebug: LongBool;
begin
if HNtDll = 0
then
begin
HNtDll := LoadLibrary(ntdll);
HNtDll2 := uallProtect.ForceLoadLibraryNt(ntdll);
if HNtDll <> 0
then
begin
RtlCreateQueryDebugBuffer := GetProcAddress(HNtDll2, '
RtlCreateQueryDebugBuffer');
RtlQueryProcessDebugInformation := GetProcAddress(HNtDll2,
'
RtlQueryProcessDebugInformation');
RtlDestroyQueryDebugBuffer := GetProcAddress(HNtDll2,
'
RtlDestroyQueryDebugBuffer');
RtlCreateUserThread := GetProcAddress(HNtDll2,'
RtlCreateUserThread');
uallHook.HookCode(@RtlCreateUserThread,@myRtlCreateUserThread, @nextRtlCreateUserThread);
end;
end;
Result := Assigned(RtlCreateQueryDebugBuffer)
and
Assigned(RtlQueryProcessDebugInformation)
and
Assigned(RtlQueryProcessDebugInformation);
end;
procedure TForm1.Button1Click(Sender: TObject);
var
DbgBuffer: PDebugBuffer;
Loop: Integer;
begin
if not LoadRtlQueryDebug
then Exit;
Memo1.Clear;
Memo1.Lines.BeginUpdate;
DbgBuffer := RtlCreateQueryDebugBuffer(0, False);
if Assigned(DbgBuffer)
then
try
if RtlQueryProcessDebugInformation(StrToIntDef(Edit1.Text, GetCurrentProcessId),
PDI_MODULES, DbgBuffer^) >= 0
then
begin
for Loop := 0
to DbgBuffer.ModuleInformation.Count - 1
do
with DbgBuffer.ModuleInformation.Modules[Loop], Memo1.Lines
do
begin
Add('
ImageName: ' + ImageName);
Add('
Reserved0: ' + IntToHex(Reserved[0], 8));
Add('
Reserved1: ' + IntToHex(Reserved[1], 8));
Add('
Base: ' + IntToHex(Base, 8));
Add('
Size: ' + IntToHex(Size, 8));
Add('
Flags: ' + IntToHex(Flags, 8));
Add('
Index: ' + IntToHex(
Index, 4));
Add('
Unknown: ' + IntToHex(Unknown, 4));
Add('
LoadCount: ' + IntToHex(LoadCount, 4));
Add('
ModuleNameOffset: ' + IntToHex(ModuleNameOffset, 4));
end;
end;
finally
RtlDestroyQueryDebugBuffer(DbgBuffer);
end;
Memo1.Lines.EndUpdate;
end;
end.