The loop

The implementation of the loop is a bit long, and we have many more interesting things to fill the space allocated for this chapter, so refer to the accompanying source code for the full version. Here, however, we will examine certain parts of the implementation:

  • Creating a stack frame and parameter markup: The procedure's prolog code would be just as usual-we allocate some space on the stack and save registers that we want not to be affected by the procedure, and that means all the registers we use in the procedure:
        run_vm:
push ebp
mov ebp, esp
sub esp, 4 * 3 ; We only need 12 bytes for storing
; the state of virtual cpu
push eax ebx ecx edx esi ; We will use these registers

virtual at ebp + 8 ; Assign local labels to parameters
.p_cmd_buffer_ptr dd ? ; Pointer to VM code
.p_data_buffer_ptr dd ? ; Pointer to data we want to
; encrypt

.p_data_length dd ? ; Length of data in bytes
.p_key dd ? ; Key value cast to double word
end virtual

virtual at ebp - 0x0c ; Assign local labels to stack
; variables

.register_a db ? ; Register A of virtual processor
.register_b db ? ; Register B of virtual processor
.register_key db ? ; Register to hold the key
.register_cnt db ? ; Counter register
.data_base dd ? ; Pointer to data buffer
.data_length dd ? ; Size of the data buffer in size
end virtual
  • Preparing a virtual processor loop: The loop itself begins with reading an opcode from the current position in the virtual code, then calls the tree_lookup procedure, and either jumps to the address returned by tree_lookup or to .exit if the procedure returns an error (zero):
        virtual_loop:
mov al, [esi + ebx] ; ESI - points to array of bytes
; containing

; virtual code
; EBX - instruction pointer (offset
; into virtual code)

movzx eax, al ; Cast opcode to double word
push eax
push tree_root
call tree_lookup ; Get address of opcode emulation
; code

or eax, 0 ; Check for error
jz .exit
jmp eax ; Jump to emulation code

The preceding code is followed by a set of instructions emulating code fragments, as you can see in the accompanying source code.

The last few lines of the run_vm procedure are, in fact, the emulation of the vm_exit opcode:

        .exit:
pop esi edx ecx ebx eax ; Restore saved registers
add esp, 4 * 3 ; Destroy stack frame
leave
ret 4 * 4
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset