GDB doesn't let me read argv memory segment - c

I have this simple script written in C:
#include <stdio.h>
void usage(char *program_name) {
printf("Usage: %s <message> <# of times to repeat>\n", program_name);
exit(1);
}
int main(int argc, char *argv[]) {
int i, count;
// if(argc < 3) // If less than 3 arguments are used,
// usage(argv[0]); // display usage message and exit.
count = atoi(argv[2]); // convert the 2nd arg into an integer
printf("Repeating %d times..\n", count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, argv[1]); // print the 1st arg
}
And I'm making some test with GDB.
I did this:
(gdb) run test
Starting program: /home/user/Desktop/booksrc/convert2 test
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
Obviusly it goes in segmentation fault because to work the program needs three argv. And I commented the lines that do the control. So it goes in error.
(gdb) where
#0 0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
#1 0x00007ffff7a53a80 in atoi () from /usr/lib/libc.so.6
#2 0x00005555555546ea in main (argc=2, argv=0x7fffffffe958) at convert2.c:14
(gdb) break main
Breakpoint 1 at 0x5555555546d2: file convert2.c, line 14.
(gdb) run test
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/user/Desktop/booksrc/convert2 test
Breakpoint 1, main (argc=2, argv=0x7fffffffe958) at convert2.c:14
14 count = atoi(argv[2]); // convert the 2nd arg into an integer
(gdb) cont
Continuing.
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff7a56e56 in ____strtoll_l_internal () from /usr/lib/libc.so.6
(gdb) x/3xw 0x7fffffffe958 // this is memory of the "argv" some line before
0x7fffffffe958: 0xffffebfe 0x00007fff 0xffffec22
(gdb) x/s 0xffffebfe
0xffffebfe: <error: Cannot access memory at address 0xffffebfe>
(gdb) x/s 0x00007fff
0x7fff: <error: Cannot access memory at address 0x7fff>
(gdb) x/s 0xffffec22
0xffffec22: <error: Cannot access memory at address 0xffffec22>
In theory, with "x/s" I should have seen the commandline in the first address and "test" in the second address and the null in the third. But nothing. If I copy paste that address to a ascii to string converter, it gives me data without any sense. What am I doing wrong?

Your platform uses 64bit pointers, so try :
(gdb) x/3xg 0x7fffffffe958
to display the 64bit pointers in the argv array, and then :
(gdb) x/s 0x00007fffffffebfe
or just :
(gdb) p argv[0]

First of all always check if the command line is correct
Uncomment the check from your code.
Then in the gdb set the arguments (before running it)
(gdb) set args "hello world" 12

Related

Cant access a specific memory address. on C program

