CpuDbg 发表于 2022-10-3 07:28:07

获取线程亲和性问题

yzdbg 线程窗口中有一个显示 的功能感觉挺不错的, 如下图:


看了od x64dbg udbg mdebug bugdbg等调试器都没有此功能! 其中 mdebug和bugdbg我甚至都没有找到线程窗口在哪里 -_-#
我知道有一个 SetProcessAffinityMask 函数, 我就以为理所当然的认为会有相应的 GetThreadAffinityMask 函数. 然并没有...只有一个 SetThreadAffinityMask
查了一下 SetThreadAffinityMask2001离线版本的返回值说明, 函数调用成功返回非0值, 如下图:


在线的MSDN, 说的就比较详细了, 函数成功返回之前的亲和力, 如下图:



既然这样, 那是不是可以利用调用两次来获取线程亲和力呢?


获取线程亲和性,方式一:

// 因为只是为了获取线程亲和力, 所以参数可以随便填写, 但是注意不能传0, 否则会失败.
DWORD dwThreadAffinityMask = SetThreadAffinityMask(hThread, 1);
// 获取到线程亲和力, 记得要恢复原始的亲和力.
SetThreadAffinityMask(hThread, dwThreadAffinityMask);


这种方法虽然能获取到,但是总感觉 这样实现 不是很友好.特别是多核多线程运算时,这样可能还会影响运算结果.也影响效率.

获取线程亲和性,方式二:
通过 Native ApiNtQueryInformationThread 函数实现.代码如下:


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;
}


两者一对比, 显然第二种方法要更为友好.


页: [1]
查看完整版本: 获取线程亲和性问题