Skip to content
KitploitKITPLOIT
ToolsBlog
Einreichen
ToolsBlog
Einreichen

Hacking-, PenTest- und Cybersicherheits-Tools für Ihr Sicherheitsarsenal!

Kitploit ist ein Verzeichnis von Hacking-, Cybersicherheits- und Pentesting-Tools. Entdecken Sie die neuesten Projekt-Updates, um Schwachstellen zu finden, Systeme zu analysieren, Tests zu automatisieren und Ihre Sicherheit zu stärken.

··Feeds·Kontakt·Datenschutz·© 2026 Kitploit

Tool-Verzeichnis

Kategorien

Alle Kategorien anzeigen
Loading categories
LeetObfuscator — Verschleiert C/C++ durch LLVM-Pässe: String-Verschlüsselung, Kontrollfluss-Abflachung, MBA-Rewriting und Anti-Analyse, um Reverse Engineering zu vereiteln. | Kitploit
Tools/GitHubGitHub/zydak/leetobfuscator
Code-AnalyseReverse EngineeringBinäranalyse
GitHubzydak/leetobfuscator

LeetObfuscator

Verschleiert C/C++ durch LLVM-Pässe: String-Verschlüsselung, Kontrollfluss-Abflachung, MBA-Rewriting und Anti-Analyse, um Reverse Engineering zu vereiteln.

Repository anzeigen
334vor 2 TagenVon Kitploit geprüft

Beliebteste

Alle anzeigen →

Entdecken Sie die meistgenutzten Tools unserer Community.

Alle Tools erkunden

Durchsuchen Sie unsere Tool-Sammlung

Alle Tools anzeigen →
Teilen

LeetObfuscator

root@kitploit:~
██╗     ███████╗███████╗████████╗
██║     ██╔════╝██╔════╝╚══██╔══╝
██║     █████╗  █████╗     ██║
██║     ██╔══╝  ██╔══╝     ██║
███████╗███████╗███████╗   ██║
╚══════╝╚══════╝╚══════╝   ╚═╝

 ██████╗ ██████╗ ███████╗██╗   ██╗███████╗ ██████╗ █████╗ ████████╗ ██████╗ ██████╗
██╔═══██╗██╔══██╗██╔════╝██║   ██║██╔════╝██╔════╝██╔══██╗╚══██╔══╝██╔═══██╗██╔══██╗
██║   ██║██████╔╝█████╗  ██║   ██║███████╗██║     ███████║   ██║   ██║   ██║██████╔╝
██║   ██║██╔══██╗██╔══╝  ██║   ██║╚════██║██║     ██╔══██║   ██║   ██║   ██║██╔══██╗
╚██████╔╝██████╔╝██║     ╚██████╔╝███████║╚██████╗██║  ██║   ██║   ╚██████╔╝██║  ██║
 ╚═════╝ ╚═════╝ ╚═╝      ╚═════╝ ╚══════╝ ╚═════╝╚═╝  ╚═╝   ╚═╝    ╚═════╝ ╚═╝  ╚═╝

Ein sehr einfacher Obfuskator für C/C++-x64- und x86-Code

Dies ist als LLVM-Fork erstellt worden, du brauchst also den eigentlichen Quellcode, um zu obfuskieren. Es ist kein beliebiger Obfuskator für ausführbare Dateien. Es ist eine modifizierte Version des Compilers.

Wenn du dir die Ergebnisse ansehen möchtest, habe ich mit diesem Tool 2 Crackmes erstellt und obfuskierte. Du findest sie in den Releases zusammen mit dem vorkompilierten Clang-Binary.

  • Crackme1 – Sehr einfach, ein einzelnes XOR des hartkodierten Schlüssels und ein Vergleich mit der Benutzereingabe. Ohne Obfuskation würde es 5 Minuten dauern, es zu knacken.
  • Crackme2 – Etwas komplexer. Wenn du mit 1 fertig bist, kannst du es gerne auch ausprobieren. Die Schlüssel sind ebenfalls hartkodiert, aber die Entschlüsselung ist viel komplizierter. Es gibt 4 Flags in diesem Crackme. Du kannst entweder versuchen, einen Keygen zu erstellen, um alle Funktionen freizuschalten und alle 4 auf einmal zu holen, oder sie einzeln separat patchen.

Funktionen

All dies wurde mit der -O3-Flagge kompiliert, und alle Screenshots stammen aus IDA Pro 9.4. Ich habe es auch mit Binary Ninja und Ghidra getestet; die Ergebnisse waren entweder gleich oder schlechter.

String-Verschlüsselung

