Assembly-sprog og x86-systemprogrammering på lavt niveau · Lektion

Brug af GDB til Assembly-debugging

Bliv fortrolig med GNU Debugger (GDB) til opsætning af breakpoints, inspektion af registre og hukommelse samt trinvis gennemgang af Assembly-kode.

Lektion 1 af 412 trin

Brug af GDB til Assembly-debugging er en gratis Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion på CoddyKit. Dette er lektion 1 af 4. Du kan læse hele lektionen gratis nedenfor — og derefter øve dig praktisk i browseren med en indbygget kodeeditor og en AI-vejleder, der er tilgængelig døgnet rundt. Den er en del af læringsforløbet i Assembly-sprog og x86-systemprogrammering på lavt niveau, og dine fremskridt synkroniseres på tværs af nettet og CoddyKit-appen. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.

Fejlfindingens bedste ven: GDB

Velkommen til fejlfindingens verden! Når du arbejder med lavniveau-sprog som assembly, er det afgørende at forstå præcis, hvad programmet gør, instruktion for instruktion.

GNU Debugger (GDB) er et utroligt effektivt værktøj, der lader dig:

  • Sætte programmet på pause på bestemte steder (stoppunkter).
  • Gå gennem koden linje for linje.
  • Undersøge værdierne i registre og hukommelse.
  • Forstå programmets forløb og identificere problemer.

Det er en uundværlig færdighed for enhver assemblyprogrammør!

Forberedelse af din assemblykode

Før GDB kan hjælpe os, skal vi kompilere vores assemblykode med særlige "fejlfindingssymboler". Disse symboler fortæller GDB om variabelnavne, funktionsetiketter og kildekodelinjer, hvilket gør fejlfinding meget nemmere.

Til NASM-assembly på Linux bruger du typisk flaget -g under kompilering og sammenkædning:

  • Assemblering: nasm -f elf32 -g your_code.asm -o your_code.o
  • Sammenkædning: ld -m elf_i386 -g your_code.o -o your_executable

Flaget -g indlejrer fejlfindingsoplysningerne direkte i objektfilen og det eksekverbare program.

Vores mål: Et enkelt program

Lad os bruge et enkelt assemblyprogram som mål for vores fejlfinding. Dette program udskriver en meddelelse i konsollen og udfører derefter en simpel addition, før det afsluttes.

Vi kompilerer det med fejlfindingssymboler og går derefter i gang med GDB.

; filename: debug_example.asm

section .data
    hello_msg db "Hello from Assembly!", 0xA ; Message to print
    hello_len equ $ - hello_msg

section .text
    global _start

_start:
    ; --- Part 1: Print "Hello from Assembly!" ---
    ; sys_write syscall (Linux x86 32-bit)
    mov eax, 4          ; syscall number for sys_write
    mov ebx, 1          ; file descriptor 1 (stdout)
    mov ecx, hello_msg  ; address of string to write
    mov edx, hello_len  ; length of string
    int 0x80            ; invoke kernel

    ; --- Part 2: Perform a simple calculation ---
    mov eax, 10         ; Move 10 into EAX
    mov ebx, 5          ; Move 5 into EBX
    add eax, ebx        ; Add EBX to EAX (EAX becomes 15)

    ; --- Part 3: Exit the program ---
    ; sys_exit syscall (Linux x86 32-bit)
    mov eax, 1          ; syscall number for sys_exit
    mov ebx, 0          ; exit code 0 (success)
    int 0x80            ; invoke kernel

Start af GDB

Når dit program er kompileret med fejlfindingssymboler, er det enkelt at starte GDB. Åbn din terminal, og skriv gdb efterfulgt af navnet på dit eksekverbare program.

Hvis det eksekverbare program i vores eksempel hedder debug_executable, skal du skrive:

gdb ./debug_executable

GDB indlæser dit program og viser sin prompt, som normalt er (gdb). Dit program kører endnu ikke; GDB er blot klar til at modtage kommandoer.

