2

我写了一个简单的 C 程序。

当我用radare2的r2ghidra-dec插件反编译它时,我不是很理解它的代码。

海合会版本

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.

系统版本

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

C程序源代码:

#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]);
    }
}

使用编译它

gcc a.c -o a.out.

它的汇编代码:

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)

它看起来只是将 0x11、0x22、0x33 加载到堆栈上并调用 printf 来打印它们。

它是来自 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;
}

做什么var_30h = 0x2200000011

我的在哪里0x33

我猜这里的0x2200000011和0x11、0x22有关。

我尝试用它的反编译代码重写它(gcc bc -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;
}

它工作正常。

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

有人可以帮我理解吗?

非常感谢。

4

0 回答 0