


当调试器出现以上这种情况时,说明程序调用NtSetInformationThread-ThreadHideFromDebugger
NTSTATUS
NTAPI
NtSetInformationThread(
_In_
HANDLE
ThreadHandle,
_In_ THREADINFOCLASS ThreadInformationClass,
_In_reads_bytes_(ThreadInformationLength)
PVOID
ThreadInformation,
_In_
ULONG
ThreadInformationLength
);
这个函数可以让调试器接受不到异常信息
内核代码的实现:
PS_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_HIDEFROMDBG);
内核对PS_CROSS_THREAD_FLAGS_HIDEFROMDBG的处理:
if
(DebugException) {
if
(PsGetCurrentThread()->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HIDEFROMDBG) {
DebugPort = NULL;
}
else
{
DebugPort = Process->DebugPort;
}
在ETHREAD的结构中
kd> dt _ETHREAD
ntdll!_ETHREAD
+0x000 Tcb : _KTHREAD
+0x360 CreateTime : _LARGE_INTEGER
+0x368 ExitTime : _LARGE_INTEGER
+0x368 KeyedWaitChain : _LIST_ENTRY
+0x378 ExitStatus : Int4B
+0x380 PostBlockList : _LIST_ENTRY
+0x380 ForwardLinkShadow : Ptr64 Void
+0x388 StartAddress : Ptr64 Void
+0x390 TerminationPort : Ptr64 _TERMINATION_PORT
+0x390 ReaperLink : Ptr64 _ETHREAD
+0x390 KeyedWaitValue : Ptr64 Void
+0x398 ActiveTimerListLock : Uint8B
+0x3a0 ActiveTimerListHead : _LIST_ENTRY
+0x3b0 Cid : _CLIENT_ID
+0x3c0 KeyedWaitSemaphore : _KSEMAPHORE
+0x3c0 AlpcWaitSemaphore : _KSEMAPHORE
+0x3e0 ClientSecurity : _PS_CLIENT_SECURITY_CONTEXT
+0x3e8 IrpList : _LIST_ENTRY
+0x3f8 TopLevelIrp : Uint8B
+0x400 DeviceToVerify : Ptr64 _DEVICE_OBJECT
+0x408 CpuQuotaApc : Ptr64 _PSP_CPU_QUOTA_APC
+0x410 Win32StartAddress : Ptr64 Void
+0x418 LegacyPowerObject : Ptr64 Void
+0x420 ThreadListEntry : _LIST_ENTRY
+0x430 RundownProtect : _EX_RUNDOWN_REF
+0x438 ThreadLock : _EX_PUSH_LOCK
+0x440 ReadClusterSize : Uint4B
+0x444 MmLockOrdering : Int4B
+0x448 CrossThreadFlags : Uint4B
+0x448 Terminated : Pos 0, 1 Bit
+0x448 ThreadInserted : Pos 1, 1 Bit
+0x448 HideFromDebugger : Pos 2, 1 Bit
+0x448 ActiveImpersonationInfo : Pos 3, 1 Bit
+0x448 Reserved : Pos 4, 1 Bit
+0x448 HardErrorsAreDisabled : Pos 5, 1 Bit
+0x448 BreakOnTermination : Pos 6, 1 Bit
+0x448 SkipCreationMsg : Pos 7, 1 Bit
+0x448 SkipTerminationMsg : Pos 8, 1 Bit
+0x448 CopyTokenOnOpen : Pos 9, 1 Bit
+0x448 ThreadIoPriority : Pos 10, 3 Bits
+0x448 ThreadPagePriority : Pos 13, 3 Bits
+0x448 RundownFail : Pos 16, 1 Bit
+0x448 NeedsWorkingSetAging : Pos 17, 1 Bit
+0x44c SameThreadPassiveFlags : Uint4B
+0x44c ActiveExWorker : Pos 0, 1 Bit
+0x44c ExWorkerCanWaitUser : Pos 1, 1 Bit
+0x44c MemoryMaker : Pos 2, 1 Bit
+0x44c ClonedThread : Pos 3, 1 Bit
+0x44c KeyedEventInUse : Pos 4, 1 Bit
+0x44c RateApcState : Pos 5, 2 Bits
+0x44c SelfTerminate : Pos 7, 1 Bit
+0x450 SameThreadApcFlags : Uint4B
+0x450 Spare : Pos 0, 1 Bit
+0x450 StartAddressInvalid : Pos 1, 1 Bit
+0x450 EtwPageFaultCalloutActive : Pos 2, 1 Bit
+0x450 OwnsProcessWorkingSetExclusive : Pos 3, 1 Bit
+0x450 OwnsProcessWorkingSetShared : Pos 4, 1 Bit
+0x450 OwnsSystemCacheWorkingSetExclusive : Pos 5, 1 Bit
+0x450 OwnsSystemCacheWorkingSetShared : Pos 6, 1 Bit
+0x450 OwnsSessionWorkingSetExclusive : Pos 7, 1 Bit
+0x451 OwnsSessionWorkingSetShared : Pos 0, 1 Bit
+0x451 OwnsProcessAddressSpaceExclusive : Pos 1, 1 Bit
+0x451 OwnsProcessAddressSpaceShared : Pos 2, 1 Bit
+0x451 SuppressSymbolLoad : Pos 3, 1 Bit
+0x451 Prefetching : Pos 4, 1 Bit
+0x451 OwnsDynamicMemoryShared : Pos 5, 1 Bit
+0x451 OwnsChangeControlAreaExclusive : Pos 6, 1 Bit
+0x451 OwnsChangeControlAreaShared : Pos 7, 1 Bit
+0x452 OwnsPagedPoolWorkingSetExclusive : Pos 0, 1 Bit
+0x452 OwnsPagedPoolWorkingSetShared : Pos 1, 1 Bit
+0x452 OwnsSystemPtesWorkingSetExclusive : Pos 2, 1 Bit
+0x452 OwnsSystemPtesWorkingSetShared : Pos 3, 1 Bit
+0x452 TrimTrigger : Pos 4, 2 Bits
+0x452 Spare1 : Pos 6, 2 Bits
+0x453 PriorityRegionActive : UChar
+0x454 CacheManagerActive : UChar
+0x455 DisablePageFaultClustering : UChar
+0x456 ActiveFaultCount : UChar
+0x457 LockOrderState : UChar
+0x458 AlpcMessageId : Uint8B
+0x460 AlpcMessage : Ptr64 Void
+0x460 AlpcReceiveAttributeSet : Uint4B
+0x468 AlpcWaitListEntry : _LIST_ENTRY
+0x478 CacheManagerCount : Uint4B
+0x47c IoBoostCount : Uint4B
+0x480 IrpListLock : Uint8B
+0x488 ReservedForSynchTracking : Ptr64 Void
+0x490 CmCallbackListHead : _SINGLE_LIST_ENTRY
HideFromDebugger可以说是主要判断目标
那么现在就很简单了 我们可以对目标线程的HideFromDebugger中的值设置为0
这样调试器就会正常工作了
But 如果驱动检测ETHREAD HideFromDebugger中的值那么还是会gg的
我们可以从内核调试函数入手
if
(PsGetCurrentThread()->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HIDEFROMDBG)
PATCH这个跳转
如:DbgkForwardException
kd> uf DbgkForwardException
nt!DbgkForwardException:
fffff800`04764678 488bc4 mov rax,rsp
fffff800`0476467b 48895808 mov qword ptr [rax+8],rbx
fffff800`0476467f 48896810 mov qword ptr [rax+10h],rbp
fffff800`04764683 48897018 mov qword ptr [rax+18h],rsi
fffff800`04764687 48897820 mov qword ptr [rax+20h],rdi
fffff800`0476468b 4154 push r12
fffff800`0476468d 4881ec30010000 sub rsp,130h
fffff800`04764694 8364244800 and dword ptr [rsp+48h],0
fffff800`04764699 c7442420a800d000 mov dword ptr [rsp+20h],0D000A8h
fffff800`047646a1 c744242408000000 mov dword ptr [rsp+24h],8
fffff800`047646a9 65488b042588010000 mov rax,qword ptr gs:[188h]
fffff800`047646b2 4c8be1 mov r12,rcx
fffff800`047646b5 418ae8 mov bpl,r8b
fffff800`047646b8 488b4870 mov rcx,qword ptr [rax+70h]
fffff800`047646bc 408afa mov dil,dl
fffff800`047646bf 80fa01 cmp dl,1
fffff800`047646c2 0f85d8c60700 jne nt! ?? ::NNGAKEGL::`string'+0x35d67 (fffff800`047e0da0) Branch
nt!DbgkForwardException+0x50:
fffff800`047646c8 65488b042588010000 mov rax,qword ptr gs:[188h]
fffff800`047646d1 f6804804000004 test byte ptr [rax+448h],4
fffff800`047646d8 0f85bbc60700 jne nt! ?? ::NNGAKEGL::`string'+0x35d60 (fffff800`047e0d99) Branch
nt!DbgkForwardException+0x66:
fffff800`047646de 488b99f0010000 mov rbx,qword ptr [rcx+1F0h]
nt!DbgkForwardException+0x6d:
fffff800`047646e5 4032f6 xor sil,sil
nt!DbgkForwardException+0x70:
fffff800`047646e8 4885db test rbx,rbx
fffff800`047646eb 0f85c7c60700 jne nt! ?? ::NNGAKEGL::`string'+0x35d7f (fffff800`047e0db8) Branch
nt!DbgkForwardException+0x79:
fffff800`047646f1 4080ff01 cmp dil,1
fffff800`047646f5 0f85bdc60700 jne nt! ?? ::NNGAKEGL::`string'+0x35d7f (fffff800`047e0db8) Branch
nt!DbgkForwardException+0x83:
fffff800`047646fb 32c0 xor al,al
nt!DbgkForwardException+0x85:
fffff800`047646fd 4c8d9c2430010000 lea r11,[rsp+130h]
fffff800`04764705 498b5b10 mov rbx,qword ptr [r11+10h]
fffff800`04764709 498b6b18 mov rbp,qword ptr [r11+18h]
fffff800`0476470d 498b7320 mov rsi,qword ptr [r11+20h]
fffff800`04764711 498b7b28 mov rdi,qword ptr [r11+28h]
fffff800`04764715 498be3 mov rsp,r11
fffff800`04764718 415c pop r12
fffff800`0476471a c3 ret
nt! ?? ::NNGAKEGL::`string'+0x35d60:
fffff800`047e0d99 33db xor ebx,ebx
fffff800`047e0d9b e94539f8ff jmp nt!DbgkForwardException+0x6d (fffff800`047646e5) Branch
nt! ?? ::NNGAKEGL::`string'+0x35d67:
fffff800`047e0da0 e8df39f9ff call nt!PsCaptureExceptionPort (fffff800`04774784)
fffff800`047e0da5 c744242407000000 mov dword ptr [rsp+24h],7
fffff800`047e0dad 40b601 mov sil,1
fffff800`047e0db0 488bd8 mov rbx,rax
fffff800`047e0db3 e93039f8ff jmp nt!DbgkForwardException+0x70 (fffff800`047646e8) Branch
nt! ?? ::NNGAKEGL::`string'+0x35d7f:
fffff800`047e0db8 488d4c2450 lea rcx,[rsp+50h]
fffff800`047e0dbd 498bd4 mov rdx,r12
fffff800`047e0dc0 41b898000000 mov r8d,98h
fffff800`047e0dc6 e82552cbff call nt!memmove (fffff800`04495ff0)
fffff800`047e0dcb 4533db xor r11d,r11d
fffff800`047e0dce 4084ed test bpl,bpl
fffff800`047e0dd1 410f94c3 sete r11b
fffff800`047e0dd5 bd01000180 mov ebp,80010001h
fffff800`047e0dda 44899c24e8000000 mov dword ptr [rsp+0E8h],r11d
fffff800`047e0de2 4080fe01 cmp sil,1
fffff800`047e0de6 752b jne nt! ?? ::NNGAKEGL::`string'+0x35dda (fffff800`047e0e13) Branch
nt! ?? ::NNGAKEGL::`string'+0x35daf:
fffff800`047e0de8 4885db test rbx,rbx
fffff800`047e0deb 741c je nt! ?? ::NNGAKEGL::`string'+0x35dd0 (fffff800`047e0e09) Branch
nt! ?? ::NNGAKEGL::`string'+0x35db4:
fffff800`047e0ded 488d4c2420 lea rcx,[rsp+20h]
fffff800`047e0df2 448ac7 mov r8b,dil
fffff800`047e0df5 488bd3 mov rdx,rbx
fffff800`047e0df8 e883cf0a00 call nt!DbgkpSendApiMessageLpc (fffff800`0488dd80)
fffff800`047e0dfd 488bcb mov rcx,rbx
fffff800`047e0e00 8bf0 mov esi,eax
fffff800`047e0e02 e83986ccff call nt!ObfDereferenceObject (fffff800`044a9440)
fffff800`047e0e07 eb1f jmp nt! ?? ::NNGAKEGL::`string'+0x35def (fffff800`047e0e28) Branch
nt! ?? ::NNGAKEGL::`string'+0x35dd0:
fffff800`047e0e09 8bc5 mov eax,ebp
fffff800`047e0e0b 33f6 xor esi,esi
fffff800`047e0e0d 8944244c mov dword ptr [rsp+4Ch],eax
fffff800`047e0e11 eb19 jmp nt! ?? ::NNGAKEGL::`string'+0x35df3 (fffff800`047e0e2c) Branch
nt! ?? ::NNGAKEGL::`string'+0x35dda:
fffff800`047e0e13 33c9 xor ecx,ecx
fffff800`047e0e15 4080ff01 cmp dil,1
fffff800`047e0e19 488d542420 lea rdx,[rsp+20h]
fffff800`047e0e1e 0f94c1 sete cl
fffff800`047e0e21 e8dad90500 call nt!DbgkpSendApiMessage (fffff800`0483e800)
fffff800`047e0e26 8bf0 mov esi,eax
nt! ?? ::NNGAKEGL::`string'+0x35def:
fffff800`047e0e28 8b44244c mov eax,dword ptr [rsp+4Ch]
nt! ?? ::NNGAKEGL::`string'+0x35df3:
fffff800`047e0e2c 85f6 test esi,esi
fffff800`047e0e2e 0f88c738f8ff js nt!DbgkForwardException+0x83 (fffff800`047646fb) Branch
nt! ?? ::NNGAKEGL::`string'+0x35dfb:
fffff800`047e0e34 3bc5 cmp eax,ebp
fffff800`047e0e36 7519 jne nt! ?? ::NNGAKEGL::`string'+0x35e18 (fffff800`047e0e51) Branch
nt! ?? ::NNGAKEGL::`string'+0x35dff:
fffff800`047e0e38 4080ff01 cmp dil,1
fffff800`047e0e3c 0f84b938f8ff je nt!DbgkForwardException+0x83 (fffff800`047646fb) Branch
nt! ?? ::NNGAKEGL::`string'+0x35e09:
fffff800`047e0e42 4c8d442420 lea r8,[rsp+20h]
fffff800`047e0e47 33d2 xor edx,edx
fffff800`047e0e49 498bcc mov rcx,r12
fffff800`047e0e4c e81fc90a00 call nt!DbgkpSendErrorMessage (fffff800`0488d770)
nt! ?? ::NNGAKEGL::`string'+0x35e18:
fffff800`047e0e51 85c0 test eax,eax
fffff800`047e0e53 0f99c0 setns al
fffff800`047e0e56 e9a238f8ff jmp nt!DbgkForwardException+0x85 (fffff800`047646fd) Branch
fffff800`047646d1 f6804804000004 test byte ptr [rax+448h],4(rax为ETHREAD)
fffff800`047646d8 0f85bbc60700 jne nt! ?? ::NNGAKEGL::`string'+0x35d60 (fffff800`047e0d99) Branch
这里就是判断了
我们可以直接nop fffff800`047646d8 这样就可以不修改HideFromDebugger的情况下让调试器正常工作