C语言获取线程启动地址源代码
#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 ;
::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);
};
页:
[1]