LDR

 - Heap 메모리의 사용되지 않는 영역을 0xABABABAB 또는 0xFEEEFEEE 값으로 채우는 특징을 이용해 프로세스의 디버깅 여부를 판별할 수 있다.

※0xABABABAB는 HeapAlloc으로 메모리 할당만 하고 아직 사용하지 않은 경우의 값이고, 0xFEEEFEEE는 Heap에서 메모리를 해제한 경우 설정되어 있는 값이다.

 - PEB.LDR 멤버는 _PEB_LDR_DATA 구조체를 가리키는 포인터이다.

 - XP이하에서만 동작하고 Vista 이후부터는 동작하지 않는다.

 - 실행 중인 프로세스에 디버거를 Attach시킨 경우, Heap 메모리의 특성이 나타나지 않으므로 동작하지 않는다.


○ LDR 의존성 확인

- Windows 7에서는 디버거로 열어도 감지하지 못한다.

- Windows 7의 PEB 주소값은 0x7EFDE000이었다. PEB.Ldr(+0xC) 주소 값 : 0x77E20200


- 0x77E20200에는 0xABABABAB 또는 0xFEEEFEEE가 보이지 않기 때문에 "Not Debugging..." 메시지가 출력되었다.


 [C언어로 작성한 예제 파일]

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>
#include <windows.h>
 
int main(){
    FARPROC pProc = NULL;
    LPBYTE pTEB = NULL;
    LPBYTE pPEB = NULL;
 
    pProc = GetProcAddress(GetModuleHandle("ntdll.dll"), "NtCurrentTeb");
    pTEB = (LPBYTE)(*pProc)();
    pPEB = (LPBYTE)*(LPDWORD)(pTEB+0x30);
 
    printf("TEB : %x\n", pTEB);
    printf("PEB : %x\n", pPEB);
 
    puts("");
}

cs


○ 디버깅 중일 때의 모습이다. (Windows XP 환경)


○ PEB.Ldr 주소를 얻고, 그 주소로 가서 0xFEEEFEEE 영역을 찾았다.

<PEB.Ldr 주소는 Little Endian으로 박혀있다. PEB.Ldr 주소 : 0x00251EA0>


<Heap 메모리에서 0xFEEEFEEE로 채워진 영역>


[우회 방법] : 0xFEEEFEEE로 채워진 영역을 NULL로 덮어쓰면 된다.

○ 0xFEEEFEEE로 채워진 영역을 NULL로 덮어쓴다.


○ NULL값으로 덮여써진 것을 확인할 수 있다.


○ 우회한 것을 확인할 수 있다.



의문점 : Windows Vista부터는 0xFEEEFEEE가 생기지 않는 이유, 왜 하필 0xABABABAB 또는 0xFEEEFEEE인가?

참고 : 리버싱 핵심원리(책), Windows 구조와 원리(책), MSDN

'Reversing' 카테고리의 다른 글

Static Anti-Debugging 0x04. NtGlobalFlag  (0) 2016.07.07
Static Anti-Debugging 0x03. Process Heap  (0) 2016.07.07
Static Anti-Debugging 0x01. IsDebuggerPresent()  (0) 2016.07.06
Anti-Debugging  (0) 2016.07.06
PEB 구조  (2) 2016.07.05

+ Recent posts