Verschlüsselt Strings zur Kompilierzeit und fügt bei jeder Verwendung des verschlüsselten Strings eine Entschlüsselungsfunktion ein. Dies deaktiviert vollständig die Möglichkeit, im Binary nach beliebigen Strings zu suchen. Und jeder String hat seinen eigenen eindeutigen Schlüssel, der in der Entschlüsselungsfunktion hartkodiert ist, was das Dumpen und Entschlüsseln erheblich erschwert.


Vor dem Pass

Danach

Mixed Boolean Arithmetic (MBA)

Ersetzt arithmetische Operationen durch ihre MBA-Äquivalente. Es ist praktisch unmöglich zu erkennen, was die ursprüngliche Operation tat, es sei denn, man führt sie zuerst durch einen MBA-Deobfuskator. Natürlich ist diese Obfuskation eher schwach, weil MBA der älteste Trick im Buch ist, daher gibt es viele Tools, die damit umgehen können, zum Beispiel CoBRA – es wird dies erfolgreich zu dem ursprünglichen Ausdruck deobfuskieren:

root@kitploit:~
./cobra-cli --mba "((x^y) - (((x^y)&0xFF)&0xA) + 10) * ((x^y) - ((x^y)|0xA) + 10) + ((x^y) - (((x^y)&0xFF)|0xFFFFFFF5) - 11) * (~(x^y) - (~(x^y)|0xA) + 10)" --bitwidth 32

10 * (x ^ y)

Deshalb habe ich den AAMBA-Pass erstellt.


Vor dem Pass

Danach

Architectural Hardening MBA (AAMBA)

Ersetzt Operanden von Binäroperationen durch ADC(X, 255) - 255 - CF und SBB(X, 255) + 255 + CF. Natürlich ergibt es immer X, aber es macht den Ausdruck vom Carry-Flag abhängig. Sofern der Decompiler den Zustand von CF nicht verfolgt (was manchmal unmöglich ist), wird er sehr verwirrt und kann diese Ausdrücke nicht zusammenfalten. Es passt sehr gut zu dem vorherigen MBA-Pass, der die Arithmetik noch weiter obfuskierte. Wie du unten sehen kannst, hat der Decompiler einige zusätzliche Variablen erstellt und verwendet viele __PAIR64__- und __CFADD__-Aufrufe, sodass es viel schwieriger wird (wenn auch nicht unmöglich), das in Tools wie CoBRA einzufügen. IDAs gooMBA-Plugin hilft bei der Vereinfachung ebenfalls nicht. Außerdem verfolgt IDAs Decompiler das Carry-Flag bis zu einem gewissen Grad, aber in Kombination mit Control-Flow-Obfuskation wird die Verfolgung ohne Ausführung praktisch unmöglich, da man nicht weiß, was die vorherige Operation war – vielleicht hat sie CF auf 1 gesetzt, vielleicht auch nicht –, sodass spätere Pässe noch mehr zu diesem hier beitragen werden.


Vor dem Pass

Danach

Control Flow Flattening

Sammelt alle Blöcke innerhalb einer Funktion und macht aus ihnen eine einzige riesige Zustandsmaschine. Es erstellt eine Sprungtabelle am Anfang der Funktion und platziert alle Blockzeiger darin. Anstatt eines normalen Sprungs am Ende jedes Blocks wird dann alles über den Dispatcher geleitet, der indirekte Sprünge verwendet. Diese sind ohne Ausführung fast unmöglich statisch aufzulösen. Es stuft außerdem Register zu Stack herab. Wenn du also einen Block in zwei Hälften teilst, liegen alle Variablen des vorherigen Blocks auf dem Stack, was bedeutet, dass es SEHR viele Variablen in jedem Ausdruck geben wird. Wenn du die Operationen eines einzelnen Blocks durch CoBRA laufen lässt, kann es nicht viel deobfuskieren, da es zu viele unbekannte Variablen gibt.

Anti Analysis

Erstellt einen Haufen Scheinblöcke, die ungültige Assembly enthalten. Das bringt Disassembler enorm durcheinander, denn wenn der Disassembler auf ein technisch ungültiges Byte stößt, das nie ausgeführt wird, versucht er trotzdem, einen Sinn daraus zu machen. Wenn das Byte unvollständig ist, erzeugt es eine Instruktion aus den Bytes, die zufällig danach kommen, und konsumiert diese im Wesentlichen. Das erzeugt eine Desynchronisation, die jede darauffolgende Instruktion zerstört. Bei Windows-Binaries kann sich IDA davon etwas erholen; in seltenen Fällen kann es einen Graphen erzeugen und decompilieren, was es kann (wenn auch kaputt und unvollständig), während es bei Linux-Binaries die Graph-Ansicht vollständig zerstört und die Dekompilierung deaktiviert. Zusätzlich fügt es RDTSC-Timer-Checks ein; wenn es zu lange dauert (zum Beispiel wenn ein Debugger angehängt ist), stürzt du ab.


