VirtualProtect 返回值

逆向工程 记忆 开发 修补
2021-07-08 23:55:20

VirtualProtect 很简单,但我得到了一些我无法解释的结果。可能在后台发生了一些事情,但我想知道是什么。

以下是在 Windows 7 SP1 Ultimate x64 下,使用 VS 2015 为 Windows 10 编译的 DLL。该 DLL 修改了内存中的一些其他 DLL。结果 DLL 在 Win 7 下运行良好,但在 Win 10 下崩溃(没有产生转储)。所以我开始关注代码,以防它很明显。

看起来很奇怪的代码如下(伪代码):

if (VirtualProtect(BaseAddr, BaseSize, PAGE_EXECUTE_READWRITE, &dwProtect) == 0)
        {
            GetLastError());
            goto _exit;
        }

此时,新的保护应该是 0x40 (PAGE_EXECUTE_READWRITE)。在 dwProtect 中返回的当前保护是 0x2 (PAGE_READONLY)。

...这里还有一些代码可以在修改后的内存块中写入数据...

_exit:
if (VirtualProtect(BaseAddr, BaseSize, PAGE_EXECUTE_READWRITE, &dwProtect) == 0)
            {
                GetLastError());
            }

此时,dwProtect 得到的值为 0x80 !!为什么?不应该是 0x40 吗?

如果在第二次调用时我尝试通过传递保存的 dwProtect 来恢复原始值 (0x2),它仍然不会返回 0x40。(我认为它返回了 0x4)。我什至尝试在第一次调用时将其设置为 0x80。它返回相同(0x80)。它没有加倍,但 DLL 会崩溃。

问题是,为什么在第二次调用时,它没有返回我在第一次调用时设置的值。

在此先感谢您的澄清。

1个回答

这似乎按预期工作。

标志 0x80 是PAGE_EXECUTE_WRITECOPY您可以在msdn 中查找

如果从操作系统请求具有“PAGE_EXECUTE_READWRITE”访问保护属性的内存页,则给出具有“PAGE_EXECUTE_WRITECOPY”属性而不是“PAGE_EXECUTE_READWRITE”属性的页。

这种行为的原因很简单,即操作系统内存管理器希望在所有流程实例之间物理共享页面(因为在任何写入之前,它保证在所有流程实例中都是相同的)。

这里找到完整的来源,版权归瓦利德·阿萨尔所有