要获取入口地址,可以用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,点击查询按钮:
打印的线程地址和上面的一致,