Hello World Analysis
Last updated
Last updated
The story doesn't end here. We need to look how registers are changing as per instructions.
For now, we will be using GDB (GNU Debugger) for analysis.
To load the final binary in gdb, use ‘gdb ./FILENAME’ command OR gdb -q ./FILENAME.
The latter will ignore the Extra content(copyright, license etc)i.e Silent mode, can be seen in above image.
Before diving into analysis, some info regarding GDB.
We can execute command from here as well. Format: shell COMMAND
To see functions present in the loaded file: info functions
To see variables present in the loaded file: info variables
At any point of time, we can check values present inside the register: info registers
To disassemble and see the assembly code: disassemble
To disassemble specific function: disassemble FUNCTION_NAME
Majority of the time its about setting breakpoint and checking content inside registers,
Breakpoint?
Breakpoints are points in your code at which gdb will stop and allow executing other gdb commands. When a breakpoint is set at any instruction, program execution will pause at the instruction, and we can analyse the registers, memory address at that particular state.
Setting breakpoint at a function: break FUNCTION_NAME
Setting breakpoint at any instruction:
break INSTRUCTION_LINE or break *ADDRESS_OF_INSTRUCTION.
Listing defined breakpoints: info break
Delete any breakpoint: delete BREAKPOINT_NUMBER
To start the execution: run OR r
To continue execution after breakpoint is hit: c
Above image contains a few example of how gdb commands(highlighted in yellow) are be used.
💡 Another thing to note here, how disassembly of program is shows. The one, shown above in image is having AT&T format(can be noticed by seeing $,%). We have another format named INTEL format. Throughout the content, INTEL format is used.
AT&T, the general format is instruction source, destination
INTEL, the general format is instruction destination, source
To convert the format from AT&T to INTEL, we use following command: set disassembly-flavor intel as shown above.
[Analysis Contd→]
Wait, do we have to type ‘info register ###’ command again and again for every instruction?
Not at all. We can use hook-stop. Every time we step into the next instruction, hook-stop will get executed. Inside hook-stop, we can define gdb commands that we want to be executed.
We will use, define hook-stop command and then start giving the commands for execution, and exit out of hook-stop using end , as shown below.
Great, we can see, how after each instruction being executed, registers values are shown. This might not be looking much fruitful now. Reason being, we already know the source code.
In reality, when we will be encountering program only, no prior knowledge of its source code. Then, changes in registers helps us to look the bigger picture.
So far, we could see register information. What about memory content? Because eventually something stored in memory could be loaded/stored during run time.
We can see memory content at a given address using the specified format, using x command
Syntax: x/[FORMAT] Address , x/[LENGTH][FORMAT] Address
Format→
o - octal
x - hexadecimal
d - decimal
u - unsigned decimal
t - binary
f - floating point
a - address
c - char
s - string
i - instruction
The following size modifiers are supported:
b - byte
h - halfword (16-bit value)
w - word (32-bit value)
g - giant word (64-bit value)
Example:
To see content at memory address 0x804a000 in string format. We will use: x/s 0x804a000
To see content at memory address 0x804a000 in decimal format(will use 10d, to see 10 decimal character. We will use: x/10d 0x804a000
💡 To see content of a variable which we came to know from info variable command: x/[FORMAT] &VAR_NAME
[Analysis Contd→]
Finally, we reached the end, and analysed how registers are being changed, what data is stored at particular memory address.
Lets look forward into data types and different operations using registers.