본문 바로가기

High Level Technique/Reversing

Thread Local Storage CallBack (TLS)

Thread Local Storage CallBack (TLS)


Thread Local Storage (TLS)는 Thread 별로 독립된 데이터 저장공간 입니다. Thrad 내에서 프로세서의 전역 데이터나 정적 데이터를 마치 지역 데이터 처럼 독립적으로 취급하고 싶을 때 사용합니다.







마찬가지로 Windows 10 환경에서 시도해 보겠습니다.




OllyDBG에 붙여서 실행을 했음에도 불구하고 Hello :)가 출력이 되었습니다.


원래는 Debugger Detected!가 출력이 되어야 합니다. 그래서 혹시나 OllyDBG Plugin 때문에 그러지 않을까 싶어서 Plugin을 모두 제거하고 실행을 했지만 마찬가지 였습니다.


그래서 reversecore.com에서 직접 실습예제를 다운 받아서 실행해 봤더니 디버거가 탐지가 되었습니다.!








IMAGE_DATA_DIRECTORY[9]


TLS 기능을 사용하도록 하면 PE Header - TLS Table 항목이 세팅됩니다.













IMAGE_TLS_DIRECTORY


IMAGE_TLS_DIRECTORY 구조체는 32비트와 64비트로 선언이 되어있습니다.



중요한 멤버는 Address of Callbacks 입니다. 이 값은 TSL Callback 함수 주소(VA) 배열을 가리키는데, 프로그램에 TLS 콜백 함수를 여러개 등록할 수 있다는 뜻입니다.



위 배열에 실제 TSL 콜백 함수들의 주소가 들어있습니다. 여기서는 00401000 으로 하나만 들어있습니다.







TLS Callback Function


TLS 콜백 함수는 프로세스의 Thread가 실행/종료 될 때마다 자동으로 호출되는 콜백함수. main thread가 실행될 때도 콜백 함수가 호출된다. EP 코드보다 먼저 호출 되서 안티 디버깅 기법으로 사용 됩니다.






IMAGE_TLS_CALLBACK


DllMain()과 정의가 비슷합니다. 


DllHandle : 모듈의 핸들, 로딩된 주소

Reason : TLS 콜백 함수 호출 이유







TlsTest.exe 예제를 통해서 TLS 콜백 함수 동작원리에 대해서 알아보도록 하겠습니다.



DLL_PROCESS_ATTACH(1) : 프로세스의 main thread가 main()을 호출하기 전에 등록된 TLS 콜백 함수들이 호출된다.


DLL_THREAD_ATTACH(2) : TLS 콜백 함수들이 모두 종료되면 main()가 실해오딘다. 그리고 ThreadProc을 생성하는 순간 TLS 콜백 함수들이 호출된다.


DLL_THREAD_DETACH(3) : TLS 콜백 함수들이 종료되면 ThreadProc() 가 실행이 된다. Thread 함수가 종료되는 순간 TLS 콜백 함수가 호출된다.


DLL_PROCESS_DETACH(0) : ThreadProc()이 종료되면 종료를 기다리던 main() 역시 종료한다. 이때 마지막으로 TLS 콜백 함수들이 호출된다.





TLS 콜백 디버깅


event - system breakpoint에 체크를 하고 실행시키면 System Startup BreakPoint에 멈추게 된다. 아니면 OllyDBG 2.0에서 TLS Callback에 체크를 하면 TLS 콜백 함수를 디버깅 할 수 있다.






TLS 콜백 함수 추가하기



마지막 Section인 .rerc Section의 크기를 확인해 보면 PointerToRawData의 값이 9000이고 SizeOfRawData는 200입니다. 따라서 PE Header에서 정의된 크기는 9200입니다.

여기서 TLS CALLBACK 함수를 추가할 것이기 때문에 200만큼 더 늘립니다.


HxD를 이용하여 200만큼 더 늘립니다. 편집 - 바이트 삽입을 눌러줍니다.


마우스 커서를 파일의 맨 끝에 해주셔야 합니다.


VirtualSize의 값이 1B4인데 Section Alignment값으로 보정하여 1000크기 만큼 메모리에 로딩시킵니다. (PE 구조를 할 때 1000 단위로 넣었던 것.) 섹션의 크기가 200만큼 들어서 실제 3B4가 되지만 1000을 넘어가지 않기 때문에 값을 바꾸지 않아도 됩니다.


이제 RawDataSize를 400으로 바꾸고 Characteristics를 E0000060로 변경합니다.



PEView를 이용하면 위치를 쉽게 찾을 수 있습니다.



IMAGE_SCN_CNT_CODE, IMAGE_SCN_MEM_EXECUTE, IMAGE_SCN_MEM_WRITE 속성을 추가 시켰습니다. TLS CALLBACK 함수를 만들기 위해서 넣어줘야 한다고 생각하면 됩니다.



이제 IMAGE_DATA_DIRECTORY[9]를 만들어 주어야 합니다.



추가로 확장한 200바이트의 RVA 주소를 확인해 보면 C200입니다.  TLS Table의 값을 RVA는 C200 Size는 18로 변경합니다.




TLS의 위치가 1A8입니다. 해당위치를 수정해 줍니다.





이제 IMAGE_TLS_DIRECTORY를 만들어야 합니다.





9200 주소에 IMAGE_TLS_DIRECTORY 구조체를 만들어줍니다. AddressOfCallbacks는 40C224이고 해당 주소에 TLS 콜백 함수의 주소를 넣어주면 됩니다.




이제 TLS CALLBACK 함수를 짜야합니다.

0x40C230에  TLS CALL BACK 함수가 있기 때문에 해당 위치부터 안티 디버깅 코드를 넣어줍니다.





위와 같이 코드를 작성합니다.


그리고 변경된 영역이 40c230부터 40c291까지 모두 선택하여 오른쪽 마우스 - Copy to executable - Selection - Save file을 하면 됩니다.


저는 Hello_TLS.exe로 저장했습니다.



이제 해당 프로그램을 OllyDBG로 열어보면 Debugger Detected!가 떠야 합니다.




성공!

'High Level Technique > Reversing' 카테고리의 다른 글

Process Environment Block (PEB)  (0) 2016.08.02
Thread Environment Block (TEB)  (0) 2016.08.02
DLL Injection in kernel 6  (0) 2016.07.27
Session in Kernel 6  (0) 2016.07.26
Address Space Layout Randomization (ASLR)  (0) 2016.07.26