AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Win32/Win64 API (native code) Delphi DLL Funktion Hook - Allgemeingültige Lösung / Codevorlage?

DLL Funktion Hook - Allgemeingültige Lösung / Codevorlage?

Offene Frage von "blackdrake"
Ein Thema von blackdrake · begonnen am 19. Jul 2009 · letzter Beitrag vom 23. Jul 2009
Antwort Antwort
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#1

DLL Funktion Hook - Allgemeingültige Lösung / Codevorlage?

  Alt 19. Jul 2009, 17:36
Hallo zusammen.

Ich habe mal endlich wieder mehr Zeit und mache mich mal wieder über ein paar alte Projekte her.

Ich hatte mehrmals schon ansatzweise versucht, eine DLL Funktion zur Laufzeit zu überschreiben (gab hier sogar ein paar Themen dazu).

* Zum einen hörte ich etwas von statischen und dynamischen DLLs (ich weiß, was das bedeutet) und dass man je nach dem unterschiedlich vorgehen muss.

* Zum anderen fiel das Wort "Inline Hook" wenn ich eine Funktion einer DLL systemweit überschreiben möchte.

Letzteres ergab bei mir eine schlechte Google Recherche, bei der ich nicht schlauer geworden bin: http://www.google.de/search?hl=de&sa...nG=Suche&meta=

Es gibt also 4 Möglichkeiten:

1. Funktion einer statisch geladenen DLL für einen Prozess umbiegen
2. Funktion einer dynamisch geladenen DLL für einen Prozess umbiegen
3. Funktion einer statisch geladenen DLL systemweit umbiegen
4. Funktion einer dynamisch geladenen DLL systemweit umbiegen

Wobei 3 und 4 eigentlich ein Punkt sind, denn wenn ich etwas systemweit umbiegen will, dann darf es im Endresultat keinen Unterschied machen, ob die DLL dynamisch oder statisch geladen ist.

Nun meine Frage, damit ich endlich mal verstehe, wie so etwas funktioniert - kann mir jemand Codes zeigen, bei denen ganz einfach das Hooken einer Funktion mit diesen 4 Möglichkeiten gezeigt wird, sodass ich das korrekt nachvollziehen kann?

Im Moment hätte ich nämlich folgenden Bedarf an Hooks:
- Ich möchte versuchen, eine Funktion der system32.dll systemweit umzubiegen (Thread: Windows dazu bringen, dass Dateien sicher gelöscht werden)
- Ich möchte versuchen, eine Funktion der winmm.dll für einen bestimmten Prozess umzubiegen, sodass ich alle ausgehenden MIDI-Kommandos mitschneiden kann. (Dynamisch/Statische DLL im Moment unbekannt)

Ich hoffe, irgendwo da draußen gibt es so eine Art "Kochbuch", in dem eine Hook Lösung für Delphi so einfach dargestellt wird, dass man sie einfach auf die eigenen Wünsche adaptieren kann.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#2

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 19. Jul 2009, 18:03
Naja es kommt auch ncoh auf die Sicherheit an, dynamisch oder statisch geladene DLLs sind eigentelich wurscht, jedenfalls wenn man CodeOverwriting verwendet.

