Wie kann man einen kostenlosen Funktionsaufruf abfangen, wie es Hippomocks tun?

StackOverflow https://stackoverflow.com//questions/25079768

  •  02-01-2020
  •  | 
  •  

Frage

Ich frage mich, was Hippomocks tun, um das abzufangen exit Rufen Sie die Funktion zum Beispiel auf, wie im folgenden Code gezeigt:

   MockRepository mocks;
   mocks.ExpectCallFunc(exit).With(2).Throw(std::exception());
War es hilfreich?

Lösung

Der Code, der das Abfangen durchführt, ist in hippomocks.h.Es ändert die Speicherschutzflags, um das Schreiben auf die Adresse des bereitgestellten Funktionszeigers zu ermöglichen, und schreibt dann einen Sprungbefehl anstelle der Anfangsbytes der Funktion.Wenn der Hook nicht mehr benötigt wird, werden die ursprünglichen Bytes wiederhergestellt.Dies ist derselbe Ansatz, der beispielsweise von der verwendet wird Microsoft-Umwege Bibliothek.

Andere Tipps

Es wandelt die übergebene Funktion (in diesem Fall einen einfachen Funktionszeiger) in ein char * um, bittet das Betriebssystem darum, darauf schreiben zu dürfen (mit mprotect unter Unices und VirtualProtect unter Windows) und ändert dann die ersten 5 bis 14 Bytes eine bedingungslose Sprunganweisung sein.Es fügt die Adresse einer (unter Verwendung von Vorlagen) generierten Funktion mit identischer Signatur an die Stelle und überschreibt so effektiv die Funktion.

Wenn Sie möchten, können Sie den HippoMocks-Code direkt wiederverwenden, indem Sie ein Objekt der Klasse „Replace“ auf dem Stapel mit den richtigen Argumenten erstellen.Sie können den Code auch herauskopieren (im neuesten hippomocks.h auf GitHub werden sowohl 32/64 Bit x86, ARM als auch Thumb unterstützt).Es liegt etwa auf der Linie 200, also relativ weit oben.Sie müssen auch die Klassen horrible_cast und Unprotect kopieren.Der erste ermöglicht die Umwandlung eines Member-Funktionszeigers in einen beliebigen anderen Typ (was mit reinterpret_cast nicht möglich ist) und der zweite umschließt die betriebssystemspezifischen Aufrufe zum Aufheben des Schutzes (und zum erneuten Schutz).

Beim Bereinigen des Codes für C++11 habe ich auch genau diese Teilmenge extrahiert, sodass Sie jetzt die Datei detail/replace.h verwenden können, um genau den Code zu erhalten, der dies tut.Einen direkten Link finden Sie unter https://github.com/dascandy/hippomocks/blob/cpp11/HippoMocks/detail/replace.h .

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top