typedef struct _CL_PROCESS_THREADINFO
{
LPVOID pvStartAddr; // 线程的起始地址
DWORD dwTid; // 线程Id
WCHAR wszModuleName[MAX_PATH]; // 所属的模块路径
{
LPVOID pvStartAddr; // 线程的起始地址
DWORD dwTid; // 线程Id
WCHAR wszModuleName[MAX_PATH]; // 所属的模块路径
}CL_PROCESS_THREADINFO;
BOOL CLThread::QueryThreadInfo_By_Pid(__in DWORD dwPid, __out vector<CL_PROCESS_THREADINFO>& vlst)
{
/************************************************************************/
/*
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;
HINSTANCE hNTDLL = ::GetModuleHandle(TEXT("ntdll"));
(FARPROC&)ZwQueryInformationThread =
::GetProcAddress(hNTDLL, "ZwQueryInformationThread");
(FARPROC&)RtlNtStatusToDosError =
::GetProcAddress(hNTDLL, "RtlNtStatusToDosError");
可以直接用
status = ZwQueryInformationThread(thread,
ThreadQuerySetWin32StartAddress,
&startaddr,
sizeof (startaddr),
NULL);
*/
/************************************************************************/
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 *ZwQueryInformationThread) (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
ZwQueryInformationThread pZwQueryInformationThread = NULL;
auto fnSetThreadInfo_By_Tid = [&pZwQueryInformationThread](__in DWORD dwTid, __out CL_PROCESS_THREADINFO& ThreadInfo)
{
THREAD_BASIC_INFORMATION tbi = { 0 };
PVOID pvStartAddr = NULL;
LONG lnStatus = NULL;
HANDLE hThread = NULL;
HANDLE hProcess = NULL;
hThread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, dwTid);
if (hThread == NULL)
return FALSE;
lnStatus = pZwQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &pvStartAddr, sizeof (pvStartAddr), NULL);
if (lnStatus < 0)
{
CloseHandle(hThread);
return FALSE;
}
ZeroMemory(&ThreadInfo, sizeof(ThreadInfo));
ThreadInfo.dwTid = dwTid;
ThreadInfo.pvStartAddr = pvStartAddr;
lnStatus = pZwQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof (tbi), NULL);
if (lnStatus < 0)
{
CloseHandle(hThread);
return FALSE;
};
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)tbi.ClientId.UniqueProcess);
if (hProcess == NULL)
{
CloseHandle(hThread);
return FALSE;
};
GetMappedFileName(hProcess, pvStartAddr, ThreadInfo.wszModuleName, MAX_PATH);
CloseHandle(hProcess);
CloseHandle(hThread);
return TRUE;
};
try
{
HMODULE hmNtDLL = ::GetModuleHandleW(L"ntdll.dll");
if (hmNtDLL == NULL)
return FALSE;
pZwQueryInformationThread = (ZwQueryInformationThread)::GetProcAddress(hmNtDLL, "ZwQueryInformationThread");
if (pZwQueryInformationThread == NULL)
return FALSE;
static CL_PROCESS_THREADINFO ThreadInfo;
HANDLE hSnapshot = NULL;
THREADENTRY32 te = { 0 };
te.dwSize = sizeof (te);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (Thread32First(hSnapshot, &te))
{
do
{
if (te.th32OwnerProcessID == dwPid && fnSetThreadInfo_By_Tid(te.th32ThreadID, ThreadInfo))
vlst.push_back(ThreadInfo);
} while (Thread32Next(hSnapshot, &te));
};
CloseHandle(hSnapshot);
return vlst.size() != NULL ? TRUE : FALSE;
}
catch (...)
{
CPrintLog::PrintLog_W(_SELF, __LINE__, L"QueryThreadInfo_By_Pid出现异常");
}
return FALSE;
}
{
/************************************************************************/
/*
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;
HINSTANCE hNTDLL = ::GetModuleHandle(TEXT("ntdll"));
(FARPROC&)ZwQueryInformationThread =
::GetProcAddress(hNTDLL, "ZwQueryInformationThread");
(FARPROC&)RtlNtStatusToDosError =
::GetProcAddress(hNTDLL, "RtlNtStatusToDosError");
可以直接用
status = ZwQueryInformationThread(thread,
ThreadQuerySetWin32StartAddress,
&startaddr,
sizeof (startaddr),
NULL);
*/
/************************************************************************/
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 *ZwQueryInformationThread) (
IN HANDLE ThreadHandle,
IN THREADINFOCLASS ThreadInformationClass,
OUT PVOID ThreadInformation,
IN ULONG ThreadInformationLength,
OUT PULONG ReturnLength OPTIONAL
);
ZwQueryInformationThread pZwQueryInformationThread = NULL;
auto fnSetThreadInfo_By_Tid = [&pZwQueryInformationThread](__in DWORD dwTid, __out CL_PROCESS_THREADINFO& ThreadInfo)
{
THREAD_BASIC_INFORMATION tbi = { 0 };
PVOID pvStartAddr = NULL;
LONG lnStatus = NULL;
HANDLE hThread = NULL;
HANDLE hProcess = NULL;
hThread = ::OpenThread(THREAD_ALL_ACCESS, FALSE, dwTid);
if (hThread == NULL)
return FALSE;
lnStatus = pZwQueryInformationThread(hThread, ThreadQuerySetWin32StartAddress, &pvStartAddr, sizeof (pvStartAddr), NULL);
if (lnStatus < 0)
{
CloseHandle(hThread);
return FALSE;
}
ZeroMemory(&ThreadInfo, sizeof(ThreadInfo));
ThreadInfo.dwTid = dwTid;
ThreadInfo.pvStartAddr = pvStartAddr;
lnStatus = pZwQueryInformationThread(hThread, ThreadBasicInformation, &tbi, sizeof (tbi), NULL);
if (lnStatus < 0)
{
CloseHandle(hThread);
return FALSE;
};
hProcess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, (DWORD)tbi.ClientId.UniqueProcess);
if (hProcess == NULL)
{
CloseHandle(hThread);
return FALSE;
};
GetMappedFileName(hProcess, pvStartAddr, ThreadInfo.wszModuleName, MAX_PATH);
CloseHandle(hProcess);
CloseHandle(hThread);
return TRUE;
};
try
{
HMODULE hmNtDLL = ::GetModuleHandleW(L"ntdll.dll");
if (hmNtDLL == NULL)
return FALSE;
pZwQueryInformationThread = (ZwQueryInformationThread)::GetProcAddress(hmNtDLL, "ZwQueryInformationThread");
if (pZwQueryInformationThread == NULL)
return FALSE;
static CL_PROCESS_THREADINFO ThreadInfo;
HANDLE hSnapshot = NULL;
THREADENTRY32 te = { 0 };
te.dwSize = sizeof (te);
hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (Thread32First(hSnapshot, &te))
{
do
{
if (te.th32OwnerProcessID == dwPid && fnSetThreadInfo_By_Tid(te.th32ThreadID, ThreadInfo))
vlst.push_back(ThreadInfo);
} while (Thread32Next(hSnapshot, &te));
};
CloseHandle(hSnapshot);
return vlst.size() != NULL ? TRUE : FALSE;
}
catch (...)
{
CPrintLog::PrintLog_W(_SELF, __LINE__, L"QueryThreadInfo_By_Pid出现异常");
}
return FALSE;
}