I am working on the book "HACKING Art Of Exploitation " exercise Convert2.c page 61.
Here's my code. Below is my question.
#include <stdio.h>
void usage(char *program_name) {
printf("Usage: %s <message> <# of times to repeat>\n", program_name);
exit(1);
}
int main(int argc, char *argv[]) {
int i, count;
// if(argc < 3) //if fewer than 3 arguments is used
// usage(argv[0]); // display usage message and exit
count = atoi(argv[2]); //convert the second arg into an interger
printf("Repeating %d times\n", count);
for(i=0; i < count; i++)
printf("%3d - %s\n", i, argv[1]); // print the first arg
}
GDB OUTPUT...
➜ git:(master) ✗ 👽 gdb -q a.out
Reading symbols from a.out...done.
(gdb) run test
Starting program: /home/fruitdealer/clones/C_zombie/hacking/a.out test
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr#entry=0x0, base=base#entry=10, group=group#entry=0,
loc=0x7ffff7dd0560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: No such file or directory.
(gdb) break main
Breakpoint 1 at 0x555555554707: file convert.c, line 14.
(gdb) where
#0 __GI_____strtol_l_internal (nptr=0x0, endptr=endptr#entry=0x0, base=base#entry=10, group=group#entry=0,
loc=0x7ffff7dd0560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
#1 0x00007ffff7a29122 in __strtol (nptr=<optimized out>, endptr=endptr#entry=0x0, base=base#entry=10)
at ../stdlib/strtol.c:106
#2 0x00007ffff7a24690 in atoi (nptr=<optimized out>) at atoi.c:27
#3 0x000055555555471f in main (argc=2, argv=0x7fffffffdeb8) at convert.c:14
(gdb) run test
The program being debugged has been started already.
Start it from the beginning? (y or n) y
Starting program: /home/fruitdealer/clones/C_zombie/hacking/a.out test
Breakpoint 1, main (argc=2, argv=0x7fffffffdeb8) at convert.c:14
14 count = atoi(argv[2]); //convert the second arg into an interger
(gdb) cont
Continuing.
Program received signal SIGSEGV, Segmentation fault.
__GI_____strtol_l_internal (nptr=0x0, endptr=endptr#entry=0x0, base=base#entry=10, group=group#entry=0,
loc=0x7ffff7dd0560 <_nl_global_locale>) at ../stdlib/strtol_l.c:292
292 ../stdlib/strtol_l.c: No such file or directory.
(gdb) x/3xw 0x7fffffffdeb8
0x7fffffffdeb8: 0xffffe220 0x00007fff 0xffffe250
(gdb) x/s 0xffffe220
0xffffe220: <error: Cannot access memory at address 0xffffe220>
(gdb) x/s 0xffffe250
0xffffe250: <error: Cannot access memory at address 0xffffe250>
(gdb) x/sw 0xffffe250
0xffffe250: <error: Cannot access memory at address 0xffffe250>
(gdb)
I posted all of gdb output because i wasn't sure how much of it you would need. My problem lies at the bottom of my GDB output when i run "x/s" on gdb and get the <error: Cannot access memory at address 0xffffe250> error.
On the book Jon Erickson is able to access 0xffffe220 and 0x00007fff and then he has an error on 0xffffe250 this part of memory.
What am i missing?
Why can't i access any of the three addresses in 0x7fffffffdeb8?
The first half of the address is cut off. If you notice, it takes 8 bytes to store the addresses because you are on a 64 bit machine, not 32. You are trying to access a truncated address.
Rather than three addresses at 0x7fffffffdeb8, you are looking at one and a half. Try accessing a byte that starts with 0x00007fff...

Segmentation Fault randomly at pclose while retrieving the PID

I am running a simple C Application which will get PID Of an process continuously.
This is running on an custom ARM Board.
pid_t GetStreamerPID()
{
pid_t pid = 0;
int ret = 0;
char line[100];
char command[50] = "pidof -s gst-launch-0.10";
memset(line, '\0', 100);
FILE *cmd = popen(command, "r");
if ( cmd == NULL )
{
perror("Popen\n");
exit(0);
}
ret = fread(line, sizeof(char), 20, cmd);
pclose(cmd);
pid = atoi(line);
return pid;
}
Randomly, the code is throwing segmentation Fault at pclose.. I am debugging this from past week and I am unable to find out the cause of the issue.
Attaching gdb backtrace:
Program received signal SIGSEGV, Segmentation fault.
0x76e3a588 in free () from /lib/libc.so.6
(gdb) bt full
#0 0x76e3a588 in free () from /lib/libc.so.6
No symbol table info available.
#1 0x76e25c20 in fclose##GLIBC_2.4 () from /lib/libc.so.6
No symbol table info available.
#2 0x000109b4 in GetStreamerPID () at getPid.c:111
pid = 0
ret = 0
line = '\000' <repeats 99 times>
command = "pidof -s gst-launch-0.10", '\000' <repeats 25 times>
cmd = 0x136c008
#3 0x00010a50 in startStreamer () at getPid.c:147
command = '\000' <repeats 255 times>
pid = 0
#4 0x0001087c in CheckVideoState () at getPid.c:81
iVideoOn = 1
#5 0x00010a20 in MainLoop () at getPid.c:137
No locals.
#6 0x00010b74 in main () at getPid.c:183
No locals.
Also, one more wierd observation is , after I close gdb and run "reboot" command it throws segmentation fault. Again this is random, it can be any command..
I can provide you as much as information you want. Please help me in debugging this wierd issue...
Your crash is happening inside free.
Any such crash is a 99.99% sign that you have heap corruption elsewhere, and very likely has absolutely nothing to do with the code you've shown, or with pclose.
Tools such as Valgrind, Address Sanitizer, or GLIBC mcheck are your best bet.

