VirtualAlloc分配疑问:64KB粒度块部分占用后剩余区域能否分配?
关于VirtualAlloc分配已部分占用的64KB粒度内存块的问题
核心问题
若分配粒度(64KB)对应的内存块已有部分被分配,能否通过VirtualAlloc分配该块的剩余区域?
测试代码
我的代码,函数实现放在末尾。
// reserve函数:参数为目标地址和内存大小,返回long类型基地址 long base = reserve(0x660000, 0x4000); // commit函数:参数为目标地址和内存大小,返回long类型基地址 commit(base + 0x0000, 0x10); commit(base + 0x2000, 0x10); // 调用QueryVirtualMemoryInformation查询指定地址内存信息 printQueryInfo(base); // 尝试分配0x66A000地址的4KB内存,VirtualAlloc返回NULL reserve(0x66A000, 0x1000);
控制台输出
尝试在0x660000地址分配长度为16384字节(十进制)的内存区域。 返回的基地址为:0x660000 尝试在0x660000地址提交长度为16字节(十进制)的内存区域。 返回的基地址为:0x660000 尝试在0x662000地址提交长度为16字节(十进制)的内存区域。 返回的基地址为:0x662000 查询0x660000地址的内存信息 分配基地址:0x660000 分配保护属性:0x4 标记:0x1 区域大小:0x4000 已提交大小:0x2000 尝试在0x66A000地址分配长度为4096字节(十进制)的内存区域。 区域分配失败(base == NULL)。 返回的基地址为:0x0
疑问
我对内存分配与提交的理解如图所示,当前仅该64KB块的前5KB被分配,剩余部分是否已无法使用?
函数实现细节
以下是函数的具体实现,代码不够规范。
// 预留内存区域:参数为目标地址和大小,返回分配的基地址 long reserve(long address, long size) { printf("尝试在0x%lX地址分配长度为%li字节(十进制)的内存区域。\n", address, size); LPVOID base1 = VirtualAlloc((LPVOID)address, size, MEM_RESERVE, PAGE_READWRITE); if (base1 == NULL) printf("区域分配失败(base == NULL)。\n"); long baseLong = (long)base1; printf("返回的基地址为:0x%lX\n", baseLong); return baseLong; } // 提交内存区域:参数为目标地址和大小,返回提交的基地址 long commit(long address, long size) { printf("尝试在0x%lX地址提交长度为%li字节(十进制)的内存区域。\n", address, size); LPVOID base1 = VirtualAlloc((LPVOID)address, size, MEM_COMMIT, PAGE_READWRITE); if (base1 == NULL) printf("区域提交失败(base == NULL)。\n"); long baseLong = (long)base1; printf("返回的基地址为:0x%lX\n", baseLong); return baseLong; } // 查询指定地址的内存信息 void printQueryInfo(long address) { WIN32_MEMORY_REGION_INFORMATION regionInformation[2]; // 多预留空间,仅用sizeof(WIN32_MEMORY_REGION_INFORMATION)会报错 long informationBufferSize; BOOL b = QueryVirtualMemoryInformation( GetCurrentProcess(), (LPVOID)address, MemoryRegionInfo, ®ionInformation, 28, &informationBufferSize ); // printf("信息缓冲区大小:%li\n", informationBufferSize); // 输出值为28 if (b == FALSE) { DWORD lastError = GetLastError(); printf("QueryVirtualMemoryInformation调用失败,错误码:%i\n", (int)lastError); } else { printf("查询0x%lX地址的内存信息\n", address); printf(" 分配基地址:0x%lX\n", (long)regionInformation->AllocationBase); printf(" 分配保护属性:0x%lX\n", (long)regionInformation->AllocationProtect); printf(" 标记:0x%lX\n", (long)regionInformation->Flags); printf(" 区域大小:0x%zX\n", regionInformation->RegionSize); printf(" 已提交大小:0x%zX\n", regionInformation->CommitSize); } }
内存区域/提交情况可参考x64dbg截图
内容的提问来源于stack exchange,提问作者AirToTec
相关产品推荐
相关产品推荐

