Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Win32/Win64 API (native code) (https://www.delphipraxis.net/17-win32-win64-api-native-code/)
-   -   Delphi Probleme beim Patchen der IAT (https://www.delphipraxis.net/110203-probleme-beim-patchen-der-iat.html)

CorVu5 14. Mär 2008 15:57


Probleme beim Patchen der IAT
 
Hallo Leute und Hallo Delphi-Praxis,
ich habe folgendes Problem. Und zwar versuche ich grad eine Funktion zu schreiben die die IAT patcht und Funktionsaufrufe sozusagen "umleiten" kann.
Ich stoße dabei auf das Problem ,dass ich zwar die korrekte Adresse ausgegeben bekomme, sagt jedenfalls PEview,
Delphi-Quellcode:
@Funktion
oder
Delphi-Quellcode:
GetProcAddress(GetModuleHAndle('user32.dll'),'Funktion')
aber andere Adressen ausgeben.
Möglicherweise liegt ja ein ganz simpler Denkfehler meinerseits vor.


Mein Code bis jetzt:
Delphi-Quellcode:
type
  PImageImportDescriptor = ^TImageImportDescriptor;
  TImageImportDescriptor = packed record
     HintNameTableOffset: DWORD;   // RVA to original unbound IAT, aka Characteristics
                                    // 0 for terminating null import descriptor
                                    // PImageThunkData
     TimeDateStamp     : DWORD;   // 0 if not bound,
                                    // -1 if bound, and real date\time stamp
                                    //     in IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT (new BIND)
                                    // O.W. date/time stamp of DLL bound to (Old BIND)
      ForwarderChain   : DWORD;   // -1 if no forwarders
      NameOffset       : DWORD;   // RVA to name of the module we're importing from
      IATOffset        : DWORD;   // RVA to IAT (if bound this IAT has actual addresses)
                                    // PImageThunkData
  end;

  PImageImportByName = ^TImageImportByName;
  TImageImportByName = packed record
    Hint : WORD;
    Name : array[0..255] of Char;
  end;

  PImageThunkData = ^TImageThunkData;
  TImageThunkData = packed record
    case integer of
      0 : (ForwarderString: PBYTE);
      1 : (FunctionPtr   : PDWORD);
      2 : (Ordinal       : DWORD);
      3 : (AddressOfData : PImageImportByName);
  end;

Delphi-Quellcode:
procedure PatchIAT(Dll : Pchar; OldFunction : Pointer; newFunc : Pointer);
var
image : LoadedImage;
pImageImportDir : PIMAGEIMPORTDESCRIPTOR;
last : PImageSectionHEader;
size : Cardinal;
dllname : Pchar;
pThunk : PImageThunkData;
lTrue : Boolean;
written : Cardinal;
begin
MapAndLoad(Pchar(ParamStr(0)),nil,@image,True,True);
pImageImportDir := ImageDirectoryEntryToData(
                    image.MappedAddress
                    ,False
                    ,IMAGE_DIRECTORY_ENTRY_IMPORT
                    ,size);

while pImageImportDir.NameOffset <> 0 Do begin
  dllname := ImageRVAToVA(image.FileHeader,image.MappedAddress,pImageImportDir.NameOffset,last);
  If (lstrcmpiA(dllname , Dll) = 0) Then break;
  Inc(pImageImportDir);
end;
{Showmessage(dllname); }
pThunk := ImageRVAToVA(image.FileHeader,image.MappedAddress,pImageImportDir.IATOffset,last);
While pThunk^.FunctionPtr <> nil Do begin
  Showmessage(FloatTostr(Cardinal(pThunk^.FunctionPtr)));
  Showmessage(IntToStr(Integer(Oldfunction)));
  ltrue := (pThunk^.FunctionPtr = OldFunction );
  If lTrue then begin
    Showmessage('FOUND2');
    {VirtualProtectEx(GetCurrentProcess,pThunk.FunctionPtr,4,PAGE_EXECUTE_READWRITE,written);
    WriteProcessMemory(GetCurrentProcess, pThunk.FunctionPtr, NewFunc, sizeof(NewFunc), Written);
    }break;
  end;
Inc(Pthunk);
end;
UnmapAndLoad(@image);
end;
ALs Beispielaufruf:
Delphi-Quellcode:
PatchIAT('user32.dll',GetProcAddress(GetModuleHAndle('user32.dll'),'MessageBoxA'),@newMessageBoxA);

Danke Im Voraus
CorVu5

Flocke 14. Mär 2008 17:55

Re: Probleme beim Patchen der IAT
 
Zitat:

Zitat von CorVu5
Ich stoße dabei auf das Problem ,dass ich zwar die korrekte Adresse ausgegeben bekomme, sagt jedenfalls PEview,
Delphi-Quellcode:
@Funktion
oder
Delphi-Quellcode:
GetProcAddress(GetModuleHAndle('user32.dll'),'Funktion')
aber andere Adressen ausgeben.
Möglicherweise liegt ja ein ganz simpler Denkfehler meinerseits vor.

Delphi fügt einen zusätzlichen Sprung ein, so dass das Symbol in Delphi und die Funktion selbst unterschiedliche Adressen haben. Im Grunde sieht das so aus:
Code:
CreateWindowExA:
0408CE4: FF2580EE6500     jmp    [user32.CreateWindowExA]
0408CEA: 8BC0             mov    eax, eax
CreateWindowExW:
0408CEC: FF257CEE6500     jmp    [user32.CreateWindowExW]
0408CF2: 8BC0             mov    eax, eax
wobei die indirekten Adressen [user32.CreateWindowEx?] in die IAT stehen.

CorVu5 16. Mär 2008 13:55

Re: Probleme beim Patchen der IAT
 
aha..danke erstmal! :thumb:
Aber was soll ich jetzt machen?
das würde ja heißen, dass der Code nur mit Nicht-Delphi-Programmen funktionieren würde. :pale:

Andere Beispiele, z.B.
http://www.koders.com/delphi/fid0092...7B.aspx?s=hook
oder
http://www.delphipraxis.net/internal...ct.php?t=59230
verzichten jedoch auf so etwas...
Außerdem, sollte der Aufruf über die API (GetProcAddress) nicht trotzdem die richtige Adresse zurückgeben?
*verwirrt*

CorVu5 18. Mär 2008 11:20

Re: Probleme beim Patchen der IAT
 
Ich habe eine neue Idee!
Nämlich nicht mehr die Adressen zu vergleichen, sondern einfach die Funktionsnamen auszulesen.
Delphi-Quellcode:
  PImageImportByName = ^TImageImportByName;
  TImageImportByName = packed record
    Hint : WORD;
    Name : array[0..255] of Char;
  end;
Wenn ich aber versuche, den Namen auszugeben, kommt eine Access Violation. :(
Delphi-Quellcode:
pbyName := pThunk^.AddressOfData;
Showmessage(pByname^.Name);
Woran könnte das liegen?

CorVu5 18. Mär 2008 11:33

Re: Probleme beim Patchen der IAT
 
:coder2: ups, sorry...schon selber rausgekriegt...
Delphi-Quellcode:
pbyName := ImageRVAtoVA(image.FileHeader,image.MappedAddress,Cardinal(pThunk^.AddressOfData),last);
Erst denken ,dann posten :oops:

CorVu5 18. Mär 2008 19:17

Re: Probleme beim Patchen der IAT
 
Ja, ich schon wieder :oops:
zu früh gefreut..
Der Code läuft jetzt ohne Fehler durch und es werden auch sämtliche Funktionen im IAT gefunden, die API (MessageBoxA) bleibt aber ausführbar :wall: :(
Mein modifizierter Code:
Delphi-Quellcode:
procedure PatchIAT(Dll : Pchar; OldFunction :String; newFunc : Pointer);
var
image : LoadedImage;
pImageImportDir : PIMAGEIMPORTDESCRIPTOR;
last : PImageSectionHEader;
size : Cardinal;
dllname : Pchar;
pThunk : PImageThunkData;
lTrue : Boolean;
written : Cardinal;
pByName : pImageImportByName;
begin
MapAndLoad(Pchar(ParamStr(0)),nil,@image,True,True);
pImageImportDir := ImageDirectoryEntryToData(
                    image.MappedAddress
                    ,False
                    ,IMAGE_DIRECTORY_ENTRY_IMPORT
                    ,size);
while pImageImportDir.NameOffset <> 0 Do begin
  dllname := ImageRVAToVA(image.FileHeader,image.MappedAddress,pImageImportDir.NameOffset,last);
  If (lstrcmpiA(dllname , Dll) = 0) Then begin
    Showmessage('DLL GEFUNDEN');
    pThunk := ImageRVAToVA(image.FileHeader,image.MappedAddress,pImageImportDir.IATOffset,last);
    While pThunk^.FunctionPtr <> nil Do begin
      pbyName := ImageRVAtoVA(image.FileHeader,image.MappedAddress,Cardinal(pThunk^.AddressOfData),last);;
      //Showmessage(pbyname.Name);
      IF pbyName.Name = OldFunction Then begin
        Showmessage('FUNKTION GEFUNDEN');
        VirtualProtectEx(GetCurrentProcess,pThunk^.FunctionPtr,4,PAGE_EXECUTE_READWRITE,written);
        WriteProcessMemory(GetCurrentProcess, pThunk^.FunctionPtr, Addr(newFunc), sizeof(newFunc), Written);
        {pThunk^.FunctionPtr := newFunc;}
      end;
        Inc(Pthunk);
    end;
  end;
  Inc(pImageImportDir);
end;
UnmapAndLoad(@image);
end;





function newMessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
Form1.Button1.Caption := 'NO MSGBOX!';
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
PatchIAT('user32.dll','MessageBoxA',@newMessageBoxA);
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
MessageBoxA(0,'DD','DD',0);
end;
Ich kann leider auch mit dem Olly nicht testen, ob wirklich in die Iat geschrieben wird :(
Weiß wer woran das liegt?
Hamtaro


Alle Zeitangaben in WEZ +1. Es ist jetzt 16:06 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz