直接以二进制形式执行计算机指令

时间:2012-03-18 19:57:11

标签: c assembly binary

在C.中,我需要一种在程序运行时直接执行计算机指令的方法。我知道如何以二进制编写指令的唯一方法是通过十六进制编辑器,然后将该文件作为应用程序运行。我如何使用程序编写二进制文件,然后从它们执行它而无需创建新的执行过程。看起来他们应该是一个简单的方法来做到这一点,但无论我在哪里,我都找不到它。

我能想到的另一种方法是通过内联汇编,但在我当前的项目中,这将是一个缺点,直接使用二进制执行是最好的方法。 (这可能需要Windows上的驱动程序吗?如何在linux上执行?换句话说,跨平台方法会很好)

谢谢。

4 个答案:

答案 0 :(得分:5)

你想做的是有点问题,并且很容易让很多人问“为什么你这样做?”

假设您的操作系统没有内存保护(这是非常罕见的),您只需将一个函数指向字节数组并调用该函数即可。这是它的要点:

unsigned char* code_to_execute = "\xB8\x13\x00\xCD\x10";
void (*runCode)();

runCode = code_to_execute;

runCode();

但是,做这样的事情时,有很多事情需要担心。你需要知道你的C编译器如何设置函数调用帧并尊重你的“二进制代码”。以这种方式创建跨平台代码是不可能的。即使在单个平台上运行多个C编译器也很棘手。然后就是内存保护。大多数现代操作系统根本不会让您随意执行数据作为代码。您需要将内存明确标记为可执行文件,许多操作系统不允许您在没有特殊权限的情况下执行此操作。也没有跨平台的方法来做到这一点。

同样,我想强调这不是一个好主意。你最好使用内联汇编语言。或者更好的是,根本不要使用汇编语言。也许你可以解释一下你的项目以及为什么在你的C程序中直接编写“二进制代码”很重要。这将有助于我们制定一个可以帮助您的答案或建议。

答案 1 :(得分:4)

这个SO问题可能涵盖了主题

How to write self-modifying code in x86 assembly

不要让人们因为“你为什么要这样做”而放慢你的速度......

您必须对语言或操作系统或两者都有足够的了解,并在保护系统内穿孔或工作。然后就是把你想要执行的二进制文件(假设你已经完成了你的工作,使它独立于positition和/或依赖于给定/找到/获取/无论的寻址)并分支到它。在C中,您可以声明一个函数指针,然后将该地址分配给该函数的地址,然后调用该函数(如果您没有其他方法可以分支到一个地址,我通常更喜欢写几行asm和将执行分支的它们链接到我传递给asm的任意地址。

答案 2 :(得分:2)

将机器代码放入内存中,将其地址转换为函数指针。当然,您需要遵守C调用约定。

在大多数桌面操作系统上,您需要更改内存权限以将其标记为可执行文件,例如在Windows上调用VirtualProtect和Linux mprotect

二进制机器指令不是跨平台的。您需要为每个处理器体系结构生成不同的代码。

只要代码只需要用户级权限,就不需要驱动程序。

答案 3 :(得分:2)

在应用程序内的运行时生成和运行代码是一个非常好理解的问题。

通过在网上搜索“及时编译器”或“JIT编译”,“动态代码生成”,您将能够找到有关生成代码并在运行中执行它的大量信息,特别是与编程语言名称,如'Java'。

动态代码生成是过去十五年的热门研究课题之一。

Java运行时系统(称为Java虚拟机或JVM)使用动态编译技术(称为HotSpot)来显着改进(即,速度提高10倍)。

Microsoft对C#等.NET语言使用即时编译,但很难找到更详细的信息。

Ian PiumartaViewpoints Research Institute开发了一些非常令人印象深刻的动态编译技术(例如Cola),与SmallTalk的“父亲”Alan Kay合作(SmallTalk是现代窗口系统的起点和某些类型的面向对象编程语言)。其中一些技术用于加速Google Summer of Code项目中的Cairo渲染引擎(用于Web浏览器等)。

Ian Piumarta的作品可能是最灵活,最紧凑的,因此也是一个好的起点。请注意,Ian非常聪明,所以如果你想使用它,请做好充分准备。

有一些JIT会生成汇编程序,这可能正是您所需要的(但我从未使用它们):

可能值得一看的其他技术包括:

其中,LLVM的JIT和GNU libjit可能是在其正常“主机”环境之外使用的最佳文档。 LLVM是Apple支持的技术。 LLVM旨在从一组库中组装,以便可以用于构建其他系统。但它的目标是非常复杂,高性能的解决方案,因此可能存在相当陡峭的学习曲线。 GNU libjit看起来更小,希望因此更容易理解。我刚刚发现了英特尔的ORP。

HTH