Announcement

Collapse
No announcement yet.

DLL-Funktionsaufruf systemweit abfangen

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • DLL-Funktionsaufruf systemweit abfangen

    Hallo,<p>
    stehe immer noch vor dem Problem, dass ich eine DLL habe, die verschiede Funktionen exportiert. Diverse Programme greifen auf diese DLL zurück. Ich muss eine Funktion ändern. Ein austauschen der DLL ist NICHT möglich. Es muss doch möglich sein, zu überwachen, wann ein Programm eine bestimmte Funktion aus der DLL importiert und ausführt. Ich müsste dann diese abfangen und auf eine andere DLL (selber Funktionsname) "umbiegen". Ich denke mal, soetwas ist nur mit einem Hook möglich. Leider habe ich mit Hooks so gut wie keine Erfahrung und bräuchte deshalb einen entsprechenden Quellcode als Beispiel. Mir ist bekannt, dass das Thema Hook mit Vorsicht zu geniesen ist. Für Hilfe auserhalb des Forums wäre ich dankbar. @Andres Kosch.

  • #2
    Hallo,

    das Thema würde mich auch interessieren, da ich ein ähnliches Problem habe.

    Aber warum ist ein Austausch der DLL nicht möglich?

    Tschüss..

    Comment


    • #3
      Hallo,

      um eine DLL-Funktion zur Laufzeit durch eine eigene Version zu ersetzen, ist folgendes notwendig:<br>
      a) Funktionstyp mit den gleichen Parametern und der gleichen Aufrufkonvention (stdcall) deklarieren <br>
      b) Variable für diesen Funktionstyp deklarieren <br>
      c) Originale Adresse der MessageBox-Funktion aus dem PE-Header ermitteln <br>
      d) Neue Adresse der eigenen Implementierung der Funktion NewMessageBox über den Aufruf der Win32-API-Funktion WriteProcessMemory eintragen

      Dank JEDI stehen für diese Aufgaben bereits fertige Routinen zur Verfügung, wie das folgende Beispiel demonstriert:
      <pre>
      { ************************************************** *******************
      Autor : Andreas Kosch
      Compiler : Delphi 5 UpdatePack#1
      Betriebssystem : Windows 2000
      Datum : 02.12.2000
      Beschreibung : Demonstration der Project JEDI Code Library (JCL)
      am Beispiel der Unit JclPeImage.
      (http://delphi-jedi.org/Jedi:CODELIBJCL)
      Die Win32-API-Funktion MessageBox kann zur Laufzeit
      durch eine eigene Version ausgetauscht werden.
      ************************************************** ******************** }

      unit HookMessageBox2Frm;

      interface

      uses
      Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs,
      ComCtrls, StdCtrls;

      type
      TForm2 = class(TForm)
      ButtonHook: TButton;
      ButtonMessageBox: TButton;
      ButtonUnHook: TButton;
      StatusBar1: TStatusBar;
      procedure ButtonHookClick(Sender: TObject);
      procedure ButtonMessageBoxClick(Sender: TObject);
      procedure ButtonUnHookClick(Sender: TObject);
      private
      { Private-Deklarationen }
      public
      { Public-Deklarationen }
      end;

      var
      Form2: TForm2;

      implementation

      {$R *.DFM}

      uses
      JclPeImage;

      type
      THookMessageBox = function(hWnd: HWND; lpText, lpCaption: PChar;
      uType: UINT): Integer; stdcall;

      var
      OrgMessageBox : THookMessageBox = nil;

      {------------------------------------------------------------}
      { Neue Fassung der Win32-API-Funktion MessageBox }
      {------------------------------------------------------------}

      function NewMessageBox(hWnd: HWND; lpText, lpCaption: PChar;
      uType: UINT): Integer; stdcall;
      begin
      MessageBeep(0);
      Result := MessageDlg(lpText, mtInformation, [mbYes], 0);
      MessageBeep(0);
      end;

      procedure TForm2.ButtonHookClick(Sender: TObject);
      begin
      if PeImportHooks.HookImport(Pointer(HInstance), user32, 'MessageBoxA',
      @NewMessageBox, @OrgMessageBox) then
      StatusBar1.SimpleText := 'API-Funktion MessageBox wurde ausgetauscht.';
      end;

      procedure TForm2.ButtonMessageBoxClick(Sender: TObject);
      begin
      MessageBox(Handle, 'Text aus dem Client', 'Test', 0);
      end;

      procedure TForm2.ButtonUnHookClick(Sender: TObject);
      begin
      if PeImportHooks.UnhookByNewAddress(@NewMessageBox) then
      begin
      @OrgMessageBox := nil;
      StatusBar1.SimpleText := '';
      end;
      end;

      end.
      </pre>
      Wenn dieser Austausch für <b>fremde</b> Anwendungen erfolgen soll, dessen Sourcecode man nicht hat, kann die von Microsoft beschriebene Technik der <b>Injekt-DLL</b> verwendet werden. Eine Suche nach dem Begriff "Injekt" liefert einige Anhangspunkte

      Comment


      • #4
        Hallo Andreas,<p>es geht um einen Austausch fremder Anwendungen. Ich hab zwar unter dem Begriff "Inject" in der MSDN nachgeschaut, aber ich verstehe das ganze nicht so richtig. Ich bitte deshalb um eine genaue Erklärung ggf. mit Quellcode. Danke

        Comment


        • #5
          theoretisch ist es einfach erklärt...<br>
          (1) man implementiere die neue Funktion in eine DLL<br>
          (2) und bringe sie in jeden Zielprozeß, der die Originalversion benutzt<br>
          (3) Dann biegt man die Funktion auf die eigene um<br>
          (xxx) und jede Menge Verwaltungsaufwand, damit das System stabil bleibt...<p>
          In der Theorie schön und gut, aber spätestens bei 2. gibt's unter NT/2K/XP Probleme.<br>
          Zudem muß man eine Menge von Windows, Prozessen, Threads und insbesondere PE's verstehen.<p>
          Dem Problem in allgemeiner Form hat schon jemand seine Zeit geopfert, und eine IMHO sehr gute Hook-API geschrieben (Delphi-Units/Beispiele sind vorhanden).<br>
          ApiHooks ist zu finden unter <a href="http://EliCZ.com">http://EliCZ.com</a>

          Gruß Nic

          Comment


          • #6
            Hallo,

            ich hatte mit dem Satz "<i>Eine Suche nach dem Begriff "Injekt" liefert einige Anhangspunkte</i>" die Suche hier im FORUM gemeint :-

            Comment


            • #7
              OffTopic: in dieser Beziehung ist das Forum allemal besser als MSDN =)

              Gruß Nic

              Comment


              • #8
                Hallo,<p>zuerteinmal danke für die Infos. Ich wollte nun mal das Beispiel von Andreas Kosch genauer anschauen. Leider funktioniert das nicht. Ich habe von JEDI die Units heruntergeladen. Ich verwende Delphi 5, Jedi VCL Version 1.02. Kann ich evtl. mal den kompletten Sourcecode des Beispiels haben

                Comment


                • #9
                  Hallo,

                  ich muss mich auch gleich mal wieder einmischen

                  Ich muss Elmar recht geben, dass die "Injekt-DLL" eine sagenumwoben Datei in diesem Forum ist, die aber nie vollständig (funktionstüchtig ) dargestellt wurde. <i>Dies soll keine so ernsthafte Kritik sein...</i>

                  Es wird sehr viel darüber diskutiert und von Andreas gute Tipps zu weiteren Informationen gegeben. Sicherlich ist dies auch ein sehr komplexes Thema, somit auch sehr verwirrend.

                  Aber nun zurück zum Thema:<br>
                  Haben die Funktionen in der DLL unbekannte Parameter oder <b><i>warum ist sie nicht ersetzbar</b></i>(es gäbe noch eine vielleicht trivialere Lösung)?

                  Tschüss..

                  Comment


                  • #10
                    Hallo,

                    eine Injekt-DLL gehört in den "Giftschrank", da man mit dem Teil schlimme Sachen machen kann. Ich unterstelle niemanden böse Absichten, aber so ganz ohne Fleiß wird es nicht gehen :-)

                    Der Grund, warum es in meinen Büchern kein Beispielprojekt dafür gibt ist einfach: Ich bin zu faul, das umfangreiche Microsoft-Beispiel aus dem Buch <i>Win32-Programmierung für Experten</i> von C nach Delphi zu übersetzen, zumal ich selbst <b>keine</b> Verwendung dafür hätte. Die erste Teilaufgabe (fremden Prozess dazu bringen, die DLL in seinen eigenen Adressraum zu laden) ist einfach, aber der Rest hat es etwas in sich.

                    Zur Frage von Elmar: <br>
                    Was funktioniert daran nicht? Ich habe das ZIP-Archiv mit dem Beispielprojekt unter dem Titel <i>Win32-API-Funktion zur Laufzeit austauschen</i> im <b>Download</b>-Ordner des Forums abgelegt

                    Comment


                    • #11
                      Hallo,<p>es ist zum heulen und ich dachte, dass ist nur ein kleines Problem.....<p>
                      <b>@Andres:</b><br>der Code vom 22.08.01 funktioniert nicht. Das Beispiel unter Downloads habe ich heruntergeladen und habe das gleiche Problem. Ich bekomme folgende Meldung:<br>
                      <i>[Fehler] HookMessageBox2Frm.pas[67] Undefinierter Bezeichner PeImportHooks</I><br>
                      Ich habe dann den Abschnitt in der JclPeImage.pas (HookImport) herausgesucht und folgende Zeile hinzugefügt:<br>
                      <i>var PeImportHooks: TJclPeMapImgHooks</i>;<br>Funktioniert aber nicht, bekomme immer eine Fehlermeldung bei folgenden Zeilen:<br>
                      <i>function TJclPeMapImgHooks.GetItemFromOriginalAddress(Origi nalAddress: Pointer): TJclPeMapImgHookItem;<br>
                      var<br>
                      I: Integer;<br>
                      begin<br>
                      Result := nil;<br>
                      for I := 0 to Count - 1 do<br>
                      if Items[I].OriginalAddress = OriginalAddress then<br>
                      begin<br>
                      Result := Items[I];<br>
                      Break;<br>
                      end;<br>
                      end;</i><br>
                      Kann ich mal die Dateien (JEDI) haben, die bei der Erstellung des Projekts verwendet wurden bzw. kann man das mal mit den neuen probieren?<p>
                      <p>
                      <b>@Tim:</b><br>Es handlet sich dabei um eine Windowssystemdatei (DLL). Diese kannst Du nicht so ohne weiteres austauschen.<br>
                      1. Unterschiedliche Betriebssystem<br>
                      2. Unterschiedliche Versionen<br>
                      3. Möglichrweise überschreibt ein anders Programm die geänderte DLL wieder.<br>
                      Das einzige was ich möchte/machen muss ist eine Funktion auf Systemebene ändern. D.H. Alle Programme usw. müssen auf diese geänderten Teil zugreifen. Vorschläge

                      Comment


                      • #12
                        Hello Elmar,

                        Es wurde nötig die globalen Variablen (und die Initialization bzw. Finalization Sektion) aus der JCLPeImage zu nehmen. Du must sie jetzt einfach der Unit HookMessageBox2Frm hinzufügen. Also

                        var
                        PeImportHooks: TJclPeMapImgHooks;

                        [...]

                        initialization
                        PeImportHooks := TJclPeMapImgHooks.Create;

                        finalization
                        PeImportHooks.Free;

                        end.

                        Getestet mit dem JCL 1.11 Release

                        Comment


                        • #13
                          Hallo,

                          erstmal ein Kompliment an Andreas . Das Beispiel im Download-Bereich ist schonmal ganz gut, aber leider hatte ich anfangs das gleiche Problem wie Elmar, aber Matthias hat es ja schon geklärt.

                          Jedoch musste ich feststellen, das sich das Beispiel mehr auf die eigene Anwendung bezieht und nicht "systemweit" gilt. Gäbe es noch eine andere Möglichkeit einen globalen Hook zu schreiben?

                          Gibt es irgendwo den C-source zum Download aus dem Buch <i><b>"Win32-Programmierung für Experten"</b></i>?

                          Tschüss Ti

                          Comment


                          • #14
                            Hallo,<p>
                            <b>@Matthias:</b><br> Danke, soetwas dachte ich mir schon. Hab wieder etwas dazugelernt.<p>
                            <b>@Andres:</b><br>Das Beispiel ist für die eigene Anwendung wirklich sehr gut, dieses kann ich bestimmt einmal später in einem Programm verwenden. Wie auch Tim interessiert mich der C-Code von Microsoft. Herr Kosch, wie schwer ist dieser, in Delphi zu übersetzten?<br><i>...zumal ich selbst keine Verwendung dafür...</i><br>Standen Sie nicht einmal vor dem Problem eine Funktion von Windows gegen eine eigene Systemweit auszutauschen oder gibt es da noch eine andere Möglichkeit

                            Comment


                            • #15
                              Hallo,<p>folgenden Auszug zum Thema <b>Injekt-DLL</b> habe ich dazu gefunden. Microsoft beschreibt hierbei die drei Möglichkeiten die es gibt:<p>
                              <i>You can use the registry, hooks, or remote threads and the
                              WriteProcessMemory() API to inject code into another process's address
                              space.
                              <p>
                              If you use the registry, the code that needs to be injected should reside in a DLL. By either running REGEDIT.EXE or using the registry APIs, add the HKEY_LOCAL_MACHINE\Software\Microsoft\Windows\AppI nit_DLLs key to the
                              registry if it does not exist. Set its value to a string containing the DLL's pathname. This key may contain more than one DLL pathname separated by single spaces. This has the effect, once the machine is restarted, of loading the library with DLL_PROCESS_ATTACH into every process at its screation time. While this method is very easy, it also has several disadvantages. For example, the computer must be restarted before it takes effect, and the DLL will last the lifetime of the process.
                              <p>
                              You can also use hooks to inject code into another process's address space. When a window hooks another thread belonging to a different process, the system maps the DLL containing the hook procedure into the address space of the hooked thread. Windows will map the entire DLL, not just the hook procedure. So to subclass a window in another process, install a WH_GETMESSAGE hook or another such hook on the thread that owns the window to be subclassed. In the DLL that contains the hook procedure, include the subclass window procedure. In the hook procedure, call SetWindowLong() to enact the subclass. It is important to leave the hook in place until the subclass is no longer needed, so the DLL remains in the target window's address space. When the subclass is removed, the hook would be unhooked,
                              thus unmapping the DLL.
                              <p>
                              A third way to inject a DLL into another address space involves the use of remote threads and the WriteProcessMemory() API. It is more flexible and significantly more complicated than the previously mentioned methods, and is described in the following reference.
                              </i>
                              <p>
                              Frage dazu, welcher Weg ist am sinnvollsten und hat jemand dazu Quelltext o.ä.

                              Comment

                              Working...
                              X