> For the complete documentation index, see [llms.txt](https://simon-6.gitbook.io/simoncyber/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://simon-6.gitbook.io/simoncyber/ctf-writeups/picoctf-2024/reverse-engineering/factcheck-medium.md).

# FactCheck (Medium)

<figure><img src="/files/R79pHGs9ugaqYp0WhawW" alt=""><figcaption></figcaption></figure>

***

I put it into decompiler Explorer, and I got this long list of source code:

### The Source Code

```
  
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  std::allocator<char>::allocator();
                    // try { // try from 001012cf to 001012d3 has its CatchHandler @ 00101975
  std::string::string(local_248,"picoCTF{wELF_d0N3_mate_",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 0010130a to 0010130e has its CatchHandler @ 00101996
  std::string::string(local_228,"5",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101345 to 00101349 has its CatchHandler @ 001019b1
  std::string::string(local_208,"5",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101380 to 00101384 has its CatchHandler @ 001019cc
  std::string::string(local_1e8,"7",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 001013bb to 001013bf has its CatchHandler @ 001019e7
  std::string::string(local_1c8,"3",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 001013f6 to 001013fa has its CatchHandler @ 00101a02
  std::string::string(local_1a8,"0",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101431 to 00101435 has its CatchHandler @ 00101a1d
  std::string::string(local_188,"5",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 0010146c to 00101470 has its CatchHandler @ 00101a38
  std::string::string(local_168,"a",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 001014a7 to 001014ab has its CatchHandler @ 00101a53
  std::string::string(local_148,"e",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 001014e2 to 001014e6 has its CatchHandler @ 00101a6e
  std::string::string(local_128,"f",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 0010151d to 00101521 has its CatchHandler @ 00101a89
  std::string::string(local_108,"d",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101558 to 0010155c has its CatchHandler @ 00101aa4
  std::string::string(local_e8,"b",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101593 to 00101597 has its CatchHandler @ 00101abf
  std::string::string(local_c8,"9",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 001015ce to 001015d2 has its CatchHandler @ 00101ada
  std::string::string(local_a8,"6",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101606 to 0010160a has its CatchHandler @ 00101af5
  std::string::string(local_88,"d",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 0010163e to 00101642 has its CatchHandler @ 00101b0d
  std::string::string(local_68,"7",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
                    // try { // try from 00101676 to 0010167a has its CatchHandler @ 00101b25
  std::string::string(local_48,"8",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
                    // try { // try from 00101699 to 0010185f has its CatchHandler @ 00101b3d
  pcVar2 = (char *)std::string::operator[]((ulong)local_208);
  if (*pcVar2 < 'B') {
    std::string::operator+=(local_248,local_c8);
  }
  pcVar2 = (char *)std::string::operator[]((ulong)local_a8);
  if (*pcVar2 != 'A') {
    std::string::operator+=(local_248,local_68);
  }
  pcVar2 = (char *)std::string::operator[]((ulong)local_1c8);
  cVar1 = *pcVar2;
  pcVar2 = (char *)std::string::operator[]((ulong)local_148);
  if ((int)cVar1 - (int)*pcVar2 == 3) {
    std::string::operator+=(local_248,local_1c8);
  }
  std::string::operator+=(local_248,local_1e8);
  std::string::operator+=(local_248,local_188);
  pcVar2 = (char *)std::string::operator[]((ulong)local_168);
  if (*pcVar2 == 'G') {
    std::string::operator+=(local_248,local_168);
  }
  std::string::operator+=(local_248,local_1a8);
  std::string::operator+=(local_248,local_88);
  std::string::operator+=(local_248,local_228);
  std::string::operator+=(local_248,local_128);
  std::string::operator+=(local_248,'}');
  std::string::~string(local_48);
  std::string::~string(local_68);
  std::string::~string(local_88);
  std::string::~string(local_a8);
  std::string::~string(local_c8);
  std::string::~string(local_e8);
  std::string::~string(local_108);
  std::string::~string(local_128);
  std::string::~string(local_148);
  std::string::~string(local_168);
  std::string::~string(local_188);
  std::string::~string(local_1a8);
  std::string::~string(local_1c8);
  std::string::~string(local_1e8);
  std::string::~string(local_208);
  std::string::~string(local_228);
  std::string::~string(local_248);
  if (local_20 == *(long *)(in_FS_OFFSET + 0x28)) {
    return 0;
  }
                    // WARNING: Subroutine does not return
  __stack_chk_fail();
}



// __static_initialization_and_destruction_0(int, int)

void __static_initialization_and_destruction_0(int param_1,int param_2)

{
  if ((param_1 == 1) && (param_2 == 0xffff)) {
    std::ios_base::Init::Init((Init *)&std::__ioinit);
    __cxa_atexit(std::ios_base::Init::~Init,&std::__ioinit,&__dso_handle);
  }
  return;
}



void _GLOBAL__sub_I_main(void)

{
  __static_initialization_and_destruction_0(1,0xffff);
  return;
}



void __libc_csu_init(EVP_PKEY_CTX *param_1,undefined8 param_2,undefined8 param_3)

{
  long lVar1;
  
  _init(param_1);
  lVar1 = 0;
  do {
    (*(code *)(&__frame_dummy_init_array_entry)[lVar1])((ulong)param_1 & 0xffffffff,param_2,param_3)
    ;
    lVar1 = lVar1 + 1;
  } while (lVar1 != 2);
  return;
}



void __libc_csu_fini(void)

{
  return;
}



void _fini(void)

{
  return;
}




```

However, this part of the source code I don't this does a great job at least using Ghidra. Hex, we'll being using Hex-Rays instead.

```

  v39 = __readfsqword(0x28u);
  std::allocator<char>::allocator(&v21, argv, envp);
  std::string::basic_string(v22, "picoCTF{wELF_d0N3_mate_", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "picoCTF{wELF_d0N3_mate_", v3);
  std::string::basic_string(v23, "5", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "5", v4);
  std::string::basic_string(v24, "5", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "5", v5);
  std::string::basic_string(v25, "7", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "7", v6);
  std::string::basic_string(v26, "3", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "3", v7);
  std::string::basic_string(v27, "0", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "0", v8);
  std::string::basic_string(v28, "5", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "5", v9);
  std::string::basic_string(v29, "a", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "a", v10);
  std::string::basic_string(v30, "e", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "e", v11);
  std::string::basic_string(v31, "f", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "f", v12);
  std::string::basic_string(v32, "d", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "d", v13);
  std::string::basic_string(v33, "b", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "b", v14);
  std::string::basic_string(v34, "9", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "9", v15);
  std::string::basic_string(v35, "6", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "6", v16);
  std::string::basic_string(v36, "d", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "d", v17);
  std::string::basic_string(v37, "7", &v21);
  std::allocator<char>::~allocator(&v21);
  std::allocator<char>::allocator(&v21, "7", v18);
  std::string::basic_string(v38, "8", &v21);
  std::allocator<char>::~allocator(&v21);
  if ( *(char *)std::string::operator[](v24, 0) <= 65 )
    std::string::operator+=(v22, v34);
  if ( *(_BYTE *)std::string::operator[](v35, 0) != 65 )
    std::string::operator+=(v22, v37);
  if ( "Hello" == "World" )
    std::string::operator+=(v22, v25);
  v19 = *(char *)std::string::operator[](v26, 0);
  if ( v19 - *(char *)std::string::operator[](v30, 0) == 3 )
    std::string::operator+=(v22, v26);
  std::string::operator+=(v22, v25);
  std::string::operator+=(v22, v28);
  if ( *(_BYTE *)std::string::operator[](v29, 0) == 71 )
    std::string::operator+=(v22, v29);
  std::string::operator+=(v22, v27);
  std::string::operator+=(v22, v36);
  std::string::operator+=(v22, v23);
  std::string::operator+=(v22, v31);
  std::string::operator+=(v22, 125);
  std::string::~string(v38);
  std::string::~string(v37);
  std::string::~string(v36);
  std::string::~string(v35);
  std::string::~string(v34);
  std::string::~string(v33);
  std::string::~string(v32);
  std::string::~string(v31);
  std::string::~string(v30);
  std::string::~string(v29);
  std::string::~string(v28);
  std::string::~string(v27);
  std::string::~string(v26);
  std::string::~string(v25);
  std::string::~string(v24);
  std::string::~string(v23);
  std::string::~string(v22);
  return 0;
```

### Solving It

We can see from the first few blocks of code that it actually gives us a part of the flag.&#x20;

```
  local_20 = *(long *)(in_FS_OFFSET + 0x28);
  std::allocator<char>::allocator();
                    // try { // try from 001012cf to 001012d3 has its CatchHandler @ 00101975
  std::string::string(local_248,"picoCTF{wELF_d0N3_mate_",&local_249);
  std::allocator<char>::~allocator((allocator<char> *)&local_249);
  std::allocator<char>::allocator();
```

However, that's just a part of the flag, we'll need to create a simple python script to really finish.

We first declare the variables:

```
v22 = 'picoCTF{wELF_d0N3_mate_'
v23 = '5'
v24 = '5'
v25 = '7'
v26 = '3'
v27 = '0'
v28 = '5'
v29 = 'a'
v30 = 'e'
v31 = 'f'
v32 = 'd'
v33 = 'b'
v34 = '9'
v35 = '6'
v36 = 'd'
v37 = '7'
v38 = '8'
```

Next, we need to add on the if statements.&#x20;

```python
  if ( *(char *)std::string::operator[](v24, 0) <= 65 )
    std::string::operator+=(v22, v34);
  if ( *(_BYTE *)std::string::operator[](v35, 0) != 65 )
    std::string::operator+=(v22, v37);
  if ( "Hello" == "World" )
    std::string::operator+=(v22, v25);
  v19 = *(char *)std::string::operator[](v26, 0);
  if ( v19 - *(char *)std::string::operator[](v30, 0) == 3 )
    std::string::operator+=(v22, v26);
  std::string::operator+=(v22, v25);
  std::string::operator+=(v22, v28);
  if ( *(_BYTE *)std::string::operator[](v29, 0) == 71 )
    std::string::operator+=(v22, v29);
    
// this becomes

if(ord(v24) <= 65):
    v22 += v34
if(ord(v35) != 65):
    v22 += v37
if("Hello" == "World"):
    v22 +=v25
v19 = v26
if(ord(v19) - ord(v30) == 3):
    v22 += v26
v22 += v25
v22 += v28
if(ord(v29) == 71):
    v22 += v29

```

Lastly, we have the rest:

```python
  std::string::operator+=(v22, v27);
  std::string::operator+=(v22, v36);
  std::string::operator+=(v22, v23);
  std::string::operator+=(v22, v31);
  std::string::operator+=(v22, 125);
  
// this becomes

v22 += v27
v22 += v36
v22 += v23
v22 += v31
v22 += chr(125)
```

For the total script: it would be:&#x20;

```

v22 = 'picoCTF{wELF_d0N3_mate_'
v23 = '5'
v24 = '5'
v25 = '7'
v26 = '3'
v27 = '0'
v28 = '5'
v29 = 'a'
v30 = 'e'
v31 = 'f'
v32 = 'd'
v33 = 'b'
v34 = '9'
v35 = '6'
v36 = 'd'
v37 = '7'
v38 = '8'

if(ord(v24) <= 65):
    v22 += v34
if(ord(v35) != 65):
    v22 += v37
if("Hello" == "World"):
    v22 +=v25

v19 = v26

if(ord(v19) - ord(v30) == 3):
    v22 += v26

v22 += v25
v22 += v28

if(ord(v29) == 71):
    v22 += v29

v22 += v27
v22 += v36
v22 += v23
v22 += v31
v22 += chr(125)

print(v22)

```

It prints out picoCTF{wELF\_d0N3\_mate\_97750d5f}Q
