Created
November 14, 2019 06:24
-
-
Save kohnakagawa/9f6b791ed86ea616213b9bb130a13502 to your computer and use it in GitHub Desktop.
TEBに含まれるTLS Slotsに含まれる内容を確認するために使うコード
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <windows.h> | |
#include <winnt.h> | |
#include <stdio.h> | |
#define THREADCOUNT 4 | |
DWORD dwTlsIndex; | |
VOID ErrorExit(LPSTR); | |
VOID CommonFunc(VOID) | |
{ | |
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. | |
printf("common: thread %d: lpvData=%lx\n", | |
GetCurrentThreadId(), lpvData); | |
Sleep(5000); | |
} | |
DWORD WINAPI ThreadFunc(VOID) | |
{ | |
LPVOID lpvData; | |
// Initialize the TLS index for this thread. | |
lpvData = (LPVOID) LocalAlloc(LPTR, 256); | |
if (! TlsSetValue(dwTlsIndex, lpvData)) | |
ErrorExit((LPSTR)"TlsSetValue error"); | |
_TEB* teb = NtCurrentTeb(); | |
DWORD* pteb = (DWORD*)((CHAR*)teb + 0x1488); | |
printf("tlsindex %d: thread %d: lpvData=%lx tlsslot=%x\n", | |
dwTlsIndex, | |
GetCurrentThreadId(), | |
lpvData, | |
*pteb | |
); | |
CommonFunc(); | |
// Release the dynamic memory before the thread returns. | |
lpvData = TlsGetValue(dwTlsIndex); | |
if (lpvData != 0) | |
LocalFree((HLOCAL) lpvData); | |
return 0; | |
} | |
int main(VOID) | |
{ | |
DWORD IDThread; | |
HANDLE hThread[THREADCOUNT]; | |
int i; | |
// Allocate a TLS index. | |
if ((dwTlsIndex = TlsAlloc()) == TLS_OUT_OF_INDEXES) | |
ErrorExit((LPSTR)"TlsAlloc failed"); | |
// 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); | |
TlsFree(dwTlsIndex); | |
return 0; | |
} | |
VOID ErrorExit (LPSTR lpszMessage) | |
{ | |
fprintf(stderr, "%s\n", lpszMessage); | |
ExitProcess(0); | |
} |
これ x64 でないと動かんようになっている
なんか色々間違ってるので、フォークして32bitも動くようにした ・ω・
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
簡単な説明
コードはMSのサンプルコードを改良したものを使っている。
サンプルコードから追加した部分は以下の部分
_TEB* teb = NtCurrentTeb(); DWORD* pteb = (DWORD*)((CHAR*)teb + 0x1488);
TEBの先頭から0x1488バイト (TEB内部で定義された TLS Slots の1番目のエントリーの内容に等しい) のDWORDを参照している。この値は
で設定された
lpvData
の値と等しくなることがわかる。以下は実際にプログラム実行した時の出力。つまり
各スレッドはTLS Slots を持っており、スレッド固有の記憶領域を持っている。これはポインターの配列となっており、各スレッドで
LocalAlloc
して確保した領域の先頭アドレスを登録することができる。どの領域にアクセスするのかは TLS Slots のインデックス (上記の例でいうと、dwTlsIndex) で指定すれば良い。