【问题标题】:cast pointer to functor, and call it将指针转换为函子,并调用它
【发布时间】:2010-07-05 10:11:25
【问题描述】:

我可以这样做吗:

typedef void (*functor)(void* param);

//machine code of function
char functionBody[] = {
    0xff,0x43,0xBC,0xC0,0xDE,....
}
//cast pointer to function
functor myFunc = (functor)functionBody;
//call to functor
myFunc(param);

【问题讨论】:

    标签: c casting pointers function-pointers machine-code


    【解决方案1】:

    形式上,C 语言不允许函数指针和对象指针之间的转换,所以不能这样做。

    但是,许多 C 实现——甚至可能是“大多数”——都支持此作为扩展。它是否有效取决于内存权限和缓存一致性等因素,这些因素会根据您的架构和操作系统而变化。

    【讨论】:

      【解决方案2】:

      取决于保护环。

      在大多数流行的桌面平台上,由于页面权限,您将无法执行data segment 中的代码。

      【讨论】:

      • 我假设 windows,使用 C 语言,像这样:wlug.org.nz/CastingPointerToFunction 他说一旦我得到一个指向你的机器代码的指针(通常是一个字节数组),你需要将它转换为适当的类型并调用它。
      • 澄清一下,理论上这是可能的,只要操作码有效,它就会执行得很好。
      【解决方案3】:

      在现代操作系统上,这取决于内存是否标记为可执行。在 POSIX 系统上,可能可以使用mmap 获取可执行内存。请记住,即使在给定的 cpu 架构上,调用约定也可能会有所不同。例如,如果调用者希望被调用者从堆栈中清除参数,那么您的代码最好这样做,否则它会在返回时崩溃。 (通常情况下,C ABI 不会提出这种愚蠢的要求,但需要考虑一下。)

      与其尝试将机器代码直接作为 C 函数指针调用,不如编写一个调用它的内联 asm 包装器。这样,您就可以控制调用约定。

      【讨论】:

      • 或者换种说法:没有便携的方法可以做到这一点。它归结为应用程序可以做什么来分配内存或将内存标记为可执行文件。对于*NIX,应该开始阅读man mmapman mprotect 并查找PROT_EXEC。请记住位置独立与依赖代码。休息对 asm 编程来说是“像往常一样”...
      【解决方案4】:

      它可以工作。可能将 const char[] 用于机器指令会更好,因为在许多平台上,静态 const 存储被放置在只读程序内存部分中。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-07-09
        • 2014-01-13
        • 2012-11-21
        • 1970-01-01
        • 2016-06-03
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多