TLS는 Thread Local Storage의 약자로 스레드별로 연관 데이터를 기록하기 위해 사용될수 있다.
예를 들어 스레드의 생성 시간을 저장할 수 있도록 각 스레드별로 공간을 마련하여 스레드가 종료될 때 이 값을 이용하여 스레드의 수행 시간을 계산할 수 있다.
TLS도 Dynamic TLS와 Static TLS로 나뉘는데 이들 각각은 애플리케이션과 DLL에서 사용할 수 있다.
Static TLS는 사실상 다룰 내용이 많이 없기 때문에 이번 포스팅에선 Dynamic TLS에 관해서 다뤄볼려한다.
애플리케이션에서 Dynamic TLS의 장점을 활용하려면 네 개의 함수를 이용해야되는데 실제로 이런 함수들은
DLL 개발시 자주 사용되기도 한다. 아래 그림은 마이크로소프트가 TLS를 관리하기 위해 내부적으로 사용하는
자료 구조의 모습이다.
위 그림은 시스템에서 수행 중인 단일 프로세스에 포함되어 있는 사용 중인 플래그들의 집합을 보여준다.
각각의 플래그는 FREE 상태나 INUSE 상태가 될 수 있으며 이 플래그들은 각각의 TLS 슬롯이 사용 중인지의
여부를 나타낸다.
Dynamic TLS를 사용하려면 가장 먼저 TlsAlloc 함수를 호출해야 하는데 이 함수는 프로세스 내의 비트 플래그 배열로부터 FREE플래그의 위치를 찾아내어 해당 플래그 값을 INUSE 상태로 변경하고 비트 플래그 배열에서의 인덱스를 반환한다.
스레드가 생성되면 시스템은 해당 스레드와 연계되는 TLS_MINIMUM_AVAILABLE 개수의 PVOID형 배열을 할당하고 0으로 초기화 한다. 스레드 별로 존재하는 PVOID 배열에 값을 저장하기 전에 이 배열의 어느 요소가 사용 가능한지를 알아야 하는데 이를 위해 TlsAlloc 함수를 호출 했다.
스레드 배열 내에 값을 할당하기 위해서는 TlsSetValue 함수를 호출하면 된다.
BOOL TlsSetValue(
DWORD dwTlsIndex,
PVOID pvTlsValue);
이 함수는 스레드가 가지고 있는 배열에서 dwTlsIndex 매개변수 값을 인덱스로 하는 공간에 pvTlsValue 매개변수로 전달하는 값을 할당한다. 스레드는 이렇게 TlsSetValue 함수를 호출하여 자신이 소유하고 있는 배열의 값을 변경할 수 있지만 다른 스레드에 있는 배열의 값은 변경하지 못한다.
스레드 배열로부터 값을 얻어오기 위해서는 TlsGetValue 함수를 호출하면 된다.
PVOID TlsGetValue(DWORD dwTlsIndex);
이 함수는 스레드가 소유하고 있는 TLS 슬롯으로부터 dwTlsIndex번째 값을 가져온다. TlsSetValue 함수와 마찬가지로 TlsGetValue 함수를 호출하는 스레드는 자신이 소유하고 있는 배열에서만 값을 가져올 수 있다.
프로세스 내의 모든 스레드에서 앞서 예약하였던 TLS 슬롯을 더이상 사용할 필요가 없는 시점이 되면 TlsFree 함수를 호출하면 된다.
BOOL TlsFree(DWORD dwTlsIndex);
아래는 스레드는 40바이트 크기의 구조체를 가리키는 포인터를 함수를 최초로 호출할때 전달한다고 가정하고 이런 종류의 함수는 이 함수가 다시 호출될 때 앞서 전달된 구조체를 다시 사용할 수 있도록 그 값을 저장하도록 하는 코드이다.
DWORD g_dwTlsIndex; // TlsAlloc 함수의 반환 값으로 가정 ... void MyFunction(PSOMESTRUCT pSomeStruct) { if (pSomeStruct != NULL) { if (TlsGetValue(g_dwTlsIndex) == NULL) { TlsSetValue(g_dwTlsIndex, HeapAlloc(GetProcessHeap(), 0, sizeof(*pSomeStruct)); } memcpy(TlsGetValue(g_dwTlsIndex), pSomeStruct, sizeof(*pSomeStruct)); } else { pSomeStruct = (PSOMESTRUCT) TlsGetValue(g_dwTlsIndex); ... } } |
# Reference
제프리 리쳐의 Windows via c/c++
http://debugjung.tistory.com/45
http://studyfoss.egloos.com/5259841
'Security' 카테고리의 다른 글
안티디버깅 간단 정리 (1) | 2013.10.30 |
---|---|
바인드쉘, 리버스쉘 (0) | 2013.10.24 |
허.. (0) | 2013.10.17 |
php extract vulnerability (0) | 2013.10.13 |
RTL시 pop pop ret, exit 함수 호출의 원리 (2) | 2013.09.26 |