Which ETHREAD data member provides starting address (start of code) of the current executing thread?

0

Issue

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

Solution

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:

  1. StartAddress is in a union with another member and might not be valid after the tread has executed some of its code.
  2. 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.

Answered By – Anders

This Answer collected from stackoverflow, is licensed under cc by-sa 2.5 , cc by-sa 3.0 and cc by-sa 4.0

Leave A Reply

Your email address will not be published.

This website uses cookies to improve your experience. We'll assume you're ok with this, but you can opt-out if you wish. Accept Read More