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

+ Recent posts