/* This file was generated by the Hex-Rays decompiler version 8.3.0.230608.
   Copyright (c) 2007-2021 Hex-Rays <info@hex-rays.com>

   Detected compiler: GNU C++
*/

#include <defs.h>


//-------------------------------------------------------------------------
// Function declarations

__int64 (**init_proc())(void);
void sub_401020();
void sub_401030();
void sub_401040();
void sub_401050();
void sub_401060();
void sub_401070();
void sub_401080();
void sub_401090();
void sub_4010A0();
void sub_4010B0();
void sub_4010C0();
// int puts(const char *s);
// int system(const char *command);
// char *fgets(char *s, int n, FILE *stream);
// __int64 __fastcall gets(_QWORD); weak
// void *malloc(size_t size);
// __int64 __printf_chk(_QWORD, const char *, ...); weak
// int setvbuf(FILE *stream, char *buf, int modes, size_t n);
// unsigned __int64 strtoul(const char *nptr, char **endptr, int base);
// void __noreturn exit(int status);
int __fastcall main(int argc, const char **argv, const char **envp);
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void));
void dl_relocate_static_pie();
FILE **deregister_tm_clones();
__int64 register_tm_clones(void); // weak
FILE **_do_global_dtors_aux();
__int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD); // weak
__int64 __fastcall my_print(const char *a1);
unsigned __int64 init();
unsigned __int64 read_int();
__int64 print_menu();
void __noreturn EZ_WIN(); // weak
int new_meme();
int edit_meme();
int print_meme();
void _libc_csu_fini(void); // idb
void term_proc();
// int __fastcall _libc_start_main(int (__fastcall *main)(int, char **, char **), int argc, char **ubp_av, void (*init)(void), void (*fini)(void), void (*rtld_fini)(void), void *stack_end);
// __int64 _gmon_start__(void); weak

//-------------------------------------------------------------------------
// Data declarations

_UNKNOWN _libc_csu_init;
__int64 (__fastcall *_frame_dummy_init_array_entry)() = &frame_dummy; // weak
__int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)() = &_do_global_dtors_aux; // weak
FILE *_bss_start; // idb
FILE *stdin; // idb
char completed_8059; // weak
__int64 memes; // weak


//----- (0000000000401000) ----------------------------------------------------
__int64 (**init_proc())(void)
{
  __int64 (**result)(void); // rax

  result = &_gmon_start__;
  if ( &_gmon_start__ )
    return (__int64 (**)(void))_gmon_start__();
  return result;
}
// 404098: using guessed type __int64 _gmon_start__(void);

//----- (0000000000401020) ----------------------------------------------------
void sub_401020()
{
  JUMPOUT(0LL);
}
// 401026: control flows out of bounds to 0

//----- (0000000000401030) ----------------------------------------------------
void sub_401030()
{
  sub_401020();
}

//----- (0000000000401040) ----------------------------------------------------
void sub_401040()
{
  sub_401020();
}

//----- (0000000000401050) ----------------------------------------------------
void sub_401050()
{
  sub_401020();
}

//----- (0000000000401060) ----------------------------------------------------
void sub_401060()
{
  sub_401020();
}

//----- (0000000000401070) ----------------------------------------------------
void sub_401070()
{
  sub_401020();
}

//----- (0000000000401080) ----------------------------------------------------
void sub_401080()
{
  sub_401020();
}

//----- (0000000000401090) ----------------------------------------------------
void sub_401090()
{
  sub_401020();
}

//----- (00000000004010A0) ----------------------------------------------------
void sub_4010A0()
{
  sub_401020();
}

//----- (00000000004010B0) ----------------------------------------------------
void sub_4010B0()
{
  sub_401020();
}

//----- (00000000004010C0) ----------------------------------------------------
void sub_4010C0()
{
  sub_401020();
}

