본문 바로가기

Reversing/Anti Debugging

TEB, PEB 구조체의 위치 구하기


*여기 있는 내용들은 리버싱 핵심원리와 고길님의 블로그(http://gogil.kr)에서 보고 공부했던 내용들을 정리하는 방식으로 했습니다.*


PEB(Process Environment Block)구조체는 프로세스의 정보를 담고 있는 구조체 입니다. 안티디버깅 기법을 적용할 때 많이 참조되기 때문에 꼭 알아야 하는 구조체 입니다. PEB구조체의 위치를 구하는 방법을 알기 전에 PEB에 대해서 조금만 알아보고 갑시다.

PEB구조체의 내용은 

이렇게 됩니다. 출처는 MSDN입니다. 향후 윈도우 버전에서는 변경될 수도 있다네요..

좀 더 자세한 정보 확인을 위해서 WinDbg로 가 줍시다.

>>>!peb

이렇게 PEB의 주소와 정보를 볼 수 있구요.

좀 더 자세한 정보를 보기위해

>>>dt_peb

구체적인 정보를 볼 수 있습니다.

이제 이 중에서 중요한 정보들을 뽑아 보자면

+0x002 BeingDebugged    : UChar

+0x008 ImageBaseAddress : Ptr32 Void

+0x00c Ldr              : Ptr32 _PEB_LDR_DATA

+0x018 ProcessHeap      : Ptr32 Void

+0x068 NtGlobalFlag     : Uint4B

이렇게 5가지 정도로 볼 수 있습니다.

실제 안티디버깅에 ImageBaseAddress는 쓰이지 않지만 프로그램의 Image Base를 구할 때 쓰이므로 추가해 봤습니다. 실제 GetModuleHandle(NULL)로 Image Base를 구할 때에도 이렇게 PEB구조체에 접근해서 구하게 됩니다.


다음은 TEB(Thread Environment Block)입니다. TEB는 쓰레드의 정보를 담고 있는 구조체 인데요. 안티디버깅에는 많이 쓰이지 않지만 PEB의 주소를 구할 때 많이 쓰이기 때문에 중요히 여겨지고 있습니다.  자세한 정보는 WinDbg에서 볼 수 있습니다.

>>>dt_teb

내용이 너무 많기 때문에 일부만 잘라 왔습니다. 저기 중간에 보면

+0x030 ProcessEnvironmentBlock : Ptr32 _PEB

이렇게 PEB의 주소를 가지고 있는 멤버변수가 있습니다. 이렇게 TEB의 주소를 구하면 PEB의 주소를 구하는데에 많은 이점이 있기 때문에 꼭 알아두어야 합니다.


이제 PEB의 주소를 구하는 방법을 알아봅시다.

일단 구할 수 있는 방법은 대체적으로 4가지가 있습니다.

1. FS레지스터를 이용하는 방법

2. NtCurrentTeb()를 이용하는 방법

3. ZwQueryInformationProcess()를 이용하는 방법

4. GetThreadContext(), GetThreadSelectorEntry()를 이용하는 방법

이렇게 볼 수 있습니다.


1. FS레지스터를 이용하는 방법

맨 먼저 FS레지스터를 이용해 봅시다. FS라는 세그먼트 레지스터가 있는데 이 레지스터는 현재 쓰레드의 TEB를 지시하는데에 사용됩니다. FS레지스터가 TEB를 가리키면 PEB는 어디에 있을까요? 바로 FS:[0x30]에 있습니다. 위에서 보았듯이 TEB구조체의 0x30만큼 떨어진 곳에 PEB의 주소가 있으니까요.

이렇게 가져올 수 있습니다.


2. NtCurrentTeb()를 이용하는 방법

이 함수 역시 내부적으로는 FS레지스터를 이용하여 TEB의 주소를 구한 뒤 PEB의 주소까지 구해줄 수 있습니다.

이렇게 생각보다 간단하게 소스를 짤 수 있습니다. 하지만 사실상 이 소스는 NtCurrentTeb함수를 풀어서 사용하면

이런 식으로 쓸 수 있게 되므로 제 생각에 많이 쓰이지는 않을 것 같습니다.

참고로 고길님은

소스를 이렇게 짜셨습니다.. 아예 NtCurrentTeb함수의 주소를 가져와서 호출을 하는군요..고길님 블로그를 참고했었는데 확실히 API를 공부해야겠다는 생각이 팍팍 드네요..


3. ZwQueryInformationProcess를 이용하는 방법

ZwQueryInformationProcess의 두번째 인자에 ProcessBasicInformation을 넣어 호출하면 PROCESS_BASIC_INFORMATION을 얻을 수 있습니다....라고 고길님은 이야기 하시는데 저는 아직 여기까지의 지식이 미처 닿지 못하기 때문에 좀 더 공부를 하고 알아봐야 겠습니다..

이렇게 구해주면 된다네요.. 자세한 건 고길님 블로그를 참고하세요!


4. GetThreadContext(), GetThreadSelectorEntry()를 이용하는 방법

API를 이용해서 FS레지스터를 읽어 옵니다.저도 잘 이해가 가지는 않습니다.. WINAPI를 좀 더 공부해야겠어요..

소스입니다. 고길님 블로그를 참고하였습니다.

이런 방식대로 PEB의 주소를 구한 뒤 구조체에 있는 값을 참조하여 안티디버깅을 할 수 있습니다. 이 부분들은 다음 포스팅에서 할께요. 감사합니다. :)

'Reversing > Anti Debugging' 카테고리의 다른 글

PEB구조체를 활용한 안티디버깅  (0) 2015.08.05