
Ein ereignisgesteuertes Multi-Core-Prozess-Debugging-, Tracing- und Manipulations-Framework.
libptrace ist ein ereignisgesteuertes Framework zum Debuggen, Tracing und Manipulieren von Prozessen/Threads. Es ist in C geschrieben und verfügt über Python-2.7- und 3.7-Bindungen.
Es soll als Bibliothek verwendet werden. Die API wurde im Hinblick auf plattformübergreifende Unterstützung entwickelt. Obwohl die aktuelle Version nur auf 32- und 64-Bit-Versionen von Windows läuft (wow64 wird unterstützt), sind das Design und die Abstraktionen so gestaltet, dass andere Plattformen und sogar Remote-Debugging-Unterstützung unter derselben API hinzugefügt werden können.
Es ist mehrkern-/threadbewusst und kann einfach verwendet werden, um mehrere Ereignisschleifen gleichzeitig auszuführen. Das Debuggen von Prozessgruppen oder Pipelines oder das Verfolgen einer großen Anzahl von Prozessen kann durch die Erhöhung der Ausführungskerne skaliert werden.
Ich habe die erste Version von libptrace im Jahr 2006 während meines Studiums geschrieben und 2011 für die vollständige Nutzung durch Immunity Inc., meinen damaligen Arbeitgeber, neu lizenziert. Zu dieser Zeit sollte das Framework in Immunity Debugger integriert werden, obwohl ich immer darauf geachtet habe, das Framework getrennt zu halten, damit es eigenständig verwendet werden kann.
Mit diesem Ziel vor Augen erlebte es bei Immunity eine umfangreiche Entwicklung, und ich bin dankbar, dass ich während meiner Arbeitszeit aktiv daran arbeiten und das Framework reifen sehen konnte. Ich habe große Teile davon neu gestaltet, um es mehrkernbewusst zu machen, Python-Bindungen bereitzustellen und bessere Abstraktionen zu schaffen.
Mit der Veröffentlichung von x64dbg wurde entschieden, dass wir nicht mehr an Immunity Debugger arbeiten, sondern uns auf andere Dinge konzentrieren würden. Dies brachte auch die Entwicklung von libptrace zum Stillstand, und in den folgenden Jahren sammelte es Staub im internen Git-Repository, bis nach der Übernahme von Immunity Inc. durch Cyxtera Technologies, jetzt unter Cyxtera Cybersecurity Inc., beschlossen wurde, das Projekt unter der LGPL Version 2.1 zu veröffentlichen, damit es hoffentlich breite Anwendung und Weiterentwicklung findet.
Ich möchte mich herzlich bei Immunity Inc., Cyxtera Technologies und Cyxtera Cybersecurity Inc. bedanken, die diese Veröffentlichung ermöglicht haben. Besonders danken möchte ich Dave Aitel, der diese Veröffentlichung durch mehrere Management-Ebenen gebracht und mich vor den bürokratischen Teilen des Prozesses geschützt hat. Es wäre traurig gewesen, meine Arbeit verloren und ohne Zweck zu sehen, und ohne ihre Bereitschaft, die intern entwickelte libptrace als Open Source zu veröffentlichen, wäre genau das passiert.
Ich möchte auch mehreren Kollegen danken, die Zeit mit der Nutzung oder Arbeit an dem Framework verbracht haben, insbesondere Massimiliano Oldani, Roderick Asselineau und Christos Kalkanis. Mein Dank gilt auch Lennert Buytenhek für seine intrusiven AVL-Baum- und Listenimplementierungen, die ich schließlich verwendet habe.
Obwohl seit den letzten Arbeiten an dem Projekt über 4 Jahre vergangen sind, hoffe ich, dass die Leute es nützlich finden werden. Ich glaube, dass das Design und der Quellcode relativ sauber sind und es zu diesem Zeitpunkt ermöglichen, das Framework relativ einfach zu erweitern und auf andere Plattformen zu portieren. Hoffentlich kann dies eines Tages zu einer echten plattformübergreifenden Debugging-Bibliothek unter einer einheitlichen API werden.
Schließlich möchte ich dieses Projekt meiner verlorenen Tochter, Yuzuyu Huizer, widmen, mit der ich hoffe, eines Tages wieder vereint zu sein. Ich liebe dich.
-- Ronald Huizer [email protected]
Die derzeit unterstützte Build-Methode ist das Cross-Compilieren des Projekts mit MinGW und CMake. Das Build-System wurde unter Ubuntu 19.04 getestet.
Ein 32-Bit-Installationsprogramm kann mit folgendem Befehl erstellt werden:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=mingw-w64-x86.cmake .
make
makensis libptrace-setup.nsi
Ein 64-Bit-Installationsprogramm kann mit folgendem Befehl erstellt werden:
cmake -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=mingw-w64-x64.cmake .
make
makensis -DUSE64 libptrace-setup.nsi
Nach den obigen Build-Schritten befindet sich das 32-Bit-Installationsprogramm unter libptrace-setup32.exe und das 64-Bit-Installationsprogramm unter libptrace-setup64.exe.
Das Installationsprogramm erkennt automatisch, welche Python-Versionen installiert sind und ob sie 32-Bit oder 64-Bit sind. Die gefundenen Versionen werden vom Installationsprogramm angeboten, und nicht gefundene Versionen werden ausgegraut.
Release-Downloads finden Sie hier.
Das Verzeichnis doc/ ist hoffnungslos veraltet. Es ist als Ausgangspunkt für neuere Dokumentation enthalten. Bitte verwenden Sie es nicht.
Mehrere Beispielskripte finden Sie im Verzeichnis python/scripts. Sie werden in Program Files\Immunity Inc\libptrace oder bei der 32-Bit-Version in Program Files (x86)\Immunity Inc\libptrace installiert.
Diese Beispiele zeigen das Framework keineswegs erschöpfend, sollten aber einen guten Ausgangspunkt für jeden bieten, der das Framework verwenden möchte. Die C-API ist nicht gut dokumentiert, aber einige Beispiele finden Sie im Verzeichnis unittests/windows. Das Verzeichnis python/, das die Python-Bindungen enthält, bietet ebenfalls einen guten Überblick. Schließlich enthält das Verzeichnis include/libptrace die öffentlichen Header-Dateien, die eine gute Liste der API-Funktionen darstellen.
Es sei darauf hingewiesen, dass die Python-API derzeit eine recht eingeschränkte Teilmenge der C-API ist.
Als Beispiel wäre der allgemeine Arbeitsablauf zum Verfolgen von RegOpenKeyExW-Aufrufen in einer ausführbaren Datei:
import _ptrace
def bp_handler(bp, thread):
(key, subkey, options, sam, result) = _ptrace.cconv.args_get(thread, "%u%p%u%u%p")
subkey = thread.process.read_utf16(subkey)
print('T{}: RegOpenKeyEx({}, "{}", 0x{:08x}, 0x{:08x}, 0x{:08x})'
.format(thread.id, key, subkey, options, sam, result), end='')
def attached_handler(process):
bp = _ptrace.breakpoint_sw("advapi32!RegOpenKeyExW", bp_handler)
process.breakpoint_set(bp)
handlers = _ptrace.event_handlers()
handlers.attached = attached_handler
_ptrace.execv(r"C:\Windows\Notepad.exe", [], handlers, 0)
_ptrace.main()
Wenn auch der Rückgabewert von RegOpenKeyExW gewünscht wird, ist es am einfachsten, einen Breakpoint auf die Rückkehradresse des Funktionsaufrufs zu setzen. Dies vermeidet die Notwendigkeit einer Codeanalyse zur statischen Bestimmung der Funktionsausstiegspfade:
def bp_end_handler(bp, thread):
print("=", _ptrace.cconv.retval_get(thread))
def bp_handler(bp, thread):
(key, subkey, options, sam, result) = _ptrace.cconv.args_get(thread, "%u%p%u%u%p")
subkey = thread.process.read_utf16(subkey)
print('T{}: RegOpenKeyEx({}, "{}", 0x{:08x}, 0x{:08x}, 0x{:08x})'
.format(thread.id, key, subkey, options, sam, result), end='')
retaddr = _ptrace.cconv.retaddr_get(thread)
if thread.process.breakpoint_find(retaddr) is None:
bp_end = _ptrace.breakpoint_sw(retaddr, bp_end_handler)
thread.process.breakpoint_set(bp_end)
Die Urheberrechtssituation ist in jeder einzelnen Datei klar angegeben. Sie liegen größtenteils bei Cyxtera Cybersecurity Inc., Ronald Huizer oder beiden gleichzeitig. Einige wenige Dateien haben Urheberrechte Dritter, wie Lennert Buytenhek.
Verteilt unter Version 2.1 der GNU Lesser General Public License. Weitere Informationen finden Sie in COPYING und COPYING.LESSER.