Nytro Posted January 21, 2019 Report Posted January 21, 2019 Anti Debugging Tricks #4 – Hidden Threads timb3r - reverse engineering January 19, 2019No Comments ANTIDEBUG CRASH HIDE FROM DEBUGGER NTSETINFORMATIONTHREAD THREADS Has this ever happened to you? You’re playing around with some application and and it crashes the moment you attach a debugger? Ever wondered why or how? I do. These types of questions keep me awake at night. I first became aware of this technique while cruising around some forums on the internet. People typically asking for a bypass or a method to work around it. But I was more interested in HOW this technique works less interested in how to bypass. During my research phase I noticed that after the application crashed out it would crash out with: Unhandled exception code 80000003 But that’s an int 3 exception? How is the Debugger not catching that? What the actual hell. Searching around for information I discovered that NtSetInformationThread has a parameter called THREADINFOCLASS. Which contains this interesting snippet: ThreadHideFromDebugger = 0x11 Why Hans? You may be wondering why this is even a ‘feature’ of Windows? Wouldn’t malware abuse the hell out of this? Yes, probably. But here’s why it exists: When you attach a debugger to a remote process a new thread is created. If this was just a normal thread the debugger would be caught in an endless loop as it attempted to stop it’s own execution. So behind the scenes when the debugging thread is created Windows calls NtSetInformationThread with the ThreadHideFromDebugger flag set (1). This way the process can be debugged and a deadlock prevented. Allowing code execution to continue as normal. However, now that this thread is hidden from the debugger any breakpoints or exceptions that are triggered will cause the process to crash. Due to the fact that the debugger cannot see this thread it’s now unable to trap these events. So as it turned out some devious individual noticed this odd behaviour and thought: “this would make a really cool anti-debug feature”. Now we’re here with this method widespread enough for me to be aware of it. Das Kode So what’s it actually look like in code? I wasn’t able find any live examples so I constructed my own based on how I thought it should work: 01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 #include <stdio.h> #include <windows.h> enum THREADINFOCLASS { ThreadHideFromDebugger = 0x11 }; typedef NTSTATUS (WINAPI *NtQueryInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG, PULONG); typedef NTSTATUS (WINAPI *NtSetInformationThread_t)(HANDLE, THREADINFOCLASS, PVOID, ULONG); NtQueryInformationThread_t fnNtQueryInformationThread = NULL; NtSetInformationThread_t fnNtSetInformationThread = NULL; DWORD WINAPI ThreadMain(LPVOID p) { while(1) { // This can be any trigger we're using this demo purposes if(IsDebuggerPresent()) // For MingW replace with __asm { int 3; } on MSVC asm("int3"); Sleep(500); } return 0; } int main(void) { DWORD dwThreadId = 0; HANDLE hThread = CreateThread(NULL, 0, ThreadMain, NULL, 0, &dwThreadId); HMODULE hDLL = LoadLibrary("ntdll.dll"); if(!hDLL) return -1; fnNtQueryInformationThread = (NtQueryInformationThread_t)GetProcAddress(hDLL, "NtQueryInformationThread"); fnNtSetInformationThread = (NtSetInformationThread_t)GetProcAddress(hDLL, "NtSetInformationThread"); if(!fnNtQueryInformationThread || !fnNtSetInformationThread) return -1; ULONG lHideThread = 1, lRet = 0; fnNtSetInformationThread(hThread, ThreadHideFromDebugger, &lHideThread, sizeof(lHideThread)); fnNtQueryInformationThread(hThread, ThreadHideFromDebugger, &lHideThread, sizeof(lHideThread), &lRet); printf("Thread is hidden: %s\n", val ? "Yes" : "No"); WaitForSingleObject(hThread, INFINITE); return 0; } Pretty simple yes? Now if you run the program and attempt to attach a debugger you’ll get this interesting crash: 0036:err:seh:raise_exception Unhandled exception code 80000003 flags 0 addr 0x401566 Oh ho ho! Poor Tony Throwing Hans off Nakatomi Well now we’ve established how this works we can look at beating it. There’s a number of ways including: Hooking the required Nt Function calls. Replacing the int 3 instruction with a nop. Nopping or hooking the “trigger” function. I opted for nopping out int 3: You can use your tool of choice to locate the required int 3 instruction: You’ll have to search around a bit Here’s our thread with the check Now we can nop that sucka out Attaching a debugger and resuming execution will result in everything working as expected. Bye Hans Ho-ho-ho One Time Donation: BTC 1DXcjix3FmcHYezFAjCrpzZA9FkbSC971e Paypal PayPal.me/timb3r Monthly Donation:Patreon Sursa: https://gamephreakers.com/2019/01/anti-debugging-tricks-4-hidden-threads/ 1 Quote
gigiRoman Posted January 21, 2019 Report Posted January 21, 2019 Asta vroiam sa zic si eu cand am citit titlul. Bagat in ida si dat nop. Hahaha. Cul! Quote