There’s a member of the NT_TIB
structure called ArbitraryUserPointer
.
typedef struct _NT_TIB { struct _EXCEPTION_REGISTRATION_RECORD *ExceptionList; PVOID StackBase; PVOID StackLimit; PVOID SubSystemTib; PVOID FiberData; PVOID ArbitraryUserPointer; struct _NT_TIB *Self; } NT_TIB;
How arbitrary is this value? Can I use it for anything I want?
This is another case of looking at the world through kernel-colored glasses. The ArbitraryUserPointer
is arbitrary from the kernel’s point of view, but that doesn’t mean that it’s available for anybody to use. The User
here means “user-mode”. The kernel is saying, “Dude, like, here’s a value for user-mode to use however it sees fit. I really don’t care.”
But user-mode might care.
In practice, the user-mode loader uses the ArbitraryUserPointer
to pass information to the debugger. It’s not a random place for programs to stash data.
My favourite field in the TEB is Win32ThreadInfo. It points to a THREADINFO structure *in kernel-mode memory*. A kernel-mode pointer in user-mode memory is never a good sign…
Going a way back to CDC KRONOS, the manuals said that for each directory entry there was a "USERCONTROLWORD". Neat, we thought, 60 bits where we could stuff some file meta-info.
But if you talked to the system programmers, they said "WE are the users!" So they stole 12 bits to store the file's language. Then the computer science department decided they were going to use all the other bits to implement a crude user-id...
https://blogs.technet.microsoft.com/askcore/2010/08/25/ntfs-file-attributes/
Any extended attribute that doesn't start with a "$" is fair game under IBM's rules, I couldn't immediately find Microsoft's rule (quit moving pages) but assume it to be the same from the naming on the article. At any rate, use a Java-format reverse domain name to prefix your attribute, and the odds Microsoft would ever pick that same name for an attribute would be so near to zero to be zero.
Note that the linked article mentions that the loader only borrows the member. The loader restores whatever value was there in case anyone cares.