【问题标题】:Searching for a nice way to define rules for decompiler, need advice寻找一种定义反编译器规则的好方法,需要建议
【发布时间】:2010-07-25 23:26:39
【问题描述】:

我正在为 MIPS 架构开发一个非常简单的反编译器,随着我的进步,我必须定义许多代码分析规则,例如“如果这个操作码是 lui 并且下一个操作码是 addiu 然后返回 var = value" 或 "如果此操作码是 bne 并且它指的是当前地址之前的地址 - 创建 loop解析树中的定义”。问题 - 有很多这样的规则,我找不到定义它们的好方法。我已经尝试为每个规则编写单独的函数,定义好的 OOP 基础逻辑类并扩展它们以创建规则,甚至尝试在 disasmed 代码上使用正则表达式(令我惊讶的是,这比预期的效果更好)但无论我尝试了什么,无论我多么努力地记录和构建它,我的代码很快就变得很大并且难以阅读。

这让我得出结论,我试图通过使用错误的工具来解决这个任务(更不用说对于如此复杂的任务来说太愚蠢了:)),但我不知道我应该尝试什么。目前我有两个未经测试的想法,一个是使用某种 DSL(我完全没有这方面的经验,所以我可能完全错了),另一个是编写某种类似于二进制正则表达式的工具来进行操作码匹配。

希望有人能指出正确的方向,谢谢。

【问题讨论】:

  • 我认为仅仅通过查看指令模式来编写反编译器是不可能的。代码流和数据分析是正确构造代码块和表达式所必需的。
  • AFAIK 操作码模式观察是获取代码流的方法,就像在我的第二个示例中一样(您会发现 bne 操作码在其自身之前引用地址 = 这是一个循环),但您是对的,它是只有其中一个步骤,因为我需要计算此循环的条件,这意味着我需要先查看代码并检查内存\寄存器修改。所以,这是两遍分析——首先构建流树,然后计算里面的一切。
  • 二进制正则表达式方法实际上听起来是个不错的主意。我能想到的唯一另一件事是将 MIPS 前端写入 LLVM,并使用 C 后端获取代码(尽管我不知道生成的代码的可读性如何,例如它可能使用 gotos 进行循环和回收变量等)
  • 感谢建议,我肯定会尝试 LLVM,但我担心它会在不了解 MIPS 内部结构和确切硬件的情况下生成代码,这有时可以帮助获取更多信息。我现在正在测试 DSL 方法,试图复制我在纸上反编译代码的方式。 :) 并感谢修复标签。

标签: mips decompiling disassembly opcode control-flow


【解决方案1】:

我猜你的一些规则太低级了,这就是它们变得难以管理的原因。

lui 后跟addiu 识别为32 位恒定负载当然看起来很合理;但试图在单个操作码级别从分支指令派生控制流似乎更可疑 - 我认为您想在那里使用基本块。

Cifuentes 的Reverse Compilation Techniques 是我看到的关于反编译的讨论中不断出现的参考;从相当简短的浏览来看,似乎值得花一些时间详细阅读您的项目。

某些特定于 x86 的东西将不相关 - 特别是,将 x86 转换为低级中间表示的步骤对于 MIPS 可能不是必需的(MIPS 本质上只是每个操作码的一个基本操作) -但除此之外,大部分内容看起来应该很有用。

【讨论】:

  • 哦,天哪,这是一篇糟糕的论文的绝佳来源,我无法表达我的感激之情(请不要问我怎么能错过这个 :))
猜你喜欢
  • 2012-05-27
  • 1970-01-01
  • 2021-08-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-09-29
相关资源
最近更新 更多