1 // 判断内存是否有效.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include <windows.h> 6 #include <iostream> 7 8 using namespace std; 9 10 #define PAGE_EXECUTE_FLAGES 11 (PAGE_EXECUTE | PAGE_EXECUTE_READ | PAGE_EXECUTE_READWRITE | PAGE_EXECUTE_WRITECOPY) 12 13 BOOL UMS_IsExecutableAddress(LPVOID VirtualAddress); 14 15 16 int main() 17 { 18 19 //判断Message函数地址是否有效 20 if (UMS_IsExecutableAddress(MessageBox) == TRUE) 21 { 22 int a = 5; 23 } 24 25 26 return 0; 27 } 28 29 30 31 32 BOOL UMS_IsExecutableAddress(LPVOID VirtualAddress) 33 { 34 BOOL IsOk = FALSE; 35 MEMORY_BASIC_INFORMATION MemoryBasicInfo = { 0 }; 36 37 38 VirtualQuery(VirtualAddress, &MemoryBasicInfo, sizeof(MEMORY_BASIC_INFORMATION)); 39 40 41 42 if ((MemoryBasicInfo.State == MEM_COMMIT && 43 (MemoryBasicInfo.Protect & PAGE_EXECUTE_FLAGES))) 44 { 45 IsOk = TRUE; 46 } 47 return IsOk; 48 } 49 50 /* 51 typedef struct _MEMORY_BASIC_INFORMATION { 52 PVOID BaseAddress; //查询内存块所占的第一个页面基地址 53 PVOID AllocationBase; //内存块所占的第一块区域基地址,小于等于BaseAddress, 54 //也就是说BaseAddress一定包含在AllocationBase分配的范围内 55 DWORD AllocationProtect; //区域被初次保留时赋予的保护属性 56 SIZE_T RegionSize; //从BaseAddress开始,具有相同属性的页面的大小, 57 DWORD State; //页面的状态,有三种可能值:MEM_COMMIT、MEM_FREE和MEM_RESERVE, 58 //这个参数对我们来说是最重要的了,从中我们便可知指定内存页面的状态了 59 DWORD Protect; //页面的属性,其可能的取值与AllocationProtect相同 60 DWORD Type; //该内存块的类型,有三种可能值:MEM_IMAGE、MEM_MAPPED和MEM_PRIVATE 61 } MEMORY_BASIC_INFORMATION, *PMEMORY_BASIC_INFORMATION; 62 */ 63 64 /* 65 MEM_COMMIT 0x1000: 66 为指定地址空间提交物理内存。这个函数初始化内在为零 67 试图提交已提交的内存页不会导致函数失败。这意味着您可以在不确定当前页的当前提交状态的情况下提交一系列页面。 68 如果尚未保留内存页,则设置此值会导致函数同时保留并提交内存页。 69 70 MEM_RESERVE 0x2000: 71 保留指定地址空间,不分配物理内存。 72 这样可以阻止其他内存分配函数malloc和LocalAlloc等再使用已保留的内存范围,直到它被被释放。 73 当使用上面的VirtualAlloc函数保留了一段地止空间后,接下还你还可以继续多次调用同样的函数提交这段地址空间中的不同页面。 74 75 MEM_RESET 0x80000: 76 表示,在所指定的内存范围内的数据lpAddress的dwSize不再是利益。页面不应该被读出或写入到分页文件。然而,将再次使用的内存块后,所以它不应该decommitted的 。这个值不能使用任何其他的价值 。 77 使用这个值并不保证范围与经营MEM_RESET将包含零。如果你想的范围包含零,decommit内存,然后将它重新作出 。 78 当您指定MEM_RESET,VirtualAlloc函数忽略值flProtect。但是,您仍然必须设置flProtect有效的值,比如,PAGE_NOACCESS。 79 如果你使用MEM_RESET的内存范围映射到一个文件,VirtualAlloc返回一个错误。如果它被映射到分页文件共享视图是唯一可以接受的的 。 80 81 82 */