![]() |
Adresse von GetProcAddress OHNE GetProcAddress ermitteln ;)
Hiermit möchte ich euch eine Routine beschreiben, mit der man ohne GetProcAddress die Adresse von GetProcAddress (und somit auch andere exportierte Funktionen) ermitteln kann.
Die Function _GetProcAddress() macht folgendes:
Referenzen: ![]() ![]() MfG und viel Spaß damit ;)
Delphi-Quellcode:
{ --| 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;
Delphi-Quellcode:
function _GetModuleAddress( ModuleName: PChar ): Pointer;
var _PEB: PPEB; _FirstItem, _CurrentItem: PListEntry; _Module: PLDR_MODULE; CurrentModule: String; ModuleFound: Boolean; begin Result := NIL; _PEB := GetPEB(); _FirstItem := @_PEB^.Ldr^.InMemoryOrderModuleList; if _FirstItem = NIL then Exit; _CurrentItem := _FirstItem^.Flink; ModuleFound := False; while ( _CurrentItem <> _FirstItem ) and ( not ModuleFound ) do begin _Module := PLDR_MODULE( _CurrentItem ); CurrentModule := WideCharToString( _Module^.FullDllName.Buffer ); ModuleFound := CurrentModule = ModuleName; _CurrentItem := _CurrentItem^.Flink; end; if ModuleFound then Result := _Module^.InInitializationOrderModuleList.Flink; end; function _GetProcAddress( ModuleAddress: Pointer; ProcName: PChar ): Pointer; var pDosHeader: ^_IMAGE_DOS_HEADER; pNTHeaders: ^_IMAGE_NT_HEADERS; pExportTable: ^_IMAGE_EXPORT_DIRECTORY; NameStartAddr: DWord; FuncStartAddr: DWord; ExportName: PChar; i: Integer; begin pDosHeader := ModuleAddress; if pDosHeader^.e_magic = IMAGE_DOS_SIGNATURE then begin pNTHeaders := ModuleAddress; inc( Cardinal( pNTHeaders ), pDosHeader^._lfanew ); if pNTHeaders^.Signature = IMAGE_NT_SIGNATURE then begin pExportTable := Pointer( DWord( ModuleAddress ) + pNTHeaders^.OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress ); NameStartAddr := DWord( ModuleAddress ) + DWord( pExportTable^.AddressOfNames ); FuncStartAddr := DWord( ModuleAddress ) + DWord( pExportTable^.AddressOfFunctions ); for i := 0 to pExportTable^.NumberOfNames-1 do begin ExportName := pChar( DWord( ModuleAddress ) + PDWord( NameStartAddr + 4*i )^ ); if String( ExportName ) = String( ProcName ) then begin Result := Pointer( DWord( ModuleAddress ) + PDWord( FuncStartAddr + 4*(i+1) )^ ); Exit; end; end; end; end; end; |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Ohne in Abrede zu stellen, dass das ein sehr interessante Stück Code ist - wozu soll das gut sein? :)
|
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Im Grunde wird sie genau dann benötigt, wenn einem GetProcAddress nicht zur Verfügung
steht - dh. Code-Injection, Shellcode Entwicklung ( Computer Sicherheit ) usw. Natürlich kann man es auch für andere Zwecke missbrauchen :P MfG |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Könntest du das nicht in zwei Funktionen zerlegen?
Mit dieser Adresse und dem Namen der Funktion (hier: 'GetProcAddress') ruft man dann die zweite Funktion auf, und erhält dann die Einsprungadresse. Dies entspricht dann Punkt (3) und (4). Nach dieser Zerlegung in zwei Funktionen versteht man den Code besser und kann auch mehr damit anfangen. |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Vorschlag angenommen; Siehe Beitrag #1
|
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Zitat:
Delphi-Quellcode:
function _GetProcAddress(): Pointer; overload;
begin Result := _GetModuleAddress('kernel.dll'); if Assigned(result) then Result := _GetProcAddress(Result, 'GetProcAddress'); end; |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
:warn:
:roll: |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
+1 Internets.
Auch wenn ich noch nicht weiß, ob ich es jemals gebrauchen kann... |
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Man kann damit auch die Leute etwas ärgern, die immer alles umsonst haben müssen :mrgreen: ;)
|
Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln
Zitat:
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 02:41 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz