API函数VirtualAlloc VirtualProtect


🧩 一、基本概念对比

函数名 作用 类比
VirtualAlloc 在内存中 申请新的空间(分配内存) “找块新地建房子”
VirtualProtect 修改一块 已有内存的保护属性(可读/可写/可执行) “给房子换个用途或权限,比如从住宅改为工厂”

🧠 二、VirtualAlloc —— 分配虚拟内存

📘 原型

c
LPVOID VirtualAlloc(
  LPVOID lpAddress,   // 申请的起始地址(一般为 NULL)
  SIZE_T dwSize,      // 申请的大小
  DWORD flAllocationType, // 分配类型
  DWORD flProtect     // 初始保护属性(读写/执行)
);

💡 主要功能

  • 在当前进程的虚拟地址空间中,开辟一段新的内存区域
  • 返回一个指向该区域的指针。
  • 这块区域可以指定是否可执行、可写、可读。

🔨 常见用法

申请一段可读可写的内存,用来存放数据、shellcode、或动态代码。

c
LPVOID p = VirtualAlloc(
    NULL,               // 系统自动选择地址
    0x1000,             // 分配 4KB
    MEM_COMMIT | MEM_RESERVE,
    PAGE_READWRITE      // 可读可写
);

📦 这就相当于:

向系统要了一间新的“房子”(内存页),可以在里面读写数据。


🧩 三、VirtualProtect —— 修改内存保护属性

📘 原型

c
BOOL VirtualProtect(
  LPVOID lpAddress,    // 要修改的内存地址
  SIZE_T dwSize,       // 修改的大小
  DWORD flNewProtect,  // 新的保护属性
  PDWORD lpflOldProtect // 保存旧属性
);

💡 主要功能

  • 改变现有内存的访问权限,比如从:
    • 只读 → 可写
    • 可写 → 可执行
    • 不可执行 → 可执行

🧱 四、二者关系形象比喻

操作 类比
VirtualAlloc 向政府申请地皮 + 建房(开辟新内存)
VirtualProtect 改房子的用途或门禁(修改已有内存属性)

举个例子:

你写了个程序,它的代码段是“只读只执行”的。
但你想在运行时动态修改一条指令,就必须:

  1. 先用 VirtualProtect 临时把那块区域改成 可写
  2. 改完后再改回原来的保护属性。

🧪 五、通俗例子:修改一段代码(内存打补丁)

假设你要在程序运行时把某个函数的第一条指令改成 RET(直接返回)。

c
DWORD oldProtect;
BYTE patch[] = { 0xC3 }; // RET 指令

// 将目标函数的前 1 字节改为可写
VirtualProtect(targetFunc, 1, PAGE_EXECUTE_READWRITE, &oldProtect);

// 写入补丁
memcpy(targetFunc, patch, 1);

// 改回原保护
VirtualProtect(targetFunc, 1, oldProtect, &oldProtect);

🔍 过程说明:

  1. 程序原本的代码段是不可写的;
  2. 用 VirtualProtect 临时打开写权限;
  3. 写入字节;
  4. 再把权限恢复;
  5. 程序继续正常执行。

💣 六、恶意代码中的典型用法

比如在 shellcode 或注入代码 中:

c
LPVOID buf = VirtualAlloc(NULL, size, MEM_COMMIT, PAGE_EXECUTE_READWRITE);
memcpy(buf, shellcode, size);
((void(*)())buf)(); // 直接执行

或:

c
VirtualProtect(shellcode, size, PAGE_EXECUTE_READ, &old);
((void(*)())shellcode)();

这意味着:

程序动态申请或修改了一段可执行内存区域,然后把机器码写进去再运行。

这种行为往往在安全分析中被标记为可疑(代码注入或自修改代码)。


⚙️ 七、保护属性常见值(flProtect

含义
PAGE_NOACCESS 不能读、写、执行
PAGE_READONLY 只读
PAGE_READWRITE 可读可写
PAGE_EXECUTE 只可执行
PAGE_EXECUTE_READ 可执行可读
PAGE_EXECUTE_READWRITE 可执行、可读、可写(常用于 shellcode)

✅ 八、总结对比表

函数 作用 举例 注意事项
VirtualAlloc 分配新内存(可设置保护属性) VirtualAlloc(NULL, 4096, MEM_COMMIT, PAGE_READWRITE) 返回地址可写、可执行等
VirtualProtect 修改已有内存的保护属性 把代码页改成可写后打补丁 必须保存原属性并恢复
配合使用 分配可执行内存 + 修改权限执行 常见于代码注入、JIT 编译、恶意程序 注意权限安全与系统保护

💬 一句话总结:

  • VirtualAlloc:开辟地盘(申请内存)。
  • VirtualProtect:改地盘的用途(改读写执行权限)。

 

此条目发表在安全分析分类目录。将固定链接加入收藏夹。

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注