Indstilling af dit første stoppunkt

Et stoppunkt er en markering, der fortæller GDB, at programkørslen skal sættes på pause, når den når en bestemt instruktion eller hukommelsesadresse. På den måde stopper du programmet på et interessant sted.

Brug kommandoen break eller b efterfulgt af et funktionsnavn, en etiket eller en hukommelsesadresse for at indstille et stoppunkt. I assembly bruger vi ofte etiketter.

  • (gdb) break _start: Indstiller et stoppunkt ved programmets startpunkt.
  • (gdb) b *0x80480a0: Indstiller et stoppunkt ved en bestemt hukommelsesadresse (eksempeladresse).

Kørsel og genoptagelse af programkørslen

Når du har indstillet stoppunkter, kan du starte programmet eller genoptage programkørslen.

  • run (eller r): Starter programmet fra begyndelsen. Det kører, indtil det rammer det første stoppunkt, afsluttes eller går ned.
  • continue (eller c): Genoptager programkørslen, efter at programmet har ramt et stoppunkt. Det fortsætter, indtil det når det næste stoppunkt eller afsluttes.

Prøv at indstille et stoppunkt ved _start og derefter bruge run. Du vil se GDB sætte programmet på pause helt i begyndelsen!

Trinvis programkørsel

Når programmet er sat på pause ved et stoppunkt, kan du udføre instruktioner én ad gangen. Det er uvurderligt, når du vil se den præcise effekt af hver instruktion.

  • stepi (eller si): Udfører den næste enkeltinstruktion. Hvis instruktionen er et call til en procedure, går si ind i proceduren.
  • nexti (eller ni): Udfører den næste enkeltinstruktion. Hvis instruktionen er et call, udfører ni hele proceduren og stopper ved instruktionen umiddelbart *efter* call.

Brug si til omhyggeligt at følge hver instruktion, eller ni til at springe over procedurekald, du ikke er interesseret i.

Kig på registrene

Registre er CPU'ens små, ekstremt hurtige lagerpladser. I assembly flytter du hele tiden data ind i og ud af dem. GDB lader dig undersøge deres aktuelle værdier.

  • info registers (eller i r): Viser de aktuelle værdier for alle generelle registre, segmentregistre, instruktionsmarkøren (EIP/RIP) og flagene.
  • info registers eax: Viser værdien af et bestemt register, f.eks. EAX.
  • print $eax: En anden måde at udskrive værdien af et bestemt register på. Præfikset $ fortæller GDB, at det er et register.

Efter vores add eax, ebx-instruktion kan du undersøge eax for at se den nye værdi (15).

Undersøgelse af hukommelsesindhold

Ud over registre får du ofte brug for at undersøge, hvad der er gemt i hukommelsen. Kommandoen x (examine) er nyttig her.

Formatet er x/<count><format><unit-size> <address>:

  • count (N): Hvor mange enheder der skal vises.
  • format (F): Hvordan de skal vises (f.eks. x for hexadecimal, d for decimal, s for streng og i for instruktioner).
  • unit-size (U): Størrelsen på hver enhed (f.eks. b for byte, h for halfword/2 byte, w for word/4 byte og g for giant/8 byte).

Eksempler:

  • (gdb) x/s hello_msg: Viser strengen ved hello_msg.
  • (gdb) x/4xw $esp: Viser 4 words (4 byte hver) i hexadecimal fra stackmarkøren.

Disassemblering af kode undervejs

Nogle gange har du under fejlfinding brug for at se assemblyinstruktionerne omkring det aktuelle kørselssted. Kommandoen disassemble (eller disas) konverterer maskinkode tilbage til assembly.

  • (gdb) disassemble: Disassemblerer den funktion, der udføres i øjeblikket.
  • (gdb) disas _start: Disassemblerer hele funktionen _start.
  • (gdb) disas $eip, +20: Disassemblerer 20 byte instruktioner fra den aktuelle instruktionsmarkør (EIP).

