x64dbg / ScyllaHide

Advanced usermode anti-anti-debugger. Forked from https://bitbucket.org/NtQuery/scyllahide
GNU General Public License v3.0
3.45k stars 433 forks source link

NtWaitForSingleObject crash with Themida #127

Open FlafyDev opened 3 years ago

FlafyDev commented 3 years ago

I have a program that I inject a DLL to with the Themida profile x86(But with NtQueryInformationProcessHook as false) in x64dbg. But after a while, the program crashes and the Call Stack in x64dbg shows that the crash happened in ntdll.NtWaitForSingleObject. Why is it happening, do I need to hook something?

Mattiwatti commented 3 years ago

Do you inject your DLL at process startup, or while it's running?

This matters because recent versions of Themida have started using the ThreadHideFromDebugger flag (accepted by both NtCreateThreadEx and NtSetInformationThread). When you attach a debugger to a process that has such threads running, it is impossible to tell what will happen since the program is outside of the debugger's control. This usually manifests as being able to look around for a while but not being able to pause or step through the program, and then seeing a crash with a bizarre stack trace that may not even be related to the original thread, i.e. exactly what you are describing.

ScyllaHide prevents ThreadHideFromDebugger from being set via either NtCreateThreadEx or NtSetInformationThread, but there is nothing that can be done after it has been set on a thread. (With one quite extreme exception: DKOM from kernel mode.)

Therefore you must be attached to the process from startup, or at least before it creates its first thread.

This actually goes for any process that uses ThreadHideFromDebugger, it's just that Themida has until recently not used this. That's why neither NtSetInformationThread nor NtCreateThreadEx are checked in the default profile for Themida. You should enable those. I will update the default profiles soon to include this change.

Re: NtQueryInformationProcess: I don't know off the top of my head whether Themida calls this or not, but I'm almost certain it does, given that it's the most powerful debugger detection technique available in user mode. I would not recommend disabling it unless you have some specific problem with it, in which case it would probably be best to create a separate issue for that.

Mattiwatti commented 3 years ago

Update: I had some more time to try out the latest Themida and quickly noticed that the NtClose hook now also needs to be enabled. (It's not clear to me whether they really weren't using this basic detection method before or if the profile was just really out of date.)

I got ScyllaHide to sort of work with an x64 target in x64dbg as follows:

  1. Enable the system breakpoint, load the updated Themida profile, start the debuggee and wait for the system breakpoint.
  2. Go to the Threads tab. Depending on which version of Windows you are running, you will now have 1 thread with suspend count 0, or multiple threads with suspend count 1. Increment the suspend count of the main thread by +1 (so to either 1 or 2) and resume debugging.
  3. Detach.
  4. Use Process Hacker or Process Explorer to resume the suspended main thread.
  5. Attach to the process with x64dbg. You will get an error from ScyllaHide about function X already being hooked, you can ignore this.
  6. Debug the target as usual.

Note 1: while the most important/dangerous functions to hook (NtSetInformationThread and NtCreateThreadEx with ThreadHideFromDebugger) are successfully intercepted when doing this, the NtUserXxx functions (for FindWindow etc.) are not. This is because at the system breakpoint, user32.dll/win32u.dll are not necessarily loaded yet. You should rename your debugger window to avoid detection. Note 2: x86/WoW64 targets do not work yet. It looks like this is a bug in ScyllaHide on attach (it gets confused because of the WOW64 gate already being hooked), but it may also be something Themida is doing. I haven't investigated this yet. Note 3; When debugging Themida with x64dbg, I recommend using GleeBug over TitanEngine.