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;
}
posted on 2009-07-22 10:29
free2000fly 阅读(4865)
评论(0) 编辑 收藏 引用