🐱Assembling & Debugging
Assembly File Structure
Here is the Hello World!
Assembly code template
Here are different parts of this output:
Directives
the file is processed line-by-line, executing the instruction of each line. We see at the first line a directive global _start
, which instructs the machine to start processing the instructions after the _start
label. So, the machine goes to the _start
label and starts executing the instructions there, which will print the message on the screen.
Variables
The .data
section holds our variables to make it easier for us to define variables and reuse them without writing them multiple times. Once we run our program, all of our variables will be loaded into memory in the data
segment.
We can define variables using db
for a list of bytes, dw
for a list of words, dd
for a list of digits, and so on
we can also use the equ
instruction with the $
token to evaluate an expression, like the length of a defined variable's string.
the following code defines a variable and then defines a constant for its length:
Code
The .text
section holds all of the assembly instructions and loads them to the text
memory segment. Once all instructions are loaded into the text
segment, the processor starts executing them one after another.
Assembling & Disassembling
Assembling
First, we will copy the code below into a file called helloWorld.s
(use the .s
or the .asm
extensions)
helloWorld.s
file:
we will assemble the file using nasm
, with the following command:
The -f elf64
flag is used to note that we want to assemble a 64-bit assembly code. If we wanted to assemble a 32-bit code, we would use -f elf
This should output a helloWorld.o
object file
Linking
Now we need to to link our file using ld
because the helloWorld.o
object file, though assembled, still cannot be executed.
Here is a simple bash script to make all of the above things easier ->
Disassembling
we will use the objdump
tool, which dumps machine code from a file and interprets the assembly instruction of each hex code.
If we wanted to only show the assembly code, without machine code or addresses, we could add the --no-show-raw-insn --no-addresses
flags
The -d
flag will only disassemble the .text
section of our code. To dump any strings, we can use the -s
flag, and add -j .data
to only examine the .data
section. This means that we also do not need to add -M intel
Download the attached file and disassemble it to find the flag
GNU Debugger (GDB)
Debugging is a term used for finding and removing issues (i.e., bugs) from our code. we perform debugging by setting breakpoints and seeing how our program acts on each of them and how our input changes between them, which should give us a clear idea of what is causing the bug
.
GEF is a free and open-source GDB plugin that is built precisely for reverse engineering and binary exploitation. To install ->
we can run gdb to debug our HelloWorld
binary
To assemble and link our assemble quickly, we can use the assembler.sh
script we wrote in the previous section with the -g
flag
we will use the info
command to check which functions
are defined within the binary
info variables
command to view all available variables within the program
Disassemble
To view the instructions within a specific function, we can use the disassemble
or disas
command
Debugging with GDB
Here are the 4 steps of debugging:
Break
The first step of debugging is setting breakpoints
to stop the execution at a specific location or when a particular condition is met. This helps us in examining the state of the program and the value of registers at that point.
we can use the run
or r
command
If we want to set a breakpoint at a certain address, like _start+10
, we can either b *_start+10
or b *0x40100a
Examine
Last updated