几天前,我想知道如何自学基于堆的溢出利用。
所以我搜索了文档,随后练习了我阅读的内容,以便更好地了解堆在 Linux 下的工作原理。
我们被告知 malloc() / free() 函数围绕Doug Lea 的内存分配器工作,但是,尽管链接给出了很好的解释,但我在调试程序时无法弄清楚。
鉴于这个例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int n = 5;
int main(int argc, char** argv) {
char* p;
char* q;
p = malloc(1024);
q = malloc(1024);
printf("real size = %d\n",*(((int*)p)-1) & 0xFFFFFFF8);
if(argc >= 2) {
strcpy(p, argv[1]);
}
free(q);
printf("n = 0x%08X\n", n);
free(p);
return EXIT_SUCCESS;
}
我想将此结构转储到内存中:
struct chunk {
int prev_size;
int size;
struct chunk *fd;
struct chunk *bk;
};
这是我的工作流程:
geo@lilith:~/c/vuln_malloc$ gcc -o vuln vuln.c -m32 -ggdb
geo@lilith:~/c/vuln_malloc$ gdb ./vuln
GNU gdb (GDB) 7.4.1-debian
Copyright (C) 2012 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-linux-gnu".
For bug reporting instructions, please see:
<http://www.gnu.org/software/gdb/bugs/>...
Reading symbols from /home/geo/c/vuln_malloc/vuln...done.
(gdb) b 21
Breakpoint 1 at 0x804850f: file vuln.c, line 21.
(gdb) r `perl -e 'print "A" x 1024'`
Starting program: /home/geo/c/vuln_malloc/vuln `perl -e 'print "A" x 1024'`
real size = 1032
Breakpoint 1, main (argc=2, argv=0xffffd414) at vuln.c:21
21 free(q);
(gdb) x/10x q-4
0x804a40c: 0x00000409 0x00000000 0x00000000 0x00000000
0x804a41c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804a42c: 0x00000000 0x00000000
(gdb)
在这里我可以看到 size-field 的值,即 0x409。我可以很容易地猜测我的块的实际大小是 0x409 & 0xFFFFFF8 = 0x408 = 1032,正如文档所解释的(三个最不重要的实际上定义了一些标志)。然后我运行直到 free() 函数被处理。
(gdb) b 22
Breakpoint 2 at 0x804851b: file vuln.c, line 22.
(gdb) c
Continuing.
Breakpoint 2, main (argc=2, argv=0xffffd414) at vuln.c:22
22 printf("n = 0x%08X\n", n);
(gdb) x/10x q-4
0x804a40c: 0x00020bf9 0x00000000 0x00000000 0x00000000
0x804a41c: 0x00000000 0x00000000 0x00000000 0x00000000
0x804a42c: 0x00000000 0x00000000
首先,我根本不理解新值 - 0x20bf9 - 其次,我不明白为什么 fd 和 bk 指针也没有任何相关值。
所有这些东西对我来说都没有多大意义,这就是为什么我想知道你是否可以给我一些关于所有这些的线索。Doug Lea 的实现是否仍然存在于最近的 glibc 版本中,或者......?