2

I wrote a simple C program.

When I decompile it with radare2's r2ghidra-dec plugin and I am not very understand it's code.

Gcc version

gcc --version                                                                   
gcc (GCC) 10.1.0
Copyright (C) 2020 Free Software Foundation, Inc.
This is free software; see the source for copying conditions.  There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.

System version

uname -a                                                                        
Linux Thinkpad-T480 5.7.15-1-MANJARO #1 SMP PREEMPT Tue Aug 11 15:00:37 UTC 2020 x86_64 GNU/Linux

Source code of C program:

#include<stdio.h>

int main(void) {
    int array[10] = { 0 };

    array[0] = 0x11;
    array[1] = 0x22;
    array[2] = 0x33;

    for (int i = 0; i < 10; i++) {
        printf("%x ", array[i]);
    }
}

Compile it by using

gcc a.c -o a.out.

It's assembly code:

0000000000001149 <main>:                                                             
push   %rbp                                                                          
mov    %rsp,%rbp                                                                     
sub    $0x40,%rsp                                                                    
mov    %fs:0x28,%rax                                                                 
mov    %rax,-0x8(%rbp)                                                               
xor    %eax,%eax                                                                     
movq   $0x0,-0x30(%rbp)                                                              
movq   $0x0,-0x28(%rbp)                                                              
movq   $0x0,-0x20(%rbp)                                                              
movq   $0x0,-0x18(%rbp)                                                              
movq   $0x0,-0x10(%rbp)                                                              
movl   $0x11,-0x30(%rbp)                                                             
movl   $0x22,-0x2c(%rbp)                                                             
movl   $0x33,-0x28(%rbp)                                                             
movl   $0x0,-0x34(%rbp)                                                              
jmp    11c6 <main+0x7d>
mov    -0x34(%rbp),%eax
cltq   
mov    -0x30(%rbp,%rax,4),%eax
mov    %eax,%esi
lea    0xe4c(%rip),%rdi        # 2004 <_IO_stdin_used+0x4>
mov    $0x0,%eax
callq  1040 <printf@plt>
addl   $0x1,-0x34(%rbp)
cmpl   $0x9,-0x34(%rbp)
jle    11a6 <main+0x5d>
mov    $0x0,%eax
mov    -0x8(%rbp),%rdx
sub    %fs:0x28,%rdx
je     11e5 <main+0x9c>
callq  1030 <__stack_chk_fail@plt>
leaveq 
retq   
nopw   0x0(%rax,%rax,1)

It looks it just load 0x11, 0x22, 0x33 on to the stack and call printf to print them.

And it's wired decompilation code from r2ghidra-dec:

undefined8 main(void)                                                                
{                                                                                    
    int64_t iVar1;                                                                   
    undefined8 uVar2;                                                                
    int64_t in_FS_OFFSET;                                                            
    int32_t var_34h;                                                                 
    int64_t var_30h;
    int64_t var_28h;
    int64_t var_20h;
    int64_t var_18h;
    int64_t var_10h;
    int64_t canary;
    iVar1 = *(int64_t *)(in_FS_OFFSET + 0x28);
    var_30h = 0x2200000011;
    var_34h = 0;
    while (var_34h < 10) {
        sym.imp.printf(0x2004, (uint64_t)*(uint32_t *)((int64_t)&var_30h + (int64_t)var_34h * 4));
        var_34h = var_34h + 1;
    }
    uVar2 = 0;
    if (iVar1 != *(int64_t *)(in_FS_OFFSET + 0x28)) {
        uVar2 = sym.imp.__stack_chk_fail();
    }
    return uVar2;
}

What does var_30h = 0x2200000011 do?

Where is my 0x33?

I guessed 0x2200000011 here has something to do with 0x11, 0x22.

I try to rewrite it from it's decompiled code(gcc b.c -o b.out):

#include<stdio.h>                                                              [1/12]
#include<stdint.h>                                                                   

int main(int argc, const char **argv)
{
  int i; // [rsp+Ch] [rbp-34h]
  int64_t v5; // [rsp+10h] [rbp-30h]
  int64_t v6; // [rsp+18h] [rbp-28h]
  int64_t v7; // [rsp+20h] [rbp-20h]
  int64_t v8; // [rsp+28h] [rbp-18h]
  int64_t v9; // [rsp+30h] [rbp-10h]

  v5 = 0x2200000011LL;
  v6 = 0x33LL;
  v7 = 0LL;
  v8 = 0LL;
  v9 = 0LL;
  for ( i = 0; i <= 9; ++i )
    printf("%x ", *((unsigned int *)&v5 + i));
  return 0;
}

It works fine.

❯ gcc b.c -o b.out                                                                
❯ ./b.out                                                                         
11 22 33 0 0 0 0 0 0 0 %          

Can someone help me to understand?

Thank you very much.

coolder
  • 144
  • 2
  • 9
  • Was the original code compiled with optimized compiler settings? Which compiloer did you use? Are you sure the code you decompiled is the code you compiled? – Jabberwocky Aug 28 '20 at 11:55
  • It also would be interesting to see the raw disassmbly – Jabberwocky Aug 28 '20 at 12:02
  • 1
    It is where the array is stored in memory. It is probably the top of the stack. – jdweng Aug 28 '20 at 12:07
  • It was compile with gcc a.c -o a.out, and from it's assembly code I can see that 0x11, 0x22, 0x33 are pushed onto the stack, only it's decompilation code looks so weird. – coolder Aug 28 '20 at 23:56
  • 0x2200000011 is use to set value of 2 32bits words with a single 64 operation? and 0x33 is 51 in decimal? – OznOg Nov 14 '20 at 17:03
  • Yes. I add 0x33 to the new program. But in original decompilation code doesn't have any 51 or 0x33. Maybe it was stored in the memory. – coolder Nov 16 '20 at 02:08

0 Answers0