首页
社区
课程
招聘
[原创]调试陷阱ThreadHideFromDebugger的另一种对抗方法
2019-2-27 10:55 17297

[原创]调试陷阱ThreadHideFromDebugger的另一种对抗方法

2019-2-27 10:55
17297
测试环境: windows 7 x64
炒个冷饭,说说ThreadHideFromDebugger的另一种对抗方法,之所以说是另一种是因为第一种方法 无论是r3还是r0都可以用hook解决。
接下来说说另一种方法 ,先来看一个函数定义:
NTSTATUS
NTAPI
NtSetInformationThread(
    _In_ HANDLE ThreadHandle,
    _In_ THREADINFOCLASS ThreadInformationClass,
    _In_reads_bytes_(ThreadInformationLength) PVOID ThreadInformation,
    _In_ ULONG ThreadInformationLength
    );
它是这么用的:
NtSetInformationThread(handle.get(), ThreadHideFromDebugger, nullptr, 0);

再来看一个结构定义:
typedef enum _THREADINFOCLASS {
    ThreadBasicInformation          = 0,
    ThreadTimes                     = 1,
    ThreadPriority                  = 2,
    ThreadBasePriority              = 3,
    ThreadAffinityMask              = 4,
    ThreadImpersonationToken        = 5,
    ThreadDescriptorTableEntry      = 6,
    ThreadEnableAlignmentFaultFixup = 7,
    ThreadEventPair_Reusable        = 8,
    ThreadQuerySetWin32StartAddress = 9,
    ThreadZeroTlsCell               = 10,
    ThreadPerformanceCount          = 11,
    ThreadAmILastThread             = 12,
    ThreadIdealProcessor            = 13,
    ThreadPriorityBoost             = 14,
    ThreadSetTlsArrayAddress        = 15,   // Obsolete
    ThreadIsIoPending               = 16,
    ThreadHideFromDebugger          = 17,
    ThreadBreakOnTermination        = 18,
    ThreadSwitchLegacyState         = 19,
    ThreadIsTerminated              = 20,
    ThreadLastSystemCall            = 21,
    ThreadIoPriority                = 22,
    ThreadCycleTime                 = 23,
    ThreadPagePriority              = 24,
    ThreadActualBasePriority        = 25,
    ThreadTebInformation            = 26,
    ThreadCSwitchMon                = 27,   // Obsolete
    ThreadCSwitchPmu                = 28,
    ThreadWow64Context              = 29,
    ThreadGroupInformation          = 30,
    ThreadUmsInformation            = 31,   // UMS
    ThreadCounterProfiling          = 32,
    ThreadIdealProcessorEx          = 33,
    ThreadCpuAccountingInformation  = 34,
    ThreadSuspendCount              = 35,
    ThreadActualGroupAffinity       = 41,
    ThreadDynamicCodePolicyInfo     = 42,
    ThreadSubsystemInformation      = 45,

    MaxThreadInfoClass              = 51,
} THREADINFOCLASS;

今天我们只关心 ThreadHideFromDebugger,由上面的结构可以看出它的值是:0x11。
好,那我们看下对于这个参数,NtSetInformationThread是怎么实现的:
    case ThreadHideFromDebugger:
        if (ThreadInformationLength != 0) {
            return STATUS_INFO_LENGTH_MISMATCH;
        }

        st = ObReferenceObjectByHandle (ThreadHandle,
                                        THREAD_SET_INFORMATION,
                                        PsThreadType,
                                        PreviousMode,
                                        &Thread,
                                        NULL);

        if (!NT_SUCCESS (st)) {
            return st;
        }

        PS_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_HIDEFROMDBG);

        ObDereferenceObject (Thread);

        return st;
        break;
接下来,来看看调试子系统对于有“PS_CROSS_THREAD_FLAGS_HIDEFROMDBG”这个标志的线程是怎么处理的:
    Process = PsGetCurrentProcess();
    if (DebugException) {
        if (PsGetCurrentThread()->CrossThreadFlags&PS_CROSS_THREAD_FLAGS_HIDEFROMDBG) {
            Port = NULL;
        } else {
            Port = Process->DebugPort;
        }
        LpcPort = FALSE;
    } else {
        Port = Process->ExceptionPort;
        m.h.u2.ZeroInit = LPC_EXCEPTION;
        LpcPort = TRUE;
    }
