VMProtect не работает с Embarcadero RAD Studio XE3

После упаковки программа не работает.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include “VMProtectSDK.h”

wchar_t *fake_string = VMProtectDecryptStringW(L"fake string");

int _tmain(int argc, _TCHAR* argv) {
wprintf(L"test string0\n");
wprintf(L"test string1\n");
wprintf(L"test string2\n");
wprintf(L"test string3\n");
wprintf(L"test string4\n");
wprintf(L"test string5\n");
}

Проблема в том, что XE3 очень странно генерит ссылки на константы:

push    ebp
mov     ebp, esp
push    ebx
mov     ebx, offset aFakeString ; "fake string"
lea     eax, [ebx+18h]
push    eax             ; format
call    _wprintf
pop     ecx
lea     edx, [ebx+34h]
push    edx             ; format
call    _wprintf
pop     ecx
lea     ecx, [ebx+50h]
push    ecx             ; format
call    _wprintf
pop     ecx
lea     ecx, [ebx+6Ch]
push    ecx             ; format
call    _wprintf
pop     ecx
lea     eax, [ebx+88h]
push    eax             ; format
call    _wprintf
pop     ecx
lea     edx, [ebx+0A4h]
push    edx             ; format
call    _wprintf
pop     ecx
xor     eax, eax
pop     ebx
pop     ebp
retn

...

.data:0040E0CC aFakeString:                            ; DATA XREF: .text:loc_401210o
.data:0040E0CC                                         ; _wmain+4o
.data:0040E0CC                 unicode 0, <fake string>,0
.data:0040E0E4 aTestString0:
.data:0040E0E4                 unicode 0, <test string0>
.data:0040E0E4                 dw 0Ah, 0
.data:0040E100 aTestString1:
.data:0040E100                 unicode 0, <test string1>
.data:0040E100                 dw 0Ah, 0
.data:0040E11C aTestString2:
.data:0040E11C                 unicode 0, <test string2>
.data:0040E11C                 dw 0Ah, 0
.data:0040E138 aTestString3:
.data:0040E138                 unicode 0, <test string3>
.data:0040E138                 dw 0Ah, 0
.data:0040E154 aTestString4:
.data:0040E154                 unicode 0, <test string4>
.data:0040E154                 dw 0Ah, 0
.data:0040E170 aTestString5:
.data:0040E170                 unicode 0, <test string5>
.data:0040E170                 dw 0Ah, 0

lea eax, [ebx+18h] - это как раз указатель на “test string0”, но он берется почему то относительно адреса “fake string”. В результате обработки вмпротектом все неявные ссылки на “fake string” автоматически преобразуются в VMProtectDecryptStringW и поэтому по смещениям ebx+XXXX лежит уже мусор а не “test stringX”.

Попробуйте поиграть настройками компилятора чтобы он изменил алгоритм кодогенерации.

Специально пример был сделан, чтобы сохранились такие ссылки. Проблема конечно решается, нужно отключить ВСЮ оптимизацию.
Я так понимаю, всё равно гарантий нет, что защищенная программу будет работать, как оригинальная, т.к. VMProtect ориентируется на обобщённое поведение компиляторов?

ПС: 3 недели ушло, чтобы выявить причину падений программы у 15% покупателей. Искали в программе баг, которого не было.

В принципе можно прикрутить эвристику к такому коду:

mov ebx, offset aFakeString ; “fake string”
lea eax, [ebx+18h]

и автоматически определять, что он обращается к данным за пределами строки, на которую ссылается.

Да, защита от дурака не помешала бы. Такие функции можно изолировать от оптимизации по #pragma option.

Самое интересное в этой ситуации то, что начальный указатель инициализируется адресом константы, которая совсем не используется:

mov ebx, offset aFakeString ; "fake string"
lea eax, [ebx+18h]

почему нельзя было инициализировать сразу так

mov ebx, aTestString0

при этом уже сэкономив немного байт, раз мы тут что-то оптимизируем :slight_smile:)

P.S. После выхода XE2 смотрел кодогенерацию для MacOS - тихий ужас. После этого решил, что с продуктов фирмы Embarcadero надо валить, причем чем раньше тем лучше :slight_smile:) Полностью перелез на MSVC (там сейчас пишется 3-ий вмпротект практически с нуля) и доволен как слон. Для GUI использую Qt - просто на голову выше VCL. К слову сказать оптимизация у MSVC просто охренительна и Embarcadero скорее всего уже никогда (судя по финтам ушами в XE3) не догонит Microsoft по качеству кода.

Отправил вам на почту доработанную версию. Проверяйте.

День добрый. Читал тут что идет перенос VMP на Qt. Не мог пройти. Когда планируется реализ новой VMP (та что с Qt)

Пока нет никаких выхода этой версии.