标签:
15.6 改变保护属性
(1)VritualProtect函数
参数 |
描述 |
PVOID pvAddress |
指向要修改属性的内存基地址 |
SIZE_T dwSize |
区域的大小,以字节为单位 |
DWORD flNewProtect |
PAGE_*(除PAGE_WRITECOPY、PAGE_EXCUTE_WRITECOPY外) |
PDWORD pflOldProtect |
返回原来的保护属性,有时虽然不需要返回这个信息,但必须传入一个有效的pflOldProtect参数 |
(2)注意点
①保护属性是与整个物理存储页相关联的,不能给一个字节指定保护属性。
②当若干连续的物理存储页跨越不同区域时,则VirtualProtect不能改变它们的保护属性。如果有相邻区域,又想改变跨区域的连续页面的保护属性,则必须多次调用该函数。
【VirtualProtect程序】
#include <windows.h> #include <tchar.h> #include <time.h> #include <locale.h> #define MEMSIZE (1024*1024) int _tmain(){ _tsetlocale(LC_ALL, _T("chs")); srand((unsigned)time(NULL)); //1.保留并提交内存(1MB) VOID* pRecv = VirtualAlloc(NULL, MEMSIZE, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); if (pRecv !=NULL){ _tprintf(_T("分配%dKB内存成功!\n"), MEMSIZE / 1024); } else{ _tprintf(_T("申请%dKB内存失败!(错误代码:%d)\n"), MEMSIZE / 1024,GetLastError()); return 0; } //2.内存写入操作 float* pfArray = (float*)pRecv; for (int i = 0; i < MEMSIZE / sizeof(float); i++){ pfArray[i] = 1.0f*(rand() % 10); } _tprintf(_T("从[0x%X]处开始,成功写入%d个Float型的数据!\n"), pRecv,MEMSIZE / sizeof(float));
//3.更改保护属性为只读 DWORD dwOldProtect = 0; BOOL bOk = VirtualProtect(pRecv, MEMSIZE, PAGE_READONLY, &dwOldProtect); if (bOk){ _tprintf(_T("成功修改申请的内存空间为只读属性!\n")); } else{ _tprintf(_T("试图修改申请的内存空间为只读属性失败!(错误代码:%d)\n"),GetLastError()); return 0; }
//4.读取所有值进行求和 float fSum = 0.0f; for (int i = 0; i < MEMSIZE / sizeof(float);i++){ fSum += pfArray[i]; } _tprintf(_T("%d个随机数总和为%f\n"), MEMSIZE / sizeof(float),fSum); //5.试图写入第10个元素,这将引起异常 __try{ pfArray[9] = 0.0f; }__except (EXCEPTION_EXECUTE_HANDLER){ _tprintf(_T("非法访问内存,试图在只读内存中写入数据!\n")); } //6.直接释放 bOk = VirtualFree(pRecv, 0, MEM_RELEASE); _tprintf(_T("释放内存%s!\n"),bOk? _T("成功"):_T("失败")); return 0; }
标签:
原文地址:http://www.cnblogs.com/5iedu/p/4859637.html