Tell GDB use 8 bytes as a pointer - c

I was using GDB on a 64-bit machine:
(gdb) show arch
The target architecture is set automatically (currently i386:x86-64)
(gdb) p sizeof(void*)
$1 = 8
I had a pointer stored on 0x600fe8:
(gdb) x /xg 0x600fe8
0x600fe8: 0x00007ffff7bd5680
I tried to examine what the pointer stored here was pointing to, so I used:
(gdb) x *0x600fe8
0xfffffffff7bd5680: Cannot access memory at address 0xfffffffff7bd5680
(gdb) x /g *0x600fe8
0xfffffffff7bd5680: Cannot access memory at address 0xfffffffff7bd5680
It seems that gdb took only 4 bytes as a pointer from 0x600fe8 and sign extended it.
How could I fix this? Thanks.
Research I've done:
Didn't find my scenario on:
GDB doc
Google

Try:
x *(void**)0x600fe8
As #zwol mentioned in the comment, gdb needs type information about the operand to decide its size. This type casting tells gdb that 0x600fe8 is a pointer to a pointer.

Related

Unexpected address output

I am trying to figure out how the addresses are assigned to variables located on the stack. I ran the little program below:
int main()
{
long a;
int b;
int c;
printf("&a = %p\n", &a);
printf("&b = %p\n", &b);
printf("&c = %p\n", &c);
}
The output I expected was (considering addresses are going down):
&a = 0x7fff6e1acb88
&b = 0x7fff6e1acb80
&c = 0x7fff6e1acb7c
But instead I got:
&a = 0x7fff6e1acb88
&b = 0x7fff6e1acb80
&c = 0x7fff6e1acb84
How come the c variable is located between the a and b variable? Are variables not put on the stack as they are declared?
I tried replacing the type of a from long to int and I got this:
&a = 0x7fff48466a74
&b = 0x7fff48466a78
&c = 0x7fff48466a7c
Here I don't understand why are the addresses going up, while they were going down previously?
I compiled the program using gcc version 4.7.2 (Ubuntu/Linaro 4.7.2-11precise2), if that's of any help.
Are variables not put on the stack as they are declared?
No.
why are the addresses going up, while they were going down previously?
They could going up, but they do not have to.
Compilers is free to rearrage the order of local variables that it sees is fit, or it could even delete or add some.
Variables are not necessarily put on the stack in the order in which they are declared. You can't predict where on the stack they will be -- they could be in any order. As glglgl pointed out in the comments, they don't even have to be on the stack and could simply be held in registers.
Even though the stack pointer is counting downwards on your given CPU, the program will be using stack frames. How a certain parameter is allocated inside the stack frame is implementation-defined.
Also note that some CPUs have up-counting stack pointers.
Also note that local variables are not necessarily allocated on the stack. More often, they are allocated in CPU registers. But when you take the address of a variable, you kind of force the compiler to allocate it on the stack, since registers have no addresses.
The direction of stack growth depends on the architecture. On x86, stack grows down (from higher address to lower). How the variables are put on the stack also depends on the OS's Application binary interface (ABI) and how the compiler follows the ABI convention. But, the compiler may not necessarily follow the ABI conventions all the time.
it depends on the compiler.
for example I test your code with "GNU GCC version 4.8.1" and the Compiler allocate all locale variables in order :
&a = 0x7fffe265d118
&b = 0x7fffe265d114
&c = 0x7fffe265d110
Agreeing with #Lundin that you cannot print the address of the registers these a most likely sitting in. The best thing you can do to see how these are stored would be to dump the object code and investigate what happens when you create more local variables then the amount of registers to hold them. That is when you'll see the stack activity (in the disassembly ).
$ gcc -c main.c -o main.o
$ objdump -D main.o > main.dump

Why the address of a string given as argument to a function changed after overflowing the ret address?

I want to exploit a vulnerability of a C piece of code for educational purposes by controlling the stack. A simple stack based buffer overflow, overwriting the return address with the address where a shellcode should be executed. The code is a simple function which takes as arguments a buffer and tries to strcpy() the buffer into a fixed size. The parameter given from main is the argv[1]. So I think that if I found the exact amount of memory that I have to overwrite then I could simply give as input a string composed by \x90 (NOP instructions) followed by the shellcode and in the end the address of this buffer. Since this is the first argument its address is $ebp+8 and you can find this by running gdb, set a breakpoint in the begining of the function and just type i args gives you the address of the string which is passed as an argument. So I found that if I overwrite n bytes and then give the values of the address then this will exactly overwrite the return address. So I have an input like this:
perl -e print(\x90 x n-sizeof(shellcode) . shellcode . address)'
It didn't work and I tried to understand why. With gdb I run the program. I put a breakpoint before the strcpy() function. At that point I have an argument which is a string pointer that points to my input and its address is the same with that given at the end of my string input, I stepped forward 1 instruction. I examined the stack. I have now the saved eip ($ebp + 4) with the value of the address given at the end of argv[1], which is the expected behavior (That implies that it doesn't overwrite other addresses above the ret address that is the value of the first argument). The weird thing is that now the content of $ebp+8 is not the "address" but something else? But the content of the saved eip is the address that points to my string that exploits the vuln. But it doesn't seem that the ret addr executes the content of that address.
How stack frames are organized is part of the ABI. The description of the ABI used by Linux on x86-64 is here. You'll find there everything that you need (and then some more probably). See section 3.2 for the stack frame organization.

