Search code examples
assemblyx86-64reverse-engineeringelfdecompiling

How to decompile 64-bit binary to retrieve content?


The binary file can be found here: BinaryFile

I'm trying to decompile the assembly code to C/ASM to find the hidden content using reverse engineering. But given binary file is quite complex or may be i'm unable to find a tweak here.

File info:

ELF 64-bit LSB executable, x86-64, version 1 (GNU/Linux) statically linked, for GNU/Linux 2.6.32 not stripped

I assembled the pseudo code for the main logic of code but unable to follow the control flow from there as i'm newbie to this kind of syntax.

 function _start {
     libc_start_main(0x400aee, stack[0], &stack[0], 0x401890, 
                     0x401920, rdx);
     asm { hlt };
     rax = loc_4009fb();
     return rax;
 }

Below is the assembly code for all procedures in a above pseudo code..

_start:
       xor        ebp, ebp                                    
       mov        r9, rdx                                     
       pop        rsi                                         
       mov        rdx, rsp                                    
       and        rsp, 0xfffffffffffffff0
       push       rax
       push       rsp
       mov        r8, __libc_csu_fini                         
       mov        rcx, __libc_csu_init                        
       mov        rdi, main                                           
       call       __libc_start_main                           
       hlt
       ; endp
       align      512  


libc_start_main:
       push       r12                                         
       push       rbp
       xor        eax, eax
       push       rbx
       mov        rbp, rdx
       mov        r12, rcx
       cpuid
       sub        rsp, 0x20
       cmp        ebx, 0x756e6547
       mov        r11d, esi
       sete       sil
       cmp        ecx, 0x6c65746e
       mov        dword [dword_6ce684], eax           ; dword_6ce684
       sete       al
       mov        r10, rdi
       mov        dword [rsp+0x38+var_28], 0x0
       test       sil, al
       mov        dword [rsp+0x38+var_24], 0x0
       mov        dword [rsp+0x38+var_20], 0x0
       je         loc_40110a   

If I run objdump -M intel -D on the file the main function appears as:

