New anti-debugging possibilities
izee / EOF
New anti-debugging possibilities Written by izee/EOF in May, 2008 xchg code, mind! Index` `````` I. Prolog II. Entry: 1. Looking for IDA database files 2. Magic debuggers keys 3. Detecting IDA Remote Debug Server 4. NtSetDebugFilterState syscall 5. DebugActiveProcess 6. Structured Exception Handler 7. Thread Local Storage Callback III. Epilog IV. References V. Thanks Prolog` ``````` Nowadays there are plenty anti-debugging tricks, some of them are known, some not. However, all publicly known tricks are Win32-specific and Win64 is still untouched currently. In the first part of article i'm going to demonstrate few new tricks, which are coded for Win64, but can be easily ported to Win32. In the second part i'll show how to implement SEH and TLS on Win64 and also some other new Win64-specific anti-debug techniques. Entry` `````` 1. Looking for IDA database files By loading something in IDA for analysis, you can notice that files with the following extensions are being created in the current directory: program file name.id0 id1 nam til These are IDA database related files. Using FindFirstFileA(W) function, we can easily check if there are files with such extensions in the current directory or not, and thus detect a presence of IDA. Let's have a look at the example. ~~~~~~~~~~~~~~~~~~~~ .data ex db '*.id0',0 fd dd ? .code lea rcx, ex lea rdx, fd call FindFirstFileA inc al jnz dbgfnd ~~~~~~~~~~~~~~~~~~~~ See also: idadb64.rar Tested on: Windows Vista SP0/SP1 32/64bit Applies to: Interactive Disassembler Can be ported to Windows XP 32/64 2. Magic debuggers keys The idea: to check if a debugger-specific keys (such as: F4, F7, F8, F9, F10, F11) were pressed during the debugging session. For that, we'll use the GetAsyncKeyState function. In the following example we'll try to determine if a typical debugger key -- F8 -- was pressed. ~~~~~~~~~~~~~~~~~~~~~~~~ cdq lea ecx, [rdx+77h] ;F8 call GetAsyncKeyState dec al jz dbgfnd ~~~~~~~~~~~~~~~~~~~~~~~~ See also: gaks64.rar Tested on: Windows Vista SP0/SP1 32/64bit Applies to: Interactive Disassembler WinDBG OllyDBG future ring3 debuggers Can be ported to Windows XP 32/64 3. Detecting IDA Remote Debug Server For a local debugging of 64bit executables an IDA Win64 Remote Debug Server must be turned on. It's a console application, which listens on port #23946. We can try to connect to this port and thus detect a presence of IDA. And now an example. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ sockaddr struc sa_family dw ? sa_data db 14 dup(?) sockaddr ends WSAData struc wVersion dw ? wHighVersion dw ? szDescription db 257 dup(?) szSystemStatus db 129 dup(?) iMaxSockets dw ? iMaxUdpDg dw ? dw ? ; undefined dw ? ; undefined lpVendorInfo dq ? ; offset WSAData ends .data ip db '127.0.0.1',0 hsocket dq ? .data? sa sockaddr <> wsd WSAData <> .code lea rdx, wsd mov cl, 2 ;Winsock 2.0 call WSAStartup mov r11d, 2 mov word ptr [sa.sa_family], r11w mov cx, 5D8Ah ;port #23946 call htons mov word ptr [sa.sa_data], ax lea rcx, ip call inet_addr mov dword ptr [sa.sa_data+2], eax mov r8d, 6 ;IPPROTO_TCP mov edx, 1 ;SOCK_STREAM mov ecx, 2 ;AF_INET call socket mov [hsocket], rax mov r8d, 10h lea rdx, [sa] mov rcx, qword ptr [hsocket] call connect test al, al jz dbgfnd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also: idardbg64.rar Tested on: Windows Vista SP0/SP1 64bit Applies to: Interactive Disassembler 64 4. NtSetDebugFilterState syscall I can't say much about this syscall, since it's not documented well, however i found it as a new anti-debug trick. What the syscall does is sets the debug output filter level for the specified component, under debugger it returns NT_STATUS_SUCCESS (0), otherwise it returns error code 22. Let's have a quick look at the example now. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ mov r10, rcx mov eax, 14Ah ;NtSetDebugFilterState syscall test al, al jz dbgfnd ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also: ntsdfs64.rar Tested on: Windows Vista SP0/SP1 64bit Applies to: Interactive Disassembler WinDBG future ring3 debuggers Can be ported to Windows XP: unknown. 5. DebugActiveProcess The function enables a debugger to attach to an active process and debug it. Not so long ago i found, that calling this function with current process handle on Windows Vista x64 under the ring-3 debugger will cause a local DoS or even BSOD. I still analyze this strange behavior,however i decided to write about my current researches. The funny thing is, that local DoS or BSOD will occur only on x64 versions of Windows Vista, not on x86. Here's the example. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ or rcx, -1 ;pseudo handle (current process handle) call DebugActiveProcess ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ Here's the disassembled version. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ;ntdll.DbgUiConnectToDbg mov r11, rsp sub rsp, 58h mov dword ptr [rsp+20h], 30h mov rcx, gs: [30h] lea r8, [r11-38h] mov r9d, 1 add rcx, 16A8h mov r10, rcx ;NtCreateDebugObject mov eax, 91h ;SP0 - 93h, SP1 - 91h syscall add rsp, 58h call CsrGetProcessId ;get csrss.exe pid lea r9, [rsp+20h] lea rcx, [rsp+78h] mov edx, 0C3Ah mov [rsp+20h], rax mov r10, rcx mov eax, 23h ;NtOpenProcess syscall mov rcx, [rsp+78h] ;ntdll.DbgUiDebugActiveProcess mov rdx, gs:[30h] mov rdx, [rdx+16A8h] mov r10, rcx ;NtDebugActiveProcess mov eax, 0ADh ;SP0 - 0AFh, SP1 - 0ADh syscall ;---DoS--- ret ;---BSOD--- ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also: dap64.rar Tested on: Windows Vista SP0/SP1 64bit Applies to: Interactive Disassembler 64 WinDBG 64 probably future ring3 64bit debuggers 6. Structured Exception Handler SEH can be used as a powerful anti-debug trick, as we know. Here is an example of SEH for Microsoft Linker x64. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ eh proc ;exception handler <-------, | ;your code goes here | | eh endp | | | eof proc frame: eh | |^ push rbp | | .pushreg rbp | .endprolog | | ud2, int3, icebp ----------------' nop > eof endp ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also: seh64.rar Now a bit of explanation. eof proc frame: eh ;setup a SEH frame push rbp ;generate unwind data for the base pointer .pushreg rbp .endprolog ;end of prologue ud2 ;invalid opcode ;generates EXCEPTION_ILLEGAL_INSTRUCTION int3 ;trap to debugger ;generates EXCEPTION_BREAKPOINT icebp ;Ice breakpoint ;generates EXCEPTION_SINGLE_STEP nop ;after SEH frame execution, RIP must point to some do-nothing code Debuggers especially don't like ud2 instruction. IDA for instance will be not capable to disassembly nor debug that instruction. Tested on: Windows Vista SP0/SP1 64bit Applies to: Interactive Disassembler 64 WinDBG 64 future ring3 64bit debuggers 7. Thread Local Storage Callback TLS Callback is called before the main entrypoint, this gives an ability to execute the virus or check for a debugger presence, before the debugger reaches the main entrypoint. Unfortunately, ml64 don't support TLS Callbacks, so FASM is the only choice then currently for implementing TLS manually in Win64 executables. Let's examine the example below. ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ format pe64 gui 5.0 include 'win64a.inc' entry $ ret proc cb, r cmp [r],DLL_PROCESS_ATTACH ;avoid double callback execution jz @f ;---PEB.BeingDebugged Win64 variation--- mov rax, [gs: 30h] ;get ProcessEnvironmentBlock pointer mov rcx, [rax+60h] ;from ThreadEnvironmentBlock movzx eax, byte [rcx+2] ;read the BeingDebugged byte-flag dec al jz @f ;--------------------------------------- xor r9d, r9d lea r8, [c] lea rdx, [nf] jmp mbox @@: xor r9d, r9d lea r8, [c] lea rdx, [f] mbox: xor rcx, rcx call [MessageBox] ret endp data 9 ;TLS structure dq sea ;StartAddressOfRawData dq sea ;EndAddressOfRawData dq sea ;AddressOfIndex dq cba ;AddressOfCallBacks sea dq 0 ;SizeOfZeroFill cba dq cb ;Characteristics dq 0 ;NULL end data section '.data' data readable writeable c db 'Debugger:' ,0 f db 'I see you!' ,0 nf db 'Not found.' ,0 section '.idata' import data readable writeable library u32, 'user32' ;rgb's optimization tip ;-) import u32,\ MessageBox,'MessageBoxA' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ See also: tls64.rar Tested on: Windows Vista SP0/SP1 64bit Applies to: Interactive Disassembler WinDBG future ring3 64bit debuggers Epilog` ``````` I hope you enjoyed reading the article as much as I enjoyed writing it. Don't forget to see attached archives also. If you will have some questions or comments, you can always write me an e-mail to: izee@eof-project.net Welcome to Win64 world and let's protect our future creations! References` ``````````` 29A #8 - Thread Local Storage (64bit AMD version) - roy g biv WASM.RU - TLS from the inside - Bill / TPOC WASM.RU - http://www.wasm.ru/forum/viewtopic.php?id=26306 - Joes http://www.tortall.net/projects/yasm/manual/html/objfmt-win64-exception.html Thanks` ``````` WarGame, roy g biv, kaze, RadiatioN, Scorpions.