Det hjælper dig hurtigt med at orientere dig og se konteksten omkring koden.

Udfordring: GDB-kommandoer

Hvilke af følgende GDB-kommandoer bruges til at styre programkørslen (starte, sætte på pause, genoptage og udføre trin)?

Fejlfindingens fulde kraft

Tillykke! Du har taget dine første skridt mod at mestre GDB til fejlfinding af assembly. Vi har gennemgået:

  • Hvorfor GDB er afgørende ved programmering på lavt niveau.
  • Hvordan du kompilerer assembly med fejlsymboler.
  • Grundlæggende GDB-kommandoer som run, break og continue.
  • Hvordan du går trin for trin gennem kode med stepi og nexti.
  • Hvordan du inspicerer registre (info registers) og hukommelse (x).
  • Dekompilering af kode undervejs (disassemble).

Disse grundlæggende færdigheder hjælper dig med at forstå og fejlfinde komplekse assemblyprogrammer, så deres indre funktioner bliver synlige instruktion for instruktion. Bliv ved med at øve dig!

Gratis at komme i gang

Lær Assembly med en AI-underviser — gratis

Skriv og kør rigtig kode i din browser, få øjeblikkelig hjælp fra en AI-underviser døgnet rundt, og fortsæt, hvor du slap, på web eller i appen.

Kurser
12
Lektioner
48

Ofte stillede spørgsmål

Er lektionen “Brug af GDB til Assembly-debugging” gratis?

Ja — hele teksten til “Brug af GDB til Assembly-debugging” kan læses gratis her på nettet. Hvis du vil øve dig interaktivt med en indbygget kodeeditor og en AI-vejleder døgnet rundt og få adgang til resten af Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset, skal du opgradere til CoddyKit PRO. Assembly-sprog og x86-systemprogrammering på lavt niveau-kurset indeholder 4 lektioner i alt.

Hvad lærer jeg i “Brug af GDB til Assembly-debugging”?

Bliv fortrolig med GNU Debugger (GDB) til opsætning af breakpoints, inspektion af registre og hukommelse samt trinvis gennemgang af Assembly-kode. Du øver dig i Assembly-sprog og x86-systemprogrammering på lavt niveau med praktisk kode, som du kører direkte i browseren, og en AI-vejleder døgnet rundt besvarer dine spørgsmål, mens du arbejder dig gennem lektionen.

Skal jeg have erfaring for at begynde på Assembly-sprog og x86-systemprogrammering på lavt niveau?

Der kræves ingen tidligere erfaring. Assembly-sprog og x86-systemprogrammering på lavt niveau på CoddyKit er tilrettelagt for både begyndere og øvede, så du kan starte her eller fra begyndelsen og lære i dit eget tempo. Dette er lektion 1 af 4.

Hvor lang tid tager lektionen “Brug af GDB til Assembly-debugging”?

De fleste CoddyKit-lektioner tager cirka 5–10 minutter. Hver lektion er kort og interaktiv, så du gør løbende fremskridt og kan fortsætte, hvor du slap – på både web og app.

Kan jeg skrive og køre kode i denne Assembly-sprog og x86-systemprogrammering på lavt niveau-lektion?

Ja. Alle Assembly-sprog og x86-systemprogrammering på lavt niveau-lektioner har en indbygget kodeeditor, så du kan skrive og køre rigtig kode direkte i din browser og få øjeblikkelig feedback fra AI – uden lokal opsætning.

Alle lektioner i dette kursus

  1. Brug af GDB til Assembly-debugging
  2. Introduktion til disassembly-værktøjer
  3. Grundlæggende reverse engineering-teknikker
  4. Dynamisk analyse med tracing og hooking
← Tilbage til Assembly-sprog og x86-systemprogrammering på lavt niveau