Wednesday, June 23, 2010

More on (moron?) packers and anti-debugging

That's a pretty nice anti-debugging trick I recently ran across.
It actually relies on those API that behave differently depending on whether the current process is being debugged or not.
This snippet comes from a protector that is, as far as I know, only used to hide malware from AV engines.
According to MSDN, FindClose() returns 0 in case of failure, which is true...unless the process is being debugged. Under a debugger, execution stops because of an access violation exception.

Let's quickly check this with the following code:
int _tmain(int argc, _TCHAR* argv[])
{
FindClose (0);
printf ("Lasterror %08x\n", GetLastError());
return 0;
}
Run from the command line, everything goes as expected:
>findclose.exe
Lasterror 000003e6 
Same thing but under the VS debugger:
First-chance exception at 0x7c90100b in findclose.exe: 0xC0000005: Access violation reading location 0x00000028.
Oops...

Our friend then goes through the PEB to read the LastError value and uses it to calculate its decryption key.

Nice one...

2 comments:

  1. Yo,

    I guess this behavior is due to ZwClose() syscall :
    "2.1.4 CloseHandle
    As with an invalid handle, if a protected handle is passed to the kernel32 CloseHandle () function (or directly to the ntdll NtClose () function) and no debugger is present, then an error code is returned. However, if a debugger is present, an EXCEPTION_HANDLE_NOT_CLOSABLE (0xC0000235) exception will be raised. This exception can be intercepted by an exception handler, and is an indication
    that a debugger is running.
    "

    from http://pferrie.tripod.com/papers/unpackers21.pdf
    +

    ReplyDelete
  2. Hey Ivanlef0u,

    Indeed, that was what I thought as well.
    I reckon I didn't bother checking though.

    Hey, nice blog btw.

    See ya dude!

    ReplyDelete