CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
山寨机中的战斗机! 程序优化工程师到底对IT界有没有贡献
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  进程/线程/DLL

关于线程

楼主lolin(lolin)2000-11-22 09:15:00 在 VC/MFC / 进程/线程/DLL 提问

知道进程句柄怎样取得其下所有线程的句柄?急! 问题点数:20、回复次数:9Top

1 楼wjf(ww)回复于 2000-11-22 09:54:00 得分 0

msdn的例子里有Process   view的源程序,不妨看看!Top

2 楼lolin(lolin)回复于 2000-11-22 17:18:00 得分 0

我已看过,但只有如何取得线程ID,不知怎样将ID转化为HANDLE!Top

3 楼net_worm(三流)回复于 2000-11-22 19:08:00 得分 0

强制转换呀……Top

4 楼wjf(ww)回复于 2000-11-22 20:58:00 得分 0

要句柄干什么?  
  记得曾经讨论过,线程的句柄除了创建时能得到之外,其他情况下几乎不可能得到!  
  你要句柄无非是为了操纵他,请记住要在进程空间外单独操纵线程几乎不可能。Top

5 楼singlerace(独行者)回复于 2000-11-23 15:23:00 得分 0

可以从线程id得到线程句柄的,当然也可以操纵它,比如TerminateThread。  
   
  Top

6 楼singlerace(独行者)回复于 2000-11-23 15:25:00 得分 0

