Excuse the ads! We need some help to keep our site up.
malloc () allocates memory using Top chunk in the following way.
Store the value of main_arene → top in "victim" and the size of the top chunk in "size".
malloc () uses the space in Top chunk if the value of "size" is greater than or equal to "Newly requested memory size (nb) + minimum chunk size (MINSIZE)".
Store the value stored in "size" minus the size of the newly requested memory (nb) in "remainder_size" and the value stored in "victim" plus the size of the newly requested memory(nb) in "remainder" It is.
"remainder" is stored in main_arene → top.
Using set_head () saves the newly requested memory size(nb) in "victim→size" and stores the value of "remainder_size" in "remainder→size".
malloc() calls chunk2mem(), returns the address(p + 2 * SIZE_SZ).
/* finally, do the allocation */ p = av->top; size = chunksize (p); /* check that one of the above allocation paths succeeded */ if ((unsigned long) (size) >= (unsigned long) (nb + MINSIZE)) { remainder_size = size - nb; remainder = chunk_at_offset (p, nb); av->top = remainder; set_head (p, nb | PREV_INUSE | (av != &main_arena ? NON_MAIN_ARENA : 0)); set_head (remainder, remainder_size | PREV_INUSE); check_malloced_chunk (av, p, nb); return chunk2mem (p); } |
#include <stdio.h> #include <string.h> #include <stdlib.h> #include <unistd.h> int main(int argc, char *argv[]) { int size; unsigned long *buf1, *buf2, *buf3; fprintf(stderr,"The house of Force"); buf1 = malloc(256); buf1[33] = 0xffffffffffffffff; buf2 = malloc(0xffffffffffffeee0); buf3 = malloc(256); buf3[0] = 0x4141414141414141; free(buf3); return 0; } |
lazenca0x0@ubuntu:~$ gcc -o test test.c lazenca0x0@ubuntu:~$ gdb -q ./test Reading symbols from ./test...(no debugging symbols found)...done. gdb-peda$ disassemble main Dump of assembler code for function main: 0x00000000004005f6 <+0>: push rbp 0x00000000004005f7 <+1>: mov rbp,rsp 0x00000000004005fa <+4>: sub rsp,0x30 0x00000000004005fe <+8>: mov DWORD PTR [rbp-0x24],edi 0x0000000000400601 <+11>: mov QWORD PTR [rbp-0x30],rsi 0x0000000000400605 <+15>: mov rax,QWORD PTR [rip+0x200a54] # 0x601060 <stderr@@GLIBC_2.2.5> 0x000000000040060c <+22>: mov rcx,rax 0x000000000040060f <+25>: mov edx,0x12 0x0000000000400614 <+30>: mov esi,0x1 0x0000000000400619 <+35>: mov edi,0x400714 0x000000000040061e <+40>: call 0x4004e0 <fwrite@plt> 0x0000000000400623 <+45>: mov edi,0x100 0x0000000000400628 <+50>: call 0x4004d0 <malloc@plt> 0x000000000040062d <+55>: mov QWORD PTR [rbp-0x18],rax 0x0000000000400631 <+59>: mov rax,QWORD PTR [rbp-0x18] 0x0000000000400635 <+63>: add rax,0x108 0x000000000040063b <+69>: mov QWORD PTR [rax],0xffffffffffffffff 0x0000000000400642 <+76>: mov rdi,0xffffffffffffeee0 0x0000000000400649 <+83>: call 0x4004d0 <malloc@plt> 0x000000000040064e <+88>: mov QWORD PTR [rbp-0x10],rax 0x0000000000400652 <+92>: mov edi,0x100 0x0000000000400657 <+97>: call 0x4004d0 <malloc@plt> 0x000000000040065c <+102>: mov QWORD PTR [rbp-0x8],rax 0x0000000000400660 <+106>: mov rax,QWORD PTR [rbp-0x8] 0x0000000000400664 <+110>: add rax,0x8 0x0000000000400668 <+114>: movabs rdx,0x4141414141414141 0x0000000000400672 <+124>: mov QWORD PTR [rax],rdx 0x0000000000400675 <+127>: mov rax,QWORD PTR [rbp-0x8] 0x0000000000400679 <+131>: mov rdi,rax 0x000000000040067c <+134>: call 0x4004b0 <free@plt> 0x0000000000400681 <+139>: mov eax,0x0 0x0000000000400686 <+144>: leave 0x0000000000400687 <+145>: ret End of assembler dump. gdb-peda$ b *0x000000000040062d Breakpoint 1 at 0x40062d gdb-peda$ b *0x000000000040063b Breakpoint 2 at 0x40063b gdb-peda$ b *0x0000000000400649 Breakpoint 3 at 0x400649 gdb-peda$ b *0x0000000000400657 Breakpoint 4 at 0x400657 gdb-peda$ b *0x0000000000400672 Breakpoint 5 at 0x400672 gdb-peda$ b *0x000000000040067c Breakpoint 6 at 0x40067c gdb-peda$ |
gdb-peda$ r Starting program: /home/lazenca0x0/test The house of Force Breakpoint 1, 0x000000000040062d in main () gdb-peda$ i r rax rax 0x602010 0x602010 gdb-peda$ p main_arena.top $1 = (mchunkptr) 0x602110 gdb-peda$ p main_arena.top.size $2 = 0x20ef1 gdb-peda$ c Continuing. Breakpoint 2, 0x000000000040063b in main () gdb-peda$ x/i $rip => 0x40063b <main+69>: mov QWORD PTR [rax],0xffffffffffffffff gdb-peda$ i r rax rax 0x602118 0x602118 gdb-peda$ |
gdb-peda$ c Continuing. Breakpoint 3, 0x0000000000400649 in main () gdb-peda$ x/i $rip => 0x400649 <main+83>: call 0x4004d0 <malloc@plt> gdb-peda$ i r rdi rdi 0xffffffffffffeee0 0xffffffffffffeee0 gdb-peda$ ni 0x000000000040064e in main () gdb-peda$ i r rax rax 0x602120 0x602120 gdb-peda$ p main_arena.top $3 = (mchunkptr) 0x601000 gdb-peda$ c Continuing. Breakpoint 4, 0x0000000000400657 in main () gdb-peda$ x/i $rip => 0x400657 <main+97>: call 0x4004d0 <malloc@plt> gdb-peda$ i r rdi rdi 0x100 0x100 gdb-peda$ ni 0x000000000040065c in main () gdb-peda$ i r rax rax 0x601010 0x601010 gdb-peda$ |
If you call the free() function at 0x40067c, the function calls free@plt(0x4004b0).
gdb-peda$ c Continuing. Breakpoint 5, 0x0000000000400672 in main () gdb-peda$ x/i $rip => 0x400672 <main+124>: mov QWORD PTR [rax],rdx gdb-peda$ i r rax rdx rax 0x601018 0x601018 rdx 0x4141414141414141 0x4141414141414141 gdb-peda$ x/gx 0x601018 0x601018: 0x00000000004004b6 gdb-peda$ x/gx 0x00000000004004b6 0x4004b6 <free@plt+6>: 0xffe0e90000000068 gdb-peda$ elfsymbol free Detail symbol info free@reloc = 0 free@plt = 0x4004b0 free@got = 0x601018 gdb-peda$ c Continuing. Breakpoint 6, 0x000000000040067c in main () gdb-peda$ x/i $rip => 0x40067c <main+134>: call 0x4004b0 <free@plt> gdb-peda$ gdb-peda$ x/2i 0x4004b0 0x4004b0 <free@plt>: jmp QWORD PTR [rip+0x200b62] # 0x601018 0x4004b6 <free@plt+6>: push 0x0 gdb-peda$ p/x 0x4004b6 + 0x200b62 $7 = 0x601018 gdb-peda$ x/gx 0x601018 0x601018: 0x4141414141414141 gdb-peda$ c Continuing. Program received signal SIGSEGV, Segmentation fault. Stopped reason: SIGSEGV 0x00000000004004b0 in free@plt () gdb-peda$ |