【问题标题】:Unexpected exit code for a C program compiled for 32 bit architecture using gcc使用 gcc 为 32 位架构编译的 C 程序的意外退出代码
【发布时间】:2015-10-27 05:11:12
【问题描述】:

我写了一个简单的 C 程序并编译为 32 位架构。

但是当我运行它时,我发现了意想不到的结果。

#include <stdio.h>

int foo(int n) {
    int sum=0;
    int i;
    if (n <= 1 || n >= 0x1000)
        return n;
    for (i=0; i<= n; i++) {
        sum = sum + i;
    }
    return foo(sum);
}

int main(int argc, char** argv) {
    int n;
    n = foo(200);
    printf("\n\n main about to return %d \n\n", n);
    return n;
}
➜  wbench  gcc -o test.elf test.c -m32 -fno-stack-protector -mpreferred-stack-boundary=2 -Wall
➜  wbench  ./test.elf 

 main about to return 20100


➜  wbench  echo $?
132

我希望 20100 是返回值,由 main 函数打印。

但是,我得到了132 作为退出代码。

我使用 GDB 验证了 20100 是 main 即将返回时 eax 寄存器中的值。

➜  wbench  gdb -q test.elf
gdb-peda$ b *main+44
Breakpoint 1 at 0x8048492
gdb-peda$ r

 main about to return 20100 

Breakpoint 1, 0x08048492 in main ()

   0x8048489 <main+35>: call   0x80482f0 <printf@plt>
   0x804848e <main+40>: mov    eax,DWORD PTR [ebp-0x4]
   0x8048491 <main+43>: leave  
=> 0x8048492 <main+44>: ret    
   0x8048493:   xchg   ax,ax



gdb-peda$ p/d $eax
$1 = 20100
gdb-peda$ c
[Inferior 1 (process 32172) exited with code 0204]
Warning: not running or target is remote
gdb-peda$ p/d 0204
$2 = 132

我什至验证了当控制权转移回__libc_start_main 并且正在调用exit 函数时,20100 被作为参数推送给exit()

gdb-peda$ r
 main returning 20100 
Breakpoint 1, 0x08048492 in main ()

gdb-peda$ finish
=> 0xf7e1ca83 <__libc_start_main+243>:  mov    DWORD PTR [esp],eax
   0xf7e1ca86 <__libc_start_main+246>:  call   0xf7e361e0 <exit>
   0xf7e1ca8b <__libc_start_main+251>:  xor    ecx,ecx
gdb-peda$ si
=> 0xf7e1ca86 <__libc_start_main+246>:  call   0xf7e361e0 <exit>
   0xf7e1ca8b <__libc_start_main+251>:  xor    ecx,ecx
gdb-peda$ x/wd $esp
0xffffd5c0: 20100

这可能是什么原因?

我不认为这里的退出代码 132SIGILL 有任何关系,因为当我将硬编码参数从 200 更改为 foo()2 时,退出代码更改为 @ 987654338@,其中预期的退出代码是 26796

【问题讨论】:

  • 另请注意,标准 C 仅支持 0(EXIT_SUCCESS 的同义词)和 EXIT_FAILURE 作为来自 main 的返回值。

标签: gcc x86 executable reverse-engineering


【解决方案1】:

您的操作似乎无效,因为您只有 8 位可以返回到操作系统。

假设你链接到libc

当程序退出时,它可以使用退出状态向父进程返回少量有关终止原因的信息。这是一个介于 0 和 255 之间的值,退出进程作为参数传递给退出。

如其文档here 中所述。同样相关的是这一行:

警告:不要尝试使用错误数作为退出状态。这实际上不是很有用;父进程通常不会关心发生了多少错误。更糟糕的是,它不起作用,因为状态值被截断为八位。因此,如果程序尝试报告 256 个错误,则父程序将收到 0 个错误的报告——即成功。

【讨论】:

  • 退出代码只有8位的原因是您从waitpid获得的status中的其他位用于其他信息:低8位是否是有效的退出状态,或者如果发生了其他事情。什么信号导致它退出,以及其他一些标志。
【解决方案2】:

20100十进制是4E84十六进制。
132十进制是84十六进制。
你的 shell 接收到的返回值只有 8 位。

【讨论】:

    【解决方案3】:

    虽然您的程序可能返回 20100,但系统仅获取最低字节,例如 return % 256

    所以20100 % 256 = 132

    【讨论】:

      猜你喜欢
      • 2012-05-15
      • 2020-10-05
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 2014-09-09
      • 2021-01-14
      • 1970-01-01
      • 2011-09-08
      相关资源
      最近更新 更多