I am playing with a simple program (source code below). And my computer configuration:
Linux mymachine 3.13.0-49-generic #83-Ubuntu SMP Fri Apr 10 20:11:33 UTC 2015 x86_64 x86_64 x86_64 GNU/Linux
gcc version 4.8.4 (Ubuntu 4.8.4-2ubuntu1~14.04.3)
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> void catcher(int a){ setresuid(geteuid(),geteuid(),geteuid()); printf("WIN!n"); system("/bin/sh"); exit(0); } int main(int argc, char **argv){ puts("source code is available in level02.cn"); if (argc != 3 || !atoi(argv[2])) //printf("!atoi(argv[2]) = %dn", !atoi(argv[2])); return 1; signal(SIGFPE, catcher); printf("endn"); return abs(atoi(argv[1])) / atoi(argv[2]); }
I intend to trigger the SIGFPE in this program by calling the executable in this way:
$./a.out -2147483648 -1 source code is available in level02.c end WIN!
As you can see, the SIGFPE is successfully triggered. However, if I uncomment a single printf line in the argument checking “if” condition:
#include <stdio.h> #include <stdlib.h> #include <signal.h> #include <unistd.h> void catcher(int a){ setresuid(geteuid(),geteuid(),geteuid()); printf("WIN!n"); system("/bin/sh"); exit(0); } int main(int argc, char **argv){ puts("source code is available in level02.cn"); if (argc != 3 || !atoi(argv[2])) printf("!atoi(argv[2]) = %dn", !atoi(argv[2])); return 1; signal(SIGFPE, catcher); printf("endn"); return abs(atoi(argv[1])) / atoi(argv[2]); }
And then I recompile the program and try to trigger SIGFPE using the same way. I only get this:
source code is available in level02.c
What is happening?
Advertisement
Answer
Because now your source code is mis-indented compared to how it is actually parsed.
if (argc != 3 || !atoi(argv[2])) printf("!atoi(argv[2]) = %dn", !atoi(argv[2])); return 1;
Consider putting both statements in a block instead to avoid this.