I'm currently reversing a virtualized sample that uses a custom VM bytecode. After defeating the anti-disassembly tricks I'm finally faced with the vm_dispatch function. I have to figure out the custom vm opcodes in order to determine what the program actually does. Unlike most other vms, there are no vftables which makes it very hard for me to reverse since there are more than 100 virtual handlers which are not defined as functions (All of the handlers are defined in loc_XXXX code blocks. Example image is below).

enter image description here

Trying to decompile the vm_dispatch function leaves me with this:

  a lot of local variable initialization
  assign vm handlers
  bytecode_array[53] = &loc_4041A3;
  regs->VIP = 0x6000;  // virtual ip
  memcpy(bytecode_array + regs->VIP, bytecode, bytecode_size);
  regs->R5 = -1;
  vm_code = *(bytecode_array + regs->VIP++);
  __asm { jmp     [ebp+eax*4+vm_handler_array]; jump to the appropriate handler }// switch jmp

I know it's not fully decompiled because there are more than 100 blocks, each executing a specific vm bytecode. None of that is reflected on the decompiler output.

It's really time-consuming to go through each loc_XXXX without being able to define VM specific structures like VM and REG and to read the low-level assembly. My question is, is there any:

  • Way to convert loc_XXXX code blocks to functions to that I can decompile the code and create structures?
  • Right approach to read the assembly / make it easier?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.