0000000000400aee <main>:
  400aee:       55                      push   rbp
  400aef:       48 89 e5                mov    rbp,rsp
  400af2:       53                      push   rbx
  400af3:       48 83 ec 38             sub    rsp,0x38
  400af7:       64 48 8b 04 25 28 00    mov    rax,QWORD PTR fs:0x28
  400afe:       00 00
  400b00:       48 89 45 e8             mov    QWORD PTR [rbp-0x18],rax
  400b04:       31 c0                   xor    eax,eax
  400b06:       48 89 e0                mov    rax,rsp
  400b09:       48 89 c3                mov    rbx,rax
  400b0c:       c7 45 cc 15 00 00 00    mov    DWORD PTR [rbp-0x34],0x15
  400b13:       8b 45 cc                mov    eax,DWORD PTR [rbp-0x34]
  400b16:       48 63 d0                movsxd rdx,eax
  400b19:       48 83 ea 01             sub    rdx,0x1
  400b1d:       48 89 55 d0             mov    QWORD PTR [rbp-0x30],rdx
  400b21:       48 63 d0                movsxd rdx,eax
  400b24:       49 89 d0                mov    r8,rdx
  400b27:       41 b9 00 00 00 00       mov    r9d,0x0
  400b2d:       48 63 d0                movsxd rdx,eax
  400b30:       48 89 d6                mov    rsi,rdx
  400b33:       bf 00 00 00 00          mov    edi,0x0
  400b38:       48 98                   cdqe
  400b3a:       48 c1 e0 02             shl    rax,0x2
  400b3e:       48 8d 50 03             lea    rdx,[rax+0x3]
  400b42:       b8 10 00 00 00          mov    eax,0x10
  400b47:       48 83 e8 01             sub    rax,0x1
  400b4b:       48 01 d0                add    rax,rdx
  400b4e:       b9 10 00 00 00          mov    ecx,0x10
  400b53:       ba 00 00 00 00          mov    edx,0x0
  400b58:       48 f7 f1                div    rcx
  400b5b:       48 6b c0 10             imul   rax,rax,0x10
  400b5f:       48 29 c4                sub    rsp,rax
  400b62:       48 89 e0                mov    rax,rsp
  400b65:       48 83 c0 03             add    rax,0x3
  400b69:       48 c1 e8 02             shr    rax,0x2
  400b6d:       48 c1 e0 02             shl    rax,0x2
  400b71:       48 89 45 d8             mov    QWORD PTR [rbp-0x28],rax
  400b75:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400b79:       c7 00 91 23 00 00       mov    DWORD PTR [rax],0x2391
  400b7f:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400b83:       c7 40 04 9d 23 00 00    mov    DWORD PTR [rax+0x4],0x239d
  400b8a:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400b8e:       c7 40 08 9d 23 00 00    mov    DWORD PTR [rax+0x8],0x239d
  400b95:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400b99:       c7 40 0c 99 23 00 00    mov    DWORD PTR [rax+0xc],0x2399
  400ba0:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400ba4:       c7 40 10 9c 23 00 00    mov    DWORD PTR [rax+0x10],0x239c
  400bab:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400baf:       c7 40 14 63 23 00 00    mov    DWORD PTR [rax+0x14],0x2363
  400bb6:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bba:       c7 40 18 58 23 00 00    mov    DWORD PTR [rax+0x18],0x2358
  400bc1:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bc5:       c7 40 1c 58 23 00 00    mov    DWORD PTR [rax+0x1c],0x2358
  400bcc:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bd0:       c7 40 20 90 23 00 00    mov    DWORD PTR [rax+0x20],0x2390
  400bd7:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bdb:       c7 40 24 98 23 00 00    mov    DWORD PTR [rax+0x24],0x2398
  400be2:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400be6:       c7 40 28 98 23 00 00    mov    DWORD PTR [rax+0x28],0x2398
  400bed:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bf1:       c7 40 2c 57 23 00 00    mov    DWORD PTR [rax+0x2c],0x2357
  400bf8:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400bfc:       c7 40 30 90 23 00 00    mov    DWORD PTR [rax+0x30],0x2390
  400c03:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c07:       c7 40 34 95 23 00 00    mov    DWORD PTR [rax+0x34],0x2395
  400c0e:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c12:       c7 40 38 58 23 00 00    mov    DWORD PTR [rax+0x38],0x2358
  400c19:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c1d:       c7 40 3c 77 23 00 00    mov    DWORD PTR [rax+0x3c],0x2377
  400c24:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c28:       c7 40 40 5e 23 00 00    mov    DWORD PTR [rax+0x40],0x235e
  400c2f:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c33:       c7 40 44 80 23 00 00    mov    DWORD PTR [rax+0x44],0x2380
  400c3a:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c3e:       c7 40 48 7a 23 00 00    mov    DWORD PTR [rax+0x48],0x237a
  400c45:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c49:       c7 40 4c 81 23 00 00    mov    DWORD PTR [rax+0x4c],0x2381
  400c50:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c54:       c7 40 50 a3 23 00 00    mov    DWORD PTR [rax+0x50],0x23a3
  400c5b:       8b 45 cc                mov    eax,DWORD PTR [rbp-0x34]
  400c5e:       48 98                   cdqe
  400c60:       48 89 c7                mov    rdi,rax
  400c63:       e8 98 e4 01 00          call   41f100 <__libc_malloc>
  400c68:       48 83 c0 01             add    rax,0x1
  400c6c:       48 89 45 e0             mov    QWORD PTR [rbp-0x20],rax
  400c70:       c7 45 c8 00 00 00 00    mov    DWORD PTR [rbp-0x38],0x0
  400c77:       eb 24                   jmp    400c9d <main+0x1af>
  400c79:       8b 45 c8                mov    eax,DWORD PTR [rbp-0x38]
  400c7c:       48 63 d0                movsxd rdx,eax
  400c7f:       48 8b 45 e0             mov    rax,QWORD PTR [rbp-0x20]
  400c83:       48 8d 0c 02             lea    rcx,[rdx+rax*1]
  400c87:       48 8b 45 d8             mov    rax,QWORD PTR [rbp-0x28]
  400c8b:       8b 55 c8                mov    edx,DWORD PTR [rbp-0x38]
  400c8e:       48 63 d2                movsxd rdx,edx
  400c91:       8b 04 90                mov    eax,DWORD PTR [rax+rdx*4]
  400c94:       83 e8 29                sub    eax,0x29
  400c97:       88 01                   mov    BYTE PTR [rcx],al
  400c99:       83 45 c8 01             add    DWORD PTR [rbp-0x38],0x1
  400c9d:       8b 45 c8                mov    eax,DWORD PTR [rbp-0x38]
  400ca0:       3b 45 cc                cmp    eax,DWORD PTR [rbp-0x34]
  400ca3:       7c d4                   jl     400c79 <main+0x18b>
  400ca5:       8b 45 c8                mov    eax,DWORD PTR [rbp-0x38]
  400ca8:       48 63 d0                movsxd rdx,eax
  400cab:       48 8b 45 e0             mov    rax,QWORD PTR [rbp-0x20]
  400caf:       48 01 d0                add    rax,rdx
  400cb2:       c6 00 00                mov    BYTE PTR [rax],0x0
  400cb5:       b8 29 23 00 00          mov    eax,0x2329
  400cba:       48 89 dc                mov    rsp,rbx
  400cbd:       48 8b 7d e8             mov    rdi,QWORD PTR [rbp-0x18]
  400cc1:       64 48 33 3c 25 28 00    xor    rdi,QWORD PTR fs:0x28
  400cc8:       00 00
  400cca:       74 05                   je     400cd1 <main+0x1e3>
  400ccc:       e8 cf 2b 04 00          call   4438a0 <__stack_chk_fail>
  400cd1:       48 8b 5d f8             mov    rbx,QWORD PTR [rbp-0x8]
  400cd5:       c9                      leave
  400cd6:       c3                      ret
  400cd7:       66 0f 1f 84 00 00 00    nop    WORD PTR [rax+rax*1+0x0]
  400cde:       00 00          

