重构反编译程序控制流程

问题描述 投票:0回答:1

我正在为基本编译的字节码(一种完全不同的语言)编写一个非常简单的反编译器(用 C++ 编写)。执行器使用基于堆栈的机器,并且大多数指令都相当容易拼凑在一起。

我遇到了一个关于条件和循环结构的有趣困境。如果前一个操作数的计算结果为 false,则字节码中的操作码之一会设置执行器的位置(有点像 jmp 指令)。因此,如果满足条件,执行器将在当前指令指针处继续执行。

目前,我已将这些实现为简单的 goto,但我想扩展此功能以将原始的 if / else 结构拼凑在一起。这是原始来源的示例:

function myFunction() {
  if (this.var1 == "foo") {
    this.var2 = "bar";
  } else {
    this.var2 = "baz";
  }
}

我的反编译输出:

goto label23;

function myFunction() {
    if (!(this.var1 == "foo")) {
        goto label16;
    }
    this.var2 = "bar";
    goto label21;
    label16:
        this.var2 = "baz";
    label21:
        return 0;
}
label23:

是否有一种方法可以应用于此“反编译”源代码,以类似于原始源代码的方式将条件重新组合在一起?我知道没有一个反编译器是完美的,但我很好奇像 Ghidra 这样的反编译器如何解决此类问题。因为我的字节码不一定是机器代码(更像是压缩源代码),所以我认为我的用例比 Ghidra 的反编译器简单得多。

c++ bytecode control-flow decompiler
1个回答
1
投票

Reko 是一个反编译器,尝试从机器代码重建类似 C 的代码。它有一个通道可以重建高级结构,如

if
while
switch
语句。该代码基于 Edward J. Schwartz、JongHyup Lee、Maverick Woo 和 David Brumley 撰写的论文“Native x86 Decompilation using Semantics-Preserving Structural Analysis and Iterative Control-Flow Structuring”。

虽然它是用 C# 编写的,但将一个类移植到 C++ 应该不会太困难。

© www.soinside.com 2019 - 2024. All rights reserved.