调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID

Posted guolongzheng

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID相关的知识,希望对你有一定的参考价值。

这段时间公司项目中为了支持XP系统同事代码中用到了

GetThreadId 

这个微软的API 但是这个API最低支持版本是

Windows version Windows Vista [desktop apps | UWP apps] Windows Server 2003 [desktop apps | UWP apps]

最后使用了

ZwQueryInformationThread 来解决

解决以后记录下 如果又遇到同样问题的 可以参考

参考文档

http://undocumented.ntinternals.net/index.html?page=UserMode%2FUndocumented%20Functions%2FNT%20Objects%2FThread%2FTHREAD_INFORMATION_CLASS.html

具体代码如下:

  1 #include "stdafx.h"
  2 #include <Windows.h>
  3 #define STATUS_SUCCESS                   ((NTSTATUS)0x00000000L)    // ntsubauth
  4 typedef enum _THREADINFOCLASS {
  5     ThreadBasicInformation = 0,
  6     ThreadTimes = 1,
  7     ThreadPriority = 2,
  8     ThreadBasePriority = 3,
  9     ThreadAffinityMask = 4,
 10     ThreadImpersonationToken = 5,
 11     ThreadDescriptorTableEntry = 6,
 12     ThreadEnableAlignmentFaultFixup = 7,
 13     ThreadEventPair_Reusable = 8,
 14     ThreadQuerySetWin32StartAddress = 9,
 15     ThreadZeroTlsCell = 10,
 16     ThreadPerformanceCount = 11,
 17     ThreadAmILastThread = 12,
 18     ThreadIdealProcessor = 13,
 19     ThreadPriorityBoost = 14,
 20     ThreadSetTlsArrayAddress = 15,   // Obsolete
 21     ThreadIsIoPending = 16,
 22     ThreadHideFromDebugger = 17,
 23     ThreadBreakOnTermination = 18,
 24     ThreadSwitchLegacyState = 19,
 25     ThreadIsTerminated = 20,
 26     ThreadLastSystemCall = 21,
 27     ThreadIoPriority = 22,
 28     ThreadCycleTime = 23,
 29     ThreadPagePriority = 24,
 30     ThreadActualBasePriority = 25,
 31     ThreadTebInformation = 26,
 32     ThreadCSwitchMon = 27,   // Obsolete
 33     ThreadCSwitchPmu = 28,
 34     ThreadWow64Context = 29,
 35     ThreadGroupInformation = 30,
 36     ThreadUmsInformation = 31,   // UMS
 37     ThreadCounterProfiling = 32,
 38     ThreadIdealProcessorEx = 33,
 39     ThreadCpuAccountingInformation = 34,
 40     ThreadSuspendCount = 35,
 41     ThreadActualGroupAffinity = 41,
 42     ThreadDynamicCodePolicyInfo = 42,
 43     MaxThreadInfoClass = 45,
 44 } THREADINFOCLASS;
 45 typedef NTSTATUS (WINAPI*ZWQUERYINFORMATIONTHREAD)(
 46     _In_      HANDLE          ThreadHandle,
 47     _In_      THREADINFOCLASS ThreadInformationClass,
 48     _In_      PVOID           ThreadInformation,
 49     _In_      ULONG           ThreadInformationLength,
 50     _Out_opt_ PULONG          ReturnLength
 51 );
 52 typedef struct _CLIENT_ID {
 53     DWORD UniqueProcess;
 54     DWORD UniqueThread;
 55 } CLIENT_ID;
 56 typedef CLIENT_ID *PCLIENT_ID;
 57 typedef struct _THREAD_BASIC_INFORMATION {
 58     NTSTATUS                ExitStatus;
 59     PVOID                   TebBaseAddress;
 60     CLIENT_ID               ClientId;
 61     KAFFINITY               AffinityMask;
 62     LONG               Priority;
 63     LONG               BasePriority;
 64 } THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;
 65 ZWQUERYINFORMATIONTHREAD ZwQueryInformationThread;
 66 HMODULE init(LPCSTR szFuncNmae)
 67 {
 68     HMODULE hModule = LoadLibrary(_T("ntdll.dll"));
 69     if (hModule)
 70         ZwQueryInformationThread = (ZWQUERYINFORMATIONTHREAD)::GetProcAddress(hModule, szFuncNmae);
 71     return hModule;
 72 }
 73 int WINAPI threadProc(LPVOID ARG)
 74 {
 75     int i = 100000;
 76     while (--i)
 77     {
 78         printf("%d
", i);
 79         Sleep(100);
 80     }
 81     return i;
 82 }
 83 int main()
 84 {
 85     DWORD dwThreadID = NULL;
 86     DWORD dwOldThreadID = NULL;
 87     HMODULE hModule = nullptr;
 88     hModule = init("ZwQueryInformationThread");
 89     HANDLE hthread = ::CreateThread(NULL, NULL, (LPTHREAD_START_ROUTINE)threadProc, NULL, NULL, &dwOldThreadID);
 90     if (hModule && ZwQueryInformationThread)
 91     {
 92         THREAD_BASIC_INFORMATION tbi;
 93         DWORD lRet = NULL;
 94         ZeroMemory(&tbi, sizeof(THREAD_BASIC_INFORMATION));
 95         if (ZwQueryInformationThread(hthread, ThreadBasicInformation, &tbi, sizeof(THREAD_BASIC_INFORMATION), &lRet) != STATUS_SUCCESS)
 96         {
 97             printf("获取失败
");
 98         }
 99         printf("PROCESSid %d ThreadID %d
", tbi.ClientId.UniqueProcess, tbi.ClientId.UniqueThread);
100         FreeLibrary(hModule);
101     }
102 
103     CloseHandle(hthread);
104     return 0;
105 }

 

以上是关于调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID的主要内容,如果未能解决你的问题,请参考以下文章

微软发布用于Kafka生态系统的Azure Event Hub公开预览版

3秒获得Win11系统管理员权限,微软高危漏洞被公开,只因悬赏奖金打骨折

免费公开课-零基础小白如何开始自己的Python运维之路(王进老师)

从承诺解决方案调用时,Vuex 商店未更新

乔布斯全新采访曝光:吐槽微软,回应争议,还要把Mac扔出窗外,然而…

如何在JOOQ中公开新的SQL函数