39

在 x86中查找任意操作码的含义(例如)的相对快速且简单的方法是什么?0xC8

搜索英特尔软件开发人员手册并不是很有趣...

4

7 回答 7

54

在 x86asm.net 上查看这个非常完整的 x86 操作码表。

CTRL+F这样,你就完成了!请务必阅读正确的行,C8例如可能出现在多个位置。

于 2011-06-19T09:32:18.083 回答
25

这是一个非常漂亮的视觉效果。没有详细介绍,但是如果您只需要非常快速地查找十六进制值,则应该这样做-

操作码参考

来源: http: //pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf

于 2015-09-09T19:25:54.193 回答
15

虽然英特尔软件开发人员手册本身绝对不是很方便搜索,但本手册中的操作码表可能会有所帮助。看看手册第2A、2B、2C、2D卷的附录A“Opcode Map” ,可能有用:

附录 A 操作码映射目录

于 2011-06-19T09:52:11.527 回答
8

还有asmjit/asmdb项目,它以类似 JSON 的格式提供公共域X86/X64 数据库(它实际上是一个节点模块,只需从节点 require() 或包含在浏览器中)。它是为附加处理而设计的(例如编写验证器、汇编器、反汇编器),但打开数据库文件并进行探索也很容易。

AsmDB 带有一个名为 x86util.js 的工具,它可以将 x86 数据库索引为更友好的表示形式,可以用来实际使用它做一些事情。让我们在 node.js 中编写一个简单的工具,打印所有与您提供的操作码字节相同的指令:

const asmdb = require("asmdb");
const x86isa = new asmdb.x86.ISA();

function printByOpCode(opcode) {
  x86isa.instructions.forEach(function(inst) {
    if (inst.opcodeHex === opcode) {
      const ops = inst.operands.map(function(op) { return op.data; });
      console.log(`INSTRUCTION '${inst.name} ${ops.join(", ")}' -> '${inst.opcodeString}'`);
    }
  });
}

if (process.argv.length < 3)
  console.log("USAGE: node x86search.js XX (opcode)")
else
  printByOpCode(process.argv[2]);

试试看:

$ node x86search.js A9
INSTRUCTION 'pop gs' -> '0F A9'
INSTRUCTION 'test ax, iw' -> '66 A9 iw'
INSTRUCTION 'test eax, id' -> 'A9 id'
INSTRUCTION 'test rax, id' -> 'REX.W A9 id'
INSTRUCTION 'vfmadd213sd xmm, xmm, xmm/m64' -> 'VEX.DDS.LIG.66.0F38.W1 A9 /r'
INSTRUCTION 'vfmadd213sd xmm, xmm, xmm/m64' -> 'EVEX.DDS.LIG.66.0F38.W1 A9 /r'
INSTRUCTION 'vfmadd213ss xmm, xmm, xmm/m32' -> 'VEX.DDS.LIG.66.0F38.W0 A9 /r'
INSTRUCTION 'vfmadd213ss xmm, xmm, xmm/m32' -> 'EVEX.DDS.LIG.66.0F38.W0 A9 /r'

$ node x86search.js FF
INSTRUCTION 'call r32/m32' -> 'FF /2'
INSTRUCTION 'call r64/m64' -> 'FF /2'
INSTRUCTION 'dec r16/m16' -> '66 FF /1'
INSTRUCTION 'dec r32/m32' -> 'FF /1'
INSTRUCTION 'dec r64/m64' -> 'REX.W FF /1'
INSTRUCTION 'fcos ' -> 'D9 FF'
INSTRUCTION 'inc r16/m16' -> '66 FF /0'
INSTRUCTION 'inc r32/m32' -> 'FF /0'
INSTRUCTION 'inc r64/m64' -> 'REX.W FF /0'
INSTRUCTION 'jmp r32/m32' -> 'FF /4'
INSTRUCTION 'jmp r64/m64' -> 'FF /4'
INSTRUCTION 'push r16/m16' -> '66 FF /6'
INSTRUCTION 'push r32/m32' -> 'FF /6'
INSTRUCTION 'push r64/m64' -> 'FF /6'

此外,还有一些命令行工具可用于快速和肮脏的反汇编,但这些工具需要整个指令(与只有操作码字节相比),这里有一些提示:

使用LLVM项目中的 llvm-mc:

$ echo "0x0f 0x28 0x44 0xd8 0x10" | llvm-mc -disassemble -triple=x86_64 -output-asm-variant=1
.text
movaps xmm0, xmmword ptr [rax + 8*rbx + 16]

使用nasm项目中的 ndisasm:

$ echo -n -e '\x0f\x28\x44\xd8\x10' | ndisasm -b64 -
00000000 0F2844D810 movaps xmm0,oword [rax+rbx*8+0x10]

还有一个AsmGrid项目来自与 AsmDB 相同的作者。它是一个正在进行中的在线 AsmDB 浏览器,它使用颜色来可视化每条指令的各种属性。

于 2016-09-05T17:41:50.900 回答
7

查找操作码的快速参考是sandpile。我需要单击两次才能找出 0xc8 的作用(它是enter,顺便说一句)。

于 2011-06-20T09:30:50.803 回答
4

沙堆可能是您正在寻找的。不过,查看 x86 编码的最佳方式不是 hex 而是octal。突然间,x86 看起来不再那么难看,而且有些道理。

1992 年左右的 Usenet alt.lang.asm 上提供了对此的经典解释,然而,今天可以在github 上找到

于 2016-08-13T21:43:52.987 回答
3

另一种方法是使用调试器(gdb、windbg、ollydbg、...)或反汇编程序(IDA),然后在可写内存区域中设置字节序列。最后,在该字节序列的起始地址进行反汇编。
它的接缝很复杂,但在您开裂/反转的某些情况下很有用。

于 2012-06-07T20:13:34.753 回答