Created
June 13, 2025 09:04
-
-
Save DarkCoderSc/9abfa4e2bb8c4b41aa8b293e30403427 to your computer and use it in GitHub Desktop.
Enumerate Local Process Modules Via PEB - Malware Gallery
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uses | |
System.SysUtils, Winapi.Windows, Generics.Collections; | |
// ... | |
type | |
_LDR_DATA_TABLE_ENTRY = record | |
InLoadOrderLinks : TListEntry; | |
InMemoryOrderLinks : TListEntry; | |
InInitializationOrderLinkes : TListEntry; | |
DllBase : PVOID; | |
EntryPoint : PVOID; | |
SizeOfImage : ULONG; | |
FullDllName : TUnicodeString; | |
BaseDllName : TUnicodeString; | |
end; | |
TLdrDataTableEntry = _LDR_DATA_TABLE_ENTRY; | |
PLdrDataTableEntry = ^TLdrDataTableEntry; | |
// ... | |
(* TModuleInformation *) | |
type | |
TModuleInformation = class | |
private | |
FImagePath : String; | |
FBaseAddress : NativeUInt; | |
FEntryPoint : NativeUInt; | |
FSizeOfImage : Cardinal; | |
public | |
{@C} | |
constructor Create(const AImagePath : String; const ABaseAddress, AEntryPoint: NativeUInt; const ASizeOfImage : Cardinal); | |
{@G} | |
property ImagePath : String read FImagePath; | |
property BaseAddress : NativeUInt read FBaseAddress; | |
property EntryPoint : NativeUInt read FEntryPoint; | |
property SizeOfImage : Cardinal read FSizeOfImage; | |
end; | |
// ... | |
constructor TModuleInformation.Create(const AImagePath : String; const ABaseAddress, AEntryPoint: NativeUInt; const ASizeOfImage : Cardinal); | |
begin | |
inherited Create(); | |
/// | |
FImagePath := AImagePath; | |
FBaseAddress := ABaseAddress; | |
FEntryPoint := AEntryPoint; | |
FSizeOfImage := ASizeOfImage; | |
end; | |
(* Local *) | |
function GetCurrentProcessPEB() : NativeUInt; | |
asm | |
{$IFDEF WIN64} | |
mov rax, gs:[$60]; | |
mov result, rax; | |
{$ELSE} | |
mov eax, fs:[$30]; | |
mov result, eax; | |
{$ENDIF} | |
end; | |
function EnumerateCurrentProcessModules(var AList : TObjectList<TModuleInformation>) : Cardinal; | |
begin | |
if not Assigned(AList) then | |
AList := TObjectList<TModuleInformation>.Create(True) | |
else begin | |
AList.Clear(); | |
/// | |
if not AList.OwnsObjects then | |
AList.OwnsObjects := True; | |
end; | |
/// | |
var pPEBLdrData := PPointer(GetCurrentProcessPEB() + {$IFDEF WIN64}$00000018{$ELSE}$0000000c{$ENDIF}); | |
var pFirstEntry := PListEntry(NativeUInt(pPEBLdrData^) + {$IFDEF WIN64}$00000010{$ELSE}$0000000c{$ENDIF}); | |
var pDataTableEntry := PLdrDataTableEntry(pFirstEntry^.Flink); | |
repeat | |
AList.Add(TModuleInformation.Create( | |
string(pDataTableEntry^.FullDllName.Buffer), | |
NativeUInt(pDataTableEntry^.DllBase), | |
NativeUInt(pDataTableEntry^.EntryPoint), | |
pDataTableEntry^.SizeOfImage | |
)); | |
/// | |
pDataTableEntry := PLdrDataTableEntry(pDataTableEntry^.InLoadOrderLinks.Flink); | |
until pFirstEntry = pDataTableEntry^.InLoadOrderLinks.Flink; | |
/// | |
result := AList.Count; | |
end; | |
// ... | |
begin | |
try | |
var AList := TObjectList<TModuleInformation>.Create(True); | |
try | |
EnumerateCurrentProcessModules(AList); | |
/// | |
for var AModuleEntry in AList do | |
WriteLn(Format('Base:[0x%p], EP:[0x%p], Size:[0x%p] -> %s', [ | |
Pointer(AModuleEntry.BaseAddress), | |
Pointer(AModuleEntry.EntryPoint), | |
Pointer(AModuleEntry.SizeOfImage), | |
AModuleEntry.ImagePath | |
])); | |
finally | |
FreeAndNil(AList); | |
end; | |
// ... |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment