Created
May 2, 2021 20:00
-
-
Save 0x00000FF/30311230107a2d960d11a4d01e3a6461 to your computer and use it in GitHub Desktop.
Heap Study
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <stdio.h> | |
#include <stdlib.h> | |
#define ALLOC ((unsigned char*)malloc(56)) | |
#define A(x) (x & 0x4) | |
#define M(x) (x & 0x2) | |
#define P(x) (x & 0x1) | |
#define PTR(x) ((void*)x) | |
#define CHUNK_PTR(x) ((allocated_chunk*)(x - 8)) | |
#define FREE_CHUNK(x) ((freed_chunk*)(x)) | |
#define RECOVER_PTR(x) ((unsigned char*)(x) + 8) | |
typedef struct { | |
size_t size; | |
unsigned char data[24]; | |
} allocated_chunk; | |
typedef struct { | |
size_t size; | |
allocated_chunk* fd; | |
allocated_chunk* bk; | |
size_t padding; | |
size_t prev_size; | |
} freed_chunk; | |
void print_allocated_chunk(allocated_chunk* chunk) { | |
printf("[CHUNK at %p from %p ]\n", PTR(chunk), RECOVER_PTR(chunk)); | |
printf("Size: %lu bytes\n", chunk->size & 0xfffffffffffffff8); | |
printf("Arena: %s, Mmap'd: %s, Prev_inuse: %s\n\n", | |
A(chunk->size) ? "Other" : "Main", | |
M(chunk->size) ? "yes" : "no", | |
P(chunk->size) ? "yes" : "no"); | |
} | |
void print_freed_chunk(freed_chunk* chunk) { | |
print_allocated_chunk((allocated_chunk*)chunk); | |
printf("fd: %p\n", chunk->fd); | |
printf("bk: %p\n", chunk->bk); | |
printf("prev_size: %lu\n\n", chunk->prev_size); | |
} | |
int main(int argc, char* argv[]) { | |
unsigned char* _mem1 = ALLOC; | |
unsigned char* _mem2 = ALLOC; | |
unsigned char* _mem3 = ALLOC; | |
printf("[user memory addresses]\n" | |
"%p, %p, %p\n\n\n", _mem1, _mem2, _mem3); | |
allocated_chunk* mem1 = CHUNK_PTR(_mem1); | |
allocated_chunk* mem2 = CHUNK_PTR(_mem2); | |
allocated_chunk* mem3 = CHUNK_PTR(_mem3); | |
allocated_chunk* mem_arr[] = { mem1, mem2, mem3 }; | |
freed_chunk* fchunk_list[3] = { NULL }; | |
int freed_chunks = 0; | |
puts("allocated 3 chunks, 24 bytes per each\n"); | |
for (int i = 0; i < 3; ++i) { | |
print_allocated_chunk(mem_arr[i]); | |
} | |
// set breakpoint here!!! | |
__asm__ ( | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop" | |
); | |
for (int i = 1; i < argc; ++i) { | |
int count = atoi(argv[i]) - 1; | |
if (count < 0 || count > 2) { | |
puts("wrong count for chunk to free; halt;"); | |
return -1; | |
} | |
freed_chunk* fchunk = FREE_CHUNK(mem_arr[count]); | |
free(RECOVER_PTR(fchunk)); | |
fchunk_list[freed_chunks] = fchunk; | |
freed_chunks++; | |
} | |
// set breakpoint here!!! | |
__asm__ ( | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop\r\n" | |
"nop\r\nnop\r\nnop\r\nnop\r\nnop" | |
); | |
printf("=== %d chunks are freed ===\n\n", freed_chunks); | |
for (int i = 0; i < 3; ++i) { | |
if (PTR(fchunk_list[0]) == PTR(mem_arr[i]) || | |
PTR(fchunk_list[1]) == PTR(mem_arr[i]) || | |
PTR(fchunk_list[2]) == PTR(mem_arr[i])) | |
print_freed_chunk(FREE_CHUNK(mem_arr[i])); | |
else | |
print_allocated_chunk(mem_arr[i]); | |
} | |
return 0; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment