Malware & Reverse Engineering

x86, x64 und Assembly

CPU-Architektur, Register, Stack, Speicherbereiche, Opcodes und wichtige Assembly-Instruktionen für Reverse Engineering.

x86, x64 und Assembly

Reverse Engineering findet oft auf Maschinenebene statt. Dafür braucht man ein Grundverständnis von CPU-Architektur, Registern, Stack, Speicherbereichen und Assembly.

Warum Assembly?

Assembly ist die niedrigste Ebene von Code, die für Menschen noch halbwegs lesbar ist.

Bei Malwareanalyse ist Assembly wichtig, weil:

  • Quellcode meist nicht vorhanden ist
  • Disassembler Maschinencode in Assembly übersetzen
  • Kontrollfluss sichtbar wird
  • Funktionsaufrufe und Parameter erkannt werden können
  • verdächtige Logik nachvollziehbar wird

Register

Register sind sehr schnelle Speicherplätze direkt in der CPU.

Wichtige Registergruppen:

RegistertypBedeutung
Instruction PointerAdresse der nächsten auszuführenden Instruktion
General-Purpose Registersallgemeine Register für Werte, Adressen und Berechnungen
Stack Pointerzeigt auf die aktuelle Position im Stack
Flags Registerspeichert Ergebniszustände früherer Operationen

Beispiele für x86/x64-Register sind EAX/RAX, EBX/RBX, ECX/RCX, EDX/RDX und EIP/RIP.

Status Flags

Flags zeigen Zustände nach Berechnungen an.

FlagBedeutung
ZFZero Flag, Ergebnis war null
CFCarry Flag, Übertrag oder Borrow
SFSign Flag, Vorzeichen des Ergebnisses
OFOverflow Flag, arithmetischer Überlauf

Bedingte Sprünge verwenden diese Flags.

Speicherbereiche

Ein Prozess nutzt verschiedene Speicherbereiche.

BereichInhalt
Codeausführbarer Maschinencode
Dataglobale und statische Daten
BSSnicht initialisierte globale Daten
Heapdynamisch angeforderter Speicher
StackFunktionsaufrufe, lokale Variablen, Rücksprungadressen

Für Malwareanalyse sind diese Bereiche wichtig, weil dort Hinweise auf Verhalten, Daten und Kontrollfluss sichtbar werden.

Stack

Der Stack arbeitet nach dem Prinzip Last In, First Out.

Er wird verwendet für:

  • Funktionsaufrufe
  • lokale Variablen
  • Argumente
  • Rücksprungadressen
  • temporäre Werte

Im Debugger ist der Stack oft hilfreich, um zu sehen, wie ein Programm an eine bestimmte Stelle gelangt ist.

Opcodes

Maschinencode besteht aus Bytes. Diese Bytes werden von der CPU als Instruktionen interpretiert.

Ein Disassembler zeigt aus diesen Bytes wieder lesbare Assembly-Befehle.

Dabei gehen aber viele Informationen verloren:

  • Variablennamen
  • Kommentare
  • ursprüngliche Struktur
  • Typinformationen
  • Absicht des Codes

Wichtige Instruktionen

InstruktionBedeutung
movkopiert Werte
addaddiert
subsubtrahiert
andbitweises UND
orbitweises ODER
xorbitweises XOR
cmpvergleicht Werte
testprüft Bits und setzt Flags
jmpspringt unbedingt
jz / jespringt, wenn Zero Flag gesetzt ist
pushlegt Wert auf den Stack
popholt Wert vom Stack
nopkeine Operation

Kontrollfluss

Malwareanalyse lebt stark vom Kontrollfluss.

Wichtige Fragen:

  • Wo beginnt die Ausführung?
  • Welche Bedingungen entscheiden über den nächsten Schritt?
  • Welche Funktionen werden aufgerufen?
  • Gibt es Sprünge in ungewöhnliche Bereiche?
  • Wird Code erst zur Laufzeit entschlüsselt oder entpackt?

Merksatz

Assembly wirkt zuerst fremd, aber es folgt klaren Regeln. Wer Register, Stack, Flags und Sprünge versteht, kann viele Binärprogramme deutlich besser lesen.

Zuletzt aktualisiert: 6. Juni 2026