[原创]LCTF 2018 easy_heap
这道题目也是一个经典的笔记本类型heap题目,不过题目创新之处在于改写prev_size的方式,我们先来看看大概代码:
unsigned __int64 free_p()
{
unsigned int _index; // [rsp+4h] [rbp-Ch]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
printf("index \n> ");
_index = read_num();
if ( _index > 9 || !*(_QWORD *)(16LL * _index + malloc_array) )
exit_p();
memset(*(void **)(16LL * _index + malloc_array), 0, *(unsigned int *)(16LL * _index + malloc_array + 8));
free(*(void **)(16LL * _index + malloc_array));
*(_DWORD *)(16LL * _index + malloc_array + 8) = 0;
*(_QWORD *)(16LL * _index + malloc_array) = 0LL;
return __readfsqword(0x28u) ^ v2;
}
unsigned __int64 put_p()
{
unsigned int _index; // [rsp+4h] [rbp-Ch]
unsigned __int64 v2; // [rsp+8h] [rbp-8h]
v2 = __readfsqword(0x28u);
printf("index \n> ");
_index = read_num();
if ( _index > 9 || !*(_QWORD *)(16LL * _index + malloc_array) )
exit_p();
puts(*(const char **)(16LL * _index + malloc_array));
return __readfsqword(0x28u) ^ v2;
int _sizea; // [rsp+0h] [rbp-20h]
unsigned int size; // [rsp+4h] [rbp-1Ch]
unsigned __int64 v5; // [rsp+8h] [rbp-18h]
v5 = __readfsqword(0x28u);
LODWORD(_size) = 0;
while ( (signed int)_size <= 9 && *(_QWORD *)(16LL * (signed int)_size + malloc_array) )
LODWORD(_size) = _size + 1;
if ( (_DWORD)_size == 10 ) // limited max size to 10
{
puts("full!");
}
else
{
m_ptr = malloc_array;
*(_QWORD *)(m_ptr + 16LL * (signed int)_size) = malloc(0xF8uLL);
if ( !*(_QWORD *)(16LL * (signed int)_size + malloc_array) )
{
puts("malloc error!");
exit_p();
}
printf("size \n> ", _size);
size = read_num();
if ( size > 0xF8 )
exit_p();
*(_DWORD *)(16LL * _sizea + malloc_array + 8) = size;
printf("content \n> ");
read_content(*(_BYTE **)(16LL * _sizea + malloc_array), *(_DWORD *)(16LL * _sizea + malloc_array + 8));
}
return __readfsqword(0x28u) ^ v5;
}
}
unsigned __int64 malloc_p()
{
__int64 m_ptr; // rbx
__int64 _size; // [rsp+0h] [rbp-20h]
int _sizea; // [rsp+0h] [rbp-20h]
unsigned int size; // [rsp+4h] [rbp-1Ch]
unsigned __int64 v5; // [rsp+8h] [rbp-18h]
v5 = __readfsqword(0x28u);
LODWORD(_size) = 0;
while ( (signed int)_size <= 9 && *(_QWORD *)(16LL * (signed int)_size + malloc_array) )
LODWORD(_size) = _size + 1;
if ( (_DWORD)_size == 10 ) // limited max size to 10
{
puts("full!");
}
else
{
m_ptr = malloc_array;
*(_QWORD *)(m_ptr + 16LL * (signed int)_size) = malloc(0xF8uLL);
if ( !*(_QWORD *)(16LL * (signed int)_size + malloc_array) )
{
puts("malloc error!");
exit_p();
}
printf("size \n> ", _size);
size = read_num();
if ( size > 0xF8 )
exit_p();
*(_DWORD *)(16LL * _sizea + malloc_array + 8) = size;
printf("content \n> ");
read_content(*(_BYTE **)(16LL * _sizea + malloc_array), *(_DWORD *)(16LL * _sizea + malloc_array + 8));
}
return __readfsqword(0x28u) ^ v5;
}
unsigned __int64 __fastcall read_content(_BYTE *content, int size)
{
unsigned int index; // [rsp+14h] [rbp-Ch]
unsigned __int64 v4; // [rsp+18h] [rbp-8h]
v4 = __readfsqword(0x28u);
index = 0;
if ( size )
{
while ( 1 )
{
read(0, &content[index], 1uLL);
if ( size - 1 < index || !content[index] || content[index] == 0xA )
break;
++index;
}
content[index] = 0;
content[size] = 0; // off by one
}
else
{
*content = 0;
}
return __readfsqword(0x28u) ^ v4;
}
void __fastcall __noreturn main(__int64 a1, char **a2, char **a3)
{
int _opt; // eax
setbuf_print_slogan();
malloc_array = (__int64)calloc(0xA0uLL, 1uLL);
if ( !malloc_array )
{
puts("init error!");
exit_p();
}
while ( 1 )
{
while ( 1 )
{
sub_B38();
_opt = read_num();
if ( _opt != 2 )
break;
free_p();
}
if ( _opt > 2 )
{
if ( _opt == 3 )
{
put_p();
}
else if ( _opt == 4 )
{
exit_p();
}
}
else if ( _opt == 1 )
{
malloc_p();
}
}
}
有必要指出来的是, malloc_array 存储了各个chunk的地址以及对应存储内容的大小。
注意:上传附件及图片大小不得大于30M。
⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途。
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。
复制成功