GCC based SIGSEGV error?

So I have been writing a handful of C libraries for my own personal use and I have been doing swell until my latest library, which just contains a bunch of string functions. As you can probably tell by the question title, I am getting a SIGSEGV signal. The problem is this: my research indicates that about 99% of all SIGSEGV errors are due to stack overflow, itself due to bad recursion, but as you will see, I am not using any recursion. Furthermore, there are a few odd problems that occur. For one, printf is exhibiting a lot of funky behavior. GDB encounters printf calls but does not actually seem to execute them until a few lines of code later. Likewise, one of my printf statements is being broken up somehow, and only a part is being called, with another part being chopped off apparently.
Here are the key code snippets, some stuff is named funny because I suspected name clashing may be the cause at one point and may have gone a little overboard...
"firstIndexOf" function (finds the first index of a character in a string, if that character is in said string), found at line 31:
int firstIndexOfFUNCTION(char thisChar, char* inThisString)
{
int lengthABC = strlen(inThisString);
printf("\nLength of %s is %d",inThisString,lengthABC);
int thisFunctionsIndex;
for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++)
{
printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar);
if (inThisString[thisFunctionsIndex] == thisChar)
{
printf("\nMatch found on iteration %d!",thisFunctionsIndex);
return thisFunctionsIndex;
}
}
printf("\nNo matches detected...");
return -3;
}
The "string_functions_test" function (a function just meant to test the other functions) at line 62:
int string_functions_test()
{
printf("PROGRAM INITIALIZED!\n\n");
char* sft_string;
int sft_index;
sft_string = malloc(sizeof(char)*100);
sft_string = "B um sbm. Sbm B bm.";
printf("2nd BREAKPOINT");
sft_index = firstIndexOfFUNCTION('B',sft_string);
sft_string[sft_index] = 'I';
return 0;
}
and last but not least, good ol' main, at line 107:
int main(int argc, char* argv[])
{
string_functions_test();
return 0;
}
Here is the gdb output for a step-through of my code:
(gdb) b 105
Breakpoint 1 at 0x400970: file string_functions.c, line 105.
(gdb) run
Starting program: /home/user/Development/projects/c/string_functions/source/c/a.out
Breakpoint 1, main (argc=1, argv=0x7fffffffde98) at string_functions.c:109
109 string_functions_test();
(gdb) step
string_functions_test () at string_functions.c:64
64 printf("PROGRAM INITIALIZED!\n\n");
(gdb) next
PROGRAM INITIALIZED!
68 sft_string = malloc(sizeof(char)*100);
(gdb) next
69 sft_string = "B um sbm. Sbm B bm.";
(gdb) next
71 printf("2nd BREAKPOINT");
(gdb) next
73 sft_index = firstIndexOfFUNCTION('B',sft_string);
(gdb) step
firstIndexOfFUNCTION (thisChar=66 'B', inThisString=0x400ab9 "B um sbm. Sbm B bm.") at string_functions.c:33
33 int lengthABC = strlen(inThisString);
(gdb) next
34 printf("\nLength of %s is %d",inThisString,lengthABC);
(gdb) next
2nd BREAKPOINT
36 for (thisFunctionsIndex=0;thisFunctionsIndex<lengthABC;thisFunctionsIndex++)
(gdb) next
38 printf("\n%dth iteration:\n-char 1 is %c\n-char2 is %c",thisFunctionsIndex,inThisString[thisFunctionsIndex],thisChar);
(gdb) next
Length of B um sbm. Sbm B bm. is 19
0th iteration:
-char 1 is B
39 if (inThisString[thisFunctionsIndex] == thisChar)
(gdb) next
41 printf("\nMatch found on iteration %d!",thisFunctionsIndex);
(gdb) next
-char2 is B
42 return thisFunctionsIndex;
(gdb) next
47 }
(gdb) next
string_functions_test () at string_functions.c:75
75 sft_string[sft_index] = 'I';
(gdb) next
Program received signal SIGSEGV, Segmentation fault.
0x0000000000400883 in string_functions_test () at string_functions.c:75
75 sft_string[sft_index] = 'I';
(gdb) next
Program terminated with signal SIGSEGV, Segmentation fault.
The program no longer exists.
(gdb) quit
You may notice that the printf which prints "2nd Breakpoint" is called, and then the program steps into a different function before the results are seen. I am assuming this is some whacky behavior on the part of the gcc compiler meant to serve as a cpu optimization, but it is sort of messing me up right now obviously. Likewise, the printf in my for loop is being broken up after the first formatted char. These two things are making it super hard to detect what exactly is happening. Has anyone experienced similar behavior?
In case it matters, I am including:
#include <string.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
You are first pointing the pointer sft_string to what is returned from malloc. In the next line you make it point to a literal string. You need to copy it. A literal is built into the source code and cannot be changed during execution. Otherwise it raises a segment fault, which means that an area of memory that has code is being changed. Use strcpy.

