Hinweis: Alle Softwarepakete sind passwortgeschützt. Bitte senden Sie uns nach dem Download eine E-Mail, und MikaTech sendet Ihnen das Passwort.
- Dies ist ein BIN-/HEX-Format-Konvertierungstool für Windows.
Nicht alle Codes können zu 100 % konvertiert werden. Sie können das Xeltek-Programmiertool herunterladen, Ihre BIN- (oder HEX-) Datei laden, ohne den Programmierer anzuschließen, und dann als HEX- (oder BIN-) Datei speichern.
BinToHex.rar
- Microchip PIC Disassembler
- Der PIC-Disassembler ist eine Windows-basierte Software zur Steuerung eines Entwicklungsprogrammierers für PIC-Mikrocontroller. Für die Bedienung dieser Software sind Grundkenntnisse in Elektronik und Windows erforderlich.
Programme: 12Cxx, 16Cxxx, 16Fxx, 16F87x, 18Fxxx, 16F7x, 24Cxx, 93Cxx, 90Sxxx, 59Cxx, 89Cx051, 89S53, 250x0, PIC, AVR, 80C51 usw.
PIC_prog.rar
- MCS-51 Core MCU Disassembler
-
Wie der Name schon sagt, handelt es sich um einen Windows-basierten Disassembler für MCS-51-Core-MCU-Codes. Atmel-, Intel-, SyncMos-, Nuvoton/Winbond- und NXP-MCS-51-Core-MCU-Codes können mit hervorragenden Ergebnissen disassembliert werden.
MCS-51_core_MCU.rar
-
AVR Studio wurde von Atmel Corp entwickelt und dient der Programmierung und Fehlersuche von Atmel AVR-MCUs. Es kann auch für die Disassemblierung verwendet werden. Da es sich um ein Atmel-Produkt handelt, kann der disassemblierte Code nicht exportiert werden; es kann jedoch zur Ergänzung anderer Disassembler verwendet werden, um genauere Disassemblierungsergebnisse zu erzielen.
Das Disassembly-Fenster ist nur im Debug-Modus verfügbar. Wenn eine unterstützte Hochsprache verwendet wird, wird das Quellfenster automatisch angezeigt und das Disassembly-Fenster ist ausgeschaltet. Aktivieren Sie es während einer Debug-Sitzung über Debug→Windows→Disassembly oder Ctrl+Alt+D.
Das Disassembly-Fenster zeigt Ihren Programmcode in disassemblierter Form an. Programmausführung und AVR-Befehle können in dieser Ansicht verfolgt werden. Durch Rechtsklick im Disassembly-Fenster können Sie Haltepunkte setzen, zur Cursorposition ausführen oder zum Quellcode wechseln. Sie können den Quellcode nicht aus dem Disassembly-Fenster ändern.
Eine höhere Edition finden Sie auf der Atmel-Website.
-
http://www.atmel.com/microsite/avr_studio_5
-
http://www.atmel.no/webdoc/atmelstudio/atmelstudio.Debug.Views.Disassembly.html
AVRstudio.rar
- Entwickelt von der MDT Company.
Dies ist tatsächlich ein MDT-OTP-Writer. Importieren Sie Ihren Code, konfigurieren Sie ihn richtig, klicken Sie auf View >> Disassemble, um die Disassemblierung anzuzeigen.
MDTWriter.rar
- Elan Microcontroller EMC Disassembler
In Version 9.0B:
- Stürzt nicht mehr ab, wenn gepackte Anwendungen geöffnet werden.
- Es ist nicht mehr nötig, den PE-Header auf E0000020 zu ändern, um disassembliert werden zu können.
- Es kann jetzt alle String_Refs von VB-, VC- und Delphi-Anwendungen anzeigen (beste Funktion).
Das Schlechte daran ist, dass es nur in chinesischer Sprache verfügbar ist.
Alle Menüsprachen wurden ins Englische übersetzt!!!!
(unter Verwendung von Resource Tuner, Crack bereitgestellt von UCEC & UCDV).
W32Dasm9b.rar
Ein Disassembler ist ein Computerprogramm, das Maschinensprache in Assemblersprache übersetzt – die Umkehroperation zu der eines Assemblers. Ein Disassembler unterscheidet sich von einem Decompiler, der auf eine Hochsprache und nicht auf eine Assemblersprache abzielt. Die Disassemblierung, das Ergebnis eines Disassemblers, wird häufig für die menschliche Lesbarkeit formatiert und nicht für die Eingabe in einen Assembler, was sie zu einem primären Reverse-Engineering-Werkzeug macht.
Assemblersprachen-Quellcode erlaubt im Allgemeinen die Verwendung von Konstanten und Programmierkommentaren. Diese werden vom Assembler normalerweise aus dem assemblierten Maschinencode entfernt. Wenn dies der Fall ist, würde ein Disassembler, der auf dem Maschinencode arbeitet, eine Disassemblierung ohne diese Konstanten und Kommentare erzeugen; die disassemblierte Ausgabe wird für einen Menschen schwieriger zu interpretieren sein als der ursprünglich annotierte Quellcode. Einige Disassembler nutzen die symbolischen Debugging-Informationen, die in Objektdateien wie ELF vorhanden sind. Der Interactive Disassembler ermöglicht es dem menschlichen Benutzer, in einer interaktiven Sitzung mnemonische Symbole für Werte oder Codebereiche zu erstellen: Die menschliche Einsicht, die auf den Disassemblierungsprozess angewendet wird, entspricht oft der menschlichen Kreativität im Codierungsprozess.
Disassemblierung ist keine exakte Wissenschaft: Auf CISC-Plattformen mit Befehlen variabler Breite oder bei selbstmodifizierendem Code ist es möglich, dass ein einzelnes Programm zwei oder mehr vernünftige Disassemblierungen hat. Die Bestimmung, welche Befehle während eines Programmablaufs tatsächlich ausgeführt werden, reduziert sich auf das bekanntermaßen unlösbare Halteproblem.
Das Schreiben eines Disassemblers, der Code erzeugt, der beim Assemblieren exakt das ursprüngliche Binärprogramm ergibt, ist möglich; jedoch gibt es oft Unterschiede. Dies stellt Anforderungen an die Ausdruckskraft des Assemblers. Beispielsweise trifft ein x86-Assembler eine willkürliche Wahl zwischen zwei Binärcodes für etwas so Einfaches wie "MOV AX,BX". Wenn der ursprüngliche Code die andere Wahl verwendet, kann der ursprüngliche Code an einem bestimmten Punkt einfach nicht reproduziert werden. Selbst wenn jedoch eine vollständig korrekte Disassemblierung erstellt wird, bleiben Probleme bestehen, wenn das Programm geändert werden muss. Beispielsweise kann derselbe Maschinensprache-Sprungbefehl durch Assemblierungscode erzeugt werden, um zu einer bestimmten Stelle zu springen (z. B. um bestimmten Code auszuführen) oder um eine bestimmte Anzahl von Bytes zu überspringen (z. B. um einen unerwünschten Zweig zu überspringen). Ein Disassembler kann nicht wissen, was beabsichtigt ist, und kann eine der beiden Syntaxen verwenden, wodurch eine Disassemblierung erzeugt wird, die das ursprüngliche Binärprogramm reproduziert [Zitat erforderlich]. Wenn ein Programmierer jedoch Befehle zwischen dem Sprungbefehl und seinem Ziel einfügen möchte, ist es notwendig, die Programmfunktion zu verstehen, um zu bestimmen, ob der Sprung absolut oder relativ sein sollte, d. h., ob sein Ziel an einer festen Stelle bleiben oder so verschoben werden sollte, dass sowohl die ursprünglichen als auch die hinzugefügten Befehle übersprungen werden.
Beispiele für Disassembler
Ein Disassembler kann eigenständig oder interaktiv sein. Ein eigenständiger Disassembler erzeugt bei der Ausführung eine Assemblerdatei, die untersucht werden kann; ein interaktiver Disassembler zeigt sofort die Auswirkung jeder vom Benutzer vorgenommenen Änderung. Beispielsweise weiß der Disassembler möglicherweise zunächst nicht, dass ein Abschnitt des Programms tatsächlich Code ist, und behandelt ihn als Daten; wenn der Benutzer angibt, dass es sich um Code handelt, wird der resultierende disassemblierte Code sofort angezeigt, sodass der Benutzer ihn untersuchen und während derselben Sitzung weitere Maßnahmen ergreifen kann.
Jeder interaktive Debugger enthält eine Möglichkeit, die Disassemblierung des zu debuggenden Programms anzuzeigen. Oft wird dasselbe Disassemblierungs-Tool als eigenständiger Disassembler zusammen mit dem Debugger vertrieben. Beispielsweise ist objdump, Teil der GNU Binutils, mit dem interaktiven Debugger gdb verwandt.
IDA
OllyDbg ist ein 32-Bit-Assembler-Ebenen-Analyse-Debugger
OLIVER und SIMON enthalten Disassembler für Assembler, COBOL und PL/1
Decompiler
Ein Decompiler ist ein Computerprogramm, das die Umkehroperation zu der eines Compilers durchführt. Das heißt, es übersetzt Programmcode auf einer relativ niedrigen Abstraktionsebene (normalerweise für die maschinelle Lesbarkeit und nicht für die menschliche Lesbarkeit ausgelegt) in eine Form mit einer höheren Abstraktionsebene (normalerweise für die menschliche Lesbarkeit ausgelegt). Decompiler rekonstruieren den ursprünglichen Quellcode normalerweise nicht perfekt und können in der Verständlichkeit ihrer Ausgaben stark variieren. Dennoch bleiben Decompiler ein wichtiges Werkzeug im Software-Reverse-Engineering.
Der Begriff Decompiler wird am häufigsten auf ein Programm angewendet, das ausführbare Programme (die Ausgabe eines Compilers) in Quellcode in einer (relativ) höheren Programmiersprache übersetzt, der, wenn er compiliert wird, ein ausführbares Programm erzeugt, dessen Verhalten dem des ursprünglichen ausführbaren Programms entspricht. Im Vergleich dazu übersetzt ein Disassembler ein ausführbares Programm in Assemblersprache (und ein Assembler könnte verwendet werden, um es zurück in ein ausführbares Programm zu assemblieren).
Decompilation ist die Verwendung eines Decompilers, obwohl der Begriff sich auch auf die Ausgabe eines Decompilers beziehen kann. Sie kann zur Wiederherstellung von verlorenem Quellcode verwendet werden und ist auch in einigen Fällen für Computersicherheit, Interoperabilität und Fehlerkorrektur nützlich.[1][unzuverlässige Quelle] Der Erfolg der Decompilation hängt von der Menge der Informationen ab, die im zu dekompilierenden Code vorhanden sind, und der Raffinesse der darauf durchgeführten Analyse. Die Bytecode-Formate, die von vielen virtuellen Maschinen verwendet werden (wie der Java Virtual Machine oder der .NET Framework Common Language Runtime), enthalten oft umfangreiche Metadaten und hochgradige Funktionen, die die Decompilation durchaus machbar machen. Das Vorhandensein von Debug-Daten kann es ermöglichen, die ursprünglichen Variablen- und Strukturnamen und sogar die Zeilennummern zu reproduzieren. Maschinensprache ohne solche Metadaten oder Debug-Daten ist viel schwieriger zu dekompilieren.[2]
Einige Compiler und Post-Compilation-Tools erzeugen verschleierten Code (d. h., sie versuchen, eine Ausgabe zu erzeugen, die sehr schwer zu dekompilieren ist). Dies geschieht, um das Reverse Engineering der ausführbaren Datei zu erschweren.
Design
Decompiler können als eine Reihe von Phasen betrachtet werden, von denen jede spezifische Aspekte des gesamten Decompilierungsprozesses beiträgt.
Loader
Die erste Decompilierungsphase lädt und parst das Binärdateiformat des eingegebenen Maschinencodes oder der Zwischensprache. Sie sollte in der Lage sein, grundlegende Fakten über das Eingabeprogramm zu entdecken, wie die Architektur (Pentium, PowerPC usw.) und den Einstiegspunkt. In vielen Fällen sollte sie in der Lage sein, das Äquivalent der main-Funktion eines C-Programms zu finden, das den Start des benutzergeschriebenen Codes darstellt. Dies schließt den Laufzeitinitialisierungscode aus, der nach Möglichkeit nicht dekompiliert werden sollte. Falls verfügbar, werden auch die Symboltabellen und Debug-Daten geladen. Das Frontend kann in der Lage sein, die verwendeten Bibliotheken zu identifizieren, selbst wenn sie mit dem Code verknüpft sind, und so Bibliotheksschnittstellen bereitzustellen. Wenn es den Compiler oder die Compiler bestimmen kann, die verwendet wurden, kann dies nützliche Informationen zur Identifizierung von Code-Idiomen liefern.
Disassemblierung
Die nächste logische Phase ist die Disassemblierung von Maschinensprachebefehlen in eine maschinenunabhängige Zwischendarstellung (IR). Zum Beispiel könnte der Pentium-Maschinensprachebefehl
mov eax, [ebx+0x04]
in die IR übersetzt werden
eax := m[ebx+4];
Idiome
Idiomatische Maschinensprache-Sequenzen sind Code-Sequenzen, deren kombinierte Semantik nicht sofort aus der individuellen Semantik der Befehle ersichtlich ist. Entweder als Teil der Disassemblierungsphase oder als Teil späterer Analysen müssen diese idiomatischen Sequenzen in bekannte äquivalente IR übersetzt werden. Beispielsweise könnte der x86-Assemblercode:
cdq eax ; edx wird auf das Vorzeichen von eax gesetzt
xor eax, edx
sub eax, edx
übersetzt werden in:
eax := abs(eax);
Einige idiomatische Sequenzen sind maschinenunabhängig; einige betreffen nur einen Befehl. Beispielsweise löscht xor eax, eax das eax-Register (setzt es auf Null). Dies kann mit einer maschinenunabhängigen Vereinfachungsregel implementiert werden, wie z. B. a xor a = 0.
Im Allgemeinen ist es am besten, die Erkennung idiomatischer Sequenzen wenn möglich zu verzögern, bis zu späteren Phasen, die weniger von der Befehlsreihenfolge betroffen sind. Beispielsweise kann die Befehlsplanungsphase eines Compilers andere Befehle in eine idiomatische Sequenz einfügen oder die Reihenfolge der Befehle in der Sequenz ändern. Ein Mustervergleichsprozess in der Disassemblierungsphase würde das geänderte Muster wahrscheinlich nicht erkennen. Spätere Phasen gruppieren Befehlsausdrücke in komplexere Ausdrücke und ändern sie in eine kanonische (standardisierte) Form, wodurch es wahrscheinlicher wird, dass selbst das geänderte Idiom später mit einem übergeordneten Muster übereinstimmt.
Es ist besonders wichtig, die Compiler-Idiome für Unterprogrammaufrufe, Ausnahmebehandlung und Switch-Anweisungen zu erkennen. Einige Sprachen haben auch umfangreiche Unterstützung für Zeichenketten oder lange Ganzzahlen.
Programmanalyse
Verschiedene Programmanalysen können auf die IR angewendet werden. Insbesondere kombiniert die Ausdruckspropagierung die Semantik mehrerer Befehle zu komplexeren Ausdrücken. Zum Beispiel:
mov eax,[ebx+0x04]
add eax,[ebx+0x08]
sub [ebx+0x0C],eax
könnte nach der Ausdruckspropagierung die folgende IR ergeben:
m[ebx+12] := m[ebx+12] - (m[ebx+4] + m[ebx+8]);
Der resultierende Ausdruck ähnelt eher einer Hochsprache und hat auch die Verwendung des Maschinenregisters eax eliminiert. Spätere Analysen können das ebx-Register eliminieren.
Datenflussanalyse
Die Stellen, an denen Registerinhalte definiert und verwendet werden, müssen mithilfe der Datenflussanalyse verfolgt werden. Dieselbe Analyse kann auf Speicherorte angewendet werden, die für Temporäre und lokale Daten verwendet werden. Für jede solche zusammenhängende Menge von Wertedefinitionen und -verwendungen kann dann ein anderer Name gebildet werden. Es ist möglich, dass derselbe lokale Variable-Speicherort für mehr als eine Variable in verschiedenen Teilen des ursprünglichen Programms verwendet wurde. Noch schlimmer ist es möglich, dass die Datenflussanalyse einen Pfad identifiziert, über den ein Wert zwischen zwei solchen Verwendungen fließen könnte, obwohl dies in der Realität nie passieren würde oder von Bedeutung wäre. Dies kann in schlimmen Fällen dazu führen, dass ein Speicherort als Vereinigung von Typen definiert werden muss. Der Decompiler kann es dem Benutzer ermöglichen, solche unnatürlichen Abhängigkeiten explizit zu unterbrechen, was zu einem klareren Code führt. Dies bedeutet natürlich, dass eine Variable möglicherweise verwendet wird, ohne initialisiert zu werden, und deutet auf ein Problem im ursprünglichen Programm hin.
Typanalyse
Ein guter Maschinensprache-Decompiler führt eine Typanalyse durch. Hier führen die Art und Weise, wie Register oder Speicherorte verwendet werden, zu Einschränkungen hinsichtlich des möglichen Typs des Speicherorts. Beispielsweise impliziert ein and-Befehl, dass der Operand eine Ganzzahl ist; Programme verwenden eine solche Operation nicht für Gleitkommawerte (außer in speziellen Bibliotheksroutinen) oder für Zeiger. Ein add-Befehl führt zu drei Einschränkungen, da die Operanden entweder beide ganzzahlig oder eine Ganzzahl und ein Zeiger sein können (mit ganzzahligen bzw. Zeigerergebnissen; die dritte Einschränkung ergibt sich aus der Reihenfolge der beiden Operanden, wenn die Typen unterschiedlich sind).
Verschiedene hochgradige Ausdrücke können erkannt werden, die die Erkennung von Strukturen oder Arrays auslösen. Es ist jedoch schwierig, viele der Möglichkeiten zu unterscheiden, aufgrund der Freiheit, die Maschinensprache oder sogar einige Hochsprachen wie C mit Typumwandlungen und Zeigerarithmetik bieten.
Das Beispiel aus dem vorherigen Abschnitt könnte den folgenden hochgradigen Code ergeben:
struct T1 *ebx;
struct T1 {
int v0004;
int v0008;
int v000C;
};
ebx->v000C -= ebx->v0004 + ebx->v0008;
Strukturierung
Die vorletzte Decompilierungsphase umfasst die Strukturierung der IR in hochgradigere Konstrukte wie while-Schleifen und if/then/else-Bedingungsanweisungen. Zum Beispiel könnte der Maschinencode
xor eax, eax
l0002:
or ebx, ebx
jge l0003
add eax,[ebx]
mov ebx,[ebx+0x4]
jmp l0002
l0003:
mov [0x10040000],eax
übersetzt werden in:
eax = 0;
while (ebx < 0) {
eax += ebx->v0000;
ebx = ebx->v0004;
}
v10040000 = eax;
Unstrukturierter Code ist schwieriger in strukturierten Code zu übersetzen als bereits strukturierter Code. Lösungen umfassen das Duplizieren von etwas Code oder das Hinzufügen von booleschen Variablen.
Codegenerierung
Die letzte Phase ist die Generierung des hochgradigen Codes im Backend des Decompilers. So wie ein Compiler mehrere Backends für die Generierung von Maschinencode für verschiedene Architekturen haben kann, kann ein Decompiler mehrere Backends für die Generierung von hochgradigem Code in verschiedenen Hochsprachen haben.
Unmittelbar vor der Codegenerierung kann es wünschenswert sein, eine interaktive Bearbeitung der IR zu ermöglichen, vielleicht mit einer Form von grafischer Benutzeroberfläche. Dies würde es dem Benutzer ermöglichen, Kommentare und nicht-generische Variablen- und Funktionsnamen einzugeben. Diese sind jedoch fast genauso einfach in einer Nachbearbeitung der Decompilation einzugeben. Der Benutzer möchte möglicherweise strukturelle Aspekte ändern, wie z. B. die Konvertierung einer while-Schleife in eine for-Schleife. Diese sind mit einem einfachen Texteditor weniger einfach zu ändern, obwohl Refactoring-Tools für Quellcode diesen Prozess unterstützen können. Der Benutzer muss möglicherweise Informationen eingeben, die während der Typanalysephase nicht identifiziert wurden, z. B. die Änderung eines Speicherausdrucks in einen Array- oder Strukturausdruck. Schließlich muss möglicherweise eine fehlerhafte IR korrigiert oder Änderungen vorgenommen werden, um den Ausgabecode lesbarer zu machen.