TEB->TlsSlots is used with TlsSetValue and TlsGetValue, but I'm unsure how TEB->TlsLinks LIST_ENTRY is associated. This is unrelated to TLS Callbacks that are sometimes written into the PE header, (as far as I know).
Some overview on TLS here
Thread Local Storage, part 1: Overview
Thread Local Storage, part 2: Explicit TLS
http://www.nynaeve.net/?p=180
http://www.nynaeve.net/?p=181
There's an implementation here that shows "walking" the linked list entry to parse the TlsLinks member.
https://www.winehq.org/pipermail/wine-d ... 35126.html
These are the related TEB structures:
Code: Select all
dx -r2 @$curthread.Environment
@$curthread.Environment
EnvironmentBlock [Type: _TEB]
[+0x000] NtTib [Type: _NT_TIB]
...
[+0x02c] ThreadLocalStoragePointer : 0xa0e6c8 [Type: void *]
...
[+0xe10] [color=#0000ff][B]TlsSlots [/B][/color][Type: void * [64]]
[+0xf10] [color=#0000ff][B]TlsLinks [/B][/color][Type: _LIST_ENTRY]
...
[+0xf94] TlsExpansionSlots : 0x0 [Type: void * *]
If an app makes use of TlsSetValue / TlsGetValue, you can click on the Windbg DML link for TlsSlots to print out the associated array:
Code: Select all
0:000> dx -r1 (*((ntdll!void * (*)[64])0x2c9e10))
(*((ntdll!void * (*)[64])0x2c9e10)) [Type: void * [64]]
[4] : 0xa077b0 [Type: void *]
...
[36] : 0x2c605c8 [Type: void *]
[37] : 0x2c64320 [Type: void *]
...
[63] : 0x0 [Type: void *]
TlsSetValue() - Stores a value in the calling thread's thread local storage (TLS) slot for the specified TLS index. Each thread of a process has its own slot for each TLS index.
The other 2 values (TlsSlot index 0x24 / 0x25) are pointers to memory allocations that the app uses to store/retrieve stack values (all registers/eflags) that it uses to covertly return to different function addresses that can't be discerned from the static disassembly. It's interesting how the app uses the TlsSlots to add a layer of obfuscation for passing around variables, rather than simply using a global variable. In any case, watching these stack related memory allocations move through TlsGetValue/TlsSetValue is a way of monitoring a bit what the program is doing.
Back to the original question, while looking at the TEB I noticed that the TEB->TlsLinks member is empty, in any thread I've looked at. I'm curious now what the _LIST_ENTRY is supposed to point to, and how it might be used. In code, LIST_ENTRY is used as a member of a structure and accessed using CONTAINING_RECORD.
Code: Select all
0:000> dx -r1 (*((ntdll!_LIST_ENTRY *)0x2c9f10))
(*((ntdll!_LIST_ENTRY *)0x2c9f10)) [Type: _LIST_ENTRY]
[+0x000] Flink : 0x0 [Type: _LIST_ENTRY *]
[+0x004] Blink : 0x0 [Type: _LIST_ENTRY *]
Being stored in the TEB, what linked list of structures might TlsLinks point to, and when might it be active?