我遵循此thread以执行一些二进制代码。
tinky_winky的答案,当我尝试执行另一个二进制文件时起作用并没有起作用。
例如我写了这个程序:
#include <stdio.h>
int main ()
{
printf("Prueba\n");
return(0);
}
使用gcc编译(不带任何参数),然后将生成的二进制文件放在代码变量
上char code[] = {0x7f,0x45,0x4c,0x46,0x02,0x01,0x01,0x00,0x00,...};
然后尝试编译新文件,但出现了分段错误错误。
实际上可以在c(或c ++)中运行任何类型的任意代码,或者只能在裸asm代码中运行函数(就像在原始线程中一样)?
答案 0 :(得分:1)
它肯定是特定于实现的,实际上取决于您的operating system和处理器instruction set(以及ABI&amp; calling conventions)。
(我猜并希望你在Linux上;但你的问题还不清楚)
在Linux / x86_64上,virtual address space中的大多数内存不可执行文件(出于安全原因)。尝试使用strace(1)运行程序以了解相关的系统调用。还可以使用调试器gdb
。您可能需要使包含二进制代码的段可执行,例如与mprotect(2)。如果您的进程是1234,请在其他终端中尝试cat /proc/1234/maps
(以查询其虚拟地址空间)。有关详细信息,请详细了解proc(5)。
也许你应该考虑JIT compilation技术和库,如asmjit,GCCJIT等......
BTW,ELF可执行文件非常复杂,并且不以可执行文件machine code开头。另请阅读elf(5)。使用objdump(1)&amp; readelf(1)来探索和理解ELF可执行文件。这可能解释了为什么你的实验失败了(但是我们不知道你是怎么来的char code[] = {0x7f,0x45,0x4c,0x46
....这几个字节看起来像一些ELF标题)
您可能小心从ELF可执行文件中提取某些函数(即其机器代码和数据)并处理relocations(和name mangling,对于C ++),如果你想继续你的实验。阅读Levine关于Linkers & Loaders的书将会有所帮助。
答案 1 :(得分:0)
您可以运行此类十六进制代码,但无法修改后无法获取可执行文件。存在用于OS的文件前缀,而不是汇编操作码。
答案 2 :(得分:0)
我认为这是在您的电脑或笔记本电脑或您正在阅读此网页的任何计算机上。防止每个程序在内存中运行任意代码,甚至访问其空间外的代码。你有一个程序,你有一个数组,你可能知道这些数据是指令,但操作系统和编译器等都知道数据。因此,您必须与操作系统通话,要求它允许您执行该代码。在stackoverflow或网络上搜索自修改代码。如果在linux上运行,可能想要使用mmap()。