Прикольный случай с защитой - последствия пустых маркеров
Posted: Sat May 29, 2010 2:38 pm
После защиты VMProtect 2.04.3 вдруг начались портиться пустые константы. Причина нашлась.
Глянем на код - простейший случай, показываем окно с пустой строкой "", причем используется только одна пустая защита после рабочего кода.
Но вместо пустой строки в окошке видим случайный символ.
Дизассемблирование показало следующее:
Оказалось, что в функции виртуализации для идентификации используется "строка маркер", которая затирается после отработки протектором. А так как мы не указываем уникальных строк, то там стоит "", которая указывает в тоже самое место ( ??_C@_00CNPNBAHC@?$AA@), что и "" из MessageBoxA.
В результате протектор бесцеременно лезет в блок строк и портит их (это описано в документации).
Причем флаг "Enable String Pooling = Yes/No" никак не развязывает эти константные строки и порча идет сказочная по всему огромному проекту. Я специально по листингам проверил - не развязывает, что удивительно!
После вставки уникальных строк идентификации в защитные маркеры все стало нормально работать. Я поправил макросы, добавив к ним в качестве маркера имя файла и строку:
в результате маркер будет вида "VMP_CMyApp::InitInstance:362"
Понятно, что я сам виноват, подсовывая пустую строку в качестве маркера, но кто же мог подумать о такой засаде
))
Наверное, разработчикам надо затирать не весь маркер, а оставлять последний 0 нетронутым. Это убережет много нервов у пользователей этого замечательного протектора.
Глянем на код - простейший случай, показываем окно с пустой строкой "", причем используется только одна пустая защита после рабочего кода.
Но вместо пустой строки в окошке видим случайный символ.
Code: Select all
BOOL CMyApp::InitInstance()
{
//--- тест для VM Protect
MessageBoxA(NULL,"","Test",MB_OK);
VMProtectBeginVirtualization("");
VMProtectEnd();
return(FALSE);
}
Code: Select all
; 424 : //--- тест для VM Protect
; 425 : MessageBoxA(NULL,"","Test",MB_OK);
00011 6a 00 push 0
00013 68 00 00 00 00 push OFFSET ??_C@_04OFFCAMCD@Test?$AA@
00018 68 00 00 00 00 push OFFSET ??_C@_00CNPNBAHC@?$AA@
0001d 6a 00 push 0
0001f ff 15 00 00 00
00 call DWORD PTR __imp__MessageBoxA@16
; 426 :
; 427 : VMProtectBeginVirtualization("");
00025 68 00 00 00 00 push OFFSET ??_C@_00CNPNBAHC@?$AA@
0002a ff 15 00 00 00
00 call DWORD PTR __imp__VMProtectBeginVirtualization@4
; 428 : VMProtectEnd();
В результате протектор бесцеременно лезет в блок строк и портит их (это описано в документации).
Причем флаг "Enable String Pooling = Yes/No" никак не развязывает эти константные строки и порча идет сказочная по всему огромному проекту. Я специально по листингам проверил - не развязывает, что удивительно!
После вставки уникальных строк идентификации в защитные маркеры все стало нормально работать. Я поправил макросы, добавив к ним в качестве маркера имя файла и строку:
Code: Select all
#define QUOTEME_(x) #x
#define QUOTEME(x) QUOTEME_(x)
VMProtectBeginVirtualization("VMP_"__FUNCTION__ ":" QUOTEME(__LINE__));
Понятно, что я сам виноват, подсовывая пустую строку в качестве маркера, но кто же мог подумать о такой засаде

Наверное, разработчикам надо затирать не весь маркер, а оставлять последний 0 нетронутым. Это убережет много нервов у пользователей этого замечательного протектора.