Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

How to read x86-64 assembly

After this lesson: I can read a few lines of x86-64 assembly.

55 min lesson4 commandsReverse engineering lab: reading programs with gdb, radare2, strace and ltrace on one VM

Assembly is a program in small steps

Assembly language is the readable form of the instructions a processor runs, one small step on each line.

You do not need to write it to use it. Knowing a handful of instructions is enough to see where a program compares two things and what it does next.

By the end of this lesson

Note

I can read a few lines of x86-64 assembly.

Key words

WordWhat it meansExample
Instructionone step the processor carries out
Mnemonicthe short name of an instructionmov
Operanda value or place an instruction works on
Registera tiny store inside the processorrax
Flaga one-bit result the processor remembers
Jumpan instruction that moves to another line

The cells students fill in are left blank in this preview.

An instruction is a name and its operands

Each line is one instruction: a mnemonic and then its operands. In Intel style the place that gets the answer comes first.

mov eax, 5 copies 5 into the register eax. The table reads five instructions the way you will meet them. A register is a tiny store inside the processor, with a name.

Worked example: five instructions

InstructionWhat it doeseax afterwards, starting at 0
mov eax, 5Copies 5 into eax5
add eax, 3Adds 3 to eax8
sub eax, 2Takes 2 from eax6
xor eax, eaxSets every bit of eax to 0 by xor with itself0
cmp eax, 8Compares eax with 8 and changes no register0

The cells students fill in are left blank in this preview.

Compare sets a flag, jump reads it

cmp a, b works out the difference and throws the answer away. It keeps only flags, such as "the two were equal".

A jump then reads a flag. je jumps when the two were equal, and jne jumps when they were not. test eax, eax is a quick way to ask whether eax is zero. With no compare in front, a jump has nothing to decide on.

The registers you meet most

NameWhat it usually holds
rax, eaxThe answer a function gives back
rdiThe first argument of a call
rsiThe second argument of a call
rspThe top of the stack
rbpThe base of the current function's stack
ripThe address of the next instruction

The cells students fill in are left blank in this preview.

Write the practice program again

Command
printf '#include <stdio.h>\n#include <string.h>\nint main(int argc, char **argv) {\n    if (argc != 2) { puts("usage: vault WORD"); return 2; }\n    if (strcmp(argv[1], "blue-harbour") == 0) { puts("Door open."); return 0; }\n    puts("Door shut.");\n    return 1;\n}\n' > vault.c

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Compile it

Command
gcc -O0 -no-pie -fno-stack-protector -o vault vault.c

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

The part of main that compares

Code: shell
cmp    DWORD PTR [rbp-0x4],0x2
je     main+0x2f
mov    rax,QWORD PTR [rbp-0x10]
add    rax,0x8
mov    rax,QWORD PTR [rax]
lea    rdx,[rip+0xe7f]
mov    rsi,rdx
mov    rdi,rax
call   strcmp@plt
test   eax,eax
jne    main+0x66

Reading the comparison in words

This is a real excerpt from main of our practice program vault, with the addresses left out. It is an example of what you will see.

The first two lines check that one word was typed after the program's own name. Then rdi and rsi are filled and strcmp is called. It leaves its answer in eax: zero means the strings are equal. test eax, eax checks for zero, and jne jumps away when it is not zero.

The compares and jumps in main

Command
objdump -d vault --disassemble=main -M intel | grep -E "[[:space:]](cmp|test|jne|je)[[:space:]]"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

What comes straight after the strcmp call

Command
objdump -d vault --disassemble=main -M intel | grep -A1 "strcmp@plt"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people read assembly like a story, from the top line to the bottom. A jump moves somewhere else, and a conditional jump only moves when the flags say so. Follow the jumps as well as the lines, or you read code that never runs.

About this lab and its source: Reverse engineering lab: reading programs with gdb, radare2, strace and ltrace on one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.