2014-01-24 1 views
1

나는 작은 바이트 코드 인터프리터 언어 쓰고 있어요 구현하는 넣어서 PAGE_GUARD 사용 방법 (또는 프레임 워크를 VM?). 나는 Windows가 스택에 PAGE_GUARD을 사용한다는 것을 알고 있으며 이것을 사용하고 싶다.는 Win32 GUARD 메모리 : I 스택

첫째, 나는 가상 메모리를 예약하고 한 페이지에 MEM_COMMIT/넣어서 PAGE_GUARD을한다.

pStack->end = VirtualAlloc(NULL, MaxSize, MEM_RESERVE, PAGE_READWRITE); 
if (pStack->end != NULL) 
{ 
    pStack->bp = pStack->sp = pStack->base = pStack->end + MaxSize; 

    if (VirtualAlloc(pStack->base - PageSize, PageSize, MEM_COMMIT, PAGE_READWRITE | PAGE_GUARD) != NULL) 

(나는 (비 넣어서 PAGE_GUARD) 한 페이지를 저지해야 알아,하지만 그것은 PAGE_GUARD을 테스트합니다.)

다음과 같이 나는 __except 쓰기 :

__except (StackOnSEHExcept(GetExceptionInformation())) {} 

/* A */ 

... 
DWORD StackOnSEHExcept(PEXCEPTION_POINTERS exc) 
{ 
    if (exc->ExceptionRecord->ExceptionCode == STATUS_GUARD_PAGE_VIOLATION) 
    { 
     return EXCEPTION_CONTINUE_EXECUTION; 
    } 
    else 
    { 
     return EXCEPTION_CONTINUE_SEARCH; 
    } 
} 

(나는 또한 알고 커밋한다/다음 페이지를 보호하지만, 너무, 테스트입니다.)

내가 스택의 메모리를 터치하면 STATUS_GUARD_PAGE_VIOLATION이 발생한다. 그러나 그 후에는 /* A */이 실행됩니다.

윈도우는 예외 이후에 발생하는 PAGE_GUARD를 해제하지 않습니다? 왜이 코드가 잘 작동하지 않습니까?


, 나는이 부분을 수행하는 방법을 모른다 : (나는 또한 내가/커밋 다음 페이지를 보호해야한다 알고 있지만, 너무, 테스트입니다.)을. 어떻게해야합니까? 내가해야한다고 생각 1. 보호 페이지의 주소 2./커밋 다음 페이지를 보호,하지만 난 1

편집 작업을 수행하는 방법을 모르는 얻을 : 나는 경비 주소가 여기에 1을 수행하는 방법을 알고있다 :

exc->ExceptionRecord->ExceptionInformation[1] 

감사합니다.

+0

당신은 적어도 두 페이지가 필요합니다! 최선을 다하고 하나와 한 페이지 가드 ... –

+0

@JochenKalmbach (~)를 참조하시기 바랍니다. 알아요.하지만 'PAGE_GUARD' 테스트입니다. – ikh

답변

1

예외 발생 후 Windows에서 PAGE_GUARD 표시를 해제하지 않습니까?

http://msdn.microsoft.com/en-us/library/windows/desktop/aa366786(v=vs.85).aspx

은 ... 지역 페이지는 가드 페이지가됩니다. 가드 페이지에 액세스하려고하면 시스템이 STATUS_GUARD_PAGE_VIOLATION 예외를 발생시키고 가드 페이지 상태를 해제합니다. 가드 페이지는 일회성 액세스 알람으로 작동합니다.

이 시도 :

DWORD OnSEH() 
{ 
    ::OutputDebugString(L"SEH!\n"); 
    return (DWORD) EXCEPTION_CONTINUE_EXECUTION; 
} 

static void Test() 
{ 
    const DWORD pageSize = 4096; 
    void* baseAddr = ::VirtualAlloc(NULL, pageSize, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); 

    DWORD oldAttr = 0; 
    void* protectedAddr = baseAddr; 
    BOOL ok = ::VirtualProtect(protectedAddr, pageSize, PAGE_READWRITE | PAGE_GUARD, &oldAttr); 
    if(!ok) { 
     int lastError = ::GetLastError(); lastError; 
     return; 
    } 

    ::OutputDebugString(L"Reading the guarded page\n"); 

    __try { 
     int* testAddr = static_cast<int*>(protectedAddr); 
     int value = *testAddr; value; 

     ::OutputDebugString(L"Continue execution\n"); 
    } 
    __except(OnSEH()) {} 
+0

그럼 왜 실패 했나요? 그에 따르면, CONTINUE_EXECUTION 실행하고 내 코드 – ikh

+0

.. 잘 작동합니다 나는 대답하는 코드를 추가했습니다. – KonstantinL

+0

정말 고마워요! 나는


에서 어떻게 할 수,'OutputDebugString' .. 그런데 – ikh