我有点理解“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函数指针?
很抱歉我的问题意图不明确
答案 0 :(得分:1)
C缺乏任何“评估”功能,这既是一种限制,也是一种允许其高效的事情。如果你需要做的就是使用一小组内置数学函数(如abs()
而不是任意C代码)来评估数学表达式,那么编写这样的表达式求值器会非常容易。
以下是类似主题的过去SO主题的链接: c expression Evaluator
答案 1 :(得分:1)
假设您已经在内存块中编译了代码,并且您拥有该块的地址,则可以将其转换为函数指针:
typedef int (*func)(int, int);
...
char * compiledCode = ...;
func f = (func) compiledCode;
然后可以调用该函数:
int x = f(2, 3);
答案 2 :(得分:1)
程序必须位于允许执行的内存区域中。
在Linux上你可以这样做:
void *address;
functype proc;
int prot, flags;
prot = PROT_READ|PROT_WRITE|PROT_EXEC;
flags = MAP_PRIVATE|MAP_ANONYMOUS;
address = mmap(NULL, length, prot, flags, -1, 0);
if (address == NULL) error;
memcpy(address, program, length);
link(address, program_info);
proc = (functype)address;