注册

CpuDbg x96

查看: 931|回复: 0
收起左侧

获取线程亲和性问题

[复制链接]
发表于 2022-10-3 07:28:07 | 显示全部楼层 |阅读模式
yzdbg 线程窗口中有一个显示 [亲和性] 的功能感觉挺不错的, 如下图:

yzdbg获取线程亲和性

yzdbg获取线程亲和性


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

离线2001版_SetThreadAffinityMask

离线2001版_SetThreadAffinityMask


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

在线版_SetThreadAffinityMask

在线版_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;
}


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


回复

使用道具 举报

游客
回复
您需要登录后才可以回帖 登录 | 注册

QQ|Archiver|手机版| CpuDbg x96

GMT, 2024-5-19 01:51 , Processed in 0.062500 second(s), 20 queries .

Powered by Discuz! X3.4 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表