// File: DimitriFourny[P]uaf_replacer/main.cc
// Function: get_type_name[abi:cxx11](rapidjson::GenericDocument<rapidjson::UTF8<char>, rapidjson::MemoryPoolAllocator<rapidjson::CrtAllocator>, rapidjson::CrtAllocator> const&, char const*)
std::string get_type_name(const rapidjson::Document& document, 
                          const char* type_id) {
  std::string type_name = std::string("#") + type_id;
  if (!document.HasMember(type_id)) {
    return type_name;
  }

  if (document[type_id].HasMember("name")) {
    return std::string(document[type_id]["name"].GetString());
  } 

  if (document[type_id].HasMember("type")) {
    std::string type = document[type_id]["type"].GetString();

    // pointer
    if (type == "pointer" && document[type_id].HasMember("type_id")) {
      type_id = document[type_id]["type_id"].GetString();
      return get_type_name(document, type_id) + "*";
    }

    // const
    if (type == "const" && document[type_id].HasMember("type_id")) {
      type_id = document[type_id]["type_id"].GetString();
      return "const " + get_type_name(document, type_id);
    }

    // array
    if (type == "array" && document[type_id].HasMember("type_id")) {
      std::string suffix = "[]";
      if (document[type_id].HasMember("count")) {
        uint64_t count = document[type_id]["count"].GetUint64();
        suffix = "[" + std::to_string(count) + "]";
      }

      type_id = document[type_id]["type_id"].GetString();
      return get_type_name(document, type_id) + suffix;
    }
  }

  return type_name;
}

