We would like to use the “Memory protection” option but we find it is very slow. For a 16mb DLL the startup time increases with almost 5 seconds which makes it unusable for our customers.
Is there any way this feature could be made faster? If the algorithm itself is slow, then maybe an option to only check the memory regions around virtualized code (+/- 1kb around each marker) or something like that could help.
I also tried the VMProtectIsValidImageCRC function, but noticed (on Windows, version 3.2.0 build 976) that this seem to only force the “Memory protection” option to be active. The DLL won’t load if VMProtectIsValidImageCRC is present and the binary has been modified (even though memory protection option is off in VMP-settings). So I think this might be a bug?
Besides these issues we are impressed with VM-protect so thank you for creating it.
Here are the steps to reproduce the second issue I noted above:
Add a call to VMProtectIsValidImageCRC in the code
Compile the binary (a Windows DLL in my case) in VM-Protect, make sure Memory Protection is set to “No”
Loading the resulting binary gives same long startup time as when Memory Protection is set to “Yes”
Try changing any byte in the binary with a hex editor
Now loading the binary results in “Initialization error 4” which I assume is VM-Protects message that shows CRC check failed. The call to VMProtectIsValidImageCRC that I added is never executed because loading fails.
Surely the idea of the VMProtectIsValidImageCRC call is to trigger the check at runtime after the binary has loaded, and not just force the Memory Protection to Yes?
Please notice that VMProtect always checks the latest segment whatever the option “Memory Protection”, so the message “Initialization error 4” says that VMProtect’s segment was modified (on a disk or in the memory). About speed of “Memory Protection” and “VMProtectIsValidImageCRC” - they check CRC of many regions and it works inside VM. Unfortunaterly we have no idea how we can increase speed of them with the same security level.
Ok the slowness is not a problem if it is possible to call VMProtectIsValidImageCRC from a separate thread at our application startup and have the delay happen in another thread. Should that be possible? I can’t get that to work here because of the issue I reported above.
Here is small Delphi example that shows the problem.
When built with CRCTEST not defined then the program shows “start”. I can edit exe with hexeditor and the program still starts.
When built with CRCTEST defined then the program shows “start” and then “crc ok”. But if I now try to edit any byte anywhere (same byte as in previous test, or at the start, middle or end) in the exe, then it will not start but instead show “Initialization error”. There is just no way I can make it display “crc failed”.
Memory protection is set to Off. Using latest version of VM-Protect, tried protecting both 32 and 64-bit Windows exe-files.
Can you please help me solve this?
program vmpcrctest;
{$APPTYPE CONSOLE}
function VMProtectIsValidImageCRC: Boolean; external 'VMProtectSDK32.dll';
{$DEFINE CRCTEST}
begin
writeln('start');
{$IFDEF CRCTEST}
if VMProtectIsValidImageCRC then
writeln('crc ok')
else
writeln('crc fail');
{$ENDIF}
end.
In addition i also confirm this on macOS. Attached original macOS binary. Got the same “Initialization Error 4”, looks like a bug in VMP - without “memory protection on” application should work without any messages i guess.
// VMProtect options used:
// Memory Protection: No
// Import Protection: No
// Debugger Detection: No
// Virtualization Tools Detection: No
#include <stdio.h>
#include <conio.h>
#include "VMProtectSDK.h"
inline void myCoolFunction()
{
VMProtectBeginVirtualization("myCoolFunction");
printf("hello from INSIDE VMProtect!\n");
VMProtectEnd();
}
int main (int argc, char *argv[])
{
// Protected Area
myCoolFunction();
// Unprotected Area
printf("Hello from OUTSIDE VMProtect!\n"); // <- changing one byte (tried first byte) of this text via Hex Editor will result in "Initialization Error 4" when starting the .exe! WHY?
bool b = VMProtectIsValidImageCRC(); // <-- When changing the above text, I would like to receive a boolean false here! I don't want the app to throw "Initialization Error 4"
if (b)
printf("CRC Valid!\n");
else
printf("CRC Invalid!\n");
_getch();
}
Just one more question: There is still the startup delay. I thought the VMProtectIsValidImageCRC function would do the CRC-check at that point, but it still seems it enables Memory protection and this happens during load (causing long startup delay), and then the VMProtectIsValidImageCRC function only returns this result? So we can’t run it in a thread to get past the startup delay.