欢迎来到 嗅灵易学

零基础也能上手的脚本技术课,一对一答疑带你入门

[原创]LCTF 2018 easy_heap

[原创]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。

⚠️ 版权声明:
本博客所有内容(含教程、源码、工具)仅供个人技术学习与研究交流使用,严禁商用、倒卖、二次分发及非法用途
未经作者书面授权,任何组织或个人不得转载、复制或用于其他平台,违者将追究相关责任。

0 0 0 举报
复制成功