ARM - 如何从 C 函数中执行单个汇编指令(机器代码)

Posted

技术标签:

【中文标题】ARM - 如何从 C 函数中执行单个汇编指令(机器代码)【英文标题】:ARM - how to execute single assembly instruction (machine code) from within a C function 【发布时间】:2017-11-09 19:15:59 【问题描述】:

我可以通过在运行的 C 代码中生成有效的本机可执行汇编指令来执行它吗?

void execute_single_asm_instruction(char * ptr_asm, int length)

    // ptr_asm[] = valid assembly instruction

    execute_asm(ptr, length);

可以写execute_asm吗?

这是在裸机 ARM 上运行的,即 RTOS 是自定义的,不是 Linux、QNX、Windows 等。

这和我之前的问题有关:how to single-step code on-target with no jtag, breakpoints, simulator, emulator

【问题讨论】:

您可以将指令写入可写和可执行的内存(如果有的话)并跳转到那里。 @EugeneSh。我会用谷歌搜索什么文档? 类似...“自修改代码” 当然,JIT 编译器(如 LLVM)可以做到这一点。但是你不需要编译器,只需要一个汇编器。为什么呢?除非您在运行时生成 asm 源字符串,否则在构建时将它们组装成机器代码会更容易。这些被称为“函数”:P,您可以通过函数指针调用它们。 @PeterCordes 哈哈。这是我另一个问题的一部分。我计划从现有函数一次执行一条 asm 指令。 【参考方案1】:

从技术上讲,安全地做你想做的事是不可能的;执行一条汇编指令。问题是“上下文”或机器状态。你需要像这样扩展API,

extern void init_asm_context(void* context);
extern void execute_asm(void* context, char * ptr_asm, int length);

// context; global or declared.
// ptr_asm[] = valid assembly instruction

init_asm_context(&context);
execute_asm(&context, ptr, length);

问题是任何汇编指令都可以随机更改“C”代码所依赖的寄存器。出于这个原因,大多数人都制作了自己的“虚拟机”,并使机器语言更易于解码。由于您没有操作系统,因此很难想到您尝试执行现成代码并在没有现有操作系统时让它工作的用例。为此,您将在每次调用时不断进行上下文切换。一次执行多条指令的解决方案会执行得更快,因为您不必为每条指令保存/恢复上下文。

如果你有一个安全应用程序并且性能很关键,我建议你研究proof carrying code,这是一个试图保持性能并保证内存访问的概念。它也不像虚拟机那样受到专利保护(目前)。

【讨论】:

对单个 asm 修改有意义,例如,sp 想试试我的other question? OP 想要执行供应商提供的种子密钥算法来访问其他设备。它仅作为 ARM 机器提供,OP 希望尽可能少地信任它。

以上是关于ARM - 如何从 C 函数中执行单个汇编指令(机器代码)的主要内容,如果未能解决你的问题,请参考以下文章

ARM体系结构和汇编指令

GNU ARM 汇编指令

如何实现对ARM汇编指令的调试?

arm汇编b指令是绝对地址还是相对地址跳转?

Solidity 中编写内联汇编(assembly)

ARM汇编的一般形式和汇编调用C语言