In our previous tutorials like stack0, stack and functions etc we used GDB many times. I explained basic GDB terms like break points, disassemble etc. However I thought it'll be better if there dedicated tutorials for GDB. So in this post I'm going to explain how to use a Linux debugger for debug and analyze a binary file. If you are planning to learn reverse engineering , malware analysis or exploit development you must be familiar with debuggers. gdb-interface 1)Starting the debugging. We can open a binary inside GDB with the command gdb ./binary command. Hear binary is the file we want to debug. You may see following screen after this command.
[email protected]:~/programming/c$ gdb  ./ptr
GNU gdb (Debian 8.1-4+b1) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-linux-gnu".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from ./ptr...(no debugging symbols found)...done.
(gdb)
However in general we don't need this banner. I think it disturb our process. So we can start GDB with -q command for prevent GDB showing this welcome banner. gdb -q ./binary So we can get following interface.
[email protected]:~/programming/c$ gdb -q  ./ptr
Reading symbols from ./ptr...(no debugging symbols found)...done.
(gdb)
2) selecting the assembly syntax. By default gdb uses AT&T assembly syntax. But in our previous tutorials we saw Intel's syntax for assembly is more easy to learn and it's clear. So Let's see how we can change the assembly syntax in our debugger.
[email protected]:~/programming/c$ gdb -q  ./ptr
Reading symbols from ./ptr...(no debugging symbols found)...done.
(gdb) set disassembly-flavor intel
(gdb)
3) Listing the source code. Of you want to see source code when debugging you can use the. Command list for it . But to use this feature you must compile your source in GCC with additional command -g or -ggdb.
[email protected]:~/programming/c$ gcc ptr.c -o ptr -ggdb
[email protected]:~/programming/c$ 
[email protected]:~/programming/c$ gdb -q  ./ptr
Reading symbols from ./ptr...done.
(gdb) list
1	#include <stdio.h>
2	
3	int main(int argc, char **argv)
4	{
5	
6		int var;
7		var = 100;
8		int *ptr;
9	
10		ptr = &var;
(gdb)
  4) Disassemble a binary. After you loading a binary in GDB you can disassemble a function and see how is the assembly code . To do that you can use disassemble function_name or disas function_name. For an example if you want to disassemble main function you may use disassemble main or disas main.
[email protected]:~/programming/c$ gdb -q ./test
Reading symbols from ./test...(no debugging symbols found)...done.
(gdb) disass main
Dump of assembler code for function main:
   0x00001199 <+0>:	push   ebp
   0x0000119a <+1>:	mov    ebp,esp
   0x0000119c <+3>:	push   ebx
   0x0000119d <+4>:	call   0x11c2 <__x86.get_pc_thunk.ax>
   0x000011a2 <+9>:	add    eax,0x2e5e
   0x000011a7 <+14>:	lea    edx,[eax-0x1ff8]
   0x000011ad <+20>:	push   edx
   0x000011ae <+21>:	mov    ebx,eax
   0x000011b0 <+23>:	call   0x1030 <[email protected]>
   0x000011b5 <+28>:	add    esp,0x4
   0x000011b8 <+31>:	mov    eax,0x0
   0x000011bd <+36>:	mov    ebx,DWORD PTR [ebp-0x4]
   0x000011c0 <+39>:	leave  
   0x000011c1 <+40>:	ret    
End of assembler dump.
(gdb)
At the left side we can see memory addresses. Our CPU instructions are loaded in there. At right side there are assembly instructions. In a separated tutorial I'll explain about all of these assembly instructions one by one. Till then just get a rough idea what they do. :-) 5) Setting a break point Break point is an essential thin in debugging. We can stop the execution of program on a decided state and examine the memory and registers . You can set a break point on a function withe command break. If you want break execution at main function you may use break main or short command b main. But when you set breakpoints with function name GDB will skip function prologue. So if you want to see how stack is building you have another option to set breakpoints. In this method we use a memory address instead of function name.
Dump of assembler code for function main:
   0x00001199 <+0>:	push   ebp
   0x0000119a <+1>:	mov    ebp,esp
   0x0000119c <+3>:	push   ebx
   0x0000119d <+4>:	call   0x11c2 <__x86.get_pc_thunk.ax>
   0x000011a2 <+9>:	add    eax,0x2e5e
   0x000011a7 <+14>:	lea    edx,[eax-0x1ff8]
   0x000011ad <+20>:	push   edx
   0x000011ae <+21>:	mov    ebx,eax
   0x000011b0 <+23>:	call   0x1030 <[email protected]>
   0x000011b5 <+28>:	add    esp,0x4
   0x000011b8 <+31>:	mov    eax,0x0
   0x000011bd <+36>:	mov    ebx,DWORD PTR [ebp-0x4]
   0x000011c0 <+39>:	leave  
   0x000011c1 <+40>:	ret    
End of assembler dump.
(gdb) break main
Breakpoint 1 at 0x119d
(gdb) break *0x00001199
Breakpoint 2 at 0x1199
(gdb)
  6) Running the binary file Now we want to run the program. You may use command run . Also you can give command line arguments to program while it running inside GDB.
(gdb) run AAAAAA
OK. I explained some basics of GDB. We can examine memory after we run this program. Because we have sat a break point. I'll explain it on next tutorial. Thanks for reading.