emmm...破案了,原来清空DebugPort不是某P首创,人家巨硬的内核里本来就是这么做的,只不过一个是暴力清空而另一个是“假装没有”。
这也就非常符合微软对“ ThreadHideFromDebugger ”这个参数的描述:设置此参数将使这条线程对调试器“隐藏”。即调试器收不到调试信息,因而就会出现当调试器对被调试进程下断点,线程执行到被下断点代码的时候就会卡死这种现象。
OK,接下来我们考虑一下怎么干掉它。
看以下定义:
#define RtlInterlockedSetBitsDiscardReturn(Flags, Flag) \
    (VOID) RtlInterlockedSetBits(Flags, Flag)

#define PS_SET_BITS(Flags, Flag) \
    RtlInterlockedSetBitsDiscardReturn (Flags, Flag)
还记得这句代码吗?
PS_SET_BITS (&Thread->CrossThreadFlags, PS_CROSS_THREAD_FLAGS_HIDEFROMDBG);
从这句代码我们得到了关键点:CrossThreadFlags
看一下 ETHREAD的结构:
dt _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
所以 CrossThreadFlags的偏移是  0x448。
然后就可以敲代码了:
auto RemoveThreadFlagByClientId(PCLIENT_ID a_cid) -> NTSTATUS
{
	auto v_ret_status { STATUS_SUCCESS };
	PETHREAD v_thread;
	CLIENT_ID v_cid;

	PAGED_CODE();
	__try
	{
		ProbeForRead(a_cid, sizeof(CLIENT_ID), sizeof(ULONG));
		v_cid = *a_cid;
	}
	__except (EXCEPTION_EXECUTE_HANDLER)
	{
		return GetExceptionCode();
	}
	
	if (nullptr != v_cid.UniqueThread)
	{
		//获得ETHREAD
		v_ret_status = PsLookupThreadByThreadId(v_cid.UniqueThread,&v_thread);
		if (!NT_SUCCESS(v_ret_status))
		{
			return v_ret_status;
		}
		//&v_thread->CrossThreadFlags & ThreadHideFromDebugger;
		//win7 sp1 x64
		#define cross_thread_flags_offest 0x448
		if(*reinterpret_cast<PULONG>(reinterpret_cast<ULONG64>(v_thread)) + cross_thread_flags_offest & ThreadHideFromDebugger)
		{
			
			*reinterpret_cast<PULONG>(reinterpret_cast<ULONG64>(v_thread) + cross_thread_flags_offest) &= ~ThreadHideFromDebugger;
			
		}
	}
	return v_ret_status;
}
这样,就可以从线程的ETHREAD摘掉这个标志了。
什么, 你问有啥用?SSDT就不说了,R3的内存加载一份调用就把你的hook绕过了。

示例代码见:https://github.com/luciouskami/RemoveFlagTest
瞎写的,见谅。


[CTF入门培训]顶尖高校博士及硕士团队亲授《30小时教你玩转CTF》,视频+靶场+题目!助力进入CTF世界

最后于 2019-2-27 23:49 被黑洛编辑 ,原因:
收藏
点赞5
打赏
分享
最新回复 (20)
雪    币: 1535
活跃值: (695)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
开花的水管 2019-2-27 13:53
2
0
雪    币: 1140
活跃值: (102)
能力值: ( LV4,RANK:48 )
在线值:
发帖
回帖
粉丝
大只狼 2019-2-27 16:16
3
0
雪    币: 368
活跃值: (431)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
又出bug了 2 2019-3-5 21:54
4
0
要是优雅的干掉Hidefromdebugger
需要重写掉调试流程的某些函数,干脆不用这个标志位就好了
3环枚举符号发送到0环,0环对着ida和wrk的源代码抄,论坛也有类似的代码
自己创建新的DebugPort类型,顺便也过了句柄表检测

最后于 2019-3-5 21:55 被又出bug了编辑 ,原因:
雪    币: 60
活跃值: (479)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
uvbs 2019-3-5 21:59
5
0
又出bug了 要是优雅的干掉Hidefromdebugger需要重写掉调试流程的某些函数,干脆不用这个标志位就好了3环枚举符号发送到0环,0环对着ida和wrk的源代码抄,论坛也有类似的代码自己创建新的DebugP ...
求教win7 和win10 如何新建DebugPort
雪    币: 368
活跃值: (431)
能力值: ( LV2,RANK:140 )
在线值:
发帖
回帖
粉丝
又出bug了 2 2019-3-5 22:04
6
0
uvbs 求教win7 和win10 如何新建DebugPort
DbgkInitialize (
    VOID
    )
