【问题标题】:Convert ASM to C (not reverse engineer)将 ASM 转换为 C(不是逆向工程)
【发布时间】:2010-11-25 11:59:33
【问题描述】:

我在谷歌上搜索,发现大量轻率的回答基本上是在嘲笑提问者提出这样的问题。

Microchip 免费提供了一些源代码(我不想在这里发布,以防万一。基本上,谷歌 AN937,点击第一个链接,有一个“源代码”链接,它是压缩的文件)。它在 ASM 中,当我看到它时,我开始对视。我想将其转换为类似于 c 类型语言的东西,以便我可以跟进。因为像这样的行:

GLOBAL  _24_bit_sub
movf    BARGB2,w
subwf   AARGB2,f

可能很简单,但对我来说毫无意义。

那里可能有一些自动 ASM 到 C 的翻译器,但我能找到的只是人们说这是不可能的。坦率地说,它不可能是不可能的。两种语言都有结构,而且这种结构肯定可以翻译。

【问题讨论】:

  • 坦率地说,请说明为什么它一定是可能的。
  • 如果你想看懂代码,唯一的办法就是学习这个汇编语言。自动翻译会给你一些不可读的东西。也许比源代码更难读。如果此代码是手写的(未先编译),反编译器(如果存在)将无法帮助您。但是,如果您只想运行/移植代码,请查看我的帖子。
  • @Gerhard 已经有一个名为 Boomerang 的汇编语言到 C 编译器。一些汇编语言程序可以自动反编译成C,比如this one here。
  • @Anderson Green。回旋镖看起来很有趣。它确实对更复杂的代码有点窒息,并且对 Microchip 的组装没有帮助。 Boomerang 假定汇编器是编译器的输出,而不是人工编写的程序。 Boomerang 为您提供了一些可以使用的东西,但它不是端到端的解决方案。对于可用的结果,您仍将手动对其进行编辑。
  • C 和汇编都是图灵完备的。因此,它们可以表达相同的东西。 Q.E.D.

标签: c assembly embedded reverse-engineering microchip


【解决方案1】:

你完全可以用汇编程序制作一个 c 程序。问题是它可能看起来不像你想的那样,或者它可能会。我的 PIC 生锈了,但使用另一个汇编器,说你有

add r1,r2

在 C 中可以说变成了

r1 = r1 + r2;

可能更具可读性。您可能会失去对变量名称的任何感觉,因为值正在从内存跳转到寄存器并返回并且寄存器正在被重用。如果您正在谈论具有两个寄存器一个累加器和另一个寄存器的较旧图片,那么实际上可能更容易,因为变量大部分都在内存中,您查看地址,类似于

q = mem[0x12];
e = q;
q = mem[0x13];
e = e + q;
mem[0x12] = e;

很长,但很明显 mem[0x12] = mem[0x12] + mem[0x13];

这些内存位置很可能是变量,它们不会像为具有一堆寄存器的处理器编译的 C 代码那样跳转。图片可能更容易找出变量,然后进行搜索和替换以在文件中命名它们。

您要查找的内容称为静态二进制翻译,不一定是从一个二进制文件到另一个(一个处理器到另一个)的翻译,但在这种情况下,是从 pic 二进制文件到 C 的翻译。理想情况下,您需要使用汇编程序在应用笔记中给出并使用微芯片工具将其组装成二进制文件,然后进行翻译。您也可以进行动态二进制翻译,但您更不可能找到其中之一,而且它通常不会导致 C 而是一个二进制到另一个。有没有想过沃尔玛 15 美元的操纵杆与 pac-man 和 galaga 是如何工作的?来自街机的 rom 使用静态二进制翻译进行转换,优化和清理,并为手持设备中的新目标处理器编译了 C 或任何中间语言。我想并不是所有的人都这样做,但我很确定有些人是这样做的。

百万美元的问题,你能找到一个图片的静态二进制翻译器吗?谁知道呢,你可能必须自己写一个。猜猜这意味着什么,你写了一个反汇编器,而不是反汇编成本地汇编语法中的指令,比如 add r0,r1 你让你的反汇编器打印出 r0=r0+r1;当你完成这个反汇编程序时,虽然你会非常了解 pic 汇编语言,以至于你不需要 asm 到 C 的翻译器。你有鸡和蛋的问题。

【讨论】:

  • 好点; +1 供您解释。但是我不相信它可以100%自动完成。因为在汇编中,代码可以使用 cpu 的每一位。例如,可以在代码中的任何位置使用零位、进位和符号位设置等副作用。这些在 C 中通常是不可见的。因此,这样的翻译器需要从非预期的更改中过滤掉预期的更改。虚拟化更容易,因为它不需要理解代码,它只是对 cpu 进行建模。
  • 它可以 100% 自动完成并保留语义。另一方面,编码风格和其他约定将完全丢失(因为它们是隐含的)。
