我写了一个简单的 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 %
有人可以帮我理解吗?
非常感谢。