EvilZone

Hacking and Security => Reverse Engineering => : z3ro February 17, 2013, 11:51:04 AM

: [TUT] Anti-Debugging
: z3ro February 17, 2013, 11:51:04 AM
(http://resources.infosecinstitute.com/wp-content/uploads/Anti-Debugging-02122013.jpg)



First, let's get something straight :P  :  completely preventing reversing is next to impossible. What is possible is that we can place as many obstacles on the way as we want to make the process slow enough that reverse engineers will give up. Actually there are hardware implementations where you can buy a black box that attaches to your computer which can do the encryption/decryption for you, but this is far from being used in everyday life.



Techniques to Harden Reverse Engineering:

   
:
// isdebuggerpresent.cpp : Defines the entry point for the console application.
//
 
#include "stdafx.h"
#include <stdio.h>
#include <Windows.h>
 
int _tmain(int argc, _TCHAR* argv[])
{
    int num;
    if(IsDebuggerPresent()) {
        num = 0;
    }
    else {
        num = 1;
    }
 
    printf("Number: %d\n", num);
 
    /* wait */
    getchar();
 
    return 0;}



// The program prints “Number: 0″ if the debugger is present and “Number: 1″ if the debugger is not. If we run the application under Visual Studio, the program will display the number 0 because it’s being run under a debugger. This can be seen on the picture below:
(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi2.png)


Let’s also run the program under OllyDbg to be sure that the number 0 is displayed. This can be quickly confirmed by loading the executable program and running it. On the picture below, we can see that the number 0 was printed when the program was run under OllyDbg debugger:
(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi3.png)


But if we run the same program under normal cmd.exe, it will display the number 1. This can be seen on the picture below:
(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi4.png)


We can see that the IsDebuggerPresent API function call works as expected, but that the function call is easy to detect and bypass. This is because we can quickly find this function call in the executable and delete it or bypass it. To do this, we can simply open the executable in Ida debugger and check out the Imports table to verify if that function exists somewhere in there. We’re right, the function IsDebuggerPresent is listed among all the imported functions as we can see on the picture below:
(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi5.png)


This is a clear indication that the executable is using the function to do something different when the debugger is attached to the executable. We can also locate the exact instructions that are used to call that function. The whole Ida graph of the main function that does exactly the same as the main function from the C++ source code above is presented on the picture below:


(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi6.png)


We can see that, at first, we’re initializing the stack for the function and calling the IsDebuggerPresent function. After that, we’re testing the returned value in eax against itself to determine whether a true or false value was returned. If the eax holds a value different than 0 (1 in our case), then the zero flag will be set and the first box that sets the [ebp+num] to 0 is called. This is exactly what happens now, because we’re running the program under a debugger, but otherwise the block that sets the [ebp+num] to 1 is called. After that, we’re just moving the value of [ebp+num] into the register eax and printing it with the printf function.
If we now set the breakpoint on the call to the IsDebuggerPresent function and rerun the program, the execution will be stopped right where we want it. After the breakpoint has been hit, we can step into the function to see what the function actually does. On the picture below, we can see the function in question:
(http://resources.infosecinstitute.com/wp-content/uploads/021213_1836_AntiDebuggi7.png)


We can see that the function is pretty simple: we’re loading the address of the currently active thread (TIB) in the register eax and then accessing the structure member that’s located at the 0×30 offset; the PEB data structures lies at that offset. After that, we’re loading the address of PEB in eax and then accessing its data member at 0×2 offset, which holds the data member named BeingDebugged. Thus, we’ve successfully taken a look at what the IsDebuggerPresent function actually does and how it does it. We can see that it’s very simple and not really hard to bypass.
We can determine that IsDebuggerPresent is being used when we try to reverse engineer an executable and the program terminates prematurely, a different execution path is taken, or something else unexpected happens. In such cases, we must first check the Imports table if the IsDebuggerPresent function is being called anywhere in the executable. If that is the case, we can simply delete the instructions that call the IsDebuggerPresent function call, so it won’t bother us when reversing the executable.
On the other hand, if we’re developing a program and we would like to use the IsDebuggerPresent function call, we can copy the above instructions directly into our code, so that we’re not actually calling the IsDebuggerPresent function directly, but using its function body instructions to figure out whether the debugger is being used to run the executable. This is just another trick so that reverse engineers won’t immediately notice the use of IsDebuggerPresent function call and will make the debugging slightly more complicated.


Conclusion  ;)
We’ve seen a few techniques to harden the reverse engineering process. The technique easiest to bypass is symbol elimination where we have to delete all the symbols presented in the executable. This effectively makes the names of the functions unavailable when debugging, which leaves it up to the debugger to properly name the functions. Another technique is program obfuscation, which can be a pretty simple operation like xoring the whole executable then running it, but it can also be pretty complicated. Things get further complicated if we’re using obfuscation with the anti-reversing techniques, which detects if the program is being reversed and terminates the program prematurely if so, greatly hardening the reverse engineering of the executable.


References:
 Reversing: Secrets of Reverse Engineering, Eldad Eilam.


http://resources.infosecinstitute.com/anti-debugging/
: Re: [TUT] Anti-Debugging
: WirelessDesert February 17, 2013, 02:31:13 PM
Awesome!!
This will sure come in handy.
Thank you for sharing! +1
: Re: [TUT] Anti-Debugging
: 0poitr February 17, 2013, 02:51:57 PM
Nice write up. +1
: Re: [TUT] Anti-Debugging
: z3ro February 17, 2013, 03:57:36 PM
Thanks guys...  ;)   
: Re: [TUT] Anti-Debugging
: Deque February 18, 2013, 12:06:38 PM
Thanks a lot. That tutorial is very good. I don't get why the font is changing all the way, though. But you get well deserved +1.