// Assembly:
subq $0x2d8, %rsp            # imm = 0x2D8
movq %rdi, 0x130(%rsp)
movq %rdi, %rax
movq %rax, 0x138(%rsp)
movq %rdi, 0x2d0(%rsp)
movq %rsi, 0x2c8(%rsp)
movq %rdx, 0x2c0(%rsp)
leaq 0x27f(%rsp), %rdi
movq %rdi, 0x140(%rsp)
callq 0x2350
movq 0x140(%rsp), %rdx
leaq 0xba31(%rip), %rsi      # 0xe0b7
leaq 0x280(%rsp), %rdi
callq 0x6b90
jmp 0x2695
movq 0x2c0(%rsp), %rdx
leaq 0x2a0(%rsp), %rdi
leaq 0x280(%rsp), %rsi
callq 0x6b40
jmp 0x26b4
leaq 0x280(%rsp), %rdi
callq 0x2130
leaq 0x27f(%rsp), %rdi
callq 0x2210
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6c50
movb %al, 0x12f(%rsp)
jmp 0x26ec
movb 0x12f(%rsp), %al
testb $0x1, %al
jne 0x2784
jmp 0x26fd
movq 0x130(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x2110
movl $0x1, 0x268(%rsp)
jmp 0x2fef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
jmp 0x2759
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x280(%rsp), %rdi
callq 0x2130
leaq 0x27f(%rsp), %rdi
callq 0x2210
jmp 0x3019
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
jmp 0x300c
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x120(%rsp)
jmp 0x27a3
movq 0x120(%rsp), %rdi
leaq 0xb907(%rip), %rsi      # 0xe0b9
callq 0x6c50
movb %al, 0x11f(%rsp)
jmp 0x27c0
movb 0x11f(%rsp), %al
testb $0x1, %al
jne 0x27d0
jmp 0x289b
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x110(%rsp)
jmp 0x27ef
movq 0x110(%rsp), %rdi
leaq 0xb8bb(%rip), %rsi      # 0xe0b9
callq 0x6ca0
movq %rax, 0x108(%rsp)
jmp 0x280d
movq 0x108(%rsp), %rdi
callq 0x6cd0
movq %rax, 0x100(%rsp)
jmp 0x2824
leaq 0x267(%rsp), %rdi
movq %rdi, 0xf8(%rsp)
callq 0x2350
movq 0x130(%rsp), %rdi
movq 0x100(%rsp), %rsi
movq 0xf8(%rsp), %rdx
callq 0x6b90
jmp 0x2858
leaq 0x267(%rsp), %rdi
callq 0x2210
movl $0x1, 0x268(%rsp)
jmp 0x2fef
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x267(%rsp), %rdi
callq 0x2210
jmp 0x300c
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0xf0(%rsp)
jmp 0x28ba
movq 0xf0(%rsp), %rdi
leaq 0xb7f5(%rip), %rsi      # 0xe0be
callq 0x6c50
movb %al, 0xef(%rsp)
jmp 0x28d7
movb 0xef(%rsp), %al
testb $0x1, %al
jne 0x28e7
jmp 0x2fcf
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0xe0(%rsp)
jmp 0x2906
movq 0xe0(%rsp), %rdi
leaq 0xb7a9(%rip), %rsi      # 0xe0be
callq 0x6ca0
movq %rax, 0xd8(%rsp)
jmp 0x2924
movq 0xd8(%rsp), %rdi
callq 0x6cd0
movq %rax, 0xd0(%rsp)
jmp 0x293b
leaq 0x23f(%rsp), %rdi
movq %rdi, 0xc8(%rsp)
callq 0x2350
movq 0xd0(%rsp), %rsi
movq 0xc8(%rsp), %rdx
leaq 0x240(%rsp), %rdi
callq 0x6b90
jmp 0x296f
leaq 0x23f(%rsp), %rdi
callq 0x2210
leaq 0xb740(%rip), %rsi      # 0xe0c3
leaq 0x240(%rsp), %rdi
callq 0x6d50
movb %al, 0xc7(%rsp)
jmp 0x2999
movb 0xc7(%rsp), %al
testb $0x1, %al
jne 0x29a9
jmp 0x2b18
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0xb8(%rsp)
jmp 0x29c8
movq 0xb8(%rsp), %rdi
leaq 0xb6f4(%rip), %rsi      # 0xe0cb
callq 0x6c50
movb %al, 0xb7(%rsp)
jmp 0x29e5
movb 0xb7(%rsp), %al
testb $0x1, %al
jne 0x29f5
jmp 0x2b18
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0xa8(%rsp)
jmp 0x2a14
movq 0xa8(%rsp), %rdi
leaq 0xb6a8(%rip), %rsi      # 0xe0cb
callq 0x6ca0
movq %rax, 0xa0(%rsp)
jmp 0x2a32
movq 0xa0(%rsp), %rdi
callq 0x6cd0
movq %rax, 0x98(%rsp)
jmp 0x2a49
movq 0x98(%rsp), %rax
movq %rax, 0x2c0(%rsp)
movq 0x2c8(%rsp), %rsi
movq 0x2c0(%rsp), %rdx
leaq 0x218(%rsp), %rdi
callq 0x2630
jmp 0x2a78
movq 0x130(%rsp), %rdi
leaq 0xb64c(%rip), %rdx      # 0xe0d3
leaq 0x218(%rsp), %rsi
callq 0x6b40
jmp 0x2a96
leaq 0x218(%rsp), %rdi
callq 0x2130
movl $0x1, 0x268(%rsp)
jmp 0x2fa4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x23f(%rsp), %rdi
callq 0x2210
jmp 0x300c
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
jmp 0x2fc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x218(%rsp), %rdi
callq 0x2130
jmp 0x2fc0
leaq 0xb5b6(%rip), %rsi      # 0xe0d5
leaq 0x240(%rsp), %rdi
callq 0x6d50
movb %al, 0x97(%rsp)
jmp 0x2b35
movb 0x97(%rsp), %al
testb $0x1, %al
jne 0x2b45
jmp 0x2c63
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x88(%rsp)
jmp 0x2b64
movq 0x88(%rsp), %rdi
leaq 0xb558(%rip), %rsi      # 0xe0cb
callq 0x6c50
movb %al, 0x87(%rsp)
jmp 0x2b81
movb 0x87(%rsp), %al
testb $0x1, %al
jne 0x2b91
jmp 0x2c63
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x78(%rsp)
jmp 0x2bad
movq 0x78(%rsp), %rdi
leaq 0xb512(%rip), %rsi      # 0xe0cb
callq 0x6ca0
movq %rax, 0x70(%rsp)
jmp 0x2bc5
movq 0x70(%rsp), %rdi
callq 0x6cd0
movq %rax, 0x68(%rsp)
jmp 0x2bd6
movq 0x68(%rsp), %rax
movq %rax, 0x2c0(%rsp)
movq 0x2c8(%rsp), %rsi
movq 0x2c0(%rsp), %rdx
leaq 0x1f8(%rsp), %rdi
callq 0x2630
jmp 0x2c02
movq 0x130(%rsp), %rdi
leaq 0xb4ca(%rip), %rsi      # 0xe0db
leaq 0x1f8(%rsp), %rdx
callq 0x6d80
jmp 0x2c20
leaq 0x1f8(%rsp), %rdi
callq 0x2130
movl $0x1, 0x268(%rsp)
jmp 0x2fa4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x1f8(%rsp), %rdi
callq 0x2130
jmp 0x2fc0
leaq 0xb478(%rip), %rsi      # 0xe0e2
leaq 0x240(%rsp), %rdi
callq 0x6d50
movb %al, 0x67(%rsp)
jmp 0x2c7d
movb 0x67(%rsp), %al
testb $0x1, %al
jne 0x2c8a
jmp 0x2f99
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x58(%rsp)
jmp 0x2ca6
movq 0x58(%rsp), %rdi
leaq 0xb419(%rip), %rsi      # 0xe0cb
callq 0x6c50
movb %al, 0x57(%rsp)
jmp 0x2cbd
movb 0x57(%rsp), %al
testb $0x1, %al
jne 0x2cca
jmp 0x2f99
leaq 0x1d7(%rsp), %rdi
movq %rdi, 0x48(%rsp)
callq 0x2350
movq 0x48(%rsp), %rdx
leaq 0xb400(%rip), %rsi      # 0xe0e8
leaq 0x1d8(%rsp), %rdi
callq 0x6b90
jmp 0x2cf7
leaq 0x1d7(%rsp), %rdi
callq 0x2210
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x40(%rsp)
jmp 0x2d20
movq 0x40(%rsp), %rdi
leaq 0xb3bf(%rip), %rsi      # 0xe0eb
callq 0x6c50
movb %al, 0x3f(%rsp)
jmp 0x2d37
movb 0x3f(%rsp), %al
testb $0x1, %al
jne 0x2d44
jmp 0x2eb2
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x30(%rsp)
jmp 0x2d60
movq 0x30(%rsp), %rdi
leaq 0xb37f(%rip), %rsi      # 0xe0eb
callq 0x6ca0
movq %rax, 0x28(%rsp)
jmp 0x2d78
movq 0x28(%rsp), %rdi
callq 0x6dd0
movq %rax, 0x20(%rsp)
jmp 0x2d89
movq 0x20(%rsp), %rax
movq %rax, 0x1c8(%rsp)
movq 0x1c8(%rsp), %rsi
leaq 0x168(%rsp), %rdi
callq 0x6e20
jmp 0x2dad
leaq 0xb33d(%rip), %rsi      # 0xe0f1
leaq 0x188(%rsp), %rdi
leaq 0x168(%rsp), %rdx
callq 0x6d80
jmp 0x2dcb
leaq 0xd963(%rip), %rdx      # 0x10735
leaq 0x1a8(%rsp), %rdi
leaq 0x188(%rsp), %rsi
callq 0x6b40
jmp 0x2de9
leaq 0x1d8(%rsp), %rdi
leaq 0x1a8(%rsp), %rsi
callq 0x2290
leaq 0x1a8(%rsp), %rdi
callq 0x2130
leaq 0x188(%rsp), %rdi
callq 0x2130
leaq 0x168(%rsp), %rdi
callq 0x2130
jmp 0x2eb2
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x1d7(%rsp), %rdi
callq 0x2210
jmp 0x2fc0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
jmp 0x2f8a
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
jmp 0x2ea0
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x188(%rsp), %rdi
callq 0x2130
leaq 0x168(%rsp), %rdi
callq 0x2130
jmp 0x2f8a
movq 0x2c8(%rsp), %rdi
movq 0x2c0(%rsp), %rsi
callq 0x6ca0
movq %rax, 0x18(%rsp)
jmp 0x2ece
movq 0x18(%rsp), %rdi
leaq 0xb1f1(%rip), %rsi      # 0xe0cb
callq 0x6ca0
movq %rax, 0x10(%rsp)
jmp 0x2ee6
movq 0x10(%rsp), %rdi
callq 0x6cd0
movq %rax, 0x8(%rsp)
jmp 0x2ef7
movq 0x8(%rsp), %rax
movq %rax, 0x2c0(%rsp)
movq 0x2c8(%rsp), %rsi
movq 0x2c0(%rsp), %rdx
leaq 0x148(%rsp), %rdi
callq 0x2630
jmp 0x2f23
movq 0x130(%rsp), %rdi
leaq 0x148(%rsp), %rsi
leaq 0x1d8(%rsp), %rdx
callq 0x6f20
jmp 0x2f42
leaq 0x148(%rsp), %rdi
callq 0x2130
movl $0x1, 0x268(%rsp)
leaq 0x1d8(%rsp), %rdi
callq 0x2130
jmp 0x2fa4
movq %rax, %rcx
movl %edx, %eax
movq %rcx, 0x270(%rsp)
movl %eax, 0x26c(%rsp)
leaq 0x148(%rsp), %rdi
callq 0x2130
leaq 0x1d8(%rsp), %rdi
callq 0x2130
jmp 0x2fc0
movl $0x0, 0x268(%rsp)
leaq 0x240(%rsp), %rdi
callq 0x2130
movl 0x268(%rsp), %eax
testl %eax, %eax
jne 0x2fef
jmp 0x2fbe
jmp 0x2fcf
leaq 0x240(%rsp), %rdi
callq 0x2130
jmp 0x300c
movq 0x130(%rsp), %rdi
leaq 0x2a0(%rsp), %rsi
callq 0x2110
movl $0x1, 0x268(%rsp)
leaq 0x2a0(%rsp), %rdi
callq 0x2130
movq 0x138(%rsp), %rax
addq $0x2d8, %rsp            # imm = 0x2D8
retq
leaq 0x2a0(%rsp), %rdi
callq 0x2130
movq 0x270(%rsp), %rdi
callq 0x2340
nopw %cs:(%rax,%rax)