How do we get buffer value using gdb - c

I would like to understand how the stack works.
I am using gdb to disassemble my code.
I disassemble the following code :
int main(){
char*buf;
buf="TEST";
return 0;
}
After compiling, I run gdb and disassemble the code.
I got this result:
0x080483db <+0>: push %ebp
0x080483dc <+1>: mov %esp,%ebp
0x080483de <+3>: sub $0x10,%esp
0x080483e1 <+6>: movl $0x8048470,-0x4(%ebp)
0x080483e8 <+13>: mov $0x0,%eax
0x080483ed <+18>: leave
0x080483ee <+19>: ret
I set a breakpoint at the instruction 0x080483e8, then I run.
When I print the value at the adress 0x8048470, I got TEST\n but I don't get same result when I execute the command x\s $ebp-0x4.
As the content of 0x8048470 has been moved to -0x4(%ebp), shouldn't I get the same value at both adresses?

Related

Strange behavior in AMD64 Instruction pointer

I was reading Hacking: The Art of Exploitation by Jon Erickson, and followed the example in the book in my Kali Linux system (64 bit).
I wrote a simple C program:
#include<stdio.h>
int main()
{
int i;
for(i=0;i<10;i++)
{
printf("Hello");
}
}
After using objdump and gdb to examine the executable, I found something strange.
As the picture shows, the main function was in the "0x000000000000063a".
But the breakpoint info after the gdb "run" command, it seems that the program stopped at 63e rather than 63a.
Another peculiar thing is that the value in the instruction pointer (rip) was 0x55555555463e.
Shouldn't it be 0x000000000000063a?
Where do those 5s come from?
GDB sets breakpoints on useful code for a function if you don't set an asterisk. It omits all preparation for a function(prologue). To make it clear try to debug the following code:
#include <stdio.h>
int main()
{
int i=10;
i++;
return 0;
}
Gdb session:
(gdb) b main
Breakpoint 1 at 0x80483e1
(gdb) b *main
Breakpoint 2 at 0x80483db
(gdb) r
Starting program: /home/src/main
Breakpoint 2, 0x080483db in main ()
(gdb) disas
Dump of assembler code for function main:
=> 0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
0x080483e1 <+6>: mov DWORD PTR [ebp-0x4],0xa
0x080483e8 <+13>: add DWORD PTR [ebp-0x4],0x1
0x080483ec <+17>: mov eax,0x0
0x080483f1 <+22>: leave
0x080483f2 <+23>: ret
End of assembler dump.
(gdb) c
Continuing.
Breakpoint 1, 0x080483e1 in main ()
(gdb) disas
Dump of assembler code for function main:
0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
=> 0x080483e1 <+6>: mov DWORD PTR [ebp-0x4],0xa
0x080483e8 <+13>: add DWORD PTR [ebp-0x4],0x1
0x080483ec <+17>: mov eax,0x0
0x080483f1 <+22>: leave
0x080483f2 <+23>: ret
End of assembler dump.
in this case, preparation to execute useful code of the function is :
0x080483db <+0>: push ebp
0x080483dc <+1>: mov ebp,esp
0x080483de <+3>: sub esp,0x10
first instruction in main:
int i=10;
compiled into:
mov DWORD PTR [ebp-0x4],0xa
GDB set a breakpoint on the instruction, when we give the command b main
But if we use the command with an asterisk(pointer) b *main we set a breakpoint on the actual address of the function(on first instruction of prologue).
In OP case, if we set breakpoint by break *main and then run, the instruction pointer register(rip) will have the value 0x55555555463a

Cannot access memory - gdb

