AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Code-Bibliothek Neuen Beitrag zur Code-Library hinzufügen Delphi Adresse von GetProcAddress OHNE GetProcAddress ermitteln ;)

Adresse von GetProcAddress OHNE GetProcAddress ermitteln ;)

Ein Thema von Aphton · begonnen am 19. Aug 2009 · letzter Beitrag vom 19. Aug 2009
Antwort Antwort
Seite 1 von 2  1 2   
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 19. Aug 2009, 00: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
Dax
(Gast)

n/a Beiträge
 
#2

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 01:19
Ohne in Abrede zu stellen, dass das ein sehr interessante Stück Code ist - wozu soll das gut sein?
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

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

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 01:44
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

MfG
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#4

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 03:53
Könntest du das nicht in zwei Funktionen zerlegen?
  • (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
Diese beiden Punkte zusammen entsprechen ja der Funktion GetModuleAddress('kernel.dll').
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.
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

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

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 04:17
Vorschlag angenommen; Siehe Beitrag #1
das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von sx2008
sx2008

Registriert seit: 16. Feb 2008
Ort: Baden-Württemberg
2.332 Beiträge
 
Delphi 2007 Professional
 
#6

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 05:11
Zitat von Aphton:
Vorschlag angenommen; Siehe Beitrag #1
Ok, und dann noch schnell die Früchte der Arbeit ernten:
Delphi-Quellcode:
function _GetProcAddress(): Pointer; overload;
begin
  Result := _GetModuleAddress('kernel.dll');
  if Assigned(result) then
    Result := _GetProcAddress(Result, 'GetProcAddress');
end;
fork me on Github
  Mit Zitat antworten Zitat
Benutzerbild von Aphton
Aphton

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

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 05:54


das Erkennen beginnt, wenn der Erkennende vom zu Erkennenden Abstand nimmt
MfG
  Mit Zitat antworten Zitat
Benutzerbild von wicht
wicht

Registriert seit: 15. Jan 2006
Ort: Das schöne Enger nahe Bielefeld
809 Beiträge
 
Delphi XE Professional
 
#8

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 08:58
+1 Internets.
Auch wenn ich noch nicht weiß, ob ich es jemals gebrauchen kann...
http://streamwriter.org

"I make hits. Not the public. I tell the DJ’s what to play. Understand?"
  Mit Zitat antworten Zitat
Benutzerbild von OldGrumpy
OldGrumpy

Registriert seit: 28. Sep 2006
Ort: Sandhausen
941 Beiträge
 
Delphi 2006 Professional
 
#9

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 09:55
Man kann damit auch die Leute etwas ärgern, die immer alles umsonst haben müssen
"Tja ja, das Ausrufezeichen... Der virtuelle Spoiler des 21. Jahrhunderts, der Breitreifen für die Datenautobahn, die k3wle Sonnenbrille fürs Usenet. " (Henning Richter)
  Mit Zitat antworten Zitat
Benutzerbild von hitzi
hitzi

Registriert seit: 2. Jan 2003
Ort: Eibau
768 Beiträge
 
Delphi 2010 Professional
 
#10

Re: Adresse von GetProcAddress OHNE GetProcAddress ermitteln

  Alt 19. Aug 2009, 10:18
Zitat von OldGrumpy:
Man kann damit auch die Leute etwas ärgern, die immer alles umsonst haben müssen
Kannst du dazu bitte ein bissl mehr sagen? Würde mich interessieren.
Thomas
Besucht doch mal http://www.hitziger.net
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2   

Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +2. Es ist jetzt 01:49 Uhr.
Powered by vBulletin® Copyright ©2000 - 2021, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2021 by Daniel R. Wolf