要获取入口地址,可以用Native API: NtQueryInformationThread,以ThreadQuerySetWin32StartAddress为参数
具体代码:
.h:
#pragma once typedef LONG NTSTATUS; typedef NTSTATUS (WINAPI *NTQUERYINFORMATIONTHREAD)( HANDLE ThreadHandle, ULONG ThreadInformationClass, PVOID ThreadInformation, ULONG ThreadInformationLength, PULONG ReturnLength); typedef enum _THREADINFOCLASS { ThreadBasicInformation, ThreadTimes, ThreadPriority, ThreadBasePriority, ThreadAffinityMask, ThreadImpersonationToken, ThreadDescriptorTableEntry, ThreadEnableAlignmentFaultFixup, ThreadEventPair_Reusable, ThreadQuerySetWin32StartAddress, ThreadZeroTlsCell, ThreadPerformanceCount, ThreadAmILastThread, ThreadIdealProcessor, ThreadPriorityBoost, ThreadSetTlsArrayAddress, // Obsolete ThreadIsIoPending, ThreadHideFromDebugger, ThreadBreakOnTermination, ThreadSwitchLegacyState, ThreadIsTerminated, ThreadLastSystemCall, ThreadIoPriority, ThreadCycleTime, ThreadPagePriority, ThreadActualBasePriority, ThreadTebInformation, ThreadCSwitchMon, // Obsolete ThreadCSwitchPmu, ThreadWow64Context, ThreadGroupInformation, ThreadUmsInformation, // UMS ThreadCounterProfiling, ThreadIdealProcessorEx, MaxThreadInfoClass } THREADINFOCLASS; class FindThreadStaAddr { public: FindThreadStaAddr(void); ~FindThreadStaAddr(void); DWORD GetThreadStartAddr1(DWORD dwThreadId); };
.cpp
#include "StdAfx.h" #include "FindThreadStaAddr.h" FindThreadStaAddr::FindThreadStaAddr(void) { } FindThreadStaAddr::~FindThreadStaAddr(void) { } DWORD FindThreadStaAddr::GetThreadStartAddr1(DWORD dwThreadId) { HMODULE hNtdll = LoadLibrary(_T("ntdll.dll")); if (!hNtdll) { return 0; } NTQUERYINFORMATIONTHREAD NtQueryInformationThread = NULL; NtQueryInformationThread = (NTQUERYINFORMATIONTHREAD) GetProcAddress(hNtdll, "NtQueryInformationThread"); if (!NtQueryInformationThread) { return 0; } HANDLE ThreadHandle = NULL; ThreadHandle = OpenThread(THREAD_QUERY_INFORMATION, FALSE, dwThreadId); if (!ThreadHandle) { return 0; } DWORD dwStaAddr = NULL; DWORD dwReturnLength = 0; if(NtQueryInformationThreadtion(ThreadHandle, ThreadQuerySetWin32StartAddress, &dwStaAddr, sizeof(dwStaAddr), &dwReturnLength)) { return 0; } return dwStaAddr; }
要注意的是
1.NtQueryInformationThread成功返回的是STATUS_SUCCESS(0)
另一种判断的方式是直接hook LdrInitializeThunk
贴个原型:
typedef void (__stdcall *LDRINITIALIZETHUNK)(ULONG param0, ULONG param1, ULONG param2, ULONG param3);
PCONTEXT pContext; pContext = (PCONTEXT)¶m3; pContext->Eax即为函数入口地址
这个是入口地址,而且是在没有进入入口函数地址之前调用的,所以可以在这里判断是否需要KILL此线程.
自己写了个demo测试第一种方式:
1。随机生成一个线程,打印它的地址和ID
2。输入要查询的线程ID,点击查询按钮:
打印的线程地址和上面的一致,