-
-
Save blackwingcat/cc056fe24b375bc51f5b7c5f646ff7a2 to your computer and use it in GitHub Desktop.
#include <windows.h> | |
#include <winnt.h> | |
#include <stdio.h> | |
#define THREADCOUNT 4 | |
DWORD dwTlsIndex; | |
VOID ErrorExit(LPSTR); | |
VOID CommonFunc(int dwTlsIndex) | |
{ | |
LPVOID lpvData; | |
// Retrieve a data pointer for the current thread. | |
lpvData = TlsGetValue(dwTlsIndex); | |
if ((lpvData == 0) && (GetLastError() != ERROR_SUCCESS)) | |
ErrorExit((LPSTR)"TlsGetValue error"); | |
// Use the data stored for the current thread. | |
#ifndef _WIN64 | |
printf("common: thread %d: lpvData=%08lx\n", | |
#else | |
printf("common: thread %d: lpvData=%016llx\n", | |
#endif | |
GetCurrentThreadId(), lpvData); | |
Sleep(5000); | |
} | |
DWORD WINAPI ThreadFunc(VOID) | |
{ | |
LPVOID lpvData; | |
int dwTlsIndex = -1; | |
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) { | |
ErrorExit((LPSTR)"TlsAlloc failed"); | |
return 0; | |
} | |
// Initialize the TLS index for this thread. | |
lpvData = (LPVOID)LocalAlloc(LPTR, 256); | |
if (!TlsSetValue(dwTlsIndex, lpvData)) | |
ErrorExit((LPSTR)"TlsSetValue error"); | |
_TEB* teb = NtCurrentTeb(); | |
#ifndef _WIN64 | |
DWORD* pteb = (DWORD*)((CHAR*)teb + 0xe10 + dwTlsIndex * 4); | |
printf("tlsindex %d: thread %d: lpvData=%08lx tlsslot=%08lx\n", | |
#else | |
LONG64* pteb = (LONG64*)((CHAR*)teb + 0x1480 + dwTlsIndex * 8); | |
printf("tlsindex %d: thread %d: lpvData=%016llx tlsslot=%016llx\n", | |
#endif | |
dwTlsIndex, | |
GetCurrentThreadId(), | |
lpvData, | |
*pteb | |
); | |
CommonFunc(dwTlsIndex); | |
// Release the dynamic memory before the thread returns. | |
lpvData = TlsGetValue(dwTlsIndex); | |
if (lpvData != 0) | |
LocalFree((HLOCAL)lpvData); | |
TlsFree(dwTlsIndex); | |
return 0; | |
} | |
int main(VOID) | |
{ | |
DWORD IDThread; | |
HANDLE hThread[THREADCOUNT]; | |
int i; | |
// Allocate a TLS index. | |
// Create multiple threads. | |
for (i = 0; i < THREADCOUNT; i++) | |
{ | |
hThread[i] = CreateThread(NULL, // default security attributes | |
0, // use default stack size | |
(LPTHREAD_START_ROUTINE)ThreadFunc, // thread function | |
NULL, // no thread function argument | |
0, // use default creation flags | |
&IDThread); // returns thread identifier | |
// Check the return value for success. | |
if (hThread[i] == NULL) | |
ErrorExit((LPSTR)"CreateThread error\n"); | |
} | |
for (i = 0; i < THREADCOUNT; i++) | |
WaitForSingleObject(hThread[i], INFINITE); | |
return 0; | |
} | |
VOID ErrorExit(LPSTR lpszMessage) | |
{ | |
fprintf(stderr, "%s\n", lpszMessage); | |
ExitProcess(0); | |
} |
32bit
C:\PFW\check_tls_slots_content>Debug\tebtest.exe
tlsindex 1: thread 26352: lpvData=012c9500 tlsslot=012c9500
common: thread 26352: lpvData=012c9500
tlsindex 2: thread 23048: lpvData=012cbff0 tlsslot=012cbff0
common: thread 23048: lpvData=012cbff0
tlsindex 3: thread 18308: lpvData=012cc848 tlsslot=012cc848
common: thread 18308: lpvData=012cc848
tlsindex 4: thread 23616: lpvData=012cffc8 tlsslot=012cffc8
common: thread 23616: lpvData=012cffc8
64bit
C:\PFW\check_tls_slots_content>x64\Debug\tebtest.exe
tlsindex 1: thread 12592: lpvData=000001f6547ff770 tlsslot=000001f6547ff770
common: thread 12592: lpvData=000001f6547ff770
tlsindex 2: thread 16536: lpvData=000001f654801090 tlsslot=000001f654801090
tlsindex 5: thread 22708: lpvData=000001f6548024f0 tlsslot=000001f6548024f0
common: thread 22708: lpvData=000001f6548024f0
tlsindex 3: thread 16348: lpvData=000001f654801ac0 tlsslot=000001f654801ac0
common: thread 16348: lpvData=000001f654801ac0
common: thread 16536: lpvData=000001f654801090
TlsAllocの使い方が間違ってるがきになったのと 32bit対応