【解决方案2】:

从已编译的程序中获取完全相同的源代码基本上是不可能的。但是反编译器一直是计算机科学的一个研究领域(例如the dcc decompiler,这是一个博士项目)。

有多种算法可用于对汇编代码进行模式匹配并生成等效的 C 代码,但很难以适用于所有输入的通用方式进行此操作。

您可能想查看Boomerang,了解最近在通用反编译器上的开源工作。

【讨论】:

  • 我说得太早了。首先,当我写“工作”时,这是一个错字——应该是“工作”。我通读了他们的页面,但实际上并没有尝试过。现在我有了,它根本不起作用!它绝对适用于逆向工程,因为它只会(愚蠢地)接受二进制文件。叹。也许“反编译器”不是我要找的,而只是一个“翻译器”
  • @Steven: - 你不能编译代码然后使用 Boomerang 反编译吗?
  • 看起来 Boomerang 不支持这个 CPU:boomerang.sourceforge.net/FAQ.php#whatbinary,所以编译不会有帮助
  • 如果你真的有源代码,你不会想先编译。人们普遍认为,从代码翻译会产生更好的输出。
  • 除了Boomerang(2009年“bobbymcr”提到)之外,现在还有很多选择。查看最近的radare2(r2),它是一个反编译器+反汇编器+调试器。还有更多:第一次转到“List of Transpilers”,然后在底部有更多的反编译器等。
【解决方案3】:

我曾经参与过一个项目,其中大部分知识产权是一些用 x86 汇编代码编码的严肃算法。为了将代码移植到嵌入式系统,该代码的开发者(不是我)使用了一个名为 MicroAPL 的工具(如果我没记错的话):

我对这个工具的表现感到非常、非常惊讶。

另一方面,我认为这是“如果你不得不问,你买不起”类型的东西(他们一次性转换项目的价格范围约为 4 行一美元处理的组装)。

但是,您从供应商处获得的汇编例程通常被打包为可以从 C 调用的函数 - 因此,只要例程执行您想要的操作(在您想要使用的处理器上),您可能只需要组装它们并或多或少忘记它们 - 它们只是您从 C 调用的库函数。

【讨论】:

  • 是的,它只是被调用。问题是,我们已经有了一个本地开发的 PID,它或多或少地工作得很好。我想看看他们的实施是否有任何优势。我不知道您是否曾经调整过 PID 控制,但它非常乏味且耗时,因此非常值得说服自己这样做是有理由的,而不是仅仅使用它并希望获得最好的结果。另一方面......它不值得为此付出任何代价:)
【解决方案4】:

您不能 确定地将汇编代码转换为 C。除了 C 中的内联汇编外,中断、自修改代码和其他低级事物没有其他表示形式。只是汇编到 C 过程可以工作的某种程度。更不用说生成的 C 代码可能比实际阅读汇编代码更难理解......除非您使用它作为开始在 C 中重新实现汇编代码的基础,否则它有点有用。查看 IDA 的 Hex-Rays 插件。

【讨论】:

  • ...虽然 Hex-Rays 也可能会相当产生误导,尤其是如果您更习惯于反汇编...
  • 同意。不知道为什么我没有提到这一点
【解决方案5】:

肯定有一些自动化的 ASM 到 C 的翻译器,但我能找到的只是人们说这是不可能的。坦率地说,它不可能是不可能的。

不,不是。编译会丢失信息:最终目标代码中的信息少于 C 源代码中的信息。反编译器无法神奇地从无到有地创建这些信息,因此真正的反编译是不可能的。

【讨论】:

  • 除非我误解了某些东西,否则问题不在于反编译,而是将 ASM 源代码转换为 C
  • 他并没有要求将其反编译回 original 源(这是汉堡包回到牛的问题)。他只想要一个 C 翻译,这是绝对可能的,因为 C 是图灵完备的。
  • 曾经使用过汇编到 C 的翻译器吗?他们吐出汇编语言,但使用 C 语法:你会得到像 eax 和 ebx (对于 IA-32)这样的变量。它们几乎,但不完全,完全没用。你不妨学着看汇编语言。
  • kquinn:不管有没有用,这正是他的要求。如果他能并排看到等效的 C 语言,也许会帮助他学习汇编语法?
  • @Steven - 你可能会找到一个程序来完成这项工作,但它不会做得很好。你不会得到钱能买到的最好的 C 代码,在某些情况下你甚至可能得不到可以编译的代码。您可能不得不猜测一些事情并尽力重写其中的一些内容以提高可读性。
【解决方案6】:

