首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Win32保护内存:如何使用PAGE_GUARD实现堆栈

Win32保护内存:如何使用PAGE_GUARD实现堆栈
EN

Stack Overflow用户
提问于 2014-01-24 13:28:00
回答 1查看 3.3K关注 0票数 2

我正在写一个很小的字节码,解释语言(或框架)?( vm?)我知道Windows在堆栈上使用PAGE_GUARD,我想使用这个。

首先,我保留虚拟内存,并在一个页面上执行MEM_COMMIT/ page _ First。

代码语言:javascript
运行
复制
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写成如下:

代码语言:javascript
运行
复制
__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 */

在出现异常后,Windows不取消标记PAGE_GUARD吗?为什么这些代码不能正常工作呢?

而且,我不知道如何完成这个部分:(我也知道我应该提交/保护下一页,但它也是用于测试的。)我该怎么做?我想我应该1.得到保护页的地址2.提交/保护下一页,但我不知道怎么做1。

编辑:我知道怎么做。有守卫的地址在这里:

代码语言:javascript
运行
复制
exc->ExceptionRecord->ExceptionInformation[1]

谢谢你的帮助!

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2014-01-24 13:38:32

在出现异常后,Windows不取消标记PAGE_GUARD吗?

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

..。该区域中的页面将成为守卫页面。任何访问保护页的尝试都会导致系统引发STATUS_GUARD_PAGE_VIOLATION异常并关闭保护页状态。因此,保护页充当一次访问警报。

试试这个:

代码语言:javascript
运行
复制
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() ) {}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/21333967

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档