曲径通幽论坛

 找回密码
 立即注册
搜索
查看: 5391|回复: 0
打印 上一主题 下一主题

[内存管理] VirtualProtect() -- 改变指定虚拟内存分页保护属性

[复制链接]

4918

主题

5880

帖子

3万

积分

GROAD

曲径通幽,安觅芳踪。

Rank: 6Rank: 6

积分
34397
跳转到指定楼层
楼主
发表于 2012-3-2 00:16:53 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
VirtualProtect() 原型如下:
[C++] 纯文本查看 复制代码
BOOL WINAPI VirtualProtect(
  __in   LPVOID lpAddress,
  __in   SIZE_T dwSize,
  __in   DWORD flNewProtect,
  __out  PDWORD lpflOldProtect
);

函数可以改变调用进程虚拟地址空间中已提交页上的一段内存的保护属性。

第 1 个参数 lpAddress 是输入参数,是虚拟内存基地址。

第 2 个参数 dwSize 是输入参数,表示要改变内存区域的大小。

第 3 个参数 flNewProtect 是输入参数,给出了要设置的新的保护属性,可以为 PAGE_READONLY, PAGE_EXECUTE,PAGE_EXECUTE_READ 等。

第 4 个参数 lpflOldProtect 是输出参数,指向保存原保护属性值(DWORD),当其为 NULL 或 指向一个错误的变量时函数都将失败。

测试代码:
[C++] 纯文本查看 复制代码
#include "stdafx.h"
#include <locale.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    setlocale(LC_ALL, "CHS");

    LPVOID lpStart = (LPVOID)0x10000000;

    SIZE_T sizeVirtual = 8192;

    DWORD dwOldProtect;

    LPVOID lpAddress = VirtualAlloc(lpStart, sizeVirtual, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE);
    if (lpAddress == NULL) {
        printf ("VirtualAlloc Error : %d\n", GetLastError());
        return (-1);
    }

    CopyMemory (lpAddress, TEXT("Hello Groad.net"), 2*_tcslen(TEXT("Hello Groad.net")));

    _tprintf (TEXT("写入到内存空间的内容为:%s\n"), lpAddress);

    _tprintf (TEXT("将内存属性更改为只读...并再次尝试写入\n"));


    if (!VirtualProtect(lpAddress, 300, PAGE_READONLY, &dwOldProtect)) {
        _tprintf (TEXT("VirtualProtect error : %d"), GetLastError());
        return (-2);
    }
    //再次写入:
    CopyMemory (lpAddress, TEXT("Hello Groad.net"), 2*_tcslen(TEXT("Hello Groad.net")));

运行程序后,会看到错误提示框,如下图所示:

这是因为内存页已经修改为只读属性。

将程序中去掉修改属性后的 CopyMemory() 函数,并在下面添加 VirtualQuery()  函数,打印出内存相关信息:
[C++] 纯文本查看 复制代码
MEMORY_BASIC_INFORMATION mbi;            // 内存信息
    VirtualQuery(lpAddress, &mbi, sizeof(mbi));
    _tprintf (TEXT( "BaseAddress: 0x%.8x\nAllocationBase: 0x%.8x\nAllocationProtect: 0x%.8x\nRegionSize: %u\nState: 0x%.8x\nProtect: 0x%.8x\nType: 0x%.8x\n"),
        mbi.BaseAddress, mbi.AllocationBase, mbi.AllocationProtect,  mbi.RegionSize, mbi.State, mbi.Protect, mbi.Type);

运行输出:
写入到内存空间的内容为:Hello Groad.net
BaseAddress: 0x10000000
AllocationBase: 0x10000000
AllocationProtect: 0x00000004
RegionSize: 4096
State: 0x00001000
Protect: 0x00000002
Type: 0x00020000
由上面的输出确实看到了内存的保护属性修改成功,即 0x2 值对应着 PAGE_READONLY 。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|曲径通幽 ( 琼ICP备11001422号-1|公安备案:46900502000207 )

GMT+8, 2025-6-20 02:19 , Processed in 0.080174 second(s), 24 queries .

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表