0

只是出于试验和玩耍的目的,我编写了以下简短的 x64 汇编程序:

.code
AsmFun proc
    mov rax, MyLabel
    mov byte ptr [rax], 0C3h    ; C3 is x64 machine code for "ret"
MyLabel:
    mov rax, 239847             ; This isn't "ret"
AsmFun endp
end

(然后我从 C 调用代码。)

它编译/组装/链接很好,但是当我浏览程序时,Visual Studio 抱怨已经引发了一个未处理的异常:“访问写入冲突为 [MyLabel]。”,当然它实际上并没有说“[MyLabel]”,而是恰好在内存中的地址。

为什么会这样?是为了避免安全漏洞而实施的 Windows 系统吗?

4

1 回答 1

0

我生活在 Linux 世界中,但也许你可以适应我发现的内容。

如果内存页具有执行权限,则它们通常是只读的。我是如何使用 mmap() 和 mprotect() 来解决这个问题的……我确信 Windows 中也有类似的东西。Mono 源代码可以提供一些启示,这是一个不错的选择。

我使用 mmap() 来分配一个具有写访问权限的新页面(但不能读取或执行)。我填充了它,然后调用 mprotect() 将其更改为只读和可执行。

不要忘记...有些寄存器要避免被丢弃。有关详细信息,请参阅 ABI 文档。

于 2015-06-21T08:23:02.987 回答