调用微软未公开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\r\n", 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("获取失败\r\n");
 98         }
 99         printf("PROCESSid %d ThreadID %d\r\n", tbi.ClientId.UniqueProcess, tbi.ClientId.UniqueThread);
100         FreeLibrary(hModule);
101     }
102
103     CloseHandle(hthread);
104     return 0;
105 }

原文地址:https://www.cnblogs.com/guolongzheng/p/9459411.html

时间: 2024-10-11 01:35:52

调用微软未公开ZwQueryInformationThread函数根据线程句柄获取线程ID的相关文章

微软未公开存储过程及有用的函数

原文:微软未公开存储过程及有用的函数 从网上收集,有些已经在2008不支持或者后续版本不支持,所以需要慎用. XP_FileExist: 用法:EXEC xp_fileexist <filename> [, <file_exists INT> OUTPUT] 例子:exec master.dbo.xp_fileexist 'C:\temp' SP_MSForEachDb: 例子1:exec dbo.sp_MSforeachdb 'select ''?'', * from [?].I

为什么关闭了线程句柄,线程仍可以运行

主线程只要拥有线程句柄,事后就可以对线程执行某些操作,比如查询线程状态等等,靠的就是句柄,如果没有句柄,系统就无从知道要查的是那个线程的状态.但保持这个句柄不关闭,并不是线程运行的必要条件. 关闭线程句柄只是释放句柄资源,新开启线程后,如果不再利用其句柄,应该关闭句柄,释放系统资源.关闭线程句柄和线程的结束与否没有关系. 句柄可以认为是系统对资源(如线程)的分配的一个编号.关闭这个编号,对于不同的资源,效果不尽相同.对于线程来说,关闭这个编号并不意味着终止线程,只是之后很难再操纵这个线程.   

微软未公开的 SP

一些用在SQL 2000的企业管理GUI中,并且不打算用于其他的流程.微软已预计将其中的一些存储过程从未来的SQL Server版本中删除(或已经删除了).虽然这些存储过程可能很有用并为你节省了很多时间,但是他们可以在任何时候改变他们的函数或简单的删除掉. 下面的图表显示了当许多存储过程从一个Microsoft SQL Server版本移入另一个版本时,引入了新的存储过程,而原来的一些则从安装包里删除了.大多数的存储过程,如果不是所有的,要求用户是系统管理员服务器角色以便执行这些存储过程.和文件

lua入门之二:c/c++ 调用lua及多个函数返回值的获取

当 Lua 调用 C 函数的时候,使用和 C 调用 Lua 同样类型的栈来交互. C 函数从栈中获取她的參数.调用结束后将返回结果放到栈中.为了区分返回结果和栈中的其它的值,每一个 C 函数还会返回结果的个数(the  function  returns  (in  C)  the  number  of  results  it  is leaving on the stack.). // luacallcpp.cpp : 定义控制台应用程序的入口点. // #include "stdafx.

软件看门狗--别让你地程序无响应(使用未公开API函数IsHungAppWindow,知识点较全)

正文一.概述一些重要的程序,必须让它一直跑着:而且还要时时关心它的状态——不能让它出现死锁现象.当然,如果一个主程序会出现死锁,肯定是设计或者编程上的失误.我们首要做的事是,把这个Bug揪出来.但如果时间紧迫,这个Bug又“飘忽不定”,那么,我们还是先写一个软件“看门狗”,暂时应一下急吧. “看门狗”的需求描述:“看门狗”的运行不出现界面窗口,具有一定的隐蔽性:定时判断目标进程是否运行在当前系统中,如果没有则启动目标进程:判断目标进程是否“没有响应”,如果是则终止目标进程:如果目标进程“没有响应

利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)

利用未公开API获取终端会话闲置时间(Idle Time)和登入时间(Logon Time)作者:Tuuzed(土仔)   发表于:2008年3月3日23:12:38 版权声明:可以任意转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明.http://www.cppblog.com/tuuzed/archive/2008/03/03/43631.html 可能很多人都知道NT系统的query user命令,命令返回“使用者名称 工作阶段名称 识别码 状态 闲置时间 登入时间”.如图

线程属性总结 线程的api属性

http://blog.csdn.net/zsf8701/article/details/7842392 //线程属性结构如下:typedef struct{ int etachstate; //线程的分离状态 int schedpolicy; //线程调度策略 structsched_param schedparam; //线程的调度参数 int inheritsched; //线程的继承性 int scope; //线程的作用域 size_t guardsize; //线程栈末尾的警戒缓冲区

Linux之线程、线程控制、线程属性

一.整体大纲 二.线程相关 1. 什么是线程    LWP:light weight process 轻量级的进程,本质仍是进程(在Linux环境下) 进程:独立地址空间,拥有PCB 线程:也有PCB,但没有独立的地址空间(共享) 区别:在于是否共享地址空间. 独居(进程):合租(线程). Linux下: 线程:最小的执行单位 进程:最小分配资源单位,可看成是只有一个线程的进程. 2. Linux内核线程实现原理     (1)线程实现原理 类Unix系统中,早期是没有“线程”概念的,80年代才

PowerBuilder -- 未公开函数

原文:http://blog.csdn.net/happymagic/article/details/51077322 @.已知一个DW中的某列的列名(在字符串变量中),以获得这个列对象的DWO 方法是: DWObject ldwo_use,ldwo_name ldwo_use = dw_1.Object ldwo_name = ldwo_use.__get_attribute("name",FALSE) 这样就可以在用setitem()设置值时,手工调用数窗的itemchanged事