我多少理解了“int a=b+abs(c)”如何被转换成简单的汇编指令,然后再转换成一些二进制blob。但是如何在内存中动态地运行和交互呢?
--编辑--
我知道C没有eval特性。但它的作用是什么。我的意思是,这就是为什么Java像JIT一样,所以,代码注入恶意软件是可能的,不是吗?例如,abs()函数只是一个指针,可以按照cdecl协议调用它。新函数应该能够通过传递cdecl函数指针来公开。我不明白的是如何在运行时注入新代码。
我问这个更多的是作为一个长期的学术好奇心,然后最有效地解决一个实际问题。
--示例--
假设我有一段嵌入的python代码,它经常从本机程序调用,还调用本机绑定notify():
def add(a, b):
notify()
return a+b
要做到这一点,这个函数可能应该包含更多的代码(而且更有用),但请容忍我。探查器(或来自c-bindings的提示)还标识出,所有调用都使用整数,其中包括所有参数和返回值。
这与:
int add(int a, int b) {
notify();
return a + b;
}
它可以编译成x86 cdecl类似的东西:
:_add
push ebp ;setting up scope
mov ebp, esp
call _notify ;or more likely by a pointer reference
mov eax, [ebp + 8]
mov edx, [ebp + 12]
add eax, edx
pop ebp
ret
最后组装成二进制字符串。当然,要做到这一点,必须为每个平台实现一个基本的编译器。但除了这个问题,假设我现在有一个指向这个有效的二进制x86代码的char指针。是否有可能以任何方式从中提取可用于本机程序的cdecl函数指针?
对不起,我的问题不清楚
最佳答案
假设您已经在内存块中编译了代码,并且您拥有该块的地址,则可以将其强制转换为函数指针:
typedef int (*func)(int, int);
...
char * compiledCode = ...;
func f = (func) compiledCode;
然后可以调用函数:
int x = f(2, 3);