在我的 Mac 上查看一些 x86_64 的汇编代码,我看到以下指令:
48 c7 c0 01 00 00 00 movq $0x1,%rax
但是我在任何地方都找不到分解操作码的参考。似乎 48c7 是一条移动指令,c0 定义了 %rax 寄存器等。
那么,我在哪里可以找到能告诉我所有这些的参考资料?
我知道http://ref.x86asm.net/,但是看着 48 个操作码,我看不到任何类似于移动的东西。
在我的 Mac 上查看一些 x86_64 的汇编代码,我看到以下指令:
48 c7 c0 01 00 00 00 movq $0x1,%rax
但是我在任何地方都找不到分解操作码的参考。似乎 48c7 是一条移动指令,c0 定义了 %rax 寄存器等。
那么,我在哪里可以找到能告诉我所有这些的参考资料?
我知道http://ref.x86asm.net/,但是看着 48 个操作码,我看不到任何类似于移动的东西。
Actually, mov
is 0xc7 there; 0x48 is, in this case, a long mode REX.W prefix.
Answering also the question in comments: 0xc0 is b11000000. Here you can find out that with REX.B = 0
(as REX prefix is 0x48, the .B bit is unset), 0xc0 means "RAX is first operand" (in Intel syntax; mov rax, 1
, RAX is first, or, in case of mov
, output operand). You can find out how to read ModR/M here.
当您查看二进制文件时
48 c7 c0 01 00 00 00
你需要拆开它才能理解它的含义。
反汇编的算法并不难,但很复杂。它假设查找多个表。
该算法在英特尔开发人员手册第 2 卷中进行了描述,
Intel® 64 and IA-32 Architectures
Software Developer’s Manual
Volume 2 (2A, 2B & 2C):
Instruction Set Reference, A-Z
您从名为 的章节开始阅读INSTRUCTION FORMAT
。
或者,有好书专门讨论这个主题的整章,例如
X86 Instruction Set Architecture, Mindshare, by Tom Shanley.
一整章专门用于反汇编二进制 X86。
或者您可以从 AMD 制作的同一语言的手册中开始阅读通用算法:
AMD64 Architecture
Programmer’s Manual
Volume 3:
General-Purpose and System Instructions
在这里,在本章中,Instruction Encoding
您将找到定义这种指令语言的自动机,并且从这个图形方案中,您可以轻松编写解码器。
完成此操作后,您可以返回英特尔手册第 2 卷,并将其用作参考书。
我还发现来自http://opensecuritytraining.info/的逆向工程课程很有用。这个网站是CMU的博士生做的,大部分做的不是很好,但是需要比较长的时间去学习和应用。
了解基本思想后,您可以查看实现该算法的免费项目。我发现distorm项目很有用。一开始不要看抽象项目(如 qemu 或 objdump),这些项目试图在相同的代码中为多种语言实现反汇编程序,因为你会迷失方向。 Distorm
仅关注 x86 并正确且详尽地实现它。它以形式语言传达了 X86 语言的定义,而 Intel 和 AMD 的手册使用自然语言来定义 X86 语言。
其他运行良好的项目是udis86。