偶尔碰到了一个小需求,要验证一个线程起始于某个模块,可以限制对代码的执行,起始于特定的线程。
线程的起始地址StartAddress,保存在了 _ETHREAD 结构中,无法从Ring3获取。
kd> dt _ethread 80553740 ntdll!_ETHREAD +0x000 Tcb : _KTHREAD +0x1c0 CreateTime : _LARGE_INTEGER 0x0 +0x1c0 NestedFaultCount : 0y00 +0x1c0 ApcNeeded : 0y0 +0x1c8 ExitTime : _LARGE_INTEGER 0x0 +0x1c8 LpcReplyChain : _LIST_ENTRY [ 0x0 - 0x0 ] +0x1c8 KeyedWaitChain : _LIST_ENTRY [ 0x0 - 0x0 ] +0x1d0 ExitStatus : 0 +0x1d0 OfsChain : (null) +0x1d4 PostBlockList : _LIST_ENTRY [ 0x0 - 0x0 ] +0x1dc TerminationPort : (null) +0x1dc ReaperLink : (null) +0x1dc KeyedWaitValue : (null) +0x1e0 ActiveTimerListLock : 0 +0x1e4 ActiveTimerListHead : _LIST_ENTRY [ 0x0 - 0x0 ] +0x1ec Cid : _CLIENT_ID +0x1f4 LpcReplySemaphore : _KSEMAPHORE +0x1f4 KeyedWaitSemaphore : _KSEMAPHORE +0x208 LpcReplyMessage : (null) +0x208 LpcWaitingOnPort : (null) +0x20c ImpersonationInfo : (null) +0x210 IrpList : _LIST_ENTRY [ 0x0 - 0x0 ] +0x218 TopLevelIrp : 0 +0x21c DeviceToVerify : (null) +0x220 ThreadsProcess : (null) +0x224 StartAddress : (null) +0x228 Win32StartAddress : (null) +0x22c ...... ......
DWORD WINAPI GetThreadStartAddress(HANDLE hThread) { NTSTATUS ntStatus; HANDLE hDupHandle; DWORD dwStartAddress; pNtQIT NtQueryInformationThread = (pNtQIT)GetProcAddress(GetModuleHandle("ntdll.dll"), "NtQueryInformationThread"); if(NtQueryInformationThread == NULL) return 0; HANDLE hCurrentProcess = GetCurrentProcess(); if(!DuplicateHandle(hCurrentProcess, hThread, hCurrentProcess, &hDupHandle, THREAD_QUERY_INFORMATION, FALSE, 0)){ SetLastError(ERROR_ACCESS_DENIED); return 0; } ntStatus = NtQueryInformationThread(hDupHandle, ThreadQuerySetWin32StartAddress, &dwStartAddress, sizeof(DWORD), NULL); CloseHandle(hDupHandle); if(ntStatus != STATUS_SUCCESS) return 0; return dwStartAddress; }