有关线程的一些函数

有关线程的一些函数
1. 根据线程ID找出其所在的模块名

#define    WIN32_LEAN_AND_MEAN  
#define    _WIN32_WINNT   0x400  
#include   
< stdio.h >   
#include   
< tchar.h >   
#include   
< locale.h >   
#include   
< windows.h >   

#include 
< psapi.h >
#pragma comment(lib, 
" psapi.lib " )

#include   
< Tlhelp32.h >   


//   
//    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;  

typedef LONG (__stdcall 
*  PFN_ZwQueryInformationThread)(  
                                                       IN   HANDLE   ThreadHandle,  
                                                       IN   THREADINFOCLASS   ThreadInformationClass,  
                                                       OUT   PVOID   ThreadInformation,  
                                                       IN   ULONG   ThreadInformationLength,  
                                                       OUT   PULONG   ReturnLength   OPTIONAL  
                                                       );
typedef LONG (__stdcall 
*  PFN_RtlNtStatusToDosError)(IN ULONG status);
typedef DWORD (__stdcall 
*  PFN_RtlGetLastWin32Error)();


EXTERN_C PFN_ZwQueryInformationThread pfn_ZwQueryInformationThread 
=  NULL; 
EXTERN_C PFN_RtlNtStatusToDosError  pfn_RtlNtStatusToDosError 
=  NULL;
EXTERN_C PFN_RtlGetLastWin32Error  pfn_RtlGetLastWin32Error 
=  NULL;