//----- (0000000000401170) ----------------------------------------------------
int __fastcall __noreturn main(int argc, const char **argv, const char **envp)
{
  unsigned int v3; // eax

  init(argc, argv, envp);
  while ( 1 )
  {
    while ( 1 )
    {
      while ( 1 )
      {
        print_menu();
        v3 = read_int();
        if ( v3 != 3 )
          break;
        print_meme();
      }
      if ( v3 <= 3 )
        break;
      if ( v3 == 4 )
      {
        puts("Bye bye!");
        exit(0);
      }
LABEL_10:
      puts("Invalid choice!");
    }
    if ( v3 == 1 )
    {
      new_meme();
    }
    else
    {
      if ( v3 != 2 )
        goto LABEL_10;
      edit_meme();
    }
  }
}
// 401350: using guessed type __int64 __fastcall init(_QWORD, _QWORD, _QWORD);
// 4013B0: using guessed type __int64 read_int(void);
// 401410: using guessed type __int64 print_menu(void);
// 4014E0: using guessed type __int64 new_meme(void);
// 401600: using guessed type __int64 edit_meme(void);
// 4016C0: using guessed type __int64 print_meme(void);

//----- (0000000000401210) ----------------------------------------------------
// positive sp value has been detected, the output may be wrong!
void __fastcall __noreturn start(__int64 a1, __int64 a2, void (*a3)(void))
{
  __int64 v3; // rax
  int v4; // esi
  __int64 v5; // [rsp-8h] [rbp-8h] BYREF
  char *retaddr; // [rsp+0h] [rbp+0h] BYREF

  v4 = v5;
  v5 = v3;
  _libc_start_main(
    (int (__fastcall *)(int, char **, char **))main,
    v4,
    &retaddr,
    (void (*)(void))_libc_csu_init,
    _libc_csu_fini,
    a3,
    &v5);
  __halt();
}
// 40121A: positive sp value 8 has been found
// 401221: variable 'v3' is possibly undefined

//----- (0000000000401240) ----------------------------------------------------
void dl_relocate_static_pie()
{
  ;
}

//----- (0000000000401250) ----------------------------------------------------
FILE **deregister_tm_clones()
{
  return &_bss_start;
}

//----- (0000000000401280) ----------------------------------------------------
__int64 register_tm_clones()
{
  return 0LL;
}
// 401280: using guessed type __int64 register_tm_clones();

//----- (00000000004012C0) ----------------------------------------------------
FILE **_do_global_dtors_aux()
{
  FILE **result; // rax

  if ( !completed_8059 )
  {
    result = deregister_tm_clones();
    completed_8059 = 1;
  }
  return result;
}
// 404028: using guessed type char completed_8059;

//----- (00000000004012F0) ----------------------------------------------------
__int64 frame_dummy()
{
  return register_tm_clones();
}
// 401280: using guessed type __int64 register_tm_clones(void);
// 4012F0: using guessed type __int64 frame_dummy();

//----- (0000000000401300) ----------------------------------------------------
__int64 __fastcall my_print(const char *a1)
{
  return __printf_chk(1LL, "Content: %s\n", a1);
}
// 401130: using guessed type __int64 __printf_chk(_QWORD, const char *, ...);

//----- (0000000000401350) ----------------------------------------------------
unsigned __int64 init()
{
  unsigned __int64 v1; // [rsp+8h] [rbp-10h]

  v1 = __readfsqword(0x28u);
  setvbuf(_bss_start, 0LL, 2, 0LL);
  memes = (__int64)malloc(0x40uLL);
  return __readfsqword(0x28u) ^ v1;
}
// 404030: using guessed type __int64 memes;

//----- (00000000004013B0) ----------------------------------------------------
unsigned __int64 read_int()
{
  char _0[24]; // [rsp+0h] [rbp+0h] BYREF
  unsigned __int64 vars18; // [rsp+18h] [rbp+18h]

  vars18 = __readfsqword(0x28u);
  fgets(_0, 16, stdin);
  return strtoul(_0, 0LL, 10);
}

//----- (0000000000401410) ----------------------------------------------------
__int64 print_menu()
{
  puts("===Meme Creator===");
  puts("1. New Meme");
  puts("2. Edit Meme");
  puts("3. Print Meme");
  puts("4. Exit");
  puts("==================");
  return __printf_chk(1LL, "Choice: ");
}
// 401130: using guessed type __int64 __printf_chk(_QWORD, const char *, ...);