/*++

Routine Description:

    Initialize the debug system

Arguments:

    None

Return Value:

    NTSTATUS - Status of operation

--*/
{
    NTSTATUS Status;
    UNICODE_STRING Name;
    OBJECT_TYPE_INITIALIZER oti = {0};
    GENERIC_MAPPING GenericMapping = {STANDARD_RIGHTS_READ | DEBUG_READ_EVENT,
                                      STANDARD_RIGHTS_WRITE | DEBUG_PROCESS_ASSIGN,
                                      STANDARD_RIGHTS_EXECUTE | SYNCHRONIZE,
                                      DEBUG_ALL_ACCESS};


    PAGED_CODE ();

    ExInitializeFastMutex (&DbgkpProcessDebugPortMutex);

    RtlInitUnicodeString (&Name, L"DebugObject");

    oti.Length                    = sizeof (oti);
    oti.SecurityRequired          = TRUE;
    oti.InvalidAttributes         = 0;
    oti.PoolType                  = NonPagedPool;
    oti.DeleteProcedure           = DbgkpDeleteObject;
    oti.CloseProcedure            = DbgkpCloseObject;
    oti.ValidAccessMask           = DEBUG_ALL_ACCESS;
    oti.GenericMapping            = GenericMapping;
    oti.DefaultPagedPoolCharge    = 0;
    oti.DefaultNonPagedPoolCharge = 0;

    Status = ObCreateObjectType (&Name, &oti, NULL, &DbgkDebugObjectType);
    if (!NT_SUCCESS (Status)) {
        return Status;
    }
    return Status;
}
--
直接抄,wrk提供了源代码,把其余函数的符号位置找到就好了,这个是楼主的帖子,写多不好(win7和win10也有这个函数,你打开ida逆下基本没怎么改)
最后于 2019-3-5 22:05 被又出bug了编辑 ,原因:
雪    币: 6124
活跃值: (4126)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
黑洛 1 2019-3-6 00:59
7
0
又出bug了 uvbs 求教win7 和win10 如何新建DebugPort DbgkInitialize&nbsp;(&nbsp;&nbs ...
实际上,你说的这个方法是最好的,也是能根本解决问题的。还准备啥时候再写写骗个回复什么的。
雪    币: 1385
活跃值: (376)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
晨曦风海 2019-3-8 16:53
8
0
这饭好冷
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Heiyiren123 2019-8-5 15:51
9
0
黑洛 实际上,你说的这个方法是最好的,也是能根本解决问题的。还准备啥时候再写写骗个回复什么的。
挖坟了,不明白为什么我SSDT HOOK了 NtSetInformationThread 并没有收到第二个参数为0x11的这条记录,大多数参数值是0x5。

我在应用层已经调用了ZwSetInformationThread ,SSDT  Hook 用的是论坛找的一位老哥的 接管MSR那份代码,系统是Win7 64位。

尝试了很多次,无论是自己写的程序调用ZwSetInformationThread,还是某游戏(调试器无法收到消息,我怀疑调用了该函数,使用CE的VEH能捕获到中断信息,使用其他方式捕获断点都会因为没有程序来处理这个异常而导致游戏崩溃),最奇怪的还是NtSetInformationThread接收不到我自己程序调用ZwSetInformationThread的过程,但是ZwSetInformationThread确实生效了。
雪    币: 6124
活跃值: (4126)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
黑洛 1 2019-8-5 18:19
10
0
Heiyiren123 挖坟了,不明白为什么我SSDT HOOK了 NtSetInformationThread 并没有收到第二个参数为0x11的这条记录,大多数参数值是0x5。 我在应用层已经调用了ZwSetInfo ...
这个问题,你要看KiUserExceptionDispatcher是不是被hook了,比如某P,或者在+8处(11平台)
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Heiyiren123 2019-8-6 14:19
11
0
黑洛 这个问题,你要看KiUserExceptionDispatcher是不是被hook了,比如某P,或者在+8处(11平台)
 首先感谢老哥抽空回复我。

我是用XT检测看到游戏在R3层没有任何HOOK,并且R0层没有任何驱动,且我自己写的程序调用ZwSetInformationThread 函数,在R0层的HOOK中也无法收到任何消息,系统调用NtSetInformationThread倒是能被我拦截到几个。

不知道是不是因为MSR接管的只有KiFastCallEntry进入内核的函数调用,而通过中断门调用的KiSystemServeive并没有被我所拦截。

目前基础还比较差,自己动手实现验证所想暂时还做不到,还在阅读内核相关材料,所以想问问老哥这个思路对不对,思路对了我后面把PG补丁给打了,然后直接 HOOK 就可以了。
雪    币: 9616
活跃值: (1826)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
Sprite雪碧 1 2019-8-6 15:05
12
0
Heiyiren123 [em_76] 首先感谢老哥抽空回复我。 我是用XT检测看到游戏在R3层没有任何HOOK,并且R0层没有任何驱动,且我自己写的程序调用ZwSetInformationThread 函数,在R0层 ...
听你这么一说还没打pg补丁,那现在应该还是在虚拟机测试咯。
自己调用这个api是在有游戏的环境下还是没游戏的环境下?
有游戏的环境下多半是检测有操作,没游戏的话检查自己的代码。
最后于 2019-8-6 15:06 被Sprite雪碧编辑 ,原因:
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Heiyiren123 2019-8-6 18:59
13
0
Sprite雪碧 Heiyiren123 [em_76] 首先感谢老哥抽空回复我。 我是用XT检测看到游戏在R3层没有任何HOOK,并且R0层没有任何驱动,且我自己写的程 ...
我使用的是一套接管MSR进行SSDT的代码,确实能捕获到其他调用的信息,比如系统某些其他函数调用了NtSetInformationThread,我都能捕获到并且打印出来,奇怪的是我自己的代码直接调用的ZwSetInformationThread消息没有被拦截到,我回去再检查检查,也再试试把PG干掉之后直接Hook看看。

目前的情况总结下就是这样:

1.在虚拟机里面,Win7 64位,没打PG补丁,用的过期驱动签名。
2.是通过接管MSR来实现SSDT的HOOK,能拦截到一些R3层调用API,但是HOOK了NtSetInformationThread,部分调用拦截不到(还是可以收到一些调用消息,比如第二个参数值位5和3的调用),怀疑接管MSR这种方式有问题,但不能确定下来是什么问题。
3.因为之前学习的时候学到3环进入0环有2种方式,systementry 和 中断门,而且systementry是走的KiFastCallEntry这条路线,但印象中那套接管MSR的代码是HOOK KiFastCallEntry入口来实现的,所以怀疑自己是不是漏掉了通过中断门这种方式进入R0层的代码。

  还有就是多谢老哥们的指点,待我解决这个问题之后,会把最后的解决方法发在这下面。
雪    币: 310
活跃值: (1917)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
niuzuoquan 2019-8-6 20:24
14
0
mark
雪    币: 9616
活跃值: (1826)
能力值: ( LV5,RANK:73 )
在线值:
发帖
回帖
粉丝
Sprite雪碧 1 2019-8-6 21:19
15
0
Heiyiren123 我使用的是一套接管MSR进行SSDT的代码,确实能捕获到其他调用的信息,比如系统某些其他函数调用了NtSetInformationThread,我都能捕获到并且打印出来,奇怪的是我自己的代码直接调用的 ...
int2e好像是在系统启动期间的时候走的,之后好像就一直是syscall,不会走int2e。
可以尝试替换函数指针来进行hook,不一定非要接管msr。
雪    币: 6124
活跃值: (4126)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
黑洛 1 2019-8-6 22:44
16
0
Heiyiren123 我使用的是一套接管MSR进行SSDT的代码,确实能捕获到其他调用的信息,比如系统某些其他函数调用了NtSetInformationThread,我都能捕获到并且打印出来,奇怪的是我自己的代码直接调用的 ...
具体是什么游戏?毕竟涉及到游戏了,如果有经验的话还是不需要去盲猜了。
雪    币: 4448
活跃值: (3513)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
木志本柯 2019-8-7 03:57
17
0
我凑,不知道该说什么。。留个足迹。。。
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
Heiyiren123 2019-8-9 16:39
18
0
黑洛 具体是什么游戏?毕竟涉及到游戏了,如果有经验的话还是不需要去盲猜了。
我在研究调试魔域这款游戏,他驱动没加载起来,只有R3层的反调试,CE的 VEH 模式下断点都没问题,但是调试器收不到消息。

注:因为自己以前玩过这款游戏,所以拿这款游戏做研究,学习他的反调试系统,不是想做外挂。
雪    币: 224
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
mb_qjljtrkk 2020-3-7 16:07
19
0
大佬加一下我的qq1255165501 高价请教您几个问题 自己搞不懂
雪    币: 89
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sanqiu 2022-12-9 05:26
20
0
接下来,来看看调试子系统对于有“PS_CROSS_THREAD_FLAGS_HIDEFROMDBG”这个标志的线程是怎么处理的

这个处理函数叫啥?
雪    币: 89
能力值: ( LV1,RANK:0 )
在线值:
发帖
回帖
粉丝
sanqiu 2022-12-9 05:53
21
0
又出bug了 要是优雅的干掉Hidefromdebugger需要重写掉调试流程的某些函数,干脆不用这个标志位就好了3环枚举符号发送到0环,0环对着ida和wrk的源代码抄,论坛也有类似的代码自己创建新的DebugP ...
debugport 不是 debugobject ...
游客
登录 | 注册 方可回帖
返回