BOOL ShowThreadInfo (DWORD tid)  
{  
    THREAD_BASIC_INFORMATION tbi 
=  {  0  };  
    PVOID   startaddr 
=  NULL;  
    LONG    status 
=   0 ;  
    HANDLE  hThread
= NULL, process = NULL;  
    TCHAR   modname   [
0x100 =  {  0  }; 
    BOOL bResult 
=  FALSE;

    
do  
    {
        hThread 
=  OpenThread(THREAD_ALL_ACCESS, FALSE, tid);  
        
if  (hThread  ==  NULL) {
            SetLastError(pfn_RtlGetLastWin32Error());
            
break ;
        }
        
        status   
=    pfn_ZwQueryInformationThread   (hThread,    
            ThreadQuerySetWin32StartAddress,    
            
& startaddr,    
            
sizeof    (startaddr),    
            NULL);  
        
if  (status  <   0 ) {
            SetLastError(pfn_RtlNtStatusToDosError(status));
            
break ;
        };  
        
        _tprintf(TEXT(
" Thread %08x  start address is %p\n " ), tid, startaddr);  
        
        status 
=  pfn_ZwQueryInformationThread(hThread,    
            ThreadBasicInformation,    
            
& tbi,    
            
sizeof    (tbi),    
            NULL);  
        
        
if  (status  <   0 )  
        {  
            SetLastError(pfn_RtlNtStatusToDosError(status));
            
break ;
        };  
        
        _tprintf   (TEXT   (
" Thread %08x 's process ID is %08x\n " ),    
            tid,    
            (DWORD)tbi.ClientId.UniqueProcess);  
        
        process   
=    OpenProcess   (PROCESS_ALL_ACCESS,    
            FALSE,    
            (DWORD)tbi.ClientId.UniqueProcess);  
        
        
if  (process  ==  NULL) { 
            SetLastError(pfn_RtlGetLastWin32Error()); 
            
break ;
        };  
        
        GetModuleFileNameEx(process, NULL, modname, 
0x100 );  
        _tprintf(TEXT(
" Thread %08x Located in Process Image %s\n " ), tid, modname);
        
        GetMappedFileName(process, startaddr, modname, 
0x100 );  
        _tprintf(TEXT(
" Thread %08x Located in module \ " % s\ " \n " ), tid, modname);
        
        bResult 
=  TRUE;
    } 
while  (FALSE);
    
    
if  (process) {
        CloseHandle(process);
    }
    
if  (hThread) {
        CloseHandle(hThread);  
    }
    
    
return    TRUE;  
};  

int    main   ( void )  
{  
    HINSTANCE hNTDLL 
=  NULL;
    HANDLE h 
=  NULL;
    THREADENTRY32 te 
=  {  sizeof (te) };  

    setlocale(LC_ALL, 
" .ACP " );  
    hNTDLL 
=  GetModuleHandle(TEXT( " ntdll " ));  
    pfn_ZwQueryInformationThread 
=  (PFN_ZwQueryInformationThread)
        GetProcAddress(hNTDLL, 
" ZwQueryInformationThread " );  
    pfn_RtlNtStatusToDosError 
=  (PFN_RtlNtStatusToDosError)
        GetProcAddress(hNTDLL, 
" RtlNtStatusToDosError " ); 
    pfn_RtlGetLastWin32Error 
=  (PFN_RtlGetLastWin32Error)
        GetProcAddress(hNTDLL, 
" RtlGetLastWin32Error " );


    h   
=    CreateToolhelp32Snapshot   (TH32CS_SNAPTHREAD,    0 );  
    te.dwSize   
=     sizeof    (te);  
    
if (Thread32First(h,  & te))  
    {  
        
do   
        {  
            
if    (ShowThreadInfo   (te.th32ThreadID))  
            {  
            }  
            
else   
            {  
                _tprintf(TEXT(
" Can't get thread %08x information, Error code is %d\r\n " ),    
                    te.th32ThreadID,   GetLastError());  
            };  
        }   
while    (Thread32Next   (h,    & te));  
    };  
    CloseHandle   (h);  
}

2. 获取线程当前状态, 是挂起还是终止, 没有直接的 API. 这段代码比较实用
#include  < stdio.h >
#include 
< windows.h >
#include 
< winbase.h >
#include 
< ntsecapi.h >


#define  UNICODE
#define  NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
#define  STATUS_SUCCESS              ((NTSTATUS) 0x00000000)
#define  STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xC0000004)
#define  SystemProcessesAndThreadsInformation    5
#define  NTAPI    __stdcall

typedef 
enum  _THREAD_STATE
{
    StateInitialized,
    StateReady,
    StateRunning,
    StateStandby,
    StateTerminated,
    StateWait,
    StateTransition,
    StateUnknown
}THREAD_STATE;

typedef 
enum  _KWAIT_REASON
{
    Executive,
    FreePage,
    PageIn,
    PoolAllocation,
    DelayExecution,
    Suspended,
    UserRequest,
    WrExecutive,
    WrFreePage,
    WrPageIn,
    WrPoolAllocation,
    WrDelayExecution,
    WrSuspended,
    WrUserRequest,
    WrEventPair,
    WrQueue,
    WrLpcReceive,
    WrLpcReply,
    WrVirtualMemory,
    WrPageOut,
    WrRendezvous,
    Spare2,
    Spare3,
    Spare4,
    Spare5,
    Spare6,
    WrKernel,
    MaximumWaitReason
}KWAIT_REASON;

typedef NTSTATUS (WINAPI 
* PNTRAISE)(NTSTATUS,
                                    ULONG,
                                    ULONG,
                                    PULONG,
                                    UINT,
                                    PULONG);   


typedef LONG NTSTATUS;
typedef LONG    KPRIORITY;

typedef 
struct  _CLIENT_ID {
    DWORD        UniqueProcess;
    DWORD        UniqueThread;
} CLIENT_ID, 
*  PCLIENT_ID;


typedef 
struct  _VM_COUNTERS {
    SIZE_T        PeakVirtualSize;
    SIZE_T        VirtualSize;
    ULONG        PageFaultCount;
    SIZE_T        PeakWorkingSetSize;
    SIZE_T        WorkingSetSize;
    SIZE_T        QuotaPeakPagedPoolUsage;
    SIZE_T        QuotaPagedPoolUsage;
    SIZE_T        QuotaPeakNonPagedPoolUsage;
    SIZE_T        QuotaNonPagedPoolUsage;
    SIZE_T        PagefileUsage;
    SIZE_T        PeakPagefileUsage;
} VM_COUNTERS;


typedef 
struct  _SYSTEM_THREAD_INFORMATION {
    LARGE_INTEGER   KernelTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   CreateTime;
    ULONG            WaitTime;
    PVOID            StartAddress;
    CLIENT_ID        ClientId;
    KPRIORITY        Priority;
    KPRIORITY        BasePriority;
    ULONG            ContextSwitchCount;
    LONG            State;
    LONG            WaitReason;
} SYSTEM_THREAD_INFORMATION, 
*  PSYSTEM_THREAD_INFORMATION;



typedef 
struct  _SYSTEM_PROCESS_INFORMATION {
    ULONG            NextEntryDelta;
    ULONG            ThreadCount;
    ULONG            Reserved1[
6 ];
    LARGE_INTEGER   CreateTime;
    LARGE_INTEGER   UserTime;
    LARGE_INTEGER   KernelTime;
    UNICODE_STRING ProcessName;
    KPRIORITY        BasePriority;
    ULONG            ProcessId;
    ULONG            InheritedFromProcessId;
    ULONG            HandleCount;
    ULONG            Reserved2[
2 ];
    VM_COUNTERS        VmCounters;
    IO_COUNTERS        IoCounters;
    SYSTEM_THREAD_INFORMATION Threads[
5 ];
} SYSTEM_PROCESS_INFORMATION, 
*  PSYSTEM_PROCESS_INFORMATION;



typedef DWORD (WINAPI
*  PQUERYSYSTEM)(UINT, PVOID, DWORD,PDWORD);

/* ********************************************************************** */
/*  函数说明:
   参数:dwThreadID 代表线程ID ,这里主要是验证线程的ID
             szProcessName,表示线程所在的进程名

返回值:
       true: 表示线程被挂起
       false: 表示线程正常。

*/
/* ********************************************************************** */

BOOL IsThreadSuspend(DWORD dwThreadID,wchar_t 
* szProcessName)
{
    ULONG cbBuffer 
=   0x5000 ;
   
    BOOL bRet 
=  FALSE;

    LPVOID pBuffer 
=  NULL;
    NTSTATUS Status;


    DWORD b
= 0 ;

    PQUERYSYSTEM NtQuerySystemInformation;
    PSYSTEM_PROCESS_INFORMATION pInfo ;

    NtQuerySystemInformation 
=  (PQUERYSYSTEM) GetProcAddress(
        LoadLibrary( 
" ntdll.dll "  ),
        
" NtQuerySystemInformation "  );

    
do
    {
        pBuffer 
=  malloc(cbBuffer);
        
if  (pBuffer  ==  NULL)
        {
            
break ;
        }

        Status 
=  NtQuerySystemInformation(
            SystemProcessesAndThreadsInformation,
            pBuffer, cbBuffer, NULL);

        
if  (Status  ==  STATUS_INFO_LENGTH_MISMATCH)
        {
            free(pBuffer);
            cbBuffer 
*=   2 ;
        }
        
else   if  ( ! NT_SUCCESS(Status))
        {
            free(pBuffer);
        }

    }   
while  (Status  ==  STATUS_INFO_LENGTH_MISMATCH);


    pInfo 
=  (PSYSTEM_PROCESS_INFORMATION)pBuffer;

    
for  (;;)
    {


        
if  (pInfo -> NextEntryDelta  ==   0 )
            
break ;
        
if (pInfo -> ProcessName.Buffer != NULL  &&
            
! _wcsicmp(pInfo -> ProcessName.Buffer,szProcessName))
        {

            
for (b = 0 ;b < pInfo -> ThreadCount ;b ++ )
            {
                
if (pInfo -> Threads[b].ClientId.UniqueThread  ==  dwThreadID )  // 找到线程              
                {

                    
if (pInfo -> Threads[b].State  ==  StateWait  &&  pInfo -> Threads[b].WaitReason  ==  Suspended)  // 线程被挂起
                    {
                        bRet 
=  TRUE;
                        
break ;
                    }
                }
            }
            
break ;
       
        }
        pInfo 
=  (PSYSTEM_PROCESS_INFORMATION)(((PUCHAR)pInfo)  +     pInfo -> NextEntryDelta);
    }

    free(pBuffer);
    
return  bRet;
}   


/* ************************************************************ */
/* 判断线程是否被终止 , 如果终止返回FALSE,如果还活着返回TRUE
/*************************************************************
*/

BOOL IsThreadAlive(DWORD dwThreadID)
{
    BOOL bRet 
=  FALSE;
    DWORD ExitCode 
=   0 ;

    HANDLE hThread 
=  OpenThread(THREAD_QUERY_INFORMATION,FALSE,dwThreadID);
    
if (hThread  !=  NULL)
    {
        
if (GetExitCodeThread(hThread, & ExitCode))
        {
            
if ( ExitCode  ==  STILL_ACTIVE)
                bRet 
=  TRUE;
        }

        CloseHandle(hThread);
    }

    
return  bRet;
}

int  _tmain( int  argc, _TCHAR *  argv[])
{

   
    BOOL bRET 
= IsThreadSuspend( 2320 ,L " EXPLORER.EXE " );


    
if (bRET)
    {
        printf(
"  2320线程被挂起了! " );
    }
    
return   0 ;
}


你可能感兴趣的:(有关线程的一些函数)