Für CodeOverwriting im User-Mode reicht es eigentlich für das systemweite hooking den hookcode in jeden Prozess zu laden.
Für kommerzielle Programme solltest du mal www.madshi.net besuchen, für freie programme und OpenSource gibts u.a. Codehooking von Flocke bzw. mir ( http://uall.cheat-project.com/uallCollection ). Da kannste dir rasukopieren was du willst.

Für sicherheitsrelevante Anwendungen, solltest du dann kernelhooking (Treiber, einfach mit c++, teilweise über das DDDK möglich) verwenden, da kannst du aber im Grunde nur die Systemfunktionen hooken. Leider aber nicht mehr einache userfunktionen aus dlls (geht zwar auch, indem man CodeOverwriting macht mit Systemcall und protecten durch hooken von VirtualProtect etc., würde ich dir aber nicht empfehlen).

Also für den Anfang mal meien Collection anschaun, da sind hooks drin für z.B. opengl.glBegin usw. und ein testweiser Treiberhook aus Delphi (der vill auf 10% aller Systeme funzt und crahsen kann, also reines konzept zum testen).

Für dich würde wohl madCodehook am besten sein (systemweit durch injecten in alle prozesse, mit codeoverwriting für statische und dynamisch geladene dlls)

Bei madshi gibt es schöne Beschreibungen:
http://help.madshi.net/ApiHookingMethods.htm

Es gibt noch den "RelocationHooking, der bisl besser ist als Import+Export), hab ich damals eingebaut, glaub Madshi verwendet den mittlerweile auch. "Safe unhooking" ist meiner meinugn nach madshis Code nicht, jedenfalls hatten nildo und ich vor 2-3 jahren da mal etwas programmiert wo das Programm danach gecrashed ist. Aber madshis Codehook hat immerhin mehr checks damit nichts crashed.

Einzige wo ich mich bisher immer mit mdashi in den haaren hatte war die sicherheit. Sein codehook wird z.b. bei asquared verwendet (malware check und instrusion dectection system). Man kann es einfach ausschalten indem man die DLL entläft (ist ja im eigene prozess und nicht im kernel). also ist das eigentlich für sicherheitsrelevante programme mist.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#3

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 19. Jul 2009, 20:05
Hallo.

Vielen Dank für deine Antwort und die Links. Ich werde mich gleich mal an dem CodeOverwriting versuchen, um zu schauen, ob ich die Funktion der WinMM umbiegen kann. Ich melde mich wieder und teile mit, ob es funktioniert oder nicht.

Leider scheint es keine allgemeingültige Lösung zu geben und es gibt auch scheinbar nicht nur 4 Fälle, so wie ich dachte, sondern viel mehr.

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#4

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 19. Jul 2009, 20:17
jupp, das Einfachste wäre die DLL auszutauschen, bzw. dafür zu sorgen, daß eine eigene DLL, mit dem selben Namen, in den Suchpfaden vorher gefunden wird
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#5

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 19. Jul 2009, 21:37
Hallo.

Irgendwie scheint das nicht ganz zu funktionieren.

Ich habe jetzt folgenden Code:

Delphi-Quellcode:
  @origMessageBoxA := GetProcAddress(LoadLibrary('winmm.dll'),'midiOutOpen');

  uallHook.HookCode(@origMessageBoxA,@callbackMessageBoxA,@newMessageBoxA);

  readln;

  uallHook.UnhookCode(@newMessageBoxA);
In meiner überschriebenen Funktion wird ein writeln() ausgeführt. Kann es sein, dass midiOutOpne nicht systemweit überschrieben wird? Wie kann ich die Funktion für einen fremden Prozess überschreiben?

// Edit

Nochmal mit MessageBoxA mit den originalen Examples probiert. Ein anderer Prozess ruft MessageBoxA() auf.

* uallHook.HookCode --> Kein Einfluss im Fremdprozess!
* ualltableHook.HookApiJmp --> Kein Einfluss im Fremdprozess!
* uallHook.HookApiIAT --> Kein Einfluss im Fremdprozess!
* uallRelocHook.HookRelocationTable --> Kein Einfluss im Fremdprozess!

(Jeweils zwei Tests gemacht: Fremdprozess läuft bereits und Fremdprozess wurde nach dem Hook gestartet)

Was soll ich machen, damit der Fremdprozess sein Verhalten bezüglich der API Funktion ändert?

// Edit 2

Ich habe mir auch mal das 1337 Example angeschaut und es hatte funktioniert. Jetzt habe ich es auf MessageBoxA umgestellt und es funktioniert nicht! Ich weiß nicht mehr, was ich machen soll.

Hier der komplette Testfall!

HOOK.DLL

Delphi-Quellcode:
library hook;

uses
  windows,
  sysutils,
  uallDisasm in '..\..\uallDisasm.pas',
  uallDisasmEx in '..\..\uallDisasmEx.pas',
  uallHook in '..\..\uallHook.pas',
  uallKernel in '..\..\uallKernel.pas',
  uallProcess in '..\..\uallProcess.pas',
  uallProtect in '..\..\uallProtect.pas',
  uallUtil in '..\..\uallUtil.pas';

var
  origMessageBoxA: function (hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
  newMessageBoxA: function (hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;

function callbackMessageBoxA(hWnd: HWND; lpText, lpCaption: PAnsiChar; uType: UINT): Integer; stdcall;
begin
  Result := newMessageBoxA(hWnd,PChar(lpText+' [hooked]'),lpCaption,uType);
end;

procedure injectmain;
var h: integer;
begin
  h := GetModuleHandle('user32.dll');
  if h > 0 then
  begin
    @origMessageBoxA := GetProcAddress(h,'MessageBoxA');
    if @origMessageBoxA <> nil then
      uallHook.HookCode(@origMessageBoxA,@callbackMessageBoxA,@newMessageBoxA);
  end;
end;

procedure uninjectmain;
begin
  uallHook.UnhookCode(@newMessageBoxA);
end;

procedure dllmain(dwReason: integer);
begin
  case dwreason of
    DLL_PROCESS_ATTACH:
      injectmain;
    DLL_PROCESS_DETACH:
      uninjectmain;
  end;
end;

begin
  DLLProc := @DLLMain;
  DLLMain(1);
end.
EXEMAIN.EXE

Delphi-Quellcode:
program exemain;

uses
  windows,
  tlhelp32,
  uallDisasm in '..\..\uallDisasm.pas',
  uallDisasmEx in '..\..\uallDisasmEx.pas',
  uallHook in '..\..\uallHook.pas',
  uallKernel in '..\..\uallKernel.pas',
  uallProcess in '..\..\uallProcess.pas',
  uallProtect in '..\..\uallProtect.pas',
  uallUtil in '..\..\uallUtil.pas';

const lh = '1337 hook';

begin
  if paramcount < 1 then
    MessageBox(0,'No Param, use PARAM -load / -unload to use 1337 hook',lh,0) else

  if uppercase(paramstr(1)) = uppercase('-load') then
    GlobalInjectLibrary(pchar(uallUtil.GetExeDirectory+'hook.dll')) else

  if uppercase(paramstr(1)) = uppercase('-unload') then
    GlobalUnloadLibrary(pchar('hook.dll')) else

    MessageBox(0,'Wrong Param, use PARAM -load / -unload to use 1337 hook',lh,0);
end.
TEST.EXE (Teil)

Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
begin
  MessageBoxA(handle, 'X', 'Y', 0);
end;
Ergebnis: Ich habe die Hook-DLL geladen (-load) und die Test.exe gestartet. Die erscheinende MessageBoxA hat nicht den erwarteten Zusatz " [hooked]".

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#6

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 22. Jul 2009, 16:58
erst die Test.exe starten dann den hook
was liefert denn HookCode zurück?

Edit: Und welches BS verwendest du?
Edit2: Hab deinen Code gerade getestet, bei mir funktioniert der einwandfrei.
  Mit Zitat antworten Zitat
blackdrake

Registriert seit: 21. Aug 2003
Ort: Bammental
618 Beiträge
 
Delphi 10.3 Rio
 
#7

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 23. Jul 2009, 18:42
Hallo.

Ich habe Win XP SP3. Ich habe alle möglichen Kombinationen probiert und kann versichern, dass MessageBoxA() partout nicht ging. Lediglich AudaCity zeigte ab und zu (!) bei dem "Möchten Sie speichern?" Dialog das [hooked]. Alle anderen Anwendungen waren nicht modifiziert. Keine Ahnung wieso!

Aber: midiOutShortMsg() konnte ich wunderbar hooken und den MIDI-Verkehr mitschneiden (ich habe zuerst den obrigen Code verwendet, dann das Traffic-Demo abgewandelt, damit die Auswertung durch eine Host-Anwendung durchgeführt wird.)

Jetzt habe ich noch ein Problem:

Delphi-Quellcode:
h := GetModuleHandle('winmm.dll');
if h > 0 then
begin
  @origMessageBoxA := GetProcAddress(h,'midiOutShortMsg');
  if @origMessageBoxA <> nil then
    uallHook.HookCode(@origMessageBoxA,@callbackMessageBoxA,@newMessageBoxA);
end;
Alle Prozesse (auch die "neu hinzugekommenen") bekommen meine MIDI-Hook.DLL injeziert. Das Problem ist, dass nicht jede Anwendung winmm.dll eingebunden hat (bei WinAmp wird die winmm.dll beispielsweise erst eingebunden, wenn man eine MIDI öffnet und abspielt.) Bedeutet: Alle Prozesse, die die winmm.dll später einbinden, werden nicht mit aufgezeichnet, da die Bedingung "h > 0" nicht beim DLL-Init erfüllt war.

Frage: (1) Was soll ich dagegen unternehmen? Soll ich vielleicht eine Endlosschleife in die DLL einfügen, sodass der Code ausgeführt wird, sobald "h > 0" wir?

Folgefrage: (2) Wenn "h > 0" eingetreten ist, muss ich dann den HookCode() immer wieder durchführen (z.B. für den Fall dass die zu hook'ende DLL geladen und dann entladen und dann wieder geladen wurde?

Und: (3) Ist es nicht fatal, wenn man eine DLL injeziert, die eine Endlosschleife beeinhaltet? Wenn jeder Prozess des Systems eine solche DLL injeziert bekommt, könnte die CPU-Auslastung ziemlich hoch werden, oder?

Gruß
blackdrake
Daniel Marschall
  Mit Zitat antworten Zitat
Benutzerbild von himitsu
himitsu

Registriert seit: 11. Okt 2003
Ort: Elbflorenz
43.114 Beiträge
 
Delphi 12 Athens
 
#8

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 23. Jul 2009, 18:54
zu 1 und 2:

eigentlich sollte es <> heißen
if h <> 0 then GetModuleHandle liefert das Handle der geladenen DLL
oder 0, wenn diese nicht geladen ist.
Garbage Collector ... Delphianer erzeugen keinen Müll, also brauchen sie auch keinen Müllsucher.
my Delphi wish list : BugReports/FeatureRequests
  Mit Zitat antworten Zitat
brechi

Registriert seit: 30. Jan 2004
823 Beiträge
 
#9

Re: DLL Funktion Hook - Allgemeingültige Lösung / Codevorlag

  Alt 23. Jul 2009, 21:10
Wenn das Modul dynamisch geladen wird kannst du natürlich GetProcAddress hooken und ggf eine andere Addresse (z.B. eine Funktion von dir zurückgeben).

Bzw. du lädst die DLL selbst in dllmain und hookst dann direkt. (ist kein problem wenn dann das programm späternochmal die dll laden will)
  Mit Zitat antworten Zitat
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 +1. Es ist jetzt 03:07 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