Can someone tell me which data member of the ETHREAD structure that provides the starting address of the current executing thread ? Would it be the StartAddress data member as seen in the following dump ? I am looking for beginning address of the code for a given ETHREAD data object. I'm not certain that the _ETHREAD contains this detail.
lkd> dt _ETHREAD
nt!_ETHREAD
+0x000 Tcb : _KTHREAD
+0x5d0 CreateTime : _LARGE_INTEGER
+0x5d8 ExitTime : _LARGE_INTEGER
+0x5d8 KeyedWaitChain : _LIST_ENTRY
+0x5e8 ChargeOnlySession : Ptr64 Void
+0x5f0 PostBlockList : _LIST_ENTRY
+0x5f0 ForwardLinkShadow : Ptr64 Void
+0x5f8 **StartAddress** : Ptr64 Void
+0x600 TerminationPort : Ptr64 _TERMINATION_PORT
+0x600 ReaperLink : Ptr64 _ETHREAD
....
+0x6bd SuppressSymbolLoad : Pos 3, 1 Bit
+0x6bd Prefetching : Pos 4, 1 Bit
+0x6bd OwnsVadExclusive : Pos 5, 1 Bit
+0x6bd OwnsChangeControlAreaExclusive : Pos 6, 1 Bit
+0x6bd OwnsChangeControlAreaShared : Pos 7, 1 Bit
+0x6be OwnsPagedPoolWorkingSetExclusive : Pos 0, 1 Bit
+0x6be OwnsPagedPoolWorkingSetShared : Pos 1, 1 Bit
+0x6be OwnsSystemPtesWorkingSetExclusive : Pos 2, 1 Bit
+0x6be OwnsSystemPtesWorkingSetShared : Pos 3, 1 Bit
+0x6be TrimTrigger : Pos 4, 2 Bits
+0x6be Spare2 : Pos 6, 2 Bits
+0x6bf SystemPagePriorityActive : Pos 0, 1 Bit
+0x6bf SystemPagePriority : Pos 1, 3 Bits
+0x6bf Spare3 : Pos 4, 4 Bits
+0x6c0 CacheManagerActive : UChar
+0x6c1 DisablePageFaultClustering : UChar
+0x6c2 ActiveFaultCount : UChar
+0x6c3 LockOrderState : UChar
+0x6c8 AlpcMessageId : Uint8B
+0x6d0 AlpcMessage : Ptr64 Void
+0x6d0 AlpcReceiveAttributeSet : Uint4B
+0x6d8 ExitStatus : Int4B
+0x6e0 AlpcWaitListEntry : _LIST_ENTRY
+0x6f0 CacheManagerCount : Uint4B
+0x6f4 IoBoostCount : Uint4B
+0x6f8 BoostList : _LIST_ENTRY
+0x708 DeboostList : _LIST_ENTRY
+0x718 BoostListLock : Uint8B
+0x720 IrpListLock : Uint8B
+0x728 ReservedForSynchTracking : Ptr64 Void
+0x730 CmCallbackListHead : _SINGLE_LIST_ENTRY
+0x738 ActivityId : Ptr64 _GUID
+0x740 SeLearningModeListHead : _SINGLE_LIST_ENTRY
+0x748 VerifierContext : Ptr64 Void
+0x750 KernelStackReference : Uint4B
+0x758 AdjustedClientToken : Ptr64 Void
+0x760 UserFsBase : Uint4B
+0x768 UserGsBase : Uint8B
+0x770 PicoContext : Ptr64 Void
From a debugging standpoint, yes the initial function is stored in StartAddress
and the more useful "unique" user-mode address is in Win32StartAddress
.
There are however two things to keep in mind:
StartAddress
is in a union
with another member and might not be valid after the tread has executed some of its code.StartAddress
is part of a struct that changes a lot between versions and its offset is not stable so you should not be using it in a driver, only while debugging.A real product should use something like PsSetCreateThreadNotifyRoutine
, not reading from unstable system structs.