Unexpected exit code for C program compiled for 32-bit architecture using gcc
I wrote a simple C program and compiled it for a 32-bit architecture.
But when I ran it, I encountered unexpected results.
#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
I expect to 20100
be the return value printed by the main function.
But I am getting 132
like exit code.
I checked with GDB that 20100
is the value in the register eax
when main returns.
➜ 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
I even confirmed that when control is passed back to a function __libc_start_main
and exit
is 20100
pushed as an argument 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
What could be causing this?
I don't think the exit code 132
here has anything to do with SIGILL
, because when I changed the hardcoded argument to foo()
from 200
to 2
, the exit code was changed to 172
where the expected exit code is 26796
.
source to share
It looks like what you are doing is wrong since you only have 8 bits to get back to the OS.
Assuming you bind to libc
:
When the program exits, it can return a little information about the reason for termination to the parent process using the exit status. This is a value between 0 and 255 that exits the process as an argument to exit.
As stated in its documentation here . This line is also relevant:
Warning. Don't try to use the error count as your exit status. This is actually not very useful; the parent process usually doesn't care how many errors happened. Worse, it doesn't work because the status value is truncated to eight bits. Thus, if the program tried to report 256 errors, the parent will receive a report of 0 errors, that is, success.
source to share