Process Heap
- PEB.ProcessHeap 멤버(+0x18)는 Heap 구조체를 가리키는 포인터이다.
- Flags 멤버(+0x0C)와 Force Flags 멤버(+0x10)는 디버깅 중 특정한 값으로 세팅된다.
- 프로세스가 정상 실행 중일 때 Heap.Flags 멤버(+0x0C)의 값은 0x02이고, Heap.ForceFlags 멤버(+0x10)의 값은 0x00이다. (Windows XP 환경)
- Windows XP에서만 효과가 있는 기법이다. Windows 7에서는 이 특성이 없어졌다.
- 실행 중인 프로세스에 디버거를 Attach시킨 경우에도 이 특성이 나타나지 않으므로 동작하지 않는다.
[Heap 구조체의 일부분]
+0x000 Entry : _HEAP_ENTRY
+0x008 Signature : Uint4B
+0x00c Flags : Uint4B
+0x010 ForceFlags : Uint4B
+0x014 VirtualMemoryThreshold : Uint4B
+0x018 SegmentReverse : Uint4B
+0x01c SegmentCommit : Uint4B
+0x020 DecommitFreeBlockThreshold : Uint4B
○ ProcessHeap 의존성 확인
- Windows 7에서는 일반 실행했을때 Heap.Flag 멤버의 값과 Heap.ForceFlags의 값이 다르다.
(Heap.Flag 멤버의 값은 0으로 고정되어있고, Heap.ForceFlags의 값은 실행할 때마다 변하는 것을 확인했다.)
[C언어로 작성한 예제 파일]
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | #include <stdio.h> #include <windows.h> #include <tchar.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); while(1){ LPBYTE pHeap = (LPBYTE)*(LPDWORD)(pPEB+0x18); DWORD dwFlags = *(pHeap+0xC); DWORD dwForceFlags = *(LPDWORD)(pHeap+0x10); printf("PEB.ProcessHeap.Flags = 0x%x\n", dwFlags); printf("PEB.ProcessHeap.ForceFlags = 0x%x\n", dwForceFlags); if(dwFlags != 0x2 || dwForceFlags != 0x0){ printf("Debugging!!!\n"); } else{ printf("Not Debugging...\n"); } Sleep(1000); } return 0; } | cs |
○ TEB → PEB → PEB.ProcessHeap 순서대로 접근한다. PEB.ProcessHeap = 0x00240000
○ 현재 디버거로 연 상태이므로 Heap.Flags = 0x50000062, Heap.ForceFlags = 0x40000060 이다.
Heap.Flags 필드는 일반적으로 이 Flag들의 bit OR연산 값으로 설정된다.
HEAP_GROWABLE (0x02)
HEAP_TAIL_CHECKING_ENABLED (0x20)
HEAP_FREE_CHECKING_ENABLED (0x40)
HEAP_SKIP_VALIDATION_CHECKS (0x10000000)
HEAP_VALIDATE_PARAMETERS_ENABLED (0x40000000)
Heap.ForceFlags 필드는 일반적으로 이 Flag들의 bit OR연산 값으로 설정된다.
HEAP_TAIL_CHECKING_ENABLED (0x20)
HEAP_FREE_CHECKING_ENABLED (0x40)
HEAP_VALIDATE_PARAMETERS_ENABLED (0x40000000)
[우회 방법] : Heap.Flags를 0x02로, Heap.ForceFlags를 0x00으로 변경하면 된다.
○ Heap.Flags = 0x00000002, Heap.ForceFlags = 0x00000000으로 변경한다.
○ 우회한 것을 확인할 수 있다.
참고 : 리버싱 핵심원리(책), Windows 구조와 원리(책), MSDN
'Reversing' 카테고리의 다른 글
Static Anti-Debugging 0x04. NtGlobalFlag (0) | 2016.07.07 |
---|---|
Static Anti-Debugging 0x02. LDR (0) | 2016.07.06 |
Static Anti-Debugging 0x01. IsDebuggerPresent() (0) | 2016.07.06 |
Anti-Debugging (0) | 2016.07.06 |
PEB 구조 (2) | 2016.07.05 |