I am trying to create a chain of pointer addresses, with the first pointing to address of the next, and so on.
For example, char *a 's address is 0x1, char *b address is 0x2, char *x address is 0x3. I want to link a->b->c, so that my hope is to store value 0x2 into 0x1 memory address, value 0x3 into 0x2 memory address.
I have following codes:
#define PUT(p, val) (*(unsigned long *)(p) = (val))
#define SET_NEXT_PTR(p, ptr) (*(char**)(p) = (char*)((unsigned long)(ptr)))
void chain(char* bp){
char *first = mem_sbrk(size);
char *second =mem_sbrk(size);
PUT(first, (unsigned long)bp);
PUT(bp, *second);
}
When I run gdb, and exam those memory address. After call mem_sbrk for first and second.
(gdb) x /x first
0x7ffff661c020: 0x00000000
(gdb) x /x bp
0x7ffff661b020: 0x00000000
(gdb) x/x second
0x7ffff661d020: 0x00000000
After call PUT macro:
(gdb) x/x second
0x7ffff661d020: 0x00000000 0x00000000
(gdb) x /2x first
0x7ffff661c020: 0xf661b020 0x00007fff
(gdb) p first
0x7ffff661c020 " \260a\366\377\177"
(gdb) x /2x bp
0x7ffff661b020: 0xf661d020 0x00007fff
It seems working. But I wonder how can I convert those memory address to a pointer. Since entire memory address stores into 0x7ffff661d020 and 0x7ffff661d024. When I use p first, it returns a meaningless string.
Second question, in gdb when I call
(gdb) p &bp
(char **) 0x7fffffffe3e8
I wonder what is 0x7fffffffe3e8? I thought & is for getting memory address,I expect gdb shows
(void*) 0x7ffff661b020
Third question what is difference between
#define PUT(p, val) (*(unsigned long *)(p) = (val))
#define SET_NEXT_PTR(p, ptr) (*(char**)(p) = (char*)((unsigned long)(ptr)))
Related
I'm currently learning about C and trying to find out more about how memory in a stack works, and how gdb can be used to help.
Below is a code snippet of my problem:
bool thisEvaluatesToFalse(char* something) {
return false;
}
void main() {
char something[10];
puts("My plan is to input a specific string over 10 characters than will achieve my goal:");
gets(something);
if (thisEvaluatesToFalse(something)) {
puts("If this runs, its a success!");
}
}
The idea is, my success message will never run unless I exploit gets to input a something over 10 characters, causing an overflow that overwrites the return address of the function to where the success message is.
I understand I'm supposed to take a look at the assembly code with gdb and look out for an address, but I'm not exactly sure how to do this.
Could anyone guide me or show me an example? Thanks!
Try this, hope it helps you figure this out. Good luck!
Consider moving gets into thisEvaluatesToFalse to overwrite the return address pushed by main so the return from thisEvaluatesToFalse will return to the puts of success.
Like this:
#include <stdio.h>
unsigned int thisEvaluatesToFalse() {
char something[10];
gets(something);
return 0xdeadbeef;
}
int main() {
puts("My plan is to input a specific string over 10 characters than will achieve my goal:");
if (thisEvaluatesToFalse()) {
puts("If this runs, its a success!");
}
return 0;
}
Here are the highlights of working w/ gdb.
gcc main.c -fno-stack-protector -ggdb
gdb a.out
(gdb) disass main
0x0000000100003eeb <+27>: call 0x100003eb0 <thisEvaluatesToFalse>
0x0000000100003ef0 <+32>: cmp $0x0,%eax
0x0000000100003ef3 <+35>: je 0x100003f05 <main+53>
0x0000000100003ef9 <+41>: lea 0x94(%rip),%rdi # 0x100003f94
0x0000000100003f00 <+48>: call 0x100003f14
# ORIG RETURN ADDRESS IS 0x0000000100003ef0
# EXPLOIT RETURN ADDRESS FOR SUCCESS IS 0x0000000100003ef9
(gdb) break thisEvaluatesToFalse
(gdb) run
(gdb) x/16x $sp
0x7ff7bfeff930: 0x000c8060 0x00000001 0x00003ed0 0x00000001
0x7ff7bfeff940: 0xbfeff960 0x00007ff7 0x00003ef0 0x00000001
0x7ff7bfeff950: 0x00000013 0x00000000 0x000c8060 0x00000000
0x7ff7bfeff960: 0xbfeffa70 0x00007ff7 0x0001552e 0x00000001
# NOTICE THE VALUE AT 0x7ff7bfeff948 IS 0x00003ef0 (ORIG RETURN)
# NOTICE THE VALUE AT 0x7ff7bfeff94C IS 0x00000001 (ORIG RETURN)
(gdb) s
warning: this program uses gets(), which is unsafe.
1234567890AAAABBBBCCCCDDDD
(gdb) x/16x $sp
0x7ff7bfeff930: 0x000c8060 0x32310001 0x36353433 0x30393837
0x7ff7bfeff940: 0x41414141 0x42424242 0x43434343 0x44444444
0x7ff7bfeff950: 0x00000000 0x00000000 0x000c8060 0x00000000
0x7ff7bfeff960: 0xbfeffa70 0x00007ff7 0x0001552e 0x00000001
# NOTICE THE VALUE AT 0x7ff7bfeff948 IS 0x43434343 (LETTER C)
# NOTICE THE VALUE AT 0x7ff7bfeff94C IS 0x44444444 (LETTER D)
(gdb) set *0x7ff7bfeff948 = 0x00003ef9
(gdb) set *0x7ff7bfeff94C = 0x00000001
(gdb) x/16x $sp
0x7ff7bfeff930: 0x000c8060 0x32310001 0x36353433 0x30393837
0x7ff7bfeff940: 0x41414141 0x42424242 0x00003ef9 0x00000001
(gdb) s
main () at main.c:17
17 puts("If this runs, its a success!");
(gdb) s
If this runs, its a success!
19 return 0;
Leaving it up to you to figure out how to input values for gets that perform the actions that replace C and D with the values you need.
If you can choose a different approach, then instead of using gets for the overflow try using memcpy and copy more than 10 bytes. Same impact, the stack gets modified.
i need the address of a particular array, i obtained other array's addresses with success but in this one i got stuck.. here is the main code:
int main(int argc, char** argv) {
string[0] = 0;
char polpetta[]="secret-file";
char buf[50] ;
printf("me Can I read the secret file?! \n\n");
if (argc > 2) {
vuln(argv[1]);
strcpy(buf, argv[2]) ;
} else {
printf("You forgot to read me!!!\n");
}
return 0;
}
ok i put the breakpoint after the first printf:
(gdb) b* 0x080485f3
Breakpoint 1 at 0x80485f3
(gdb) r 12 12
Starting program: /home/andrew/Desktop/Software-Security-Lab/rop/rop-vuln
me Can I read the secret file?!
Breakpoint 1, 0x080485f3 in main ()
(gdb) p &buf
$1 = (char **) 0xb7fb9ef0 <buf>
(gdb) p &polpetta
No symbol "polpetta" in current context.
ok i obtained with success the address of buf... but not the address of polpetta! so i tried with different methods:
(gdb) p $polpetta
$2 = void
(gdb) p &$polpetta
Attempt to take address of value not located in memory.
(gdb) p polpetta
No symbol "polpetta" in current context.
(gdb) info locals
No symbol table info available.
(gdb) p *polpetta
No symbol "polpetta" in current context.
what the hell?? i also tried to repeat this routine at different breakpoints inside the main function...
thanks for your kindness!
Take this gdb output for example:
(gdb) info proc mappings
process 3975
cmdline = '/mnt/hw6/rop-exploit'
cwd = '/mnt/hw6'
exe = '/mnt/hw6/rop-exploit'
Mapped address spaces:
Start Addr End Addr Size Offset objfile
0x8048000 0x8049000 0x1000 0 /mnt/hw6/rop-exploit
0x8049000 0x804a000 0x1000 0 /mnt/hw6/rop-exploit
0x804a000 0x806b000 0x21000 0x804a000 [heap]
0xb7d51000 0xb7e84000 0x133000 0 /lib/libc-2.7.so
0xb7e84000 0xb7e85000 0x1000 0x133000 /lib/libc-2.7.so
0xb7e85000 0xb7e87000 0x2000 0x134000 /lib/libc-2.7.so
0xb7e87000 0xb7e8b000 0x4000 0xb7e87000
0xb7e8b000 0xb7fd4000 0x149000 0 /lib/tls/i686/cmov/libc-2.7.so
0xb7fd4000 0xb7fd5000 0x1000 0x149000 /lib/tls/i686/cmov/libc-2.7.so
0xb7fd5000 0xb7fd7000 0x2000 0x14a000 /lib/tls/i686/cmov/libc-2.7.so
0xb7fd7000 0xb7fda000 0x3000 0xb7fd7000
0xb7fda000 0xb7fdc000 0x2000 0 /lib/tls/i686/cmov/libdl-2.7.so
0xb7fdc000 0xb7fde000 0x2000 0x1000 /lib/tls/i686/cmov/libdl-2.7.so
0xb7fe1000 0xb7fe3000 0x2000 0xb7fe1000
0xb7fe3000 0xb7fe4000 0x1000 0xb7fe3000 [vdso]
0xb7fe4000 0xb7ffe000 0x1a000 0 /lib/ld-2.7.so
0xb7ffe000 0xb8000000 0x2000 0x19000 /lib/ld-2.7.so
0xbffeb000 0xc0000000 0x15000 0xbffeb000 [stack]
(gdb) list
13 }
14
15 int main(int argc, char** argv) {
16 void* libc = dlopen("/lib/libc-2.7.so", RTLD_NOW);
17 void* address = dlsym( libc, "__libc_init_first");
18 printf("Address of <__libc_init_first>: %p\n", address);
19 if(argc > 1) {
20 foo(argv[1]);
21 }
22 printf("Done.\n");
(gdb) x libc
0x804a020: 0xb7d51000
(gdb) print address
$4 = (void *) 0xb7d672a0
You can see that three libraries are dynamically linked with the binary. libc-2.7, libc2-7.so (from a different location, maybe this is done automatically) and libdl-2.7.so
I dont understand why there are two to three entries in this list per library, I want to know what is going on there, and why they are separate entries.
I dont have any assumptions what is going on there and I dont know how I can explain any of this.
Take the first linked library for example:
The first section I assume is the library itself, it has the ELF header so I am convinced that it truly is the libc I have linked.
When I peek into the second entry of /lib/libc-2.7-so I just get lots of NULL bytes, dont know whats going on here.
(gdb) x/100x 0xb7e84000
0xb7e84000: 0x00000000 0x00000000 0x00000000 0x00000000
0xb7e84010: 0x00000000 0x00000000 0x00000000 0x00000000
0xb7e84020: 0x00000000 0x00000000 0x00000000 0x00000000
When I peek into the third entry of /lib/libc-2.6.so I get addresses to instructions (gadgets or functions maybe).
(gdb) x/100x 0xb7e85000
0xb7e85000: 0x0000006f 0xb7e671dc 0xb7e671e0 0xb7e671e4
0xb7e85010: 0xb7e671e8 0xb7e671ec 0xb7e671f0 0xb7e671f4
0xb7e85020: 0xb7e671f8 0xb7e671ff 0xb7e67206 0xb7e6720e
This is the example output I get from one of the addresses, seems pretty convincing that this could be usable code.
(gdb) x/10i 0xb7e671e8
0xb7e671e8: push %edi
0xb7e671e9: add %dl,%fs:%gs:0x75(%eax,%ebp,2)
0xb7e671ef: add %al,0x72(%esi)
0xb7e671f2: imul $0x746153,(%eax),%eax
0xb7e671f8: push %ebx
0xb7e671f9: jne 0xb7e67269
0xb7e671fb: fs
0xb7e671fc: popa
0xb7e671fd: jns 0xb7e671ff
0xb7e671ff: dec %ebp
(gdb)
My questions are, what are these three sections doing each ? Why are they split up like that ? What happens in the area where no corresponding label exists but is still mapped ?
I have an issue with my pointer to a structure variable. I just started using GDB to debug the issue. The application stops when it hits on the line of code below due to segmentation fault. ptr_var is a pointer to a structure
ptr_var->page = 0;
I discovered that ptr_var is set to an invalid memory 0x0 after a series of function calls which caused the segmentation fault when assigning the value "0" to struct member "page". The series of function calls does not have a reference to ptr_var. The old address that used to be assigned to ptr_var is still in memory. I can still still print the values of members from the struct ptr_var using the old address. GDB session below shows that I am printing a string member of the struct ptr_var using its address
(gdb) x /s *0x7e11c0
0x7e0810: "Sample String"
I couldn't tell when the variable ptr_var gets assigned an invalid address 0x0. I'm a newbie to GDB and an average C programmer. Your assistance in this matter is greatly appreciated. Thank you.
What you want to do is set a watchpoint, GDB will then stop execution every time a member of a struct is modified.
With the following example code
typedef struct {
int val;
} Foo;
int main(void) {
Foo foo;
foo.val = 5;
foo.val = 10;
}
Drop a breakpoint at the creation of the struct and execute watch -l foo.val Then every time that member is changed you will get a break. The following is my GDB session, with my input
(gdb) break test.c:8
Breakpoint 3 at 0x4006f9: file test.c, line 8.
(gdb) run
Starting program: /usr/home/sean/a.out
Breakpoint 3, main () at test.c:9
9 foo.val = 5;
(gdb) watch -l foo.val
Hardware watchpoint 4: -location foo.val
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 0
New value = 5
main () at test.c:10
(gdb) cont
Continuing.
Hardware watchpoint 4: -location foo.val
Old value = 5
New value = 10
main () at test.c:11
(gdb) cont
If you can rerun, then break at a point where ptr_var is correct you can set a watch point on ptr_var like this: (gdb) watch ptr_var. Now when you continue every time ptr_var is modified gdb should stop.
Here's an example. This does contain undefined behaviour, as I'm trying to reproduce a bug, but hopefully it should be good enough to show you what I'm suggesting:
#include <stdio.h>
#include <stdint.h>
int target1;
int target2;
void
bad_func (int **bar)
{
/* Set contents of bar. */
uintptr_t ptr = (uintptr_t) bar;
printf ("Should clear %p\n", (void *) ptr);
ptr += sizeof (int *);
printf ("Will clear %p\n", (void *) ptr);
/* Bad! We just corrupted foo (maybe). */
*((int **) ptr) = NULL;
}
int
main ()
{
int *foo = &target1;
int *bar = &target2;
printf ("&foo = %p\n", (void *) &foo);
printf ("&boo = %p\n", (void *) &bar);
bad_func (&bar);
return *foo;
}
And here's a gdb session:
(gdb) break bad_func
Breakpoint 1 at 0x400542: file watch.c, line 11.
(gdb) r
&foo = 0x7fffffffdb88
&boo = 0x7fffffffdb80
Breakpoint 1, bad_func (bar=0x7fffffffdb80) at watch.c:11
11 uintptr_t ptr = (uintptr_t) bar;
(gdb) up
#1 0x00000000004005d9 in main () at watch.c:27
27 bad_func (&bar);
(gdb) watch foo
Hardware watchpoint 2: foo
(gdb) c
Continuing.
Should clear 0x7fffffffdb80
Will clear 0x7fffffffdb88
Hardware watchpoint 2: foo
Old value = (int *) 0x60103c <target1>
New value = (int *) 0x0
bad_func (bar=0x7fffffffdb80) at watch.c:18
18 }
(gdb)
For some reason the watchpoint appears to trigger on the line after the change was made, even though I compiled this with -O0, which is a bit of a shame. Still, it's usually close enough to help identify the problem.
For such kind of problems I often use the old electric fence library, it can be used to find bug in "software that overruns the boundaries of a malloc() memory allocation". You will find all the instructions and basic usage at this page:
http://elinux.org/Electric_Fence
(At the very end of the page linked above you will find the download link)
I am trying to find out how to print an integer value (I saw that it is x/d) but I am missing something.
So, my code is the following
1 #include <stdio.h>
2 main(){
3 int a;
4 int b;
5 int c;
6 int d;
7 int multiplied;
8 a = 5;
9 b = 6;
10 c = 7;
11 d = adding(a,b,c);
12 multiplied = multiply(a,b,c);
13 printf("The value of d is %d \n",d);
14 printf("The multiplied values are %d \n", multiplied);
15 }
16 int adding(a,b,c){
17 int e;
18 e = a+b+c;
19 return e;
20 }
21 int multiply(a,b,c){
22 int f = a*b*c;
23 return f;
24 }
// I compiled with -q and I want to print the values of the variables (from their addresses) So...
(gdb) disassemble main
0x080483ed <+9>: mov DWORD PTR [esp+0x2c],0x5
0x080483f5 <+17>: mov DWORD PTR [esp+0x28],0x6
0x080483fd <+25>: mov DWORD PTR [esp+0x24],0x7
0x08048405 <+33>: mov eax,DWORD PTR [esp+0x24] <code>
I put some breakpoints in main / multiply / adding and then I was trying to do the following thing.
I used
print $esp+0x24
and
(gdb) x/4d 0xbffff47c but im not getting the right answers back.
I used the 4d because I thought that an integer is 4 bytes (or maybe again im missing something) but the results arent showing the value 5.
Can you please help me? Thanks and sorry for the bad output / format of gdb.. seriously i cant understand whats wrong
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff494
(gdb) print $esp+0x28
$3 = (void *) 0xbffff490
(gdb) print $esp+0x24
$4 = (void *) 0xbffff48c
(gdb) x/d 0xbffff494
0xbffff494: -1208180748
(gdb) x/d 0xbffff490
0xbffff490: -1208179932
(gdb) x/d 0xbffff48c
0xbffff48c: 134513881
Also this happens ofcourse after the first breakpoint of main and actually the same values are coming all the time in all breakpoints (except the one before main...)
Another interesting thing that I found is the following... Im sure that the first values are garbages. But why it considers 0x5 as an address when it should print the actual value?
Breakpoint 1, main () at functioncalling.c:10
10 a = 5;
(gdb) x/s a
0xb7fc9ff4: "|M\025"
(gdb) cont
Continuing.
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
I compiled your program with -g and no optimization, and set a breakpoint before line 11. My stack addresses are a bit different from yours, which isn't surprising given the variety of systems out there.
(gdb) print $esp+0x2c
$2 = (void *) 0xbffff44c
This is printing the address of a. To confirm:
(gdb) print &a
$4 = (int *) 0xbffff44c
Use x/wd to show a 4-byte integer in decimal.
(gdb) x/wd $esp+0x2c
0xbffff44c: 5
x/4d will show 4 values (4 is the repeat count) starting at the address. If you omit the size letter w here, the x command will default to the size previously used.
(gdb) x/4d $esp+0x2c
0xbffff44c: 5 134513856 0 -1073744680
There's your 5. As for the 3 other numbers, they are things further up the stack.
(gdb) x/4a $esp+0x2c
0xbffff44c: 0x5 0x80484c0 <__libc_csu_init> 0x0 0xbffff4d8
Your next question:
Another interesting thing that I found is the following... Im sure that the first values are garbages. But why it considers 0x5 as an address when it should print the actual value?
Breakpoint 3, adding (a=5, b=6, c=7) at functioncalling.c:21
21 e = a+b+c;
(gdb) x/s a
0x5: <Address 0x5 out of bounds>
The x command, when given a program's variable as its argument, retrieves its value and uses that as the address. x/s a means to retrieve the value in a and use it as the starting address of a NUL-terminated string. If a were of type char * and contained a suitable value, x/s would print sensible output. To print a's actual value, give the x command the argument &a.
(gdb) x/wd &a
0xbffff44c: 5
This may seem counterintuitive. Just consider the x command to operate just like the C statement printf(fmt, *(argument)) would. The argument to the x command is almost always a literal memory address or an address expression involving the stack pointer, base pointer, or pc registers.