您的位置:首页 > 理论基础 > 计算机网络

获取线程启动地址 C 源码[收藏]http://www.jm-m.cn/html/366.html

2008-11-03 15:43 232 查看
#define   WIN32_LEAN_AND_MEAN  
  #define   _WIN32_WINNT   0x400  
  #include   <stdio.h>  
  #include   <tchar.h>  
  #include   <locale.h>  
  #include   <windows.h>  
  #include   <psapi.h>  
  #include   <Tlhelp32.h>  
   
  #pragma   comment   (lib,   "psapi.lib")  
   
  //  
  //   Thread   Information   Classes  
  //  
   
  typedef   enum   _THREADINFOCLASS   {  
          ThreadBasicInformation,  
          ThreadTimes,  
          ThreadPriority,  
          ThreadBasePriority,  
          ThreadAffinityMask,  
          ThreadImpersonationToken,  
          ThreadDescriptorTableEntry,  
          ThreadEnableAlignmentFaultFixup,  
          ThreadEventPair_Reusable,  
          ThreadQuerySetWin32StartAddress,  
          ThreadZeroTlsCell,  
          ThreadPerformanceCount,  
          ThreadAmILastThread,  
          ThreadIdealProcessor,  
          ThreadPriorityBoost,  
          ThreadSetTlsArrayAddress,  
          ThreadIsIoPending,  
          ThreadHideFromDebugger,  
          ThreadBreakOnTermination,  
          MaxThreadInfoClass  
          }   THREADINFOCLASS;  
   
  typedef   struct   _CLIENT_ID   {  
          HANDLE   UniqueProcess;  
          HANDLE   UniqueThread;  
  }   CLIENT_ID;  
  typedef   CLIENT_ID   *PCLIENT_ID;  
   
  typedef   struct   _THREAD_BASIC_INFORMATION   {   //   Information   Class   0  
          LONG           ExitStatus;  
          PVOID         TebBaseAddress;  
          CLIENT_ID   ClientId;  
          LONG   AffinityMask;  
          LONG   Priority;  
          LONG   BasePriority;  
  }   THREAD_BASIC_INFORMATION,   *PTHREAD_BASIC_INFORMATION;  
   
  extern   "C"   LONG   (__stdcall   *ZwQueryInformationThread)   (  
          IN   HANDLE   ThreadHandle,  
          IN   THREADINFOCLASS   ThreadInformationClass,  
          OUT   PVOID   ThreadInformation,  
          IN   ULONG   ThreadInformationLength,  
          OUT   PULONG   ReturnLength   OPTIONAL  
          )   =   NULL;  
   
   
  extern   "C"   LONG   (__stdcall   *RtlNtStatusToDosError)   (  
          IN     ULONG   status)   =   NULL;

 

BOOL   ShowThreadInfo   (DWORD   tid)  
          {  
                  THREAD_BASIC_INFORMATION         tbi;  
                  PVOID                                               startaddr;  
                  LONG                                                 status;  
                  HANDLE                                             thread,   process;  
                   
                  thread   =   ::OpenThread   (THREAD_ALL_ACCESS,   FALSE,   tid);  
                  if   (thread   ==   NULL)  
                          return   FALSE;  
   
                  status   =   ZwQueryInformationThread   (thread,    
                          ThreadQuerySetWin32StartAddress,    
                          &startaddr,    
                          sizeof   (startaddr),    
                          NULL);  
   
                  if   (status   <   0)  
                  {  
                          CloseHandle   (thread);  
                          SetLastError   (RtlNtStatusToDosError   (status));  
                          return   FALSE;  
                  };  
   
                  _tprintf   (TEXT   ("线程   %08x   的起始地址为   %p/n"),    
                          tid,    
                          startaddr);  
   
                  status   =   ZwQueryInformationThread   (thread,    
                          ThreadBasicInformation,    
                          &tbi,    
                          sizeof   (tbi),    
                          NULL);  
   
                  if   (status   <   0)  
                  {  
                          CloseHandle   (thread);  
                          SetLastError   (RtlNtStatusToDosError   (status));  
                          return   FALSE;  
                  };  
   
                  _tprintf   (TEXT   ("线程   %08x   所在进程ID为   %08x/n"),    
                          tid,    
                          (DWORD)tbi.ClientId.UniqueProcess);  
   
                  process   =   ::OpenProcess   (PROCESS_ALL_ACCESS,    
                          FALSE,    
                          (DWORD)tbi.ClientId.UniqueProcess);  
   
                  if   (process   ==   NULL)  
                  {  
                          DWORD   error   =   ::GetLastError   ();  
                          CloseHandle   (thread);  
                          SetLastError   (error);  
                          return   FALSE;  
                  };  
   
                  TCHAR   modname   [0x100];  
                  ::GetModuleFileNameEx   (process,   NULL,   modname,   0x100);  
   
                  _tprintf   (TEXT   ("线程   %08x   所在进程映象为   %s/n"),    
                          tid,    
                          modname);  
   
                  GetMappedFileName(process,    
                          startaddr,    
                          modname,    
                          0x100);  
   
                  _tprintf   (TEXT   ("线程   %08x   可执行代码所在模块为   %s/n"),    
                          tid,    
                          modname);  
   
                  CloseHandle   (process);  
                  CloseHandle   (thread);  
                  return   TRUE;  
          };  
   
  int   main   (void)  
          {  
                  setlocale   (LC_ALL,   ".ACP");  
   
                  HINSTANCE   hNTDLL   =   ::GetModuleHandle   (TEXT   ("ntdll"));  
   
                  (FARPROC&)ZwQueryInformationThread     =  
                          ::GetProcAddress   (hNTDLL,   "ZwQueryInformationThread");  
   
                  (FARPROC&)RtlNtStatusToDosError           =  
                          ::GetProcAddress   (hNTDLL,   "RtlNtStatusToDosError");  
   
                  HANDLE   h   =   CreateToolhelp32Snapshot   (TH32CS_SNAPTHREAD,   0);  
                  THREADENTRY32   te;  
                  te.dwSize   =   sizeof   (te);  
                  if   (Thread32First   (h,   &te))  
                  {  
                          do  
                          {  
                                  if   (ShowThreadInfo   (te.th32ThreadID))  
                                  {  
                                  }  
                                  else  
                                  {  
                                          _tprintf   (TEXT("无法获得线程   %08x   的相关信息,错误代码为   %d/n"),    
                                                  te.th32ThreadID,   GetLastError   ());  
                                  };  
                          }   while   (Thread32Next   (h,   &te));  
                  };  
                  CloseHandle   (h);  
          };  
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  c thread basic null struct access
相关文章推荐