Skip to content

Instantly share code, notes, and snippets.

@0x00000FF
Created May 2, 2021 20:00
Show Gist options
  • Save 0x00000FF/30311230107a2d960d11a4d01e3a6461 to your computer and use it in GitHub Desktop.
Save 0x00000FF/30311230107a2d960d11a4d01e3a6461 to your computer and use it in GitHub Desktop.
Heap Study
#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