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(""); } |
○ 디버깅 중일 때의 모습이다. (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 |