PVOID WINAPI TlsGetValue( __in DWORD dwTlsIndex ) { PTEB Teb = NtCurrentTeb(); // fs:[0x18] // Reset the last error state. Teb->LastErrorValue = 0; // If the variable is in the main array, return it. if (dwTlsIndex < 64) return Teb->TlsSlots[ dwTlsIndex ]; if (dwTlsIndex > 1088) { BaseSetLastNTError( STATUS_INVALID_PARAMETER ); return 0; } // Otherwise it's in the expansion array, ensure that it is allocated. if (!Teb->TlsExpansionSlots) return 0; // Fetch the value from the expansion array. return Teb->TlsExpansionSlots[ dwTlsIndex - 64 ]; } 0:000> uf kernel32!TlsGetValue kernel32!TlsGetValue: mov edi,edi push ebp mov ebp,esp ; +0x018 Self : Ptr32 _NT_TIB mov eax,dword ptr fs:[00000018h] mov ecx,dword ptr [ebp+8] ; SetLastError( 0 ); ; +0x034 LastErrorValue : Uint4B and dword ptr [eax+34h],0 ; ; if (dwTlsIndex < 64) cmp ecx,40h jae kernel32!TlsGetValue+0x20 ; return Teb->TlsSlots[ dwTlsIndex ] ; +0xe10 TlsSlots : [64] Ptr32 Void kernel32!TlsGetValue+0x17: mov eax,dword ptr [eax+ecx*4+0E10h] kernel32!TlsGetValue+0x34: pop ebp ret 4 kernel32!TlsGetValue+0x20: ; if (dwTlsIndex > 1088) cmp ecx,440h jb kernel32!TlsGetValue+0x38 kernel32!TlsGetValue+0x28: ; SetLastError( ERROR_INVALID_PARAMETER ); ; return 0; ; ( 0xC000000D == STATUS_INVALID_PARAMETER ) push 0C000000Dh call kernel32!BaseSetLastNTError kernel32!TlsGetValue+0x32: xor eax,eax jmp kernel32!TlsGetValue+0x34 kernel32!TlsGetValue+0x38: ; if (!Teb->TlsExpansionSlots) ; return 0; ; +0xf94 TlsExpansionSlots : Ptr32 Ptr32 Void mov eax,dword ptr [eax+0F94h] test eax,eax je kernel32!TlsGetValue+0x32 kernel32!TlsGetValue+0x42: ; return Teb->TlsExpansionSlots[ dwTlsIndex - 64 ]; mov eax,dword ptr [eax+ecx*4-100h] jmp kernel32!TlsGetValue+0x34