In Windows, it's long been common, if undocumented, knowledge that the Thread Information Block (TIB) of the current thread can be found at FS:0. But that only works on Intel CPUs, where the FS register exists in the first place. Now I wanna get to the TIB on an ARM-based Windows system (Windows Phone and maybe Windows RT). Is there an API for that, please?
EDIT: I want to get the thread stack base for crash reporting purposes.
Information about TIB/TEB: http://www.microsoft.com/msj/archive/S2CE.aspx
The Thread Environment Block (TEB structure) describes the state of a thread.
FS:[0x00] : Current SEH Frame. FS:[0x18] : TEB (Thread Environment Block) FS:[0x20] : PID. FS:[0x24] : TID. FS:[0x30] : PEB (Process Environment Block)
The Thread Environment Block ( TEB structure) holds context information for a thread. In the following versions of Windows, the offset of the 32-bit TEB address within the 64-bit TEB is 0. This can be used to directly access the 32-bit TEB of a WOW64 thread. This might change in later versions of Windows
TIB - Windows Thread Information Block The TIB is also referred to as TEB (Thread Environment Block)? The TIB is also known as Thread Environment Block. In a Win32 environment, the FSregisteralways points at the TEB, in a Win64 environment, it's the GSregister. Programattically, the TEB can be found with NtCurrentTeb().
In computing, the Win32 Thread Information Block (TIB) is a data structure in Win32 on x86 that stores information about the currently running thread. This structure is also known as the Thread Environment Block (TEB).
Access Code executing in user mode can easily find the TEBfor the current thread. While a thread that has a TEBexecutes in user mode, the fsor gsregister, for 32-bit and 64-bit code respectively, addresses this TEB. The TEBconveniently holds its own address in its NtTib.Selfmember.
The macro NtCurrentTeb()
is available in winnt.h
for all supported architectures, including ARM (Windows RT):
#if defined(_M_ARM) && !defined(__midl) && !defined(_M_CEE_PURE)
__forceinline
struct _TEB *
NtCurrentTeb (
VOID
)
{
return (struct _TEB *)(ULONG_PTR)_MoveFromCoprocessor(CP15_TPIDRURW);
}
To answer your posted question, you can use NtQueryInformationThread()
to retrieve a THREAD_BASIC_INFORMATION
structure, which contains a pointer to the thread's TIB
in its TebBaseAddress
member.
Igor nailed it. But FYI, in ARM assembly it goes like this:
mrc p15, 0, r12, c13, c0, 2 ; r12 now points at TEB/TIB
ldr r12, [r12, #4] ; r12 now holds stack base
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With