0

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
JoeT
  • 27
  • 8
  • Do you want the actual initial user-mode address where the first instruction is executed or the address passed to `CreateThread`? (They are not the same thing) – Anders Dec 07 '21 at 00:18
  • @Anders thank you. I'm looking for the first instruction (code) that is executed by the processor once a context switch takes place and a new thread has been selected to run on a given processor. – JoeT Dec 07 '21 at 00:37
  • At least on Vista and later this is always going to be `ntdll!RtlUserThreadStart` for user-mode threads, are you sure this is what you are after? – Anders Dec 07 '21 at 00:50

1 Answers1

2

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.

Anders
  • 97,548
  • 12
  • 110
  • 164
  • Anders@ I know that this post is old but I was curious as to how does one find out what each of the fields in the _ETHREAD structure actually mean and where they can be used? Since the structure is opaque how does one find out these details ? – JoeT Jul 20 '22 at 15:15
  • @JoeT The names should provide some clues but you are not supposed to use them in your own code. https://www.nirsoft.net/kernel_struct/vista/ETHREAD.html and perhaps the Windows Internals books... – Anders Jul 20 '22 at 16:16