Windows

Linux

Darüber hinaus: Wenn der Pass eine Instruktion sieht, die mit 0xFF beginnt, fügt er ein einzelnes 0xEB-Byte davor ein. Das erzeugt JMP RIP+1, sodass der Kontrollfluss unverändert bleibt (RIP rückt einfach ein Byte in die ursprüngliche Instruktion vor), aber die Disassembler werden erneut desynchronisiert. Instruktionen, die mit 0xFF beginnen, sind meistens INC/DEC und indirekte JMP/CALL. Leider sind die meisten gewöhnlichen Calls und Sprünge relativ (0xE8/0xE9/0xEB) und bleiben unbeeinflusst. Aber die Technik ist besonders nützlich mit dem Dispatcher-Pass, da dort alles indirekte Sprünge verwendet. Für Calls ist sie jedoch nicht so nützlich; die einzigen Calls, die davon betroffen sind, sind die indirekten – typischerweise virtuelle Calls, Calls über Funktionszeiger und einige externe/Bibliotheks-Calls.

Anti Aliasing

Wirft alle Stack-Lokalen einer Funktion in einen einzigen großen gemeinsamen Stack-Puffer, auf den die Indizes zur Laufzeit berechnet werden. Auf diese Weise können Decompiler keine Variablen aliassen, wodurch Zugriffe auf dieselbe Variable mehrmals so erscheinen, als würde auf unterschiedliche Werte zugegriffen. Das spielt sehr gut mit dem Dispatcher zusammen, da dieser Register zu Stack herabstuft, sodass es viele dieser Stack-Slots geben wird.


Vor dem Pass

Danach

Nanomites

Obfuskieren den Kontrollfluss durch Exceptions. Es ersetzt alle Calls durch int3-Traps. Wenn der Trap ausgelöst wird, geht der Kontrollfluss zum Exception-Handler, der RIP auf den tatsächlichen Call anpasst. Es fügt außerdem direkt nach dem Trap ungültige Bytes ein, um den Disassembler noch weiter zu desynchronisieren.


Vor dem Pass

Danach

Kombination aller Pässe

Durch die Kombination aller Pässe wird die statische Analyse sehr schwierig, ohne zusätzliche Tools, die das deobfuskieren würden. Selbst wenn du irgendwie alle ungültigen Bytes mit NOPs überschreibst und in der Lage bist, dies zu etwas Pseudocode zu decompilieren oder zumindest eine Graph-Ansicht zu bekommen, bleibt dir immer noch die Control-Flow-Obfuskation durch Exceptions und den Dispatcher, und selbst wenn du diese durchbrichst, gibt es einen Berg von redundanten MBAs, Scheinblöcken, Stack-Variablen und String-Verschlüsselung, die die eigentlichen Operationen verschleiern. Hier sind Screenshots des Haupt-Einstiegspunkts eines einfachen Programms, das die einfache XOR-Foo-Funktion von vorhin in allen drei großen Disassemblern enthält. Wie du sehen kannst, können sie nicht viel daraus machen.

Ich wollte wirklich ein Ergebnis von Deobfuskator-Versuchen einbauen, die versuchen, daraus schlau zu werden, aber leider konnte ich keine funktionierenden mit symbolischer Ausführung finden, um den tatsächlichen Kontrollfluss zu sehen. Alle, die ich finden konnte, sind entweder stark auf bestimmte Anwendungsfälle begrenzt (wie speziell das Deobfuskieren von VMProtect), zu alt, nicht gewartet und kaputt (fast jedes IDA/BN-Plugin, das ich ausprobiert habe), oder schwere Maschinerie, die zu viel manuelle Führung und Einrichtung über APIs erfordert, mit denen ich einfach nicht vertraut bin (Angr, Triton, IntelPin). Wenn du Deobfuskatoren für beliebige Binaries kennst, die überhaupt irgendetwas extrahieren könnten, lass es mich wissen.

Leistung

Natürlich wird das Einfügen all dieses Bullshits in das Binary es enorm verlangsamen – bei den Standardeinstellungen im Durchschnitt über 200-mal langsamer:


Es ist jedoch nicht so schlimm, wie es aussieht, aus 2 Gründen: 1. Fast 95% der Leistungseinbußen hier werden durch Nanomites verursacht, denn – nun ja – Interrupts sind einfach langsam. Die Exception muss zum Kernel gehen und zurück zur App kommen; das braucht Zeit. Ohne Nanomites sinkt es auf nur 7,5-mal langsamer:


