
Ein interaktives Binary-Patching-Plugin für IDA Pro

Das Patchen von Assemblercode, um das Verhalten eines bestehenden Programms zu ändern, ist in der Malware-Analyse, der Reverse-Engineering von Software und weiteren Bereichen der Sicherheitsforschung nicht ungewöhnlich. Dieses Projekt erweitert den beliebten Disassembler IDA Pro um einen robusteren interaktiven Workflow für Binär-Patches, der für schnelle Iterationen ausgelegt ist.
Dieses Projekt wird derzeit von einem kleinen Fork der allgegenwärtigen Keystone Engine unterstützt und ermöglicht das Patchen von x86/x64 und Arm/Arm64 – mit dem Plan, die übrigen Keystone-Architekturen in einer zukünftigen Version zu aktivieren.
Besonderer Dank gilt Hex-Rays für die Unterstützung der Entwicklung dieses Plugins.
Dieses Plugin erfordert IDA 7.6 und Python 3. Es unterstützt Windows, Linux und macOS.
Bitte beachten Sie, dass ältere Versionen von IDA (8.2 und älter) nicht kompatibel mit Python 3.11 und höher sind.
Führen Sie die folgende Zeile in der IDA-Konsole aus, um das Plugin automatisch zu installieren:
import urllib.request as r; exec(r.urlopen('https://github.com/gaasedelen/patching/raw/main/install.py').read())
import urllib.request as r; exec(r.urlopen('https://github.com/gaasedelen/patching/raw/main/install.py', cafile='/etc/ssl/cert.pem').read())
Alternativ kann das Plugin manuell installiert werden, indem Sie das verteilbare Plugin-Paket für Ihre jeweilige Plattform von der Releases-Seite herunterladen und in Ihren Plugins-Ordner entpacken.
Es wird dringend empfohlen, dieses Plugin in das Benutzer-Plugin-Verzeichnis von IDA zu installieren:
import ida_diskio, os; print(os.path.join(ida_diskio.get_user_idadir(), "plugins"))
Das Patching-Plugin wird automatisch für unterstützte Architekturen (x86/x64/Arm/Arm64) geladen und fügt relevante Patching-Aktionen in das Rechtsklick-Kontextmenü der IDA-Disassembly-Ansichten ein:

Eine vollständige Auflistung der kontextuellen Patching-Aktionen wird in den folgenden Abschnitten beschrieben.
Der Hauptdialog für Patches kann über die Aktion 'Assemblieren' im Rechtsklick-Kontextmenü geöffnet werden. Er simuliert eine einfache IDA-Disassembly-Ansicht, die zum schnellen Bearbeiten einer oder mehrerer Anweisungen verwendet werden kann.

Die Assemblerzeile ist ein bearbeitbares Feld, das zum Ändern von Anweisungen in Echtzeit verwendet werden kann. Durch Drücken der Eingabetaste wird die eingegebene Anweisung übernommen (gepatcht) und in der Datenbank gespeichert.
Ihre aktuelle Position (auch bekannt als Cursor) wird immer grün hervorgehoben. Anweisungen, die durch Ihren Patch/Ihre Bearbeitung überschrieben werden, werden vor dem Übernehmen des Patches rot hervorgehoben.

Schließlich können die Pfeiltasten UP und DOWN verwendet werden, während der Fokus noch auf dem bearbeitbaren Assembler-Textfeld liegt, um den Cursor schnell ohne Maus in der Disassembly-Ansicht nach oben und unten zu bewegen.
Die häufigste Patching-Aktion ist das NOPen einer oder mehrerer Anweisungen. Aus diesem Grund ist die NOP-Aktion im Rechtsklick-Menü immer für den schnellen Zugriff sichtbar.

Einzelne Anweisungen können genauso wie ein ausgewählter Bereich von Anweisungen genopet werden.
Das Erzwingen eines bedingten Sprungs, damit immer ein 'guter' Pfad ausgeführt wird, ist eine weitere häufige Patching-Aktion. Das Plugin zeigt diese Aktion nur an, wenn Sie mit der rechten Maustaste auf eine bedingte Sprunganweisung klicken.

Wenn Sie nie möchten, dass ein bedingter Sprung genommen wird, können Sie ihn stattdessen einfach NOPen!
Patches können über das Patching-Untermenü jederzeit in einer ausgewählten ausführbaren Datei gespeichert (angewendet) werden. Die Aktion 'Schnell anwenden' macht es noch schneller, nachfolgende Patches mit denselben Einstellungen zu speichern.

Das Plugin wird sich auch aktiv darum bemühen, ein Backup (.bak) der ursprünglichen ausführbaren Datei zu behalten, das es verwendet, um den aktuellen Satz von Datenbank-Patches bei jedem Speichern 'sauber' anzuwenden.
Wenn Sie schließlich mit einem Patch unzufrieden sind, können Sie einfach mit der rechten Maustaste auf gepatchte (gelbe) Blöcke von Anweisungen klicken, um sie auf ihren ursprünglichen Wert zurückzusetzen.

Obwohl es 'einfach' ist, Bytes auf ihren ursprünglichen Wert zurückzusetzen, kann es 'schwierig' sein, die Analyse wieder in den vorherigen Zustand zu versetzen. Das Rückgängigmachen eines Patches kann gelegentlich zusätzliche manuelle Nachbesserungen erfordern.
Zeit und Motivation vorausgesetzt, könnten zukünftige Arbeiten Folgendes umfassen:
xor eax, eax; ret;)Pretty: mov [rsp+48h+dwCreationDisposition], 3
Raw: mov [rsp+20h], 3
Ich begrüße externe Beiträge, Issues und Feature Requests. Bitte stellen Sie Pull-Requests für den develop-Branch dieses Repositorys, wenn Sie möchten, dass sie für eine zukünftige Version berücksichtigt werden.