从堆执行指令

时间:2013-11-27 03:22:30

标签: c++ c

我可以在堆上分配一个块,将其字节设置为与函数调用及其参数对应的值,然后使用函数调用和解除引用运算符来执行该序列吗?

4 个答案:

答案 0 :(得分:4)

因此,如果我正确读到你,你想在堆上动态创建CPU汇编指令并执行它们。有点像自修改代码。理论上这是可能的,但在实践中可能不是。

问题在于堆存在于数据段中,而现在CPU /操作系统已采取措施来防止这种行为(它被称为NX位,或x86 CPU的No-eXecute位)。如果标记被标记为NX,则无法从中执行代码。这是为了阻止计算机病毒使用缓冲区溢出将可执行代码放入数据/堆/堆栈内存中,然后尝试调用程序来执行此类代码。

请注意,DLL和库是在代码段中加载的,这当然允许代码执行。

答案 1 :(得分:3)

是。 Dynamic loadingLinking还有什么用呢?还记得一些(大多数?)操作系统和一些(大多数?)连接器也是用C / C ++编写的。例如,

#include <dlfcn.h>
void* initializer = dlsym(sdl_library,"SDL_Init");
if (initializer == NULL) {
    // report error ...
} else {
    // cast initializer to its proper type and use
}

另外,我认为JIT(例如GNU lightning和其他人)通常会执行这些操作。

答案 2 :(得分:2)

在Windows中,例如,当它曾经非常简单时,现在很难做到。我曾经能够在C中获取一个字节数组,然后将其转换为函数指针类型来执行它......但不再是。

现在,如果可以调用Global或VirtualAlloc函数并专门请求可执行内存,则可以执行此操作。在大多数平台上,它要么完全打开,要么大规模锁定。例如,在iOS上执行此类操作非常令人头疼,如果发现,它将导致应用商店提交失败。

这里有一些奇妙的过时和硬壳代码,我做了你描述的原始内容:

https://code.google.com/p/fridgescript/source/browse/trunk/src/w32/Code/Platform_FSCompiledCode.cpp

使用https://code.google.com/p/fsassembler

中的字节

你可能会注意到我需要提供平台(windows)特定的分配函数来获得一些可执行的内存:

https://code.google.com/p/fridgescript/source/browse/trunk/src/w32/Core/Platform_FSExecutableAlloc.cpp

答案 3 :(得分:0)

是的,但您必须确保内存标记为可执行文件。你如何做到这一点取决于架构。