Here is my disas code:
Dump of assembler code for function main:
0x00000000000006b0 <+0>: push %rbp
0x00000000000006b1 <+1>: mov %rsp,%rbp
0x00000000000006b4 <+4>: sub $0x10,%rsp
0x00000000000006b8 <+8>: movl $0xa,-0xc(%rbp)
0x00000000000006bf <+15>: lea -0xc(%rbp),%rax
0x00000000000006c3 <+19>: mov %rax,-0x8(%rbp)
0x00000000000006c7 <+23>: lea 0x96(%rip),%rdi # 0x764
0x00000000000006ce <+30>: mov $0x0,%eax
0x00000000000006d3 <+35>: callq 0x560 <printf#plt>
0x00000000000006d8 <+40>: mov $0x0,%eax
0x00000000000006dd <+45>: leaveq
0x00000000000006de <+46>: retq
when I set the breakpoint at 0x06b4 by b *0x00000000000006b4 and run the code it is giving an error
Starting program: /root/print.out
Warning:
Cannot insert breakpoint 4.
Cannot access memory at address 0x6b4
but when I do it with b 4 and run the code ,it is working normal. so what am I doing wrong in the first case.
Dump of assembler code for function main:
0x00000000000006b0 <+0>: push %rbp
0x00000000000006b1 <+1>: mov %rsp,%rbp
You are looking at position-independent executable (a special kind of shared library). The code for main gets relocated to a different address when the executable starts running.
Because there is no code at 0x6b4 once the executable is relocated, GDB complains that it can't set a breakpoint there.
but when I do it with b 4 and run the code ,it is working normal.
In this case, GDB understands that you want to set breakpoint on line 4, and inserts appropriate breakpoint after the executable has been relocated.
Use info break to see what the relocated address is.

Can not find return address in gdb

I wrote that program in C (just for debugging purposes):
void return_input(void)
{
char array[10];
gets(array);
printf("%s\n", array);
}
main()
{
return_input();
return 0;
}
I have been experimenting with stack overflows, and since I am working with a 64 bit machine I compiled it with
gcc -m32 -mpreferred-stack-boundary=2 -ggdb overflow.c -o overflow
I then debugged the program with gdb, and disassembled the return_input function, I got:
0x0804841b <+0>: push %ebp
0x0804841c <+1>: mov %esp,%ebp
0x0804841e <+3>: sub $0xc,%esp
0x08048421 <+6>: lea -0xa(%ebp),%eax
0x08048424 <+9>: push %eax
0x08048425 <+10>: call 0x80482e0 <gets#plt>
0x0804842a <+15>: add $0x4,%esp
0x0804842d <+18>: lea -0xa(%ebp),%eax
0x08048430 <+21>: push %eax
0x08048431 <+22>: call 0x80482f0 <puts#plt>
0x08048436 <+27>: add $0x4,%esp
0x08048439 <+30>: nop
0x0804843a <+31>: leave
0x0804843b <+32>: ret
This marks that the return address should be 0x0804843b (or is it not?) However, when examining the esp (remember this is a 32bit compiled program on a 64bit machine) with x/20x $esp (after setting a breakpoint at the gets function and the ret), I can't find the return address:
0xffffd400: 0xffffd406 0x080481ec 0x08048459 0x00000000
0xffffd410: 0xffffd418 0x08048444 0x00000000 0xf7e195f7
0xffffd420: 0x00000001 0xffffd4b4 0xffffd4bc 0x00000000
0xffffd430: 0x00000000 0x00000000 0xf7fb0000 0xf7ffdc04
0xffffd440: 0xf7ffd000 0x00000000 0xf7fb0000 0xf7fb0000
Why can't I see the return address? Sorry for the long question. Thanks in advance
0x0804843b is 'ret'. It seems you confused that with 'return address'. The return address is the address of the next instruction to execute in the calling function. In particular for this code:
0x08048425 <+10>: call 0x80482e0 <gets#plt>
0x0804842a <+15>: add $0x4,%esp
The return address is 0x0804842a.
Now, it is unclear what exactly did you do. Compiling as you specified, doing 'break gets' + 'run' works just fine for me. Are you sure you are dumping regs from "within" gets?
(gdb) disassemble return_input
Dump of assembler code for function return_input:
0x0804843b <+0>: push %ebp
0x0804843c <+1>: mov %esp,%ebp
0x0804843e <+3>: sub $0xc,%esp
0x08048441 <+6>: lea -0xa(%ebp),%eax
0x08048444 <+9>: push %eax
0x08048445 <+10>: call 0x8048300 <gets#plt>
0x0804844a <+15>: add $0x4,%esp
That's the instruction gets should return to.
0x0804844d <+18>: lea -0xa(%ebp),%eax
0x08048450 <+21>: push %eax
0x08048451 <+22>: call 0x8048310 <puts#plt>
0x08048456 <+27>: add $0x4,%esp
0x08048459 <+30>: nop
0x0804845a <+31>: leave
0x0804845b <+32>: ret
End of assembler dump.
(gdb) break gets
Breakpoint 1 at 0x8048300
(gdb) run
[..]
Breakpoint 1, 0xf7e3a005 in gets () from /lib/libc.so.6
(gdb) x/20x $esp
0xffffd160: 0x00000001 0xf7fa3000 0xffffd180 0x0804844a
And here it is on the 4th spot.
0xffffd170: 0xffffd176 0x0804820c 0x08048479 0x00000000
0xffffd180: 0xffffd188 0x08048464 0x00000000 0xf7df15a6
0xffffd190: 0x00000001 0xffffd224 0xffffd22c 0x00000000
0xffffd1a0: 0x00000000 0x00000000 0xf7fa3000 0xf7ffdbe4
(gdb)

