Friday, January 28, 2011

~GDB Basic Hacking~

Hello Everyone,

I am going to show basic hack of wonderful wonderful software gdb in this
article. As we know gdb(GNU Debugger) can be used for debugging C/C++ and
many more other languages program.

I am the very frequent user of gdb. There are quite a few commands of gdb which i always set once i am inside gdb session. Once i was going through the official manual of gdb, after reading i got the idea about the file ".gdbinit". Whenever we start gdb session for debugging, it tries to read the .gdbinit file from the user $HOME directory. I searched into my $HOME directory but there was no such file.


For better understanding how gdb gets the information from .gdbinit file, i used the other very very useful tool provided on GNU/Linux machine (strace,ltrace). I strongly recommend to do at least "man strace" and "man ltrace" on your command prompt to know the basics of these stuff.These tools are useful for understanding the flow of program.They are also very special in the sense that even you don't have the source code of a program, you can get good amount of information from these tools.It might take some time before you start to interpret/understand the output of utilities like strace, ltrace.


I did the "strace gdb " from the command line and output was something like :


mantosh@ubuntu:~$ strace gdb
execve("/usr/bin/gdb", ["gdb"], [/* 39 vars */]) = 0
brk(0) = 0x87d3000
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7f63000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=96330, ...}) = 0
mmap2(NULL, 96330, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7f4b000
close(3) = 0
access("/etc/ld.so.nohwcap",F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libreadline.so.5", O_RDONLY) = 3
......
......
......
......
......
......
......
......
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
stat64("/home/mantosh/.gdbinit",0xbf9fee54)= -1 ENOENT (No such file or directory)

stat64("/home/mantosh/.gdbinit",0xbf9fefe4) = -1 ENOENT (No such file or directory)

stat64(".gdbinit",0xbf9fefe4) = -1 ENOENT (No such file or directory)
open("/home/mantosh/Desktop/LinuxPI/.gdb_history", O_RDONLY) = -1 ENOENT (No such file or directory)
rt_sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
rt_sigprocmask(SIG_BLOCK, [INT], [], 8) = 0


===>
The output of "strace gdb " would be like above. Best way the get information
about the .gdbinit file is to just search name from the the output of strace.
The following line from the strace output is the important for our current discussion.
stat64("/home/mantosh/.gdbinit",0xbf9fee54)=-1 ENOENT (No such file or directory)

The when system calls stat64() system call for the file $HOME/.gdbinit, it gets -1
as return value which says no such file or directory exists.



So i created .gdbinit file into my $HOME directory. I have put some of my favorite
commands into this file so that i don't need to type those every time i am inside
gdb session. My .gdbinit looks something like

mantosh@ubuntu:~$ cat .gdbinit
set height -1
set print pretty on
set print array on
set print array-indexes on
set print repeats 0
set print symbol-filename on
set print elements 0
set listsize 15
set print vtbl on
set print object on



If any of you want to know what these command is all about, please check the
official GNU manual. You can add more commands into the file .gdbinit. Its depend on the user what he/she want to put.

Once i done with the .gdbinit file , i once again did "strace gdb" to confirm that whether gdb is able to read the file .gdbinit of not.This time the strace
output was something like this:


mantosh@ubuntu:~$ strace gdb
execve("/usr/bin/gdb", ["gdb"], [/* 39 vars */]) = 0
brk(0) = 0x9596000
access("/etc/ld.so.nohwcap", F_OK)= -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7fbd000
access("/etc/ld.so.preload", R_OK) = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=96330, ...}) = 0
mmap2(NULL, 96330, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7fa5000
close(3) = 0
access("/etc/ld.so.nohwcap", F_OK) = -1 ENOENT (No such file or directory)
open("/lib/libreadline.so.5", O_RDONLY) = 3
......
......
......
......
......
......
......
......
......
......

sigprocmask(SIG_BLOCK, NULL, [], 8) = 0
stat64("home/mantosh/.gdbinit",{st_mode=S_IFREG|0644,st_size=204, ...})= 0
open("/home/mantosh/.gdbinit", O_RDONLY) = 5
lstat64("/home", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/mantosh", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
fcntl64(5, F_GETFL) = 0 (flags O_RDONLY)


===>
As we can see that now strace64() call return 0 which confirm that there is .gdbinit file in the $HOME directory. In the next line we can see now gdb is able to open the file in the O_RDONLY mode. The return value of open() call is 5 better know as the file descriptor.



Hope that this article might be of some use for the reader. Feel free to put yours comment, so that from next time i could try to incorporate those suggestions.Thanks for reading this article......Happy Hacking!!!!!!!!!!!!!!

No comments:

Post a Comment