哇哦,我不在的时候这个爆炸了。
我通过篡改 YASM 源代码解决了这个问题,并且完全忘记了 SO 中的问题,因为它在 8 个月前完全没有受到关注。下面是详细信息,然后是更好的建议。
对于我想要的项目,我需要使用 YASM 作为库,而且我很着急,因为我是为一家公司做这件事。那时我不知道有什么好的图书馆;我得出的结论是,习惯 LLVM 框架对于这项任务来说有点过分了(因为我想要的只是组装单个 x86 - x86_64 指令并接收字节)。
所以我下载了YASM的源代码。
在对代码进行了一段时间的干预后,我注意到可执行文件接收输入和输出文件的文件路径;并传递这两个字符串。我想要内存中的字符数组用于输入和输出;不是文件。所以我想,也许如果我能找到所有传递的 FILE 指针,我可以将它们转换为 char 指针,并将每个文件读/写更改为数组操作。
事实证明这比听起来更麻烦。显然,YASM 不会打开一次输入/输出文件并使用相同的 FILE 指针;相反,它传递文件路径字符串的副本。我需要一个可以为我进行所有必要更改的脚本,这对我来说并不好。
最终,我用脚本找到了程序中所有的fopen/fclose调用,并用my_fopen/my_fclose替换了它们。对于我进行这些替换的每个文件,我都包含了实现这两个函数的头文件。
在这两个函数中,我检查了传入的字符串,并将其与“fake_file”进行比较。如果它们相等,我会传递一个指向两部分内存的“假”FILE 指针,该指针是从函数调用 fmemopen 和 open_memstream 获得的。否则我只是调用实际的 fopen/fclose 函数。换句话说,我将这两个调用(仅针对给定的文件名)重定向到内存文件。然后,我调用该库,并将文件名参数设置为“fake_file”。
由于当时我只使用 Linux,所以这种方法对我很有效。我还发现(使用Valgrind)库版本存在内存泄漏,因此我为其编写了一个非常原始的垃圾收集器。基本上我包装了 malloc 等来跟踪所有未释放的分配,并在每次执行后清理它们。
这种方法还允许我使用脚本自动执行这些更改。不幸的是,我在一家公司做了所有这些,所以我不能泄露任何实际代码。
更好的建议: 截至2016年5月31日;您可以使用 Keystone 引擎代替。它“基于 LLVM,但它更进一步,提供更多功能”。拆卸引擎 Capstone 和它是组装和拆卸方面近乎完美的一对。如果您需要这些组件中的任何一个,我建议使用这些组件,而不是进行我描述的黑客攻击。这两种发动机目前都在开发中;尽管 Keystone 有一些小错误,但 Capstone 目前非常强大。
TL;DR:使用梯形校正。