Skip to content

x86 Arkitektur

Malware udnytter ofte systemers designprincipper. For at forstå hvordan malware fungerer, er det essentielt at kende arkitekturen i de systemer, de kører på.


CPU-Arkitektur

Von Neumann Arkitekturen

Den mest anvendte CPU-arkitektur er afledt af Von Neumann-arkitekturen.

CPU-komponenter

Control Unit (Kontrolenhed) - Henter instruktioner fra hovedhukommelsen

  • Adressen til næste instruktion gemmes i et register kaldet Instruction Pointer (IP)

  • I 32-bit systemer: EIP (Extended Instruction Pointer)

  • I 64-bit systemer: RIP (Register Instruction Pointer)

Arithmetic Logic Unit (ALU) - Udfører de instruktioner, der hentes fra hukommelsen - Resultaterne gemmes i enten registre eller hukommelsen

Registre - CPU'ens lager

  • Meget mindre end hovedhukommelsen

  • Hjælper med at spare tid ved at CPU'en har direkte adgang til data'en

Hukommelse (Memory) - Også kaldet Main Memory eller RAM

  • Indeholder al kode og data for et program

  • Når et program udføres, indlæses dets kode og data i hukommelsen


CPU-Registre

Instruction Pointer

  • Indeholder adressen til næste instruktion, der skal udføres

  • Også kaldet Program Counter

  • 16-bit (IP) → 32-bit (EIP) → 64-bit (RIP)

General Purpose Registers (Generelle Registre)

EAX/RAX (Accumulator Register) - Resultater af aritmetiske operationer gemmes ofte her

  • 32-bit: EAX

  • 64-bit: RAX

  • Kan også adresseres som: AX (16-bit)

EBX/RBX (Base Register) - Bruges ofte til at gemme base adressen for referencering af offset

  • Samme adresseringsmuligheder: RBX, EBX, BX, BH, BL

ECX/RCX (Counter Register) - Bruges ofte i tælleoperationer som loops

  • Samme adresseringsmuligheder: RCX, ECX, CX, CH, CL

EDX/RDX (Data Register) - Bruges ofte i multiplikation/divisions-operationer

  • Samme adresseringsmuligheder: RDX, EDX, DX, DH, DL

ESP/RSP (Stack Pointer) - Peger på toppen af stacken

  • Bruges sammen med Stack Segment registeret

  • 32-bit: ESP | 64-bit: RSP

EBP/RBP (Base Pointer) - Bruges til at tilgå parametre passed via stacken

  • Bruges sammen med Stack Segment registeret

  • 32-bit: EBP | 64-bit: RBP

ESI/RSI (Source Index Register) - Bruges til string-operationer

  • Bruges med Data Segment (DS) registeret som offset

  • 32-bit: ESI | 64-bit: RSI

EDI/RDI (Destination Index Register) - Bruges også til string-operationer

  • 32-bit: EDI | 64-bit: RDI

Status Flag Registers

EFLAGS/RFLAGS

  • 32-bit register (EFLAGS) i 32-bit systemer

  • 64-bit register (RFLAGS) i 64-bit systemer

  • Består af individuelle single-bit flags (1 eller 0)

Zero Flag (ZF) - Indikerer når resultatet af sidste instruktion var nul

  • Eksempel: RAX - RAX = 0, så ZF = 1

Carry Flag (CF) - Indikerer når resultatet er for stort eller for lille til destinationen

  • Eksempel: 0xFFFFFFFF + 0x00000001 i et 32-bit register → CF = 1

Sign Flag (SF) - Indikerer om resultatet er negativt eller MSB (mest signifikante bit) er sat til 1

  • Hvis betingelser opfyldt: SF = 1, ellers SF = 0

Trap Flag (TF) - Indikerer om processoren er i debugging-mode

  • Når TF er sat, udfører CPU'en én instruktion ad gangen

  • Kan bruges af malware til at identificere om de kører i en debugger


Segment Registers

16-bit registre der konverterer flad hukommelse til forskellige segmenter for lettere adressering.

CS (Code Segment) - Peger på kodesektionen i hukommelsen

DS (Data Segment) - Peger på programmets datasektion i hukommelsen

SS (Stack Segment) - Peger på programmets stack i hukommelsen

ES, FS, GS (Extra Segments) - Peger på forskellige datasektioner - Sammen med DS opdeles programmets hukommelse i fire distinkte datasektioner


Hukommelseslayout

Når et program indlæses i hukommelsen i Windows, ser det et abstraheret view af hukommelsen. Programmet har kun adgang til sin egen hukommelse.

Hukommelsessektioner

Code-sektion - Indeholder programmets kode

  • Refererer til text-sektionen i en Portable Executable-fil

  • Indeholder instruktioner udført af CPU'en

  • Har execute-rettigheder

Data-sektion - Indeholder initialiserede data, der ikke er variable

  • Ofte globale variabler og data, der ikke skal ændres under programudførelse

Heap - Også kendt som dynamisk hukommelse

  • Indeholder variabler og data oprettet og destrueret under programudførelse

  • Hukommelse allokeres ved runtime og frigives når variablen slettes

Stack - Meget vigtig fra et malwareanalyse-perspektiv

  • Indeholder lokale variabler, argumenter passed til programmet, og returadresse

  • Ofte målrettet af malware for at kapre kontrolflowet


Stack-layout

Stack Karakteristika

  • Last In First Out (LIFO) hukommelse

  • Sidste element pushed på stacken er første til at blive popped ud

Stack-registre

Stack Pointer (ESP/RSP) - Peger på toppen af stacken

  • Ændrer position når elementer pushes eller poppes

Base Pointer (EBP/RBP) - Forbliver konstant for et program

  • Referenceadresse hvor stacken tracker sine lokale variabler og argumenter

Stack-elementer (fra bund til top)

  1. Argumenter (laveste adresse, pushes først)

  2. Return Address

  3. Old Base Pointer ← Base Pointer (EBP/RBP) peger her

  4. Lokale variabler ← Stack Pointer (ESP/RSP) peger her (højeste adresse)

Stack Buffer Overflow

En almindelig teknik til at kapre kontrolflow:

  • Overflow en lokal variabel på stacken

  • Overskriv Return Address med en adresse efter malware-forfatterens valg

Function Prologue

Kode der forbereder stacken når en funktion kaldes:

  1. Argumenter pushes på stacken

  2. Return Address pushes på stacken

  3. Old Base Pointer pushes på stacken

  4. Base Pointer ændres til toppen af stacken

Function Epilogue

Kode der rydder op når funktionen afsluttes:

  1. Old Base Pointer poppes tilbage til Base Pointer

  2. Return Address poppes til Instruction Pointer

  3. Stack Pointer omarrangeres til at pege på toppen


Sources

https://tryhackme.com/room/x8664arch

Bemærkning

Noterne er struktureret og rettet med hjælp af LLM'en Claude.