【问题标题】:c library x86/x64 assemblerc 库 x86/x64 汇编器
【发布时间】:2013-06-08 15:35:47
【问题描述】:

是否有用于将 x86/x64 汇编字符串组装成操作码的 C 库?

示例代码:

/* size_t assemble(char *string, int asm_flavor, char *out, size_t max_size); */

unsigned char bytes[32];
size_t size = assemble("xor eax, eax\n"
                       "inc eax\n"
                       "ret",
                       asm_x64, &bytes, 32);

for(int i = 0; i < size; i++) {
    printf("%02x ", bytes[i]);
}

/* Output: 31 C0 40 C3 */

我查看了asmpure,但是它需要修改才能在非 Windows 机器上运行。

我实际上都需要一个汇编器和一个反汇编器,有没有一个库可以同时提供?

【问题讨论】:

  • 我怀疑你会得到一个库,但你可以捆绑 NASM 并使用 system/popen 调用它
  • @Tyilo 不要听 Linuxios,你的感觉会给你正确的方向 - system()ing nasm(或任何其他工具,就此而言)错误.也许您想看一下它的源代码并提取基本部分。或者看看 TCC,微型 C 编译器 - 它有一个 x86 后端,也许你可以将 C 解析与机器代码生成分开。
  • @H2CO3:这是错误的,但总比停止一个项目要好。
  • @Tyilo 或者甚至更好:如果你可以使用 C++,那么一定要考虑LLVM,它是一个优秀的框架。或者JITAsm,就此而言。
  • @Gilbert 我不需要 inline 汇编器,我需要 runtime 汇编器!

标签: c assembly x86 64-bit


【解决方案1】:

有一个图书馆,看起来像个鬼;它的存在广为人知:

XED(X86 编码器解码器)

英特尔写道:https://software.intel.com/sites/landingpage/pintool/docs/71313/Xed/html/

可以用Pin下载:https://software.intel.com/en-us/articles/pintool-downloads

【讨论】:

【解决方案2】:

当然 - 您可以使用 llvm。严格来说是C++,但是有C接口。它还将处理您尝试进行的组装和拆卸。

【讨论】:

  • LLVM 是一大组库,如果您下载/构建源代码树,也可以构建几个工具。您可以查看那些用于组装/拆卸的示例代码。
  • LLVM 确实是一个好主意,但请记住,它是一个完整的编译器,该过程正在获取 c/c++ 源代码,将其转换为中间表示,对其进行操作以进行无平台编译器优化,而不是将它转换成汇编(实际上它也首先经过一些无平台版本),基于平台能力执行更多优化,然后才吐出机器代码。如果您只希望最后一部分关注 llvm/lib/Target/X86 和 llvm/lib/MC
【解决方案3】:

给你:

http://www.gnu.org/software/lightning/manual/lightning.html

Gnu Lightning 是一个 C 库,旨在完全满足您的需求。它使用了一种可移植的汇编语言,而不是 x86 特定的一种。可移植程序集在运行时以非常直接的方式编译为特定于机器的程序集。

作为一个额外的好处,它比 LLVM 更小更简单(它相当大而且很麻烦)。

【讨论】:

  • 我有需要组装的 x86 汇编代码,所以我不能使用它。
【解决方案4】:

您可能需要libyasm(后端 YASM 使用)。您可以使用frontends 作为示例(尤其是YASM's driver)。

【讨论】:

    【解决方案5】:

    我正在使用 fasm.dll:http://board.flatassembler.net/topic.php?t=6239 如果不是PE格式的,别忘了在代码开头写上“use32”。

    【讨论】:

      【解决方案6】:

      Keystone 现在似乎是个不错的选择,但是当我问这个问题时它并不存在。

      【讨论】:

        【解决方案7】:

        将程序集写入自己的文件,然后使用extern 从您的C 程序中调用它。你必须做一些 makefile 技巧,但除此之外还不错。 你的汇编代码必须遵循 C 约定,所以它应该看起来像

                  global _myfunc 
        _myfunc:  push ebp               ; create new stack frame for procedure 
                  mov ebp,esp            ;
                  sub esp,0x40           ; 64 bytes of local stack space 
                  mov ebx,[ebp+8]        ; first parameter to function 
                  ; some more code 
                  leave                  ; return to C program's frame
                  ret                    ; exit
        

        要获取 C 变量的内容,或声明 C 可以访问的变量,只需将名称声明为 GLOBAL 或 EXTERN。 (同样,名称需要前导下划线。)因此,声明为 int i 的 C 变量可以从汇编程序访问为

        extern _i 
        mov eax,[_i]
        

        并且要将您自己的 C 程序可以访问的整数变量声明为 extern int j,请执行此操作(确保在 _DATA 段中进行汇编,如有必要):

            global _j 
        _j        dd 0
        

        你的 C 代码应该是这样的

        extern void myasmfunc(variable a);
        
        int main(void)
        {
            myasmfunc(a);
        }
        

        编译文件,然后使用链接

        gcc mycfile.o myasmfile.o
        

        【讨论】:

        • 如果你愿意,也可以试试inline assembly
        • 正如我在问题的 cmets 中所说,我不需要内联汇编程序,我需要运行时汇编程序!
        • 对错误问题的很好回答。不过对我有用:)
        猜你喜欢
        • 1970-01-01
        • 2010-12-21
        • 2017-01-11
        • 1970-01-01
        • 2018-10-13
        • 1970-01-01
        • 2014-03-25
        • 2011-07-08
        • 1970-01-01
        相关资源
        最近更新 更多