是的,很可能将汇编代码逆向工程为高质量的 C。

我在一家 MicroAPL 工作,该公司生产一种名为 Relogix 的工具,用于将汇编代码转换为 C。在其他帖子中提到过。

请查看我们网站上的示例:

http://www.microapl.co.uk/asm2c/index.html

【讨论】:

    【解决方案7】:

    这并非不可能,只是非常困难。熟练的汇编和 C 程序员可能会这样做,或者您可以使用Decompiler 来查看。其中一些在将 asm 转换为 C 方面做得很好,尽管您可能必须重命名一些变量和方法。

    查看this site 了解可用于 x86 架构的反编译器列表。

    【讨论】:

      【解决方案8】:

      不容易。

      除了可读性之外,C 相对于 ASM 的一大优势在于它可以防止“聪明”的编程技巧。

      您可以在汇编程序中执行许多没有直接 C 等效项的事情, 或在 C 中涉及曲折的语法。

      另一个问题是大多数汇编程序本质上只有两种可互换的数据类型:字节和字。可能有一些语言结构来定义整数和浮点数 等等,但没有尝试检查内存是否按定义使用。因此,将 ASM 存储映射到 C 数据类型非常困难。

      此外,所有的汇编存储本质上都是一个“结构”;存储按定义的顺序排列(与 C 不同,C 中的存储是在运行时随心所欲地进行排序的)。许多 ASM 程序依赖于确切的存储布局——为了在 C 中实现相同的效果,您需要将所有存储定义为单个结构的一部分。

      还有很多被滥用的指令(在老式的 IBM manframes 上,LA、加载地址、指令通常用于执行简单的算术运算,因为它更快且不需要溢出寄存器)

      虽然在技术上可能翻译成 C 语言,但生成的 C 语言代码的可读性低于被翻译的 ASM 代码。

      【讨论】:

        【解决方案9】:

        看看这个:decompiler

        反编译器是给 执行以下操作的计算机程序 反向操作的一个 编译器。也就是说,它翻译了一个 包含信息的文件 相对较低的抽象级别 (通常设计为计算机 可读而不是人类可读) 转化为更高层次的形式 抽象(通常设计为 人类可读)。

        【讨论】:

          【解决方案10】:

          我可以 99% 的保证,这种汇编语言没有现成的转换器,所以你需要编写一个。您可以简单地用 C 函数替换 ASM 命令来实现它:

          movf    BARGB2,w -> c_movf(BARGB2,w);
          subwf   AARGB2,f -> c_subwf(AARGB2,f);
          

          这部分很简单:) 然后你需要实现每个功能。您可以将寄存器声明为全局变量以使事情变得简单。您也可以使用不是函数,而是#defines,如果需要调用函数。这将有助于处理参数/结果。

          #define c_subwf(x,y) // I don't know this ASM, but this is some Substraction must be here
          

          特殊情况是 ASM 指令/标签,我认为只能使用#defines 进行转换。

          当您接触到一些特定于 CPU 的功能时,乐趣就开始了。这可以是带有堆栈操作的简单函数调用,一些特定的 IO/内存操作。更有趣的是程序计数器寄存器的操作,用于计算,或使用/计数滴答/延迟。

          但是如果发生这种硬核,还有另一种方法。也很硬核:) 存在一种名为dynamic recompilation 的技术。它被许多emulators使用。

          您不需要重新编译您的 ASM,但想法几乎相同。您可以使用第一步中的所有#defines,但添加对所需功能的支持(增加 PC/Ticks)。此外,您还需要为您的代码添加一些虚拟环境,例如内存/IO 管理器等。

          祝你好运:)

          【讨论】:

            【解决方案11】:

            我认为拿起一本关于 PIC 汇编的书并学习阅读它会更容易。汇编程序通常很容易学习,因为它的级别很低。

            【讨论】:

              【解决方案12】:

              查看asm2c

              将 DOS/PMODEW 386 TASM 汇编代码转换为 C 代码的 Swift 工具

              【讨论】:

                【解决方案13】:

                将函数从 asm 转换为 C 很困难,但可以手动完成。使用反编译器转换整个程序会给你的代码可能无法理解,因为在编译过程中大部分结构都丢失了。如果没有有意义的变量和函数名,生成的 C 代码仍然很难理解。

                由于重复的模式和结构,基本程序的 C 编译器的输出(尤其是未优化的输出)可以翻译成 C。

                【讨论】:

                  猜你喜欢
                  • 1970-01-01
                  • 2012-05-01
                  • 1970-01-01
                  • 2015-12-29
                  • 1970-01-01
                  • 2010-10-12
                  • 2011-01-17
                  • 2015-08-15
                  • 2015-04-13
                  相关资源
                  最近更新 更多