yzdbg 线程窗口中有一个显示 [亲和性] 的功能感觉挺不错的, 如下图:
yzdbg获取线程亲和性
看了od x64dbg udbg mdebug bugdbg等调试器都没有此功能! 其中 mdebug和bugdbg我甚至都没有找到线程窗口在哪里 -_-#
我知道有一个 SetProcessAffinityMask 函数, 我就以为理所当然的认为会有相应的 GetThreadAffinityMask 函数. 然并没有... 只有一个 SetThreadAffinityMask
查了一下 SetThreadAffinityMask 2001离线版本的返回值说明, 函数调用成功返回非0值, 如下图:
离线2001版_SetThreadAffinityMask
在线的MSDN, 说的就比较详细了, 函数成功返回之前的亲和力, 如下图:
在线版_SetThreadAffinityMask
既然这样, 那是不是可以利用调用两次来获取线程亲和力呢?
获取线程亲和性,方式一:
[C++] 纯文本查看 复制代码
// 因为只是为了获取线程亲和力, 所以参数可以随便填写, 但是注意不能传0, 否则会失败.
DWORD dwThreadAffinityMask = SetThreadAffinityMask(hThread, 1);
// 获取到线程亲和力, 记得要恢复原始的亲和力.
SetThreadAffinityMask(hThread, dwThreadAffinityMask);
这种方法虽然能获取到,但是总感觉 这样实现 不是很友好.特别是多核多线程运算时,这样可能还会影响运算结果.也影响效率.
获取线程亲和性,方式二:
通过 Native Api NtQueryInformationThread 函数实现.代码如下:
[C++] 纯文本查看 复制代码
typedef enum _THREADINFOCLASS{
ThreadBasicInformation = 0,
ThreadTimes = 1,
ThreadPriority = 2,
ThreadBasePriority = 3,
ThreadAffinityMask = 4,
ThreadImpersonationToken = 5,
ThreadDescriptorTableEntry = 6,
ThreadEnableAlignmentFaultFixup = 7,
ThreadEventPair = 8,
ThreadQuerySetWin32StartAddress = 9, // 入口
ThreadZeroTlsCell = 10,
ThreadPerformanceCount = 11,
ThreadAmILastThread = 12,
ThreadIdealProcessor = 13,
ThreadPriorityBoost = 14,
ThreadSetTlsArrayAddress = 15,
ThreadIsIoPending = 16,
ThreadHideFromDebugger = 17,
ThreadBreakOnTermination = 18,
ThreadSwitchLegacyState = 19,
ThreadIsTerminated = 20,
ThreadLastSystemCall = 21,
ThreadIoPriority = 22,
ThreadCycleTime = 23,
ThreadPagePriority = 24,
ThreadActualBasePriority = 25,
ThreadTebInformation = 26, // TEB
ThreadCSwitchMon = 27,
ThreadCSwitchPmu = 28,
ThreadWow64Context = 29,
ThreadGroupInformation = 30,
ThreadUmsInformation = 31,
ThreadCounterProfiling = 32,
ThreadIdealProcessorEx = 33,
ThreadCpuAccountingInformation = 34,
ThreadSuspendCount = 35, // 挂起次数
ThreadHeterogeneousCpuPolicy = 36,
ThreadContainerId = 37,
ThreadNameInformation = 38,
ThreadSelectedCpuSets = 39,
ThreadSystemThreadInformation = 40,
ThreadActualGroupAffinity = 41,
ThreadDynamicCodePolicyInfo = 42,
ThreadExplicitCaseSensitivity = 43,
ThreadWorkOnBehalfTicket = 44,
ThreadSubsystemInformation = 45,
ThreadDbgkWerReportActive = 46,
ThreadAttachContainer = 47,
ThreadManageWritesToExecutableMemory = 48,
ThreadPowerThrottlingState = 49,
ThreadWorkloadClass = 50,
MaxThreadInfoClass = 51,
}THREADINFOCLASS;
typedef struct _THREAD_BASIC_INFORMATION
{
LONG ExitStatus;
PVOID TebBaseAddress;
CLIENT_ID ClientId;
LONG AffinityMask; // 这个就是亲和性
LONG Priority;
LONG BasePriority;
}THREAD_BASIC_INFORMATION,*PTHREAD_BASIC_INFORMATION;
DWORD dwReturnLength = 0;
THREAD_BASIC_INFORMATION tbi = {0};
if(CNativeApi::NtQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof(tbi), &dwReturnLength))
{
LogErrorLine("ThreadBasicInformation Error");
return 0;
}
两者一对比, 显然第二种方法要更为友好.
|