Daher rate ich dringend, die Funktionen und Calls, die du mit Nanomites obfuskieren möchtest, manuell zu markieren, anstatt es einfach auf alles zu setzen. Jeden einzelnen Call in einem Binary zu obfuskieren ist sinnlos und kostet viel. Und der zweite Grund: Meistens kümmert es dich nicht wirklich, wie performant die Dinge sind, die du verstecken möchtest. Dieser Obfuskator kann selektiv aktiviert und deaktiviert werden. Du kannst ihn also für leistungskritische Abschnitte deines Codes deaktivieren und überall dort aktivieren, wo er tatsächlich benötigt wird. Niemanden interessiert es, ob dein Lizenzcheck 1 ms oder 0,001 ms dauert; es ist für einen Menschen weiterhin unbemerkt.

Für die Konfigurationsoptionen und die vollständige Anleitung siehe das Wiki.

Du kannst auch alle Funktionen, die mit dem Exception-Handler in Leet.h zusammenhängen, mit dem LEET_SKIP-Makro markieren. Auf diese Weise wird der Exception-Handler von den meisten Pässen nicht obfuskierte, was die Kosten der Nanomites halbiert (bei Standardeinstellungen), dich aber auch mit einem nicht obfuskierte Exception-Handler zurücklässt, was ich für schlimmer halte als eine leichte Verlangsamung.

Erstellen

Linux

Voraussetzungen:

  • CMake
  • Ninja
  • Clang
  • Mold (optional – wenn du es nicht möchtest, entferne -DLLVM_USE_LINKER=mold aus dem cmake. Aber mit mold wird es schneller)
root@kitploit:~
git clone https://github.com/Zydak/LeetObfuscator.git --recursive
cd LeetObfuscator

mkdir build
cd build

cmake ../leet-llvm-project/llvm -G Ninja -DCMAKE_C_COMPILER=clang -DCMAKE_CXX_COMPILER=clang++ -DLLVM_USE_LINKER=mold -DLLVM_USE_SPLIT_DWARF=ON -DLLVM_ENABLE_ASSERTIONS=ON -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLLVM_ENABLE_PROJECTS=clang -DLLVM_TARGETS_TO_BUILD=X86 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON
ninja clang

Der modifizierte Compiler befindet sich in build/bin/. Verwende einfach den, um den Quellcode zu kompilieren, den du obfuskieren möchtest.

Du musst es auch nicht selbst bauen; es gibt ein vorgefertigtes Binary in den Releases. Lade es einfach herunter und entpacke es.

Windows

Das Erstellen dieses Projekts für Windows wird derzeit nicht unterstützt. Aber das Cross-Kompilieren mit diesem Projekt nach Windows wird unterstützt. Wenn du es also wirklich möchtest, kannst du das Linux-Binary nehmen und die obfuskierte App von Linux oder WSL aus für Windows cross-kompilieren.

Verwendung

Für die vollständige Anleitung zur genauen Verwendung siehe das Wiki.

Beispielverwendung:

Kopiere Leet.h in dein Projekt, und füge es dann in einer .c/.cpp-Datei ein und definiere LEET_IMPLEMENTATION

Definiere dies nicht in mehreren Modulen!

root@kitploit:~
#define LEET_IMPLEMENTATION
#include "Leet.h"

Kompiliere dann einfach den Quellcode mit dem gebauten Compiler:

root@kitploit:~
./build/bin/clang++ ./test.cpp -o test -fno-exceptions

Aktuelle Einschränkungen

  • Funktioniert nur für x64 und x86 unter Windows und Linux.
  • Nur C++ wurde intensiv getestet, aber es sollte auch in der Lage sein, C-Code zu obfuskieren.
  • Muss mit der -fno-exceptions-Flagge kompiliert werden, also natürlich kein try catch im obfuskierte Code.
  • Grundsätzlich ein Work in Progress. Erwarte nicht, dass dies für größere Projekte funktioniert (wahrscheinlich wird es das nicht, aber du kannst es gerne versuchen). Es ist nicht sehr gut getestet. Ich habe zwar einige Tests, die von LLMs geschrieben wurden, weil ich keine echten Projekte (außer den Crackmes) zur Hand hatte, aber die zählen kaum als große Anwendungen. Es sind meistens einzelne Dateien, die einen bestimmten Teil von C++ unter Stress setzen. Sie haben viele Fehler gefunden, aber es werden wahrscheinlich neue bei größeren Binaries auftauchen, besonders bei solchen mit mehreren Modulen. Wenn du also auf welche stößt, öffne bitte ein Issue.
Tool herunterladen

IDA Pro 9.4

Binary Ninja Personal 5.2

Ghidra 12.1.2