//----- (00000000004014A0) ----------------------------------------------------
void __noreturn EZ_WIN()
{
  puts("EAAAAAAAAAAAASYYYYYYYYYYYYY");
  system("/bin/sh");
  exit(0);
}
// 4014A0: using guessed type void __noreturn EZ_WIN();

//----- (00000000004014E0) ----------------------------------------------------
int new_meme()
{
  unsigned int v0; // eax
  unsigned int v1; // r12d
  __int64 v2; // rbx
  _QWORD *v3; // rbp
  _QWORD *v4; // rax

  __printf_chk(1LL, "Enter meme size: ");
  v0 = read_int();
  if ( v0 > 0x200 )
  {
    puts("Please, noone wants to read the entire bee movie script");
    exit(-1);
  }
  v1 = v0;
  v2 = 0LL;
  while ( 1 )
  {
    v3 = (_QWORD *)(memes + v2);
    if ( !*(_QWORD *)(memes + v2) )
      break;
    v2 += 8LL;
    if ( v2 == 64 )
    {
      puts("No more memes for you!");
      exit(-1);
    }
  }
  v4 = malloc(8uLL);
  *v3 = v4;
  *v4 = my_print;
  v4[1] = malloc(v1);
  __printf_chk(1LL, "Enter meme content: ");
  fgets(*(char **)(*(_QWORD *)(memes + v2) + 8LL), v1, stdin);
  return puts("Done!");
}
// 401130: using guessed type __int64 __printf_chk(_QWORD, const char *, ...);
// 404030: using guessed type __int64 memes;

//----- (0000000000401600) ----------------------------------------------------
int edit_meme()
{
  __int64 v0; // rbx

  __printf_chk(1LL, "Index: ");
  v0 = (unsigned int)read_int();
  if ( !*(_QWORD *)(memes + 8 * v0) )
    return puts("There's no meme there!");
  __printf_chk(1LL, "Enter meme content: ");
  gets(*(_QWORD *)(*(_QWORD *)(memes + 8 * v0) + 8LL));
  return puts("Done!");
}
// 401110: using guessed type __int64 __fastcall gets(_QWORD);
// 401130: using guessed type __int64 __printf_chk(_QWORD, const char *, ...);
// 404030: using guessed type __int64 memes;

//----- (00000000004016C0) ----------------------------------------------------
int print_meme()
{
  __int64 v0; // rax

  __printf_chk(1LL, "Index: ");
  v0 = *(_QWORD *)(memes + 8LL * (unsigned int)read_int());
  if ( v0 )
    return (*(__int64 (__fastcall **)(_QWORD))v0)(*(_QWORD *)(v0 + 8));
  else
    return puts("There's no meme there!");
}
// 401130: using guessed type __int64 __printf_chk(_QWORD, const char *, ...);
// 404030: using guessed type __int64 memes;

//----- (0000000000401750) ----------------------------------------------------
void __fastcall _libc_csu_init(unsigned int a1, __int64 a2, __int64 a3)
{
  signed __int64 v4; // rbp
  __int64 i; // rbx

  init_proc();
  v4 = &_do_global_dtors_aux_fini_array_entry - &_frame_dummy_init_array_entry;
  if ( v4 )
  {
    for ( i = 0LL; i != v4; ++i )
      ((void (__fastcall *)(_QWORD, __int64, __int64))*(&_frame_dummy_init_array_entry + i))(a1, a2, a3);
  }
}
// 4012F0: using guessed type __int64 __fastcall frame_dummy(_QWORD, _QWORD, _QWORD);
// 403D88: using guessed type __int64 (__fastcall *_frame_dummy_init_array_entry)();
// 403D90: using guessed type __int64 (__fastcall *_do_global_dtors_aux_fini_array_entry)();

//----- (00000000004017C0) ----------------------------------------------------
void _libc_csu_fini(void)
{
  ;
}

//----- (00000000004017C8) ----------------------------------------------------
void term_proc()
{
  ;
}

// nfuncs=52 queued=30 decompiled=30 lumina nreq=0 worse=0 better=0
// ALL OK, 30 function(s) have been successfully decompiled