I'm trying to find hidden info which is encoded in main function of the program. I also know that this program is having conditions based on value stored in the array and from it is calling another function or returning values but unable to crack it..


Solution

  • I added to your question the disassembly of the function main using the command:

    objdump -D -M intel addbin.64 
    

    addbin.64 was the name of the binary you linked to in the question. You can start your analysis in main as everything else is the C runtime setting up the program.

    My first impression of the code in main was that there were many MOVs to build data on the stack. Rather than try to figure out what all that code did I kept scanning the code until I saw:

      400c60:       48 89 c7                mov    rdi,rax
      400c63:       e8 98 e4 01 00          call   41f100 <__libc_malloc>
      400c68:       48 83 c0 01             add    rax,0x1
      400c6c:       48 89 45 e0             mov    QWORD PTR [rbp-0x20],rax
    

    My gut instinct told me that if I were going to hide something it would probably be inside the malloc'ed buffer. A quick glance at the code below the malloc suggested that an algorithm (some form of decryption) was being used to convert the data placed on the stack into some kind of data in the malloc'ed buffer. Rather than try to figure out the algorithm I decided that I'd use the GDB debugger to tell me the address that malloc returned plus 1. The return value (address) of malloc will be in RAX. They added 1 to it so I figured that is the beginning of the data they would generate. I then decided I'd find the address where main returns:

      400cd5:       c9                      leave
      400cd6:       c3                      ret
    

    I ran GDB1 and set a breakpoint at 0x400c6c (just after add rax,0x1) and a breakpoint at 400cd6 at the ret. My hope was that when main was finished that there would be some kind of secret data in the memory allocated on the heap.

    My GDB session is below:

    gdb ./addbin.64
    GNU gdb (GDB) 8.1.0.20180206-git
    Copyright (C) 2018 Free Software Foundation, Inc.
    License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
    This is free software: you are free to change and redistribute it.
    There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
    and "show warranty" for details.
    This GDB was configured as "x86_64-pc-linux-gnu".
    Type "show configuration" for configuration details.
    For bug reporting instructions, please see:
    <http://www.gnu.org/software/gdb/bugs/>.
    Find the GDB manual and other documentation resources online at:
    <http://www.gnu.org/software/gdb/documentation/>.
    For help, type "help".
    Type "apropos word" to search for commands related to "word"...
    Reading symbols from ./addbin.64...(no debugging symbols found)...done.
    (gdb) b *0x400cd6
    Breakpoint 1 at 0x400cd6
    (gdb) b *0x400c6c
    Breakpoint 2 at 0x400c6c
    (gdb) run
    Starting program: ./addbin.64
    
    Breakpoint 2, 0x0000000000400c6c in main ()
    (gdb) p/x $rax
    $1 = 0x6d2bf1
    (gdb) c
    Continuing.
    
    Breakpoint 1, 0x0000000000400cd6 in main ()
    (gdb) x/s 0x6d2bf1
    0x6d2bf1:       "https://gooY.gl/N5WQXz"
    (gdb)
    

    I set the two breakpoints as discussed earlier. I printed RAX which contained the address of the malloc'ed memory (+1) which was 0x6d2bf1 . I then used the continue command to run until the second breakpoint as the function was exiting. I then print the contents of memory as a string starting at 0x6d2bf1 with the x/s command. The result was:

    0x6d2bf1:       "https://gooY.gl/N5WQXz"
    

    remove the Y in the URL. I had to insert it because Stackoverflow doesn't allow goo.gl as a URL shortener and refused to accept the answer.

    When I went to the URL I got this webpage:

    enter image description here

    There may be more to the challenge or I have overlooked something in the code. I haven't had time to investigate further but this is probably a starting point for you to find your own answer.


    Footnotes

    • 1I chose GDB as a debugger but you can use any debugger that is available that can be used to run x86-64 Linux programs. Most debuggers allow the setting of breakpoints and viewing the contents of registers and memory.