Einzelnen Beitrag anzeigen

Benutzerbild von Aphton
Aphton

Registriert seit: 31. Mai 2009
1.198 Beiträge
 
Turbo Delphi für Win32
 
#1

Adresse von GetProcAddress OHNE GetProcAddress ermitteln ;)

  Alt 18. Aug 2009, 23:53
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:
  • (1) Zuerst wird die Adresse von PEB (Process Enviroment Block) ermittelt
  • (2) Anschließend wird die doppelt verkettete Liste (LDR) abgearbeitet und nach dem Module "kernel32.dll" gesucht: wird sie gefunden, darfs weiter gehen
  • (3) die Funktion hangelt sich durch das Image-Format bis zur Export Table der DLL;
  • (4) hier werden alle Namen ausgelesen, verglichen und bei Übereinstimmung wird die Adresse der Funktion als Result zurück gegeben

Referenzen:
Undocumented.ntinternals - struct _PEB
msdn - PEB

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;
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat