Hi Steemiters,
I think that most of the peoples who follow these entries understand what features gdb has and how it is installed, thus, not to mention what is already known and save time in it, merely reference will be made to some of the parameters that shall can be use in the debugging of an executable with gdb. This post has is intended to be only a practical mini guide with some examples in code, we will see some screenshot to show the output of commands executed once the process has been attacked. In the future, this document shall be used as a reference for another post.
The main motivation of this post is to give the reader a small cheatsheet or a brief introduction of this excellent tool.
This document shall may be modified in the long term, in order to add improvements and complement certain sections of it.
All these tests have been performed under a 64-bit operating system.
(gdb) b main
Assign a breakpoint in the attach process in the main function
(gdb) disas main
Gets an assembly dump from the main function
(gdb) s
Step over, execute instruction by instruction after a breakpoint
(gdb) p strEjmploVal
Print, makes a dump of the value of a variable in this case strEjmploVal, in this case it is necessary that the executable is running suspended by a breakpoint to observe the values.
Another way to see the data in an even more useful way is ...
(gdb) x /1bt &int16var1
EXamine obtains the memory address of the variable int16var1, note the &, syntax similar to that of C or C ++ in the same way obtains the value of said variable; this command will can be decomposed in the following way.
/ 1bt Displays 1 byte in memory, in which case you need to display a value of 4 bytes you can define / 4bt; if you want to show a value of 10 bytes then it will be set / 10bt
The eXemine command has several parameters and is pretty flexible when presenting values and memory locations.
(gdb) bt
Backtrace, shows the functions in the stack and its arguments
(gdb) x /4xw $sp
EXamine 4 words (w)
in hexadecimal notation (x)
of the Stack Pointer ($sp)
.
(gdb) info registers
As it should be noted, it shows the information of some important records; If you provide a specific usage record (rdi, rsi, rdx) then it will return the value of it. For example:
(gdb) info registers rdi
(gdb) info registers rsi
We better see it in short and simple code in ASM x64.
global _start
section .text
_start:
mov rax, 9099
mov rbx, 555
; sycall_exit()
mov rbx, 0
mov rax, 1
int 0x80
We compile and then in the gdb we see something like this:
")
With the gdb, we break, launch and go running the application with many s
until we reach the instruction that interests us themov rax, 9099
and we see the dump of the records that we establish in the assembler code, the first column shows the name of the record rax
in the second column the value in memory of the register in hexadecimal and finally the third column shows the value in decimal system of the recordrax
with values 9099 and 555 for the record rbx
Well, I think the idea is understood when they are variables with integers, but what about the variable strings? let's see another example with character strings in ASM x64:
section .text
global _start
_start:
mov rbx, txt
; syscal_exit()
mov rbx, 0
mov rax, 1
int 0x80
section .data
txt db 'oPen syLar', 0
We compiled and then in the gdb we see something like this:
Therefore, it is noted that the format presented by eXamine is the appropriate to explain several issues that had not been dealt with in more detail.
In the first instance, we see commands b
r
that were already treated in this same post, then we observed the command x
but this one shows binary values that can be decomposed in different ways:
If you do not have enough time, you also like to simplify things, you can take a calculator, convert binary values to decimals and decimals to ASCII values.
Address in memory | Binario | Decimal | ASCII |
---|---|---|---|
0x6000c8 | 01101111 | 111 | o |
0x6000c8 | 01010000 | 80 | P |
0x6000c8 | 01100101 | 101 | e |
0x6000c8 | 01101110 | 110 | n |
0x6000c8 | 00100000 | 32 | |
0x6000c8 | 01110011 | 115 | s |
0x6000c8 | 01111001 | 121 | y |
0x6000c8 | 01001100 | 76 | L |
0x6000d0 | 01100001 | 97 | a |
0x6000d0 | 01110010 | 114 | r |
0x6000d0 | 00000000 | 0 | NULL |
I do not think it's necessary to explain the table
Bonus track
If you have free time so, you can use the next tactic to convert decimals to binaries and compare values with an ASCII table.
I saw this procedure in a blog, it is very helpful for those who are passionate about doing the most interesting things; This method is just one of many than exists to convert decimal values to binary, it is not the best or the wors.
Well, let's take the y
character of the example string oPen syLar
If to the number we can subtract 128, we do it and write a one, if is not possible so we put a zero
- According to the ASCII table the decimal value is 121 therefore we can not subtract 128, then we write 0
We verify if we can subtract 32 since the previous result, if so, we do it and than write an 1, if it is allow it, we put a zero.
- 57 if will can be subtract 32 therefore we write 1
We verify if we can subtract 16 since the previous result, if so, we do it and than write an 1, if it is allow it, we put a zero.
- 25 if will can be subtract 16 therefore we write 1
We verify if we can subtract 8 since the previous result, if so, we do it and than write an 1, if it is allow it, we put a zero.
- 9 if will can be subtract 8 therefore we write 1
We verify if we can subtract 2 since the previous result, if so, we do it and than write an 1, if it is allow it, we put a zero.
- 1 if will can be subtract 4 therefore we write 0
We verify if we can subtract 1 since the previous result, if so, we do it and than write an 1, if it is allow it, we put a zero.
- 1 if will can be subtract 1 therefore we write 1
Result: 01111001
References |
---|
Dartmouth |
ASM86 Wordpress |
Sourceware |
SCSS |
Si hablas español puedes leerlo acá