본문 바로가기

Reversing/Anti Debugging

PEB구조체를 활용한 안티디버깅


*이 포스팅은 리버싱 핵심원리에서 공부한 내용을 정리한 내용입니다. 틀린 부분이 있을시 지적해 주세요.*


이전 글에 이어 PEB구조체를 활용한 안티디버깅 방법입니다.

PEB의 값을 참조해서 할 수 있는 안티디버깅 방식으로는 약 4가지 정도가 있습니다.

1. BeingDebugged

2. Ldr

3. Process Heap

4. NtGlobalFlag

이렇게 4가지로 분류할 수 있습니다. 하나씩 알아보겠습니다.


1. BeingDebugged

PEB.BeingDebugged(+0x2)의 값을 참조하여 안티디버깅을 할 수 있습니다.

WinDbg로 봐 보면

여기에 존재합니다. 이 BeingDebugged는 디버깅 중일 때는 1(True)로 설정이 되며 디버깅 중이지 않을 때는 0(False)로 설정이 됩니다. 이를 이용해서 디버깅을 탐지하는 소스를 짜 보면

이렇게 짤 수 있습니다. 사실 우리가 잘 알고 있는 IsDebuggerPresent함수도 이 값을 참조해서 디버깅 중인지를 판단합니다.

올리디버거에서 직접 PEB주소로 가서 봐보면

실제로 값이 1로 세트되어 있는 것을 볼 수 있습니다.


2. Ldr

두 번째로는 PEB.Ldr(+0xC)에 있는 Ldr구조체의 주소를 가리키고 있는 값을 참조해서 안티디버깅을 할 수 있습니다. 

이 Ldr구조체가 어떻게 쓰이냐면 일단 디버깅 당하는 프로세스는 힙(Heap)메모리 영역에 자신이 디버깅 당하는 프로세스라는 표시를 합니다. 그 표시가 뭐냐면 바로 Heap메모리 영역에서 사용되지 않는 부분은 0xFEEEFEEE 또는 0xABABABAB로 채워 버리는 겁니다. 이 표시를 보고 이 프로세스가 디버깅 당하는 중인지를 알 수 있습니다. 그리고 Ldr구조체의 +0x0C영역부터 있는 주소가 heap과 연결된 주소인데 여기서 가장 많이 쓰이는 0x10부분의 데이터들을 스캔하면 쉽게 안티디버깅을 확인할 수 있습니다.(정확히 이 부분이 무엇을 하는 영역인지는 좀 더 공부를 해 봐야 알 것 같습니다.) 소스로 보자면

이렇게 짜 줄 수 있습니다. 올리디버거로 진행해 보면

이렇게 0xABABABAB 로 채워져 있는 부분들을 볼 수 있습니다. 다만 이 방법은 프로세스를 Attach시켰을 때는 탐지하지 못합니다..


3. Process Heap

역시 Heap영역에 있는 Heap구조체의 값을 참조하여 안티디버깅을 합니다. Heap구조체는 PEB구조체의 +0x18에 위치하는 값으로 알 수도 있고 또는 GetProcessHeap() API를 이용해서 구할 수도 있습니다. 이 Heap구조체에서 안티디버깅에 쓰이는 영역은 두 군데가 있습니다. 0xC와 0x40에 Flags가 위치하고 0x10과 0x44에 Force Flags가 위치합니다. 운영체제마다 이 값들이 변동이 있어서 각 플래그마다 위치하는 두 군데의 값을 모두 비교하여 주셔야 확실한 안티디버깅을 하실 수 있습니다. 소스로 보자면

이렇게 짤 수 있습니다. Flags는 정상 실행시에는 0x2, 디버깅 중일때는 0x2가 아닌 값이고 Force Flags는 정상 실행시 0x0이고 역시 디버깅 중에는 다른 값입니다. 


4. NtGlobalFlag

마지막으로 PEB구조체의 +0x68에 존재하는 NtGlobalFlag입니다. 이 값은 디버깅 중일 때에는 0x70으로 세팅이 되며 정상 실행일 때는 0이 됩니다. 소스로 짜면

이렇게 짤 수 있습니다. 다만 이 값은 프로세스를 Attach하였을 때는 탐지하지 못합니다.


이렇게 PEB구조체를 활용하여 안티디버깅을 하는 방법을 알아봤습니다.

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

TEB, PEB 구조체의 위치 구하기  (0) 2015.07.28