![]() |
1
1
x86是可变指令长度,这意味着很难分解。如果这是你的第一个拆卸器,这是不可取的。 说……我采用的方法是,你必须在二进制文件中识别出操作码的第一个字节,并将它们与操作码或数据中的第二个或其他字节分开。一旦你知道你可以从二进制文件的开头开始分解操作码。 如何从其他字节中找出操作码?您需要遍历所有可能的执行路径,听起来像是递归问题,可能是,但不一定是。查看中断向量表和/或代码中的所有硬件入口点。这会给您一个操作码字节的简短列表。一种非递归方法是对二进制文件进行多次传递,查看每个被标记为操作码的字节,然后对其进行足够的解码,以知道它消耗了多少字节。您还需要知道它是否是无条件分支、条件分支、返回、调用等。如果它不是无条件分支或返回,您可以假定此指令之后的字节是下一条指令的第一个字节。每当遇到某种分支或调用时,计算目标地址,将该字节添加到列表中。一直进行传递,直到您进行了一个不会向列表中添加新字节的传递。您还需要确保,如果假设您找到一个字节,它是一个3字节的指令,但后面的字节被标记为一个指令,那么您就有问题了。像条件分支这样的东西,被某些确保它们永远不会分支的东西所控制。如果将高级代码编译成二进制代码,您就不会看到这样的情况,但是手工编写汇编程序或希望保护其代码的人过去的好时光会这样做。 不幸的是,如果您所拥有的是二进制的,对于一个可变长度的instruction集,您将无法得到一个完美的反汇编。有些分支目的地是在运行时计算的,有时手工编码的程序集会在执行返回操作之前修改堆栈,以更改下一步执行的代码,如果这是该代码的唯一路径,那么您很可能无法通过编程的方式解决问题,除非您能够模拟代码。即使使用模拟,也不会覆盖所有的执行路径。 使用固定长度的指令集,例如arm(只要它是arm,而不是arm和thumb的混合),您可以从二进制文件的开头开始,然后进行反汇编,直到用完字为止。您可以将一个数据字反汇编成一个有效的、无效的或不太可能被使用的指令,但这没关系。 如果在ELF中的某个地方有一些东西指示二进制文件的哪些部分是可执行的,哪些部分是数据,我不会感到惊讶。也许即使如此,您不必走数据路径,我怀疑objdump执行这样的任务,它可能会使用elf文件中的某些内容。 ELF文件格式在许多地方都有文档记录。有基本的结构,供应商可以添加特定的块类型,这些类型将由供应商记录。 |
![]() |
2
1
查看我的虚拟机教程: http://www.icemanind.com 它教你如何逐步建立你自己的虚拟机和汇编程序。通过阅读和完成本教程中的程序,您将对程序、汇编语言和二进制代码的工作方式有更深入的了解。 |
|
3
1
您可以在google code上找到一个详细记录的8086的python反汇编程序: http://code.google.com/p/dasm3/ |
|
themiurge · C#中的无用变量用于捕获委托的循环反汇编? 8 年前 |
![]() |
Mecki · 为什么otool会截断我的反汇编输出? 8 年前 |
![]() |
AkThao · 反汇编程序是如何工作的,它与反编译程序有何不同? 9 年前 |
![]() |
Xaqron · Win32Dasm折叠点操作错误 9 年前 |
![]() |
Gian U. · javap输出中缺少指令号 11 年前 |