When protecting an application, VMProtect utilizes the space that becomes free during compilation for its own needs, including storage of various data (virtualized or mutated code, VM interpreters and so on). As a result, certain situations may occur when a jump “inside” the protected code is made from other parts of the program. Addresses such a jump is performed from are called external. A situation described above can happen when code markers are used and a jump from a non-protected part of the program is performed inside the markers:
VMProtectBegin(nil); for I:=0 to 10 do begin Inc(J); VMProtectEnd; end;
In the assembler code this cycle looks as:
----------------- marker begin ---------------- 0044D12C mov eax, 0000000B 0044D131 inc ebx ----------------- marker end ----------------- 0044D132 dec eax 0044D133 jnz 0044D131
Apparently, when commands at 0044D12C and 0044D131 addresses are virtualized and a non-virtualized conditional jump at 0044D133 is performed, an error occurs, because the address of 0044D131 contains various data or just garbage instead of the original code. In this example, 0044D131 is an external address.
When the “Debug mode” option is enabled, the INT 03 command replaces the original code. This is a simple breakpoint and a debugger command. When the protected application is executed under a debugger and control is passed to the 0044D131 address, a breakpoint is activated, and the debugger window displays the address the given jump is initiated at.
When such jumps are detected, we recommend to check all code markers, whether they are set properly. If the protected code is not marked, or if the program logic cannot be changed so to avoid passing control inside the protected code, you should mark such addresses as external in the GUI.