Берем GrdUtil от версии 6.2 (демо коды).
Создаем маску ключа Stealth I. По умолчанию в ней 4 алгоритма. Сохраняем Исходный код записи (он с сокращениями приведен ниже) .
Алгоритмы заканчиваются по адресу 78 УАМ, то есть 108 САМ. А в исходном коде мы видим:
GrdProtect(hGrd, 77, 77, 4, 0, 0, NULL)
В документации про параметры dwWrProt и dwRdProt сказано:
SAM-адрес первого байта, доступного для записи (в байтах). Адрес должен быть четным, в противном случае возвращается ошибка GrdE_InvalidArg
Почему нам предлагают поставить защиту до 77 адреса? Разве не 108 должно быть? Кстати, 77 еще и нечетное.
...
const unsigned char g_byDongleImage[] = {\
0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1A, 0x20, \
0x28, 0x2E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x04, 0x04, 0xD3, 0xF5, \
0x4D, 0x48, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, \
0x08, 0x20, 0x12, 0x79, 0x64, 0x73, 0x37, 0x16, \
0xF4, 0x73, 0x06, 0x00, 0xFE, 0xFF, 0xFF, 0xFF, \
0x04, 0x04, 0x91, 0xE2, 0x03, 0x5E, 0x00, 0x00, \
0x00, 0x00, 0x00, 0x00, 0x08, 0x04, 0x78, 0x54, \
0xA3, 0x22, 0x17, 0xE2, 0xFE, 0x61};
int main(int argc, char* argv[])
{
......................
if(::GrdWrite(hGrd, GrdUAM_bNProg, sizeof(g_byDongleImage), (void*)g_byDongleImage, NULL) == GrdE_OK)
{
if(::GrdProtect(hGrd, 77, 77, 4, 0, 0, NULL) == GrdE_OK)
{
printf("Dongle image has been successfully written to the dongle");
}
}
......................
return nLastError;
}