{ --| Code Snippet |-- }
uses
Windows;
type
_UNICODE_STRING =
record
Length: Word;
MaximumLength: Word;
Buffer: PWideChar;
end;
PUnicodeString = ^TUnicodeString;
TUnicodeString = _UNICODE_STRING;
PPEB_LDR_DATA = ^TPEB_LDR_DATA;
TPEB_LDR_DATA =
packed record
Reserved1:
Array[0..7]
of Byte;
Reserved2:
Array[0..2]
of Pointer;
InMemoryOrderModuleList: LIST_ENTRY;
end;
PLDR_MODULE = ^LDR_MODULE;
LDR_MODULE =
packed record
InLoadOrderModuleList: LIST_ENTRY;
InMemoryOrderModuleList: LIST_ENTRY;
InInitializationOrderModuleList: LIST_ENTRY;
BaseAddress: Pointer;
EntryPoint: Pointer;
SizeOfImage: DWord;
FullDllName: TUnicodeString;
BaseDllName: TUnicodeString;
Flags: DWord;
LoadCount: Short;
TlsIndex: SHort;
HashTableEntry: LIST_ENTRY;
TimeDateStamp: DWord;
end;
PPEB = ^PEB;
PEB =
record
Reserved1:
Array[0..1]
of Byte;
BeingDebugged: Byte;
Spare: Byte;
Mutant: DWord;
ImageBase: Pointer;
Ldr: PPEB_LDR_DATA;
{REST NICHT IMPLEMENTIERT: WIRD FÜR >MEINE< ZWECKE NICHT BENÖTIGT}
end;
function GetPEB(): PPEB;
asm
mov eax, FS:[$30]
end;
function _GetProcAddress(): Pointer;
var
_PEB: PPEB;
_FirstItem, _CurrentItem: PListEntry;
_Module: PLDR_MODULE;
ModuleName:
String;
ModuleFound: Boolean;
ImageBase: DWord;
pDosHeader: ^_IMAGE_DOS_HEADER;
pNTHeaders: ^_IMAGE_NT_HEADERS;
pExportTable: ^_IMAGE_EXPORT_DIRECTORY;
NameStartAddr: DWord;
FuncStartAddr: DWord;
ExportName: PChar;
i: Integer;
const
k32: PChar = '
kernel32.dll';
GPA: PChar = '
GetProcAddress';
begin
// (1)
Result :=
NIL;
_PEB := GetPEB();
_FirstItem := @_PEB^.Ldr^.InMemoryOrderModuleList;
if _FirstItem =
NIL then
Exit;
// (2)
_CurrentItem := _FirstItem^.Flink;
ModuleFound := False;
while ( _CurrentItem <> _FirstItem )
and (
not ModuleFound )
do
begin
_Module := PLDR_MODULE( _CurrentItem );
ModuleName := WideCharToString( _Module^.FullDllName.Buffer );
ModuleFound := ModuleName = k32;
_CurrentItem := _CurrentItem^.Flink;
end;
// (3)
if ModuleFound
then
begin
ImageBase := DWord( _Module^.InInitializationOrderModuleList.Flink );
pDosHeader := Pointer( ImageBase );
if pDosHeader^.e_magic = IMAGE_DOS_SIGNATURE
then
begin
pNTHeaders := Pointer( ImageBase );
inc( Cardinal( pNTHeaders ), pDosHeader^._lfanew );
if pNTHeaders^.Signature = IMAGE_NT_SIGNATURE
then
begin
pExportTable := Pointer( ImageBase +
pNTHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress );
NameStartAddr := ImageBase + DWord( pExportTable^.AddressOfNames );
FuncStartAddr := ImageBase + DWord( pExportTable^.AddressOfFunctions );
// (4)
for i := 0
to pExportTable^.NumberOfNames-1
do
begin
ExportName := pChar( ImageBase + PDWord( NameStartAddr + 4*i )^ );
if String( ExportName ) =
String( GPA )
then
begin
Result := Pointer( ImageBase + PDWord( FuncStartAddr + 4*(i+1) )^ );
Exit;
end;
end;
end;
end;
end;
end;