first_fit other test

0x001

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
  char*	a	=	malloc(0x18);
char* b = malloc(0x19);
char* c = malloc(0x28);
char* d = malloc(0x29);


pwndbg> heap
Top Chunk: 0x6020c0
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x21,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x31
}
0x602020 FASTBIN {
prev_size = 0x0,
size = 0x31,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}

接上

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
0x602050 FASTBIN {
prev_size = 0x0,
size = 0x31,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602080 FASTBIN {
prev_size = 0x0,
size = 0x41,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6020c0 PREV_INUSE {
prev_size = 0x0,
size = 0x20f41,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg>

所以说申请0x19 ~ 0x28大小的内存都是返回0x30大小的chunk
0x19是多分配了,0x

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
	free(a);
free(b);
free(c);
free(d);



pwndbg> bins
fastbins
0x20: 0x602000 ◂— 0x0
0x30: 0x602050 —▸ 0x602020 ◂— 0x0
0x40: 0x602080 ◂— 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty


pwndbg> p main_arena
$1 = {
mutex = 0x0,
flags = 0x0,
fastbinsY = {0x602000, 0x602050, 0x602080, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
top = 0x6020c0,
last_remainder = 0x0,
bins = {0x7ffff7dd1b78 <main_arena+88>, 0x7ffff7dd1b78 <main_arena+88>, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1be8 <main_arena+200>...},
binmap = {0x0, 0x0, 0x0, 0x0},
next = 0x7ffff7dd1b20 <main_arena>,
next_free = 0x0,
attached_threads = 0x1,
system_mem = 0x21000,
max_system_mem = 0x21000
}
pwndbg>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
	char*	a	=	malloc(0x8);
char* b = malloc(0x9);
char* c = malloc(0x18);
char* d = malloc(0x19);


0x602000 FASTBIN {
prev_size = 0x0,
size = 0x21,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x21
}
0x602020 FASTBIN {
prev_size = 0x0,
size = 0x21,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x21
}
0x602040 FASTBIN {
prev_size = 0x0,
size = 0x21,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x31
}
0x602060 FASTBIN {
prev_size = 0x0,
size = 0x31,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602090 PREV_INUSE {
prev_size = 0x0,
size = 0x20f71,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}

但是这里哪怕是申请0x8的大小也会分配0x10而不是0x8的数据域大小不像上面
所以0x00~0x18都是分配0x20大小的chunk,有点特殊

ApplicationSize returnSize
0x00~0x18 0x20
0x09~0x28 0x30
0x29~0x38 0x40
0x39~0x48 0x50
0x49~0x58 0x60
0x59~0x68 0x70
0x69~0x78 0x80

0x02 chunksize>=maxfast且与top_chunk相邻,释放的时候,触发了fastbins的合并

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54

char* a = malloc(0x68);
char* b = malloc(0x69);
char* c = malloc(0x78);
char* d = malloc(0x79);




pwndbg> heap
Top Chunk: 0x602200
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x71,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602070 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6020f0 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602170 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602200 PREV_INUSE {
prev_size = 0x0,
size = 0x20e01,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
	free(a);
free(b);
free(c);

pwndbg> heap
Top Chunk: 0x602200
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x71,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602070 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6020f0 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x602070,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602170 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602200 PREV_INUSE {
prev_size = 0x0,
size = 0x20e01,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}


pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x602000 ◂— 0x0
0x80: 0x6020f0 —▸ 0x602070 ◂— 0x0
unsortedbin
all: 0x0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
	free(d);


pwndbg> heap
Top Chunk: 0x602000
Last Remainder: 0

0x602000 PREV_INUSE {
prev_size = 0x0,
size = 0x21001,
fd = 0x7ffff7dd1b78 <main_arena+88>,
bk = 0x7ffff7dd1b78 <main_arena+88>,
fd_nextsize = 0x0,
bk_nextsize = 0x0

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg>

这里当chunk的大小大于0x78后在释放,并不会被放到fastbins中,而且整个堆都没了被合并了,
但是unsorted bins中也没看见咧、、、、
会跟跟top_chunk合并???

0x0x3 chunksizr<=fast_max且与top_chunk相邻,释放时的情况

再试一下下面这个看看top_chunk合并

1
2
3
4
5
6
   char*	a	=	malloc(0x68);
char* b = malloc(0x69);
char* c = malloc(0x78);
free(a);
free(b);
free(c);

这里与seebug上说的不一致咧

判断 chunk 的大小和所处的位置, 若 chunk_size <= max_fast, 并且 chunk 并不位于 heap 的顶部, 也就是说并不与 Top chunk 相邻, 则转到下一步, 否则跳到第 5 步.(因为与 top chunk 相邻的 chunk(fastbin) ,会与 top chunk 进行合并, 所以这里不仅需要判断大小, 还需要判断相邻情况)

上为seebug原话,现在这个chunk c大小是等于maxfast但是他与top_chunk相邻。
但是这里把 c free掉之后并没有与top_chunk合并,
还是这样丢到fastbins里面去了
不明白!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
pwndbg> heap
Top Chunk: 0x602170
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x71,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602070 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6020f0 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x602070,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602170 PREV_INUSE {
prev_size = 0x0,
size = 0x20e91,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x602000 ◂— 0x0
0x80: 0x6020f0 —▸ 0x602070 ◂— 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg>


0x04 chunksize>=maxfast但不予与top_chunk相邻,释放的时候,没有触发fastbins的合并,他也被丢到unsorted_bin里了。

1
2
3
4
5
6
   char*	a	=	malloc(0x78);
char* b = malloc(0x79);
char* c = malloc(0x78);
free(a);
free(b);
free(c);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
    char*	a	=	malloc(0x78);
char* b = malloc(0x79);
char* c = malloc(0x78);

pwndbg> heap
Top Chunk: 0x6021a0
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602080 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602110 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6021a0 PREV_INUSE {
prev_size = 0x0,
size = 0x20e61,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
	free(a);
free(b);

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x602000 ◂— 0x0
unsortedbin
all: 0x7ffff7dd1b78 (main_arena+88) —▸ 0x602080 ◂— 0x7ffff7dd1b78
smallbins
empty
largebins
empty

pwndbg> p main_arena
$1 = {
mutex = 0x0,
flags = 0x0,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602000, 0x0, 0x0, 0x0},
top = 0x6021a0,
last_remainder = 0x0,
bins = {0x602080, 0x602080, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1be8 <main_arena+200>...},
binmap = {0x0, 0x0, 0x0, 0x0},
next = 0x7ffff7dd1b20 <main_arena>,
next_free = 0x0,
attached_threads = 0x1,
system_mem = 0x21000,
max_system_mem = 0x21000
}

Bins 本身就是一个数组, 每一个存放的是一个对应长度的 chunk 双向环链表的头结点和尾节点。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
    free(c);

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x0
unsortedbin
all: 0x0
smallbins
empty
largebins
empty
pwndbg> heap
Top Chunk: 0x602000
Last Remainder: 0

0x602000 PREV_INUSE {
prev_size = 0x0,
size = 0x21001,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}

pwndbg> bins
fastbins
0x20: 0x0
0x30: 0x0
0x40: 0x0
0x50: 0x0
0x60: 0x0
0x70: 0x0
0x80: 0x602110 —▸ 0x602000 ◂— 0x0
unsortedbin
all: 0x602080 —▸ 0x7ffff7dd1b78 (main_arena+88) —▸ 0x602190 ◂— 0x602080
smallbins
empty
largebins
empty
pwndbg> heap
Top Chunk: 0x6022a0
Last Remainder: 0

0x602000 FASTBIN {
prev_size = 0x0,
size = 0x81,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602080 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x7ffff7dd1b78 <main_arena+88>,
bk = 0x602190,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602110 {
prev_size = 0x90,
size = 0x80,
fd = 0x602000,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602190 PREV_INUSE {
prev_size = 0x0,
size = 0x91,
fd = 0x602080,
bk = 0x7ffff7dd1b78 <main_arena+88>,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x602220 {
prev_size = 0x90,
size = 0x80,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
0x6022a0 PREV_INUSE {
prev_size = 0x0,
size = 0x20d61,
fd = 0x0,
bk = 0x0,
fd_nextsize = 0x0,
bk_nextsize = 0x0
}
pwndbg> p main_arena
$3 = {
mutex = 0x0,
flags = 0x0,
fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x602110, 0x0, 0x0, 0x0},
top = 0x6022a0,
last_remainder = 0x0,
bins = {0x602190, 0x602080, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b88 <main_arena+104>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1b98 <main_arena+120>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1ba8 <main_arena+136>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bb8 <main_arena+152>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bc8 <main_arena+168>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1bd8 <main_arena+184>, 0x7ffff7dd1be8 <main_arena+200>...},
binmap = {0x0, 0x0, 0x0, 0x0},
next = 0x7ffff7dd1b20 <main_arena>,
next_free = 0x0,
attached_threads = 0x1,
system_mem = 0x21000,
max_system_mem = 0x21000
}
pwndbg>