在我的Mac上查看x86_64的一些汇编代码,我看到以下说明:
48 c7 c0 01 00 00 00 movq $0x1,%rax
但我无处可找到一个分解操作码的引用。似乎48c7是移动指令,c0定义了%rax寄存器等等。
那么,我在哪里可以找到告诉我这一切的参考?
我知道http://ref.x86asm.net/,但是看了48个操作码,我没有看到任何类似移动的内容。
答案 0 :(得分:13)
实际上,mov
在那里是0xc7;在这种情况下,0x48是长模式REX.W prefix。
回答评论中的问题:0xc0是b11000000。 Here您可以使用REX.B = 0
找到它(因为REX前缀是0x48,未设置.B位),0xc0表示“RAX是第一个操作数”(在Intel语法中为mov rax, 1
, RAX是第一个,或者在mov
的情况下,输出操作数)。您可以了解如何阅读ModR / M here。
答案 1 :(得分:2)
当你看二进制文件
时 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卷,并将其用作参考书。
我还发现来自reverse engineering class的http://opensecuritytraining.info/很有用。这个网站是由CMU的博士生创建的,大部分都做得不好,但是需要更长的时间来学习和应用它。
在了解了基本思路之后,您可以查看实现该算法的免费项目。我觉得distorm项目很有用。在开始时,重要的是不要查看抽象项目(如qemu或objdump),它们试图在同一代码中为许多语言实现dissasemblers,因为你会迷失方向。 Distorm
仅关注x86并正确而详尽地实现它。它以正式语言传达X86语言的定义,而Intel和AMD手册则使用自然语言定义X86语言。
其他效果良好的项目是udis86。