Stack-Based Buffer Overflow Vulnerabilities

I am reading a book titled Hacking: The Art of Exploitation, and I have a problem with the section Stack-Based Buffer Overflow Vulnerabilities.
I am following the instructions given by the author, but I don't get the expected results.
First, here is the program auth_overflow2.c, copied from the book:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int check_authentication(char *password) {
char password_buffer[16];
int auth_flag = 0;
strcpy(password_buffer, password);
if(strcmp(password_buffer, "brillig") == 0)
auth_flag = 1;
if(strcmp(password_buffer, "outgrabe") == 0)
auth_flag = 1;
return auth_flag;
}
int main(int argc, char *argv[]) {
if(argc < 2) {
printf("Usage: %s <password>\n", argv[0]);
exit(0);
}
if(check_authentication(argv[1])) {
printf("\n-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
printf(" Access Granted.\n");
printf("-=-=-=-=-=-=-=-=-=-=-=-=-=-\n");
} else {
printf("\nAccess Denied.\n");
}
}
This is a copy of my Ubuntu terminal:
(gdb) break 19
Breakpoint 1 at 0x40077b: file auth_overflow.c, line 19.
(gdb) break 7
Breakpoint 2 at 0x4006df: file auth_overflow.c, line 7.
(gdb) break 12
Breakpoint 3 at 0x40072a: file auth_overflow.c, line 12.
(gdb) run AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Starting program: /home/test/a.out AAAAAAAAAAAAAAAAAAAAAAAAAAAAAA
Breakpoint 1, main (argc=2, argv=0x7fffffffdf08) at auth_overflow.c:19
19 if(check_authentication(argv[1])) {
(gdb) i r esp
esp 0xffffde10 -8688
(gdb) x/32xw $esp
0xffffffffffffde10: Cannot access memory at address 0xffffffffffffde10
(gdb) c
Continuing.
Breakpoint 2, check_authentication (password=0x7fffffffe2cc 'A' <repeats 30 times>) at auth_overflow.c:7
7 strcpy(password_buffer, password);
(gdb) i r esp
esp 0xffffddc0 -8768
(gdb) x/32xw $esp
0xffffffffffffddc0: Cannot access memory at address 0xffffffffffffddc0
(gdb) p 0xffffde10 - 0xffffddc0
$1 = 80
(gdb) x/s password_buffer
0x7fffffffdde0: "\001"
(gdb) x/x &auth_flag
0x7fffffffdddc: 0x00
(gdb)
When i try x/32xw $esp i get:
0xffffffffffffde10: cannot access memory at address 0xffffffffffffde10
Same thing happens when i continue to the second break point.
When author types x/s password_buffer the output is:
0xbffff7c0: "?o??\200????????o???G??\020\205\004\b?????\204\004\b????\020\205\004\bH???????\002"
but my output looks like this:
0x7fffffffdde0: "\001"
My i r esp result is also different from the book.
in the book there are two hexadecimal numbers:
esp 0xbffff7e0 0xbffff7e0
I am using Ubuntu and GCC and GDB.
I think I might have the answer - your argv[ 1 ] is pointing to the 30 'A's - and you have a password buffer of 16. The strcpy() will just fill the buffer and beyond.
I would increase the buffer size to a larger size (say 255 bytes).
In practise, you should review your code, even examples, and make them more robust (example: allowing for larger passwords then 16 )
Please less the number of As try A(17) times it will work

Weird execution path caused by stack buffer overflow

I read some articles about Stack Buffer Overflow, like this one, and learned how attackers can exploit a Stack Buffer-Overflow bug by overwriting function pointers. Then I wrote a small program to demonstrate an attack:
#include <stdio.h>
#include <string.h>
void fun1 ( char * input ) {
char buffer[10];
strcpy( buffer, input );
printf( "In fun1, buffer= %s\n", buffer );
}
void fun2 ( void ) {
printf ( "HELLO fun2!\n" );
}
int main ( int argc, char * argv[] )
{
printf ( "Address of fun2: %p\n", fun2 );
fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
return 0;
}
The program was compiled with GCC 4.5.1, under Fedora 14 x86. Below is the output:
$ ./exp01
Address of fun2: 0x8048452
In fun1, buffer= abcdefghijklmnopqrstuvR�
HELLO fun2!
HELLO fun2!
We can see that fun2() was called successfully, but I don't know why it ran twice. Then I GDBed it (See Below). (I know only some basic instruction about GDB ╮( ̄▽ ̄)╭ )
I Googled some key words such as "__libc_csu_fini ()", but didn't find a clear way that can help me to understand the program's execution path. I know too little about compiler and the inner structure of a process, so I consider that I may have to find some books or articles that describe these stuff in detail. Any suggestion? Thank you!
GDB Record:
(gdb) list
7 printf( "In fun1, buffer= %s\n", buffer );
8 }
9
10 void fun2 ( void ) {
11 printf ( "HELLO fun2!\n" );
12 }
13
14 int main ( int argc, char * argv[] )
15 {
16 printf ( "Address of fun2: %p\n", fun2 );
(gdb)
17 fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
18 return 0;
19 }
(gdb) break 16
Breakpoint 1 at 0x804846f: file hello.c, line 16.
(gdb) run
Starting program: /home/yuliang/test/hello
Breakpoint 1, main (argc=1, argv=0xbffff394) at hello.c:16
16 printf ( "Address of fun2: %p\n", fun2 );
Missing separate debuginfos, use: debuginfo-install glibc-2.13-2.i686
(gdb) step
Address of fun2: 0x8048452
17 fun1( "abcdefghijklmnopqrstuv\x52\x84\x04\x08" );
(gdb)
fun1 (input=0x804859a "abcdefghijklmnopqrstuvR\204\004\b") at hello.c:6
6 strcpy( buffer, input );
(gdb)
7 printf( "In fun1, buffer= %s\n", buffer );
(gdb)
In fun1, buffer= abcdefghijklmnopqrstuvR�
8 }
(gdb)
fun2 () at hello.c:10
10 void fun2 ( void ) {
(gdb)
11 printf ( "HELLO fun2!\n" );
(gdb)
HELLO fun2!
12 }
(gdb)
0x08048500 in __libc_csu_fini ()
(gdb)
Single stepping until exit from function __libc_csu_fini,
which has no line number information.
fun2 () at hello.c:10
10 void fun2 ( void ) {
(gdb)
11 printf ( "HELLO fun2!\n" );
(gdb)
HELLO fun2!
12 }
(gdb)
Cannot access memory at address 0x76757477
(gdb)
Single stepping until exit from function __libc_csu_init,
which has no line number information.
0x009aae36 in __libc_start_main () from /lib/libc.so.6
(gdb)
Single stepping until exit from function __libc_start_main,
which has no line number information.
Program exited with code 0241.
(gdb)
When running your program in gdb break shortly before the strcpy() and have a look at the stack-frame (that is where the save eip is stored). then run until shortly after the printf() and again have a look at the stored eip (command is info frame).
since you pass the address of function fun2() to fun1() it will overwrite the saved eip and as soon as return is called (implicit in your case) the next instruction will be executed (which is given by eip and in your case it is the address of fun2())
And don't forget to read Smashing the stack for fun and profit by aleph1

Resources