用于x86反编译的资源

时间:2010-07-07 21:55:14

标签: assembly x86 disassembly

我想深入了解代表和运行程序的低级过程。我决定通过编写一个程序来解析和显示目标文件信息(标题,部分等)。我差不多完成了这部分。自然扩展是将剩余的相关数据反编译为汇编指令。最初,我将专注于x86。

在哪里可以找到与此反编译相关的资源(二进制 - > ASM)?我已经读过x86与ASM有一对一的对应关系,虽然我不知道从中提取转换表的最佳参考。

另外,当我在这里时,我会对跟踪任何提供的调试信息感兴趣。是否有关于此信息使用的格式的参考(假设ELF和GCC使用-g选项)?

你们有没有任何一般性建议?这里的目标是一个实践项目,以增加我的理解。

3 个答案:

答案 0 :(得分:1)

查看我的虚拟机教程:http://www.icemanind.com

它教你如何构建自己的虚拟机和汇编程序。通过阅读和完成本教程中的程序,您将更加牢固地掌握程序,汇编语言和二进制文件的工作方式

答案 1 :(得分:1)

你可以在谷歌代码上找到8086的精心记录的python反汇编程序:http://code.google.com/p/dasm3/

答案 2 :(得分:1)

x86是可变指令长度,这意味着很难拆解。如果这是您的第一个反汇编程序,则不可取。

说...我采取的方法是你必须在二进制文件中识别作为操作码的第一个字节的字节,并将这些字节与操作码或数据中的第二个或其他字节的字节分开。一旦你知道你可以从二进制文件的开头开始并反汇编操作码。

你如何从其他字节中找出操作码?您需要遍历所有可能的执行路径,听起来像递归问题,并且可能但不一定必须如此。查看中断向量表和/或代码中的所有硬件入口点。这给你一个操作码字节的简短列表。非递归方法是在二进制文件上进行多次传递,查看标记为操作码的每个字节,对其进行解码就足以知道它消耗了多少字节。您还需要知道它是无条件分支,条件分支,返回,调用等。如果它不是无条件分支或返回,则可以假定该指令之后的字节是下一条指令的第一个字节。每当遇到某种分支或调用时,计算目标地址,将该字节添加到列表中。继续制作传递,直到你做了一个不向列表添加新字节的传递。您还需要确保如果您发现一个3字节指令的字节,但将其后面的字节标记为指令,那么您就遇到了问题。像条件分支这样的东西之前是确保它们永远不会分支的东西。如果将高级代码编译成二进制代码,你就不会看到这么多,但是手写汇编程序的好时光,或者想要保护代码的人都会做这样的事情。

不幸的是,如果您拥有的只是二进制文件,对于可变长度的指令集,您将无法获得完美的反汇编。一些分支目的地是在运行时计算的,有时手工编码的程序集会在返回之前修改堆栈以更改接下来执行的代码,如果这是该代码的唯一路径,那么除非你到目前为止,否则你可能不会以编程方式解决它模拟代码。即使使用模拟,您也不会涵盖所有执行路径。

使用固定长度的指令集(例如ARM)(只要它是手臂而不是手臂和拇指的混合物),您可以简单地从二进制文件的开头开始并反汇编,直到用完单词为止。您可以将数据字反汇编为有效或无效或不太可能被使用的指令,但这没关系。

如果精灵中的某个地方有东西表明二进制文件的哪些部分是可执行的,哪些部分是数据,我不会感到惊讶。甚至可能甚至没有走过数据路径,我怀疑objdump执行的任务就像它可能在elf文件中使用了一些东西。

许多地方都记录了精灵文件格式。有基本结构,供应商可能会添加特定的块类型,供供应商记录。