View previous topic :: View next topic |
Author |
Message |
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Fri Mar 20, 2015 1:16 pm Post subject: Unhiding threads from the debugger |
|
|
Some games protect themselves by hiding certain threads from the debugger.
When that happens, and a breakpoint is hit, the debugger won't receive the breakpoint exception and can't handle it. Therefore, the exception goes unhandled, and if the game doesn't handle it (it could but most games won't) the whole application will terminate.
One often used way to bypass this issue, is to hook the creation of the game and prevent it from hiding in the first place. Or using a different way of debugging. But today I'll show you an 'easy' to use method to unhide such threads after they have been hidden.
This involves knowing the layout of the EThread of the windows version you're on. More specifically, the location of the CrossThreadFlags field, and possible the bit position of HideFromDebugger. (which is usually bit 2 from what i've seen)
For this example i'll go with windows 7 build 6.1.7601. In here bit 2 of offset 0x450 of the EThread structure contains the flag for hidefromdebugger
Tip for other operating systems, or a way to automate the lookup: the exported function PsIsThreadTerminating ( in ce known under the exported symbol kernel_PsIsThreadTerminating ) references that offset. So just disassemble it to get the offset
Code: |
local FLAGS_OFFSET=0x450 --adjust this to your windows version
--first we enable kernelmode access
dbk_initialize()
dbk_useKernelmodeOpenProcess()
dbk_useKernelmodeProcessMemoryAccess()
--then reopen the process in case it was opened with usermode access:
openProcess(getOpenedProcessID()) --reopen with kernel access
--now create a list of threads
local list=createStringlist()
getThreadlist(list) --fills a stringlist with the threadid's
local i
for i=0, list.count-1 do
local tid=tonumber('0x'..list[i])
--for every thread we get the EThread address
local PEThread=dbk_getPEThread(tid)
local PEThread_Flags=PEThread+FLAGS_OFFSET
--then we check if the hidefromdebugger bit is set
local flags=readBytes(PEThread_Flags,1)
if bAnd(flags,4)==4 then --test bit 4 (adjust if your windows has it at a different position)
--and if so, we remove that bit
print("Thread "..list[i].." is hiding from the debugger. Unhiding it")
flags=bAnd(flags,0xfb) --unset bit 4
writeBytes(PEThread_Flags, flags)
end
end
--some cleanup
list.destroy()
print("Done") --and done
|
now when this lua script gets executed it will go through all the threads of the target process, and unset the hidefromdebugger flag where it's present
tips for enhancement: As I mentioned, you can disassemble kernel_PsIsSystemThread to get the offset, and alternatively, you could call NtSetInformationThread(threadhandle, ThreadHideFromDebugger(17), NULL, 0);
on multiple threads/processes and see if you can pinpoint the flags register that way by looking at the differences(keep in mind, eflags changes constantly, so filter out the fields that change when the field hasn't changed, but that's basic me scanning)
Or you could keep a database of windows build numbers and offsets
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping
Last edited by Dark Byte on Tue Mar 01, 2016 4:11 pm; edited 1 time in total |
|
Back to top |
|
|
flarn2006 Advanced Cheater Reputation: 1
Joined: 27 Nov 2012 Posts: 73
|
Posted: Thu Apr 16, 2015 7:09 pm Post subject: |
|
|
That's interesting, why is there even an OS-provided flag to hide threads from debuggers in the first place?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Thu Apr 16, 2015 7:57 pm Post subject: |
|
|
Probably when the OS injects a debugger thread into the target process. So when it freezes on a breakpoint the debugger can still query data about the target from inside the target
It's something I wanted to do myself for a while (the mono data collector then doesn't have to shut down when debugging is in progress)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Tue Apr 28, 2015 7:07 am Post subject: |
|
|
in windows 10 (the current bad build) the offset is 6bc
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Sadfaffel Newbie cheater Reputation: 0
Joined: 12 Jun 2015 Posts: 13
|
Posted: Sun Jun 14, 2015 12:13 pm Post subject: |
|
|
i dont understand:/
|
|
Back to top |
|
|
STN I post too much Reputation: 42
Joined: 09 Nov 2005 Posts: 2672
|
Posted: Sun Jun 14, 2015 1:24 pm Post subject: |
|
|
Sadfaffel wrote: | i dont understand:/ |
Then it doesn't concern you. Still, thanks for bumping this thread because this is interesting. Which games have you noticed this on Dark Byte ?.
_________________
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Sun Jun 14, 2015 2:20 pm Post subject: |
|
|
i've seen this thread hiding in a couple of steam games.
not all, but a few where the windows debugger interface would crash the game had their main thread hidden
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Hatschi Master Cheater Reputation: 2
Joined: 28 Jan 2010 Posts: 327
|
Posted: Mon Apr 03, 2017 6:10 am Post subject: |
|
|
Is it possible to achieve the same without kernel mode driver, possibly using Win API?
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Mon Apr 03, 2017 6:22 am Post subject: |
|
|
No, not unless you use a different kind of debugging method, like the VEH debug method.
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
Hatschi Master Cheater Reputation: 2
Joined: 28 Jan 2010 Posts: 327
|
Posted: Mon Apr 03, 2017 7:39 am Post subject: |
|
|
Hm I see, the address your script gaves me is negative. I tried using Process Explorer which gives me the start address of the thread too but it's positive and completely different.. what a shame.
|
|
Back to top |
|
|
atom0s Moderator Reputation: 199
Joined: 25 Jan 2006 Posts: 8518 Location: 127.0.0.1
|
Posted: Tue Apr 04, 2017 4:00 am Post subject: |
|
|
Dark Byte wrote: | i've seen this thread hiding in a couple of steam games.
not all, but a few where the windows debugger interface would crash the game had their main thread hidden |
Steams homebrew DRM (referred to as SteamStub) uses typical NtSetInformationThread to hide the main thread while doing it's unpacking process at game launch. (Done in the payload DLL it manually maps into memory named SteamDRMP.dll.)
I posted a small write up on it here:
http://atom0s.com/forums/viewtopic.php?f=2&t=52
My unpacker handles removing the DRM here:
https://github.com/atom0s/Steamless
_________________
- Retired. |
|
Back to top |
|
|
Hatschi Master Cheater Reputation: 2
Joined: 28 Jan 2010 Posts: 327
|
Posted: Thu Apr 06, 2017 3:23 am Post subject: |
|
|
I've seen your great work before. In your thread you mentioned blocking NTSetInformationThread call but this is something for "starting the game under a debugger". But I wonder if this can be done "on the fly" while the target is already running. But from what I've read so far it seems to be impossible without a kernel driver to unreveal a hidden thread, isn't it ?!
|
|
Back to top |
|
|
Dark Byte Site Admin Reputation: 458
Joined: 09 May 2003 Posts: 25296 Location: The netherlands
|
Posted: Thu Apr 06, 2017 4:51 am Post subject: |
|
|
yup. Only a kernelmode driver can reset the HideFromDebugger flag back to 0. (it's located in kernelmode and NtSetInformationThread can only set it to true, not false)
_________________
Do not ask me about online cheats. I don't know any and wont help finding them.
Like my help? Join me on Patreon so i can keep helping |
|
Back to top |
|
|
|