GDB, examine pointer to pointer

Ok, so I'm trying to learn gdb. I know most of the basics but I have not been able to figure out how to examine a pointer to a pointer in a oneliner. It might be possible by defining a macro/command but I haven't been able to do so.
This question began when learning the cdecl calling convention where $esp contained a pointer to a string, passed as an argument to a function. In order to get this out I had to do the following:
gdb$ x $esp+0x08
0xbffff6a4: 0x980eb192
gdb$ x/s 0x980eb192
0x980eb192: "Hello world"
So, the question is. Can this be done in an easier way? Cutting and pasting just feels too slow.
Appreciate any hints/ideas!
(gdb) x/s *(char**)($esp+8) might do the trick.
You can reuse results of print in subsequent expressions:
(gdb) p *(void **)($esp + 4)
$4 = (void *) 0x80aec48
(gdb) x/s $4
0x80aec48: "alabala"

can not access memory when accessing pointer to a struct GDB error

I have run gdb, as my code show segfault. I understand that the code that give the error is
210 if (colour_s->colorlist.colorlist_id == 1)
(gdb) print colour_s
$1 = (car_colour_list_t_slot *) 0x21
(gdb) print colorlist
$2 = (car_colour_list_t *) 0x12d1a80
(gdb) print colour_s->colorlist
Cannot access memory at address 0x21
typedef struct {
int colorlist_id;
} car_colour_list_t;
typedef struct _car_colour_list_t_slot {
car_colour_list_t colorlist;
struct _car_colour_list_t_slot *next, *prev;
} car_colour_list_t_slot;
car_colour_list_t_slot *colour_s;
colour_s = (car_colour_list_t_slot *)malloc(sizeof(car_colour_list_t_slot));
car_colour_list_t *colorlist;
colorlist = (car_colour_list_t *)malloc(sizeof(car_colour_list_t));
I have already assigned those pointers memory, but when I tried to print colour_s->colorlist it fails (can not access memory at address 0x21)
Can anyone understand why this happens, although I have already assign memory to each poitner?
Thank you
The colour_s pointer is definitely invalid. There is no doubt about it. GDB is simply informing you of this fact. (Any pointer near 0x0 is invalid, and any pointer with a residue modulo 4 is invalid for your structure.) The malloc function will never return 0x21.
There are lots of ways your program can do this. They boil down to two basic types of errors in your program:
colour_s was not initialized.
colour_s was initialized, but it was accidentally overwritten by an error in a different part of your code.
there is an error in GDB or your compiler (not worth considering)
Run your program with Valgrind or set a watchpoint on colour_s. These will help you discover where the error is in your code.
As an alternative exercise, see if you can find the error just by reading your code, without running it. Read carefully. This kind of exercise will make you a better programmer.

Help interpreting gdb: segfault in function

I am trying to debug a segfault, and I have this output from gdb:
(gdb) n
Program received signal SIGSEGV, Segmentation fault.
0x08048af9 in parse_option_list (ptr=0x6f72505f <Address 0x6f72505f out of bounds>, box_name=0x696d6978 <Address 0x696d6978 out of bounds>, option_list=0x313a7974,
num_elements=0x33313532) at submit.c:125
125 memcpy(&(option_list[(*num_elements)].value), value, 24);
(gdb) p num_elements
$15 = (int *) 0x33313532
(gdb) p *num_elements
Cannot access memory at address 0x33313532
(gdb)
It looks to me like something in memcpy() is going haywire. But I can't figure out what exactly the problem is, since that line references so many variables.
Can somebody help figure out what the 0x8048af9 in parse_option_list... line is telling me?
My function signature is:
int parse_option_list(char *ptr, char *box_name,
struct option_list_values *option_list, int *num_elements)
And this might be useful:
struct option_list_values {
char value[24];
char name[24];
};
Also, the variables value and name are not segfaulting (but if you think they are, i can post the code which sets those values.) But right now, if I can understand this gdb output, I will be happy as a clam! Thank you!
You have all the signs of a classic buffer overflow. The values of all the stack parameters have been overwritten by ASCII text - here is the translation of those values (assuming you have a little-endian architecture, which looks right):
ptr = 0x6f72505f = "_Pro"
box_name = 0x696d6978 = "ximi"
option_list = 0x313a7974 = "ty:1"
num_elements = 0x33313532 = "2513"
Concatenating them together gives "_Proximity:12513" - if this substring looks familiar to you, you should be able to track down where that data is being copied around - somewhere you are copying it into an array stored on the stack, without proper bounds checking.
0x8048af9 is the instruction pointer - the address of the executable code in memory that your code was at when the SEGFAULT occurred.
Are you sure that option_list[(*num_elements)].value is a valid address? You might have a buffer overflow, and be overwriting something you shouldn't be.
If num_elements is the length of option_list, then option_list[(*num_elements)] refers to just after the end of the list.
ptr=0x6f72505f - Address 0x6f72505f out of bounds
This is the useful part in this case
The first input to parse_option_list is invalid. Possibly an uninitialized pointer.

Resources