gcc - 使用 gcc 为 32 位体系结构编译的 C 程序的意外退出代码

标签 gcc x86 executable reverse-engineering

我编写了一个简单的 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 验证了 20100eax 中的值在 main 即将返回时注册。

➜  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

这可能是什么原因?

我不认为退出代码 132这里与SIGILL有关因为当我将硬编码参数更改为 foo() 时来自 2002 ,退出码改为172其中预期的退出代码是 26796 .

最佳答案

看起来您正在做的事情无效,因为您只有 8 位可以返回到操作系统。

假设您正在链接 libc :

When a program exits, it can return to the parent process a small amount of information about the cause of termination, using the exit status. This is a value between 0 and 255 that the exiting process passes as an argument to exit.



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

Warning: Don’t try to use the number of errors as the exit status. This is actually not very useful; a parent process would generally not care how many errors occurred. Worse than that, it does not work, because the status value is truncated to eight bits. Thus, if the program tried to report 256 errors, the parent would receive a report of 0 errors—that is, success.

关于gcc - 使用 gcc 为 32 位体系结构编译的 C 程序的意外退出代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31815346/

相关文章:

x86 - SSE 内在函数 : Convert 32-bit floats to UNSIGNED 8-bit integers

exception - 这个汇编代码如何设置 SEH?

iphone - 从 asp.net JQuery 应用程序准备可执行文件

go - 在 Go 中执行二进制时获取输入

c++ - 为什么我不能运行目标文件?

c++ - 安装 RPM 时对 libstdc++(GLIBCXX_...) 的依赖失败

c - 告诉 gcc 专门展开一个循环

assembly - x86 的交叉编译 arm 程序集

android - 如何使 native C 可执行文件在 Android 中永远运行?

c - 为什么 gcc 以不同的方式编译 f(1199) 和 f(1200)?