What is a relatively quick and easy method of looking up what an arbitrary opcode means (say, 0xC8
) in x86?
The Intel Software Developer's manual isn't very fun to search through...
What is a relatively quick and easy method of looking up what an arbitrary opcode means (say, 0xC8
) in x86?
The Intel Software Developer's manual isn't very fun to search through...
Check this very complete table of x86 opcodes on x86asm.net.
Just CTRL+F
and you're done! Be sure to read the correct line tho, as C8
for example may appear in several locations.
vmovups
for example.) It's otherwise a great reference though, so this is a good answer. But if people want something "very complete", the only reference I see now is Sandpile, as others mention. Though there is also AsmJit's database, which might also be helpful. Finally, for the benefit of anyone who doesn't scroll down to read other answers: x86 is much more readable in octal, grouping the bits as [AA][BBB][CCC]. –
Goeselt Here is a pretty nice visual. Doesn't go into much detail, but if you just need to look up a hex value really quick, this should do it-
Source: http://pnx.tf/files/x86_opcode_structure_and_instruction_overview.pdf
XCHG EAX, ECX
Memory? –
Nidanidaros 0x90..7
xchg eax, reg
single-byte encodings can't include data memory. Neither do the 0xb?
mov
opcodes that put an imm8 or imm32 into a register. Also, cwd
and cdq
are clearly ALU instructions, sign-extending EAX into EDX:EAX. Wait a minute, that table isn't even right. 0x98 is CWDE (and with a 66 prefix, CBW). 0x99 is CDQ (and with a 66 prefix, CWD). –
Kinetics repe scasb
is a branchless (and slow) memchr, for example. If you had to pick one colour for those, IDK. I guess their "control flow and conditional" includes flag-setting / reading for some reason, even though that's just ALU. –
Kinetics While Intel Software Developer's Manual itself is definitely not very convenient to search through, the opcode tables in this manual could help. Take a look at the Appendix A "Opcode Map" in the volume 2A, 2B, 2C, and 2D of the manual, it might be useful:
There is also asmjit/asmdb project, which provides public domain X86/X64 database in a JSON-like format (it's a node module actually, just require() it from node or include in browser). It's designed for additional processing (for example to write validators, assemblers, disassemblers), but it's also very easy to just open the database file and explore it.
AsmDB comes with a tool called x86util.js, which can index the x86 database into much more friendly representation that can be used to actually do something with it. Let's write a simple tool in node.js that prints all instructions that have the same opcode byte as you provide:
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]);
Try it:
$ 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'
Additionally, there are command line tools that can be used for quick and dirty disassembling, but these require the whole instruction (in contrast of having just the opcode byte), here are some tips:
Using llvm-mc from LLVM project:
$ 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]
Using ndisasm from nasm project:
$ echo -n -e '\x0f\x28\x44\xd8\x10' | ndisasm -b64 -
00000000 0F2844D810 movaps xmm0,oword [rax+rbx*8+0x10]
There is also an AsmGrid project from the same author as AsmDB. It a work-in-progress online AsmDB explorer that uses colors to visualize various properties of each instruction.
A fast reference for looking up opcodes is sandpile. I need two clicks to find out what 0xc8 does (it's enter
, btw).
Sandpile is probably what you're looking for. Still, the best way to look at the x86 encoding is not in hex but rather in octal. Suddenly x86 doesn't look so ugly and it makes some sense.
The classic explanation of this was available at Usenet alt.lang.asm circa 1992, however, today is available in github
inc r32
, dec r32
, xchg r32, eax
, and mov r32, imm32
). This makes it natural to have groups of 3 bits in the encoding for other instructions, too. –
Kinetics Another way, using a debugger (gdb, windbg, ollydbg, ...) or disassembler (IDA), and then, set byte sequences in writable memory region. Finally, disassembly at the starting address of that byte sequences.
It's seam complicated, but useful in some situations when you cracking/reversing.
© 2022 - 2024 — McMap. All rights reserved.