In my BA thesis, I wanted to present a program for Windows, using various anti-debugging techniques.
One of them, which I came up on my own (possibly it is well known, but I didn't find it anywhere) involves changing control flow by using signal handlers. As far as I know, when program receives certain signal and has a function registered to handle it, the main thread is paused and the execution is passed to the handler. After it returns from the function, the main thread can either continue execution, or even terminate in case where SIGFPE
or SIGSEGV
was passed, for example (see this question).
However, in such a case, it is possible to cause the thread executing handler not to stop after it leaves handler scope. The anti-debugging technique I've mentioned before takes advantage of this fact and is presented below.
First of all, I'm aware that the code I'm about to present uses concepts that should never appear in a real program, should be avoided in almost every situation and never tried at home :). After establishing this, consider the following program: (I'm using GCC targeting minGW to compile it)
#include <csignal>
#include <windows.h>
#include <cstdio>
void handler(int)
{
asm("jmp continue"); // do not return from this function; just jump to another place in the code
}
int main()
{
signal(SIGFPE, handler); // I know that sigaction should be used instead, but it's simpler and, as far as I know it wouldn't work for Windows
// and I know, that after receiving second signal, there will be undefined behaviour, but let's assume it won't happen
int a = 1 / 0; // cause SIGFPE to happen
asm("continue:");
printf("continue execution\n");
Sleep(5000); // to show a printed message for a while, so that the console is not being closed immediately
ExitProcess(0);
}
So here comes my question: how could be such a program debugged, such that it's possible to see printf("continue execution\n");
line being executed?
When I tried to do this using Code::Blocks debugger (GDB), only the information that a program received SIGFPE
appeared and the program crushed without printing "continue execution"
string.
On the other hand, when I tried to debug it in OllyDbg
, execution just stopped, nothing was printed on the screen, and I wasn't able to continue execution to the point where this string should be printed.
Upon "normal" execution it prints the string end finishes as expected.
Edit:
I've also tried to pass the exception to the application (using SHIFT
+F7
), but I only get message saying "Debugged program was unable to process exception" and I'm unable to continue the execution.
Edit2: I will not upload the binary, since when I tried to download it, my antivirus software started to complain about it, so it would probably be marked as suspicious if someone else downloaded it.