Stack address not corresponding (Trying to understand Buffer overflow)

I have been following this tutorial at http://insecure.org/stf/smashstack.html but at example3.c my function return address doesn't correspond to the logic he implies. I can understand how the return address can be changed at a function but doing it on my computer just doesn't do the trick. I have used -fno-stack-protector and gdb with info registers and disassemble main and also disassemble the function but to no avail. I'm kinda new to Assembly.
My computer is running xubuntu 14 32bits.
My gcc instruction is: gcc -Wall -ansi -g -fno-stack-protector example3.c
example3.c:
------------------------------------------------------------------------------
void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
int *ret;
ret = buffer1 + 12;
(*ret) += 8;
}
void main() {
int x;
x = 0;
function(1,2,3);
x = 1;
printf("%d\n",x);
}
------------------------------------------------------------------------------
gdb disassemble on main with a breakpoint on function call
(gdb) disassemble main
Dump of assembler code for function main:
0x0804843b <+0>: push %ebp
0x0804843c <+1>: mov %esp,%ebp
0x0804843e <+3>: and $0xfffffff0,%esp
0x08048441 <+6>: sub $0x20,%esp
0x08048444 <+9>: movl $0x0,0x1c(%esp)
=> 0x0804844c <+17>: movl $0x3,0x8(%esp)
0x08048454 <+25>: movl $0x2,0x4(%esp)
0x0804845c <+33>: movl $0x1,(%esp)
0x08048463 <+40>: call 0x804841d <function>
0x08048468 <+45>: movl $0x1,0x1c(%esp)
0x08048470 <+53>: mov 0x1c(%esp),%eax
0x08048474 <+57>: mov %eax,0x4(%esp)
0x08048478 <+61>: movl $0x8048520,(%esp)
0x0804847f <+68>: call 0x80482f0 <printf#plt>
0x08048484 <+73>: leave
0x08048485 <+74>: ret
End of assembler dump.
(gdb) disassemble function
Dump of assembler code for function function:
0x0804841d <+0>: push %ebp
0x0804841e <+1>: mov %esp,%ebp
0x08048420 <+3>: sub $0x20,%esp
=> 0x08048423 <+6>: lea -0x9(%ebp),%eax
0x08048426 <+9>: add $0xc,%eax
0x08048429 <+12>: mov %eax,-0x4(%ebp)
0x0804842c <+15>: mov -0x4(%ebp),%eax
0x0804842f <+18>: mov (%eax),%eax
0x08048431 <+20>: lea 0x8(%eax),%edx
0x08048434 <+23>: mov -0x4(%ebp),%eax
0x08048437 <+26>: mov %edx,(%eax)
0x08048439 <+28>: leave
0x0804843a <+29>: ret
End of assembler dump.
At line 9 of function, *ret points to a completely different address
9 (*ret) += 8;
(gdb) p/x *ret
$1 = 0x48468c7 (already with the + 8)
So to clarify, this program is supose to print 0 since the return was changed to jump over the x = 1 instruction.
My question is, why isn't *ret pointing to an address that is somewhat close to main's corresponding addresses?
I'm sorry for my English.
Best regards,
Vcoder
Your tutorial is about some very old compiler.
Lets handle experiment (say gcc 4.8.1, 64-bit Win32) with identical results:
Step 1. Identify where function really starts:
(gdb) disassemble function
Dump of assembler code for function function:
=> 0x00000000004014f0 <+0>: push %rbp
Step 2. Store somewhere its address and break here
(gdb) b *0x00000000004014f0
Breakpoint 1 at 0x4014f0: file test3.c, line 1.
(gdb) r
Breakpoint 1, function (a=1, b=4200201, c=4) at test3.c:1
1 void function(int a, int b, int c) {
Step 3. Okay, here we are. Lets explore where do our return address stored:
(gdb) p $rsp
$1 = (void *) 0x22fe18
(gdb) x 0x22fe18
0x22fe18: 0x0040154c
Wow. Lets check inside main:
0x0000000000401547 <+36>: callq 0x4014f0 <function>
0x000000000040154c <+41>: movl $0x1,-0x4(%rbp)
Step 4. Looks like we found it. Store somewhere value of $rsp=0x22fe18 and now lets see what is buffer starts:
7 (*ret) += 8;
(gdb) p &buffer1[0]
$2 = 0x22fe00 "`\035L"
So buffer[0] address is 0x22fe18 - 0x22fe00 = 0x18 from our target. Not 0xc, as in your example, uh-oh.
P.S. On your compiler and OS, and your optimization options it might be not 0x18, but other value. Try. Experiment. Being hacker is about experimenting, not about running someones scripts.
Good luck.

Experimental buffer overflow in Ubuntu 10 (assembly)

I am trying to overflow buffer in Ubuntu 10.04 using a C program and diverting the return address to function "junk". But I am not able to overwrite the return address with the address of unused function "junk". It just dumps some unknown address on 12 bytes of stack. Please help me troubleshoot it. Here is the C code:-
(gdb) list
1 #include<stdio.h>
2 void display()
3 {
4 char buff[8];
5 gets(buff);
6 puts(buff);
7 }
8 main()
9 {
10 display();
(gdb)
11 return(0);
12 }
13 junk()
14 {
15 printf("cracked");
16 }
The disasambled code for main is:-
Dump of assembler code for function main:
0x08048462 <+0>: push %ebp
0x08048463 <+1>: mov %esp,%ebp
0x08048465 <+3>: call 0x8048444 <display>
0x0804846a <+8>: mov $0x0,%eax
0x0804846f <+13>: pop %ebp
0x08048470 <+14>: ret
End of assembler dump.
Dump of assembler code for function display:
0x08048444 <+0>: push %ebp
0x08048445 <+1>: mov %esp,%ebp
0x08048447 <+3>: sub $0xc,%esp
0x0804844a <+6>: lea -0x8(%ebp),%eax
0x0804844d <+9>: mov %eax,(%esp)
0x08048450 <+12>: call 0x8048350 <gets#plt>
0x08048455 <+17>: lea -0x8(%ebp),%eax
0x08048458 <+20>: mov %eax,(%esp)
0x0804845b <+23>: call 0x8048380 <puts#plt>
0x08048460 <+28>: leave
0x08048461 <+29>: ret
End of assembler dump.
Dump of assembler code for function junk:
0x08048471 <+0>: push %ebp
0x08048472 <+1>: mov %esp,%ebp
0x08048474 <+3>: sub $0x4,%esp
0x08048477 <+6>: mov $0x8048550,%eax
0x0804847c <+11>: mov %eax,(%esp)
0x0804847f <+14>: call 0x8048370 <printf#plt>
0x08048484 <+19>: leave
0x08048485 <+20>: ret
End of assembler dump.
Now i assemble it without stack protection:-
gcc -ggdb -fno-stack-protector -mpreferred-stack-boundary=2 -o buffer buffer.c
If i give input of:- printf "wwwwwwwwwwww\x72\x84\x04\x08" | ./buffer
The value:- "x72\x84\x04\x08" as the diverted address of 1st instruction of unused function "junk".
It stores some strange memory values on the 12 bytes alongwith return address also, but not my address. And again gives "Segmentation Fault". Is there some other way to exploit buffer in newer Linux flavors?
leave is equivalent to the following:
movl %ebp, %esp
popl %ebp
Thus, in your case, if you supply 'wwww' for %ebp, the program is going to try and do something like this:
movl $0x77777777, %esp ; 0x77777777 = 'wwww'
popl %ebp ; read from address 0x77777777!
You need to supply a reasonable value for %esp!

Resources