How does the parser parse the machine code? Does it go byte by byte? How does it know how many bytes to read when parsing an instruction? Does it have some sorts of tables of bytes to translate the machine code via table directly into assembly like AST?
I am starting to understand how to generate the machine code from Assembly, but how do you go from machine code to assembly essentially, from machine code to an AST used by a VM? What are the general principles?
Are there any open source projects that demonstrate this for x86? I have seem many "x86 vms" on GitHub which interpret assembly instructions, but none that interpret machine code directly. I guess this would be some sort of reverse engineering project (maybe this is one?), but not sure where to look. Even something which takes the machine code and converts it to assembly string would be valuable to see, something similar to objdump, but ideally in JavaScript/Node.js :)
This looks like a good start, is this standard?
void
xed_instruction_length_decode(xed_decoded_inst_t* ild)
{
prefix_scanner(ild);
#if defined(XED_AVX)
if (xed3_operand_get_out_of_bytes(ild))
return;
vex_scanner(ild);
#endif
#if defined(XED_SUPPORTS_AVX512) || defined(XED_SUPPORTS_KNC)
// evex scanner assumes it can read bytes so we must check for limit first.
if (xed3_operand_get_out_of_bytes(ild))
return;
// if we got a vex prefix (which also sucks down the opcode),
// then we do not need to scan for evex prefixes.
if (!xed3_operand_get_vexvalid(ild) && chip_supports_avx512(ild))
evex_scanner(ild);
#endif
if (xed3_operand_get_out_of_bytes(ild))
return;
#if defined(XED_AVX)
// vex/xop prefixes also eat the vex/xop opcode
if (!xed3_operand_get_vexvalid(ild) &&
!xed3_operand_get_error(ild) )
opcode_scanner(ild);
#else
opcode_scanner(ild);
#endif
modrm_scanner(ild);
sib_scanner(ild);
disp_scanner(ild);
imm_scanner(ild);
}
It looks like a lot of processing to figure out the instructions.
But alas, some of the functions source code are missing, like xed3_operand_get_out_of_bytes
...