在NT下是可以的。我已经试成功了。  
  用了ntdll.dll里的3个函数:  
  NtQuerySystemInformation,  
  NtQueryObject,  
  NtQueryInformationThread  
  不光得到线程handle,还可以在系统范围枚举所进程、线程、内核句柄。    
     
  回复人:singlerace(2000-11-10   12:15:00   )   得0分    
  #include   <windows.h>  
  #include   <stdio.h>  
  #include   <TCHAR.h>  
   
   
   
   
   
   
  typedef   DWORD   (WINAPI   *PNtQueryObject)(   HANDLE,   DWORD,   VOID*,   DWORD,   VOID*   );  
  typedef   DWORD   (WINAPI   *PNtQuerySystemInformation)(   DWORD,   VOID*,   DWORD,   ULONG*   );  
  typedef   DWORD   (WINAPI   *PNtQueryInformationThread)(HANDLE,   ULONG,   PVOID,   DWORD,   DWORD*   );  
  typedef   DWORD   (WINAPI   *PNtQueryInformationFile)(HANDLE,   PVOID,   PVOID,   DWORD,   DWORD   );  
  typedef   DWORD   (WINAPI   *PNtQueryInformationProcess)(HANDLE,   DWORD,   PVOID,   DWORD,   PVOID   );  
   
   
   
  typedef   struct   _THREAD_INFORMATION  
  {  
  DWORD   ProcessId;  
  DWORD   ThreadId;  
  HANDLE   ThreadHandle;    
  }   THREAD_INFORMATION;  
   
   
   
   
   
   
  typedef   struct   _BASIC_THREAD_INFORMATION   {  
  DWORD   u1;  
  DWORD   u2;  
  DWORD   u3;  
  DWORD   ThreadId;  
  DWORD   u5;  
  DWORD   u6;  
  DWORD   u7;  
  }   BASIC_THREAD_INFORMATION;  
   
   
   
  enum   {  
  OB_TYPE_UNKNOWN   =   0,  
  OB_TYPE_TYPE   =   1,  
  OB_TYPE_DIRECTORY,  
  OB_TYPE_SYMBOLIC_LINK,  
  OB_TYPE_TOKEN,  
  OB_TYPE_PROCESS,  
  OB_TYPE_THREAD,  
  OB_TYPE_UNKNOWN_7,  
  OB_TYPE_EVENT,  
  OB_TYPE_EVENT_PAIR,  
  OB_TYPE_MUTANT,  
  OB_TYPE_UNKNOWN_11,  
  OB_TYPE_SEMAPHORE,  
  OB_TYPE_TIMER,  
  OB_TYPE_PROFILE,  
  OB_TYPE_WINDOW_STATION,  
  OB_TYPE_DESKTOP,  
  OB_TYPE_SECTION,  
  OB_TYPE_KEY,  
  OB_TYPE_PORT,  
  OB_TYPE_WAITABLE_PORT,  
  OB_TYPE_UNKNOWN_21,  
  OB_TYPE_UNKNOWN_22,  
  OB_TYPE_UNKNOWN_23,  
  OB_TYPE_UNKNOWN_24,  
  //OB_TYPE_CONTROLLER,  
  //OB_TYPE_DEVICE,  
  //OB_TYPE_DRIVER,  
  OB_TYPE_IO_COMPLETION,  
  OB_TYPE_FILE                                                  
  }   SystemHandleType;  
   
   
   
  typedef   struct   _SYSTEM_HANDLE  
  {  
  DWORD   ProcessID;  
  WORD   HandleType;  
  WORD   HandleNumber;  
  DWORD   KernelAddress;  
  DWORD   Flags;  
  }   SYSTEM_HANDLE;  
   
   
   
  typedef   struct   _SYSTEM_HANDLE_INFORMATION  
  {  
  DWORD   Count;  
  SYSTEM_HANDLE   Handles[1];  
  }   SYSTEM_HANDLE_INFORMATION;  
   
   
   
  PNtQuerySystemInformation   NtQuerySystemInformation   =   NULL;  
  PNtQueryObject   NtQueryObject   =   NULL;  
  PNtQueryInformationThread   NtQueryInformationThread   =   NULL;  
  PNtQueryInformationFile   NtQueryInformationFile   =   NULL;  
  PNtQueryInformationProcess   NtQueryInformationProcess   =   NULL;  
   
   
   
  BOOL   Init();  
  BOOL   NtDllStatus   =   Init();  
   
   
   
  //   Enable   the   SeDebugPrivilege  
  static   void   EnableDebugPriv(   void   )  
  {  
  HANDLE   hToken;  
  LUID   sedebugnameValue;  
  TOKEN_PRIVILEGES   tkp;  
   
   
   
  //   enable   the   SeDebugPrivilege  
  if   (   !   OpenProcessToken(   GetCurrentProcess(),  
  TOKEN_ADJUST_PRIVILEGES   |   TOKEN_QUERY,   &hToken   )   )  
  {  
  _tprintf(   _T("OpenProcessToken()   failed,   Error   =   %d   SeDebugPrivilege   is   not   available.\n")   ,   GetLastError()   );  
  return;  
  }  
   
   
   
  if   (   !   LookupPrivilegeValue(   NULL,   SE_DEBUG_NAME,   &sedebugnameValue   )   )  
  {  
  _tprintf(   _T("LookupPrivilegeValue()   failed,   Error   =   %d   SeDebugPrivilege   is   not   available.\n"),   GetLastError()   );  
  CloseHandle(   hToken   );  
  return;  
  }  
   
   
   
  tkp.PrivilegeCount   =   1;  
  tkp.Privileges[0].Luid   =   sedebugnameValue;  
  tkp.Privileges[0].Attributes   =   SE_PRIVILEGE_ENABLED;  
   
   
   
  if   (   !   AdjustTokenPrivileges(   hToken,   FALSE,   &tkp,   sizeof   tkp,   NULL,   NULL   )   )  
  _tprintf(   _T("AdjustTokenPrivileges()   failed,   Error   =   %d   SeDebugPrivilege   is   not   available.\n"),   GetLastError()   );  
   
  CloseHandle(   hToken   );  
  }  
   
   
   
  static   BOOL   Init()  
  {  
  //   Get   the   NtDll   function   pointers  
  NtQuerySystemInformation   =   (PNtQuerySystemInformation)  
  GetProcAddress(   GetModuleHandle(   _T(   "ntdll.dll"   )   ),  
                                          _T("NtQuerySystemInformation")   );  
   
   
   
  NtQueryObject   =   (PNtQueryObject)  
  GetProcAddress(   GetModuleHandle(   _T(   "ntdll.dll"   )   ),  
                                          _T("NtQueryObject")   );  
   
   
   
  NtQueryInformationThread   =   (PNtQueryInformationThread)  
  GetProcAddress(   GetModuleHandle(   _T(   "ntdll.dll"   )   ),  
                                          _T("NtQueryInformationThread")   );  
   
   
   
  NtQueryInformationFile   =   (PNtQueryInformationFile)  
  GetProcAddress(   GetModuleHandle(   _T(   "ntdll.dll"   )   ),  
  _T("NtQueryInformationFile")   );  
   
   
   
  NtQueryInformationProcess   =   (PNtQueryInformationProcess)  
  GetProcAddress(   GetModuleHandle(   _T(   "ntdll.dll"   )   ),  
                                          _T("NtQueryInformationProcess")   );  
   
   
   
  EnableDebugPriv();  
   
   
   
  return     NtQuerySystemInformation   !=   NULL   &&  
  NtQueryObject   !=   NULL   &&  
  NtQueryInformationThread   !=   NULL   &&  
  NtQueryInformationFile   !=   NULL   &&  
  NtQueryInformationProcess   !=   NULL;  
  }  
   
   
   
  void   LPCWSTR2CString(   LPCWSTR   strW,   LPTSTR   str   )  
  {  
  #ifdef   UNICODE  
  //   if   it   is   already   UNICODE,   no   problem  
  wcscpy(strW,   str);  
  #else  
  str[0]   =   _T('\0');  
   
   
   
  TCHAR*   actChar   =   (TCHAR*)strW;  
   
   
   
  if   (   actChar   ==   _T('\0')   )  
  return;  
   
   
   
  ULONG   len   =   wcslen(strW)   +   1;  
  TCHAR*   pBuffer   =   new   TCHAR[   len   ];  
  TCHAR*   pNewStr   =   pBuffer;  
   
   
   
  while   (   len--   )  
  {  
  *(pNewStr++)   =   *actChar;  
  actChar   +=   2;  
  }  
   
   
   
  _tcscpy(str,   pBuffer);  
   
   
   
  delete   []   pBuffer;  
  #endif  
  }  
   
   
   
  //Information   functions  
  static   BOOL   GetTypeToken(   HANDLE   h,   LPTSTR   str,   DWORD   processId   )  
  {  
  ULONG   size   =   0x2000;  
  UCHAR*   lpBuffer   =   NULL;  
  BOOL   ret   =   FALSE;  
   
   
   
  HANDLE   handle;  
  HANDLE   hRemoteProcess   =   NULL;  
  BOOL   remote   =   processId   !=   GetCurrentProcessId();  
   
  if   (   remote   )  
  {  
  //   Open   the   remote   process  
  hRemoteProcess   =   OpenProcess(   PROCESS_DUP_HANDLE,   TRUE,   processId   );  
   
  if   (   hRemoteProcess   ==   NULL   )  
  return   FALSE;  
   
   
   
  //   Duplicate   the   handle  
  handle   =   NULL;  
  DuplicateHandle(   hRemoteProcess,   h,   GetCurrentProcess(),   &handle,   0,   FALSE,   DUPLICATE_SAME_ACCESS   );  
  }  
  else  
  handle   =   h;  
   
   
   
  //   Query   the   info   size  
  NtQueryObject(   handle,   2,   NULL,   0,   &size   );  
   
   
   
  lpBuffer   =   new   UCHAR[size];  
   
   
   
  //   Query   the   info   size   (   type   )  
  if   (   NtQueryObject(   handle,   2,   lpBuffer,   size,   NULL   )   ==   0   )  
  {  
  str[0]   =   _T('\0');  
  LPCWSTR2CString(   (LPCWSTR)(lpBuffer+0x60),   str   );  
   
   
   
  ret   =   TRUE;  
  }  
   
   
   
  if   (   remote   )  
  {  
  if   (   hRemoteProcess   !=   NULL   )  
  CloseHandle(   hRemoteProcess   );  
   
   
   
  if   (   handle   !=   NULL   )  
  CloseHandle(   handle   );  
  }  
   
  if   (   lpBuffer   !=   NULL   )  
  delete   []   lpBuffer;  
   
   
   
  return   ret;  
  }  
   
   
   
  //Thread   related   functions  
  static   BOOL   GetThreadId(   HANDLE   h,   DWORD&   threadID,   DWORD   processId   )  
  {  
  BASIC_THREAD_INFORMATION   ti;  
  HANDLE   handle;  
  HANDLE   hRemoteProcess   =   NULL;  
  BOOL   remote   =   processId   !=   GetCurrentProcessId();  
   
  if   (   remote   )  
  {  
  //   Open   process  
  hRemoteProcess   =   OpenProcess(   PROCESS_DUP_HANDLE,   TRUE,   processId   );  
   
  if   (   hRemoteProcess   ==   NULL   )  
  return   FALSE;  
   
   
   
  //   Duplicate   handle  
  handle   =   NULL;  
  DuplicateHandle(   hRemoteProcess,   h,   GetCurrentProcess(),   &handle,   0,   FALSE,   DUPLICATE_SAME_ACCESS   );  
  }  
  else  
  handle   =   h;  
   
  //   Get   the   thread   information  
  if   (   NtQueryInformationThread(   handle,   0,   &ti,   sizeof(ti),   NULL   )   ==   0   )  
  threadID   =   ti.ThreadId;  
   
   
   
  if   (   remote   )  
  {  
  if   (   hRemoteProcess   !=   NULL   )  
  CloseHandle(   hRemoteProcess   );  
   
   
   
  if   (   handle   !=   NULL   )  
  CloseHandle(   handle   );  
  }  
   
   
   
  return   TRUE;  
  }  
   
   
   
  HANDLE   Mine_OpenThread(DWORD   dwProcessId,   DWORD   dwThreadId)  
  {  
  DWORD   size   =   0x2000;  
  DWORD   needed   =   0;  
  DWORD   i   =   0;  
  TCHAR   szFilter[]   =   _T("Thread");  
  TCHAR   szType[500];  
   
   
   
  THREAD_INFORMATION   ti;  
  HANDLE   h   =   NULL;  
   
   
   
  if   (   !NtDllStatus   )  
  return   NULL;  
   
   
   
  //   Allocate   the   memory   for   the   buffer  
  SYSTEM_HANDLE_INFORMATION*   pSysHandleInformation   =   (SYSTEM_HANDLE_INFORMATION*)  
  VirtualAlloc(   NULL,   size,   MEM_COMMIT,   PAGE_READWRITE   );  
   
   
   
  if   (   pSysHandleInformation   ==   NULL   )  
  return   NULL;  
   
   
   
  //   Query   the   needed   buffer   size   for   the   objects   (   system   wide   )  
  if   (   NtQuerySystemInformation(   16,   pSysHandleInformation,   size,   &needed   )   !=   0   )  
  {  
  if   (   needed   ==   0   )  
  goto   cleanup;  
   
   
   
  //   The   size   was   not   enough  
  VirtualFree(   pSysHandleInformation,   0,   MEM_RELEASE   );  
   
   
   
  pSysHandleInformation   =   (SYSTEM_HANDLE_INFORMATION*)  
  VirtualAlloc(   NULL,   size   =   needed   +   256,   MEM_COMMIT,   PAGE_READWRITE   );  
  }  
   
  if   (   pSysHandleInformation   ==   NULL   )  
  return   NULL;  
   
   
   
  //   Query   the   objects   (   system   wide   )  
  if   (   NtQuerySystemInformation(   16,   pSysHandleInformation,   size,   NULL   )   !=   0   )  
  goto   cleanup;  
   
  //   Iterating   through   the   objects  
  for   (   i   =   0;   i   <   pSysHandleInformation->Count;   i++   )  
  {  
  //   ProcessId   filtering   check  
  if   (   pSysHandleInformation->Handles[i].ProcessID   ==   dwProcessId   ||   dwProcessId   ==   (DWORD)-1   )  
  {  
  //   Type   filtering  
  GetTypeToken(   (HANDLE)pSysHandleInformation->Handles[i].HandleNumber,   szType,   pSysHandleInformation->Handles[i].ProcessID     );  
  if(   _tcsicmp(   szType,   szFilter   )   ==   0   )  
  {  
  ti.ProcessId   =   pSysHandleInformation->Handles[i].ProcessID;  
  ti.ThreadHandle   =   (HANDLE)pSysHandleInformation->Handles[i].HandleNumber;  
   
   
   
  //   ThreadId   filtering   check  
  if(GetThreadId(   ti.ThreadHandle,   ti.ThreadId,   ti.ProcessId   )   &&   ti.ThreadId   ==   dwThreadId)  
  {  
  if(dwProcessId   !=   GetCurrentProcessId())  
  {  
  //   Open   remote   process  
  HANDLE   hRemoteProcess   =   OpenProcess(   PROCESS_DUP_HANDLE,   TRUE,   dwProcessId   );  
   
  if   (   hRemoteProcess   ==   NULL   )  
  goto   cleanup;  
   
   
   
  //   Duplicate   handle  
  DuplicateHandle(   hRemoteProcess,   ti.ThreadHandle,   GetCurrentProcess(),   &h,   0,   FALSE,   DUPLICATE_SAME_ACCESS   );  
  CloseHandle(   hRemoteProcess   );  
  }  
  else  
  DuplicateHandle(   GetCurrentProcess(),   ti.ThreadHandle,   GetCurrentProcess(),   &h,   0,   FALSE,   DUPLICATE_SAME_ACCESS   );  
  break;  
  }  
   
   
   
  ti.ThreadHandle   =   NULL;  
  }  
  }  
  }  
   
   
   
  cleanup:  
   
  if   (   pSysHandleInformation   !=   NULL   )  
  VirtualFree(   pSysHandleInformation,   0,   MEM_RELEASE   );  
   
   
   
  return   h;  
  }    
  Top

7 楼singlerace(独行者)回复于 2000-11-23 15:27:00 得分 0

简单调用Mine_OpenThread就可以了,当然用完后记得CloseHandleTop

8 楼lolin(lolin)回复于 2000-11-24 12:57:00 得分 0

虽然还未试,但很厉害。佩服、佩服!值得给100分!  
  不过我还有一点不太明白,以NT等开头的应是MS未文档载明的函数,  
  不知singlerace兄是从哪知道它的参数及功能的?(有些唐突,但真的忍不住很想知道)  
  非常感激你,真的!Top

9 楼singlerace(独行者)回复于 2000-11-26 13:12:00 得分 20

ntddk.h里有部分说明Top

相关问题

  • 线程
  • 多线程啊多线程
  • 线程问题
  • 线程--------消息?????
  • 谁会线程??
  • 线程困难!!!!!
  • 线程111
  • 线程问题
  • ***************** 线程问题 *******************
  • 关于线程

关键词

  • 线程
  • ti
  • null
  • psyshandleinformation
  • 句柄
  • ob
  • threadhandle
  • processid
  • dword
  • hremoteprocess

得分解答快速导航

  • 帖主:lolin
  • singlerace

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo