有没有一种较为简便快速的方法来查找x86指令的含义(比如说,0xC8
)?
查看Intel软件开发者手册不太方便...
有没有一种较为简便快速的方法来查找x86指令的含义(比如说,0xC8
)?
查看Intel软件开发者手册不太方便...
只需使用CTRL+F
,您就完成了! 请确保阅读正确的行,因为例如C8
可能出现在多个位置。
vmovups
)。尽管如此,它仍然是一个很好的参考,所以这是一个好答案。但是,如果人们想要“非常完整”的东西,我现在看到的唯一参考是 Sandpile,正如其他人提到的那样。虽然也有 AsmJit 的数据库,这也可能会有所帮助。最后,为了让任何没有向下滚动阅读其他答案的人受益:x86 在八进制中更易读,将位分组为[AA][BBB][CCC]。 - user541686这里有一个非常好的图示。虽然没有详细解释,但如果您只需要快速查找十六进制值,则可以使用此方法-
来源:http://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf
XCHG EAX, ECX
是内存操作? - l4m20x90..7
xchg eax, reg
单字节编码的数据移动不能包括数据内存。0xb?
mov
操作码也不会将imm8或imm32放入寄存器中。此外,cwd
和cdq
显然是ALU指令,将EAX符号扩展为EDX:EAX。等一下,那个表格甚至都不正确。0x98是CWDE(并带有66前缀的CBW)。0x99是CDQ(并带有66前缀的CWD)。 - Peter Cordesrepe scasb
是一种无分支(而且慢)的memchr。如果你必须选择其中一种颜色,我不知道。我猜他们的“控制流和条件”包括某些原因的标志设置/读取,即使那只是ALU。 - Peter Cordes虽然英特尔软件开发手册本身不太方便查找,但是这个手册中的操作码表可能会有所帮助。请查看附录A“操作码映射”在手册的卷2A、2B、2C和2D,这可能会很有用:
此外还有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'
$ 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浏览器,使用颜色来可视化每个指令的各种属性。
另一种方法是使用调试器(gdb,windbg,ollydbg等)或反汇编器(IDA),然后在可写内存区域中设置字节序列。最后,在该字节序列的起始地址处进行反汇编。
这看起来很复杂,但在某些破解/反向工程的情况下非常有用。