【发布时间】:2013-02-12 05:26:59
【问题描述】:
我想在运行时在 C 中生成一个函数。我的意思是我本质上想分配一些内存,指向它并通过函数指针执行它。我意识到这是一个非常复杂的话题,我的问题很幼稚。我也意识到有一些非常强大的库可以做到这一点(例如nanojit)。
但我想从基础开始学习这项技术。有知识的人可以给我一个非常简单的 C 示例吗?
编辑: 下面的答案很好,但这里是 Windows 的相同示例:
#include <Windows.h>
#define MEMSIZE 100*1024*1024
typedef void (*func_t)(void);
int main() {
HANDLE proc = GetCurrentProcess();
LPVOID p = VirtualAlloc(
NULL,
MEMSIZE,
MEM_RESERVE|MEM_COMMIT,
PAGE_EXECUTE_READWRITE);
func_t func = (func_t)p;
PDWORD code = (PDWORD)p;
code[0] = 0xC3; // ret
if(FlushInstructionCache(
proc,
NULL,
0))
{
func();
}
CloseHandle(proc);
VirtualFree(p, 0, MEM_RELEASE);
return 0;
}
【问题讨论】:
-
这有一个普遍的问题,即 C89/90 标准明确规定将任意指针转换为函数指针是未定义的行为(G.2: i> 指向函数的指针被转换为指向对象的指针,或者指向对象的指针被转换为指向函数的指针。)我会很惊讶(但很感兴趣) !)如果你真的能以一种可移植的、符合标准的方式做到这一点。
-
请注意,在运行时生成代码存在重大的安全缺陷。攻击者通常对流经您的程序的数据有一定程度的控制。如果您有攻击者控制的数据成为攻击者控制的代码的途径,那么攻击者就有途径在您/您客户的机器上安装恶意软件。混合数据和代码后果自负!
-
谢谢马特,我知道它的风险和复杂性。我的理解是,这通常是 JIT 工具使用的技术,本质上是编译器。如果我错了,请纠正我。
-
从 C11 开始(尚未检查 C99),将函数指针转换为对象指针不再是未定义行为:它现在被视为实现提供的扩展 (J.5.7)。即它是允许的。
标签: c function function-pointers jit dynamically-generated