<<< back

Manual of MultiKey


с изменениями до multikey 0.19.1.9 включительно




*** Общая часть **************************************************************************************************************


Для полноценной работы эмулятора необходимо наличие в реестре данных о эмулируемом ключе.
Для каждого типа ключей данные будут отличаться.
При составлении рег-файлов рекомендуется смотреть на содержимое примеров рег-файлов.

Путь в реестре с данными для эмулятора:

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\MultiKey\Dumps\xxxxxxxx]

xxxxxxxx - пароль ключа (8 hex символов)

Для использования ключей с одинаковыми паролями необходимо добавить любой символ
после пароля ключа :
...MultiKey\Dumps\xxxxxxxxa]
...MultiKey\Dumps\xxxxxxxx1]


"Name"="xxx"
"Copyright"="xxx"
"Created"="xxx"

"DongleType"=dword:0000000x - тип ключа
1 - HASP (3,4,HL,SRM)
2 - HARDLOCK
3 - SENTINEL (spro,upro)
4 - GUARDANT (I,II)
5 - DINKEY


Лицензионные данные для эмулятора:

"License"=hex:xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx,xx

Для получения лицензии под х32 системы использовать онлайн-форму генерации на сайте
http://testprotect.com/appendix/LicMkOnline


********************************************************************************************************************************



*** HASP (3,4,HL,SRM) *******************************************************************************************************


"SN"=dword:xxxxxxxx - серийный номер

"Type"=dword:000000xx - модель
12 - Time HASP 3
0A - HASP4 M1 (deafult)
1A - HASP4 Time
EA - HASP HL
FA - HASP HL Time

"Memory"=dword:00000001 - размер памяти

00000001 - 0x80
00000004 - 0x1F0
00000020 - 0xFD0
00000021 - 0x70


"SecTable"=hex:00,00,00,00,00,00,00,00 - приватная таблица

"NetMemory"=hex:03,00,0F,D0,02,00,00,00,FF,FF,FE,FF - ячейки "сетевой" памяти

// Typical data into NetMemory:
// 12 1A 12 0F 03 00 70 00 02 FF 00 00 FF FF FF FF
// 12 1A 12 0F - sn
// 03 00 - key type
// 70 00 - memory size in bytes
// 02 FF - ?
// 00 00 - net user count
// FF FF - ?
// FF - key type (FF - local, FE - net, FD - time)
// FF - ?


"Option"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00 - дополнительные опции:

(для сборки от 18.2.4)
[0]=01..7F - задает временную задержку при работе с ключем, (типовая-1..4)
[0]=0 - без временных задержек (для сборки от 18.2.4)

"Data"=hex: - ячейки памяти



=TIME dongles=

Для тайм-хасп ключей добавляются такие поля, пример :

"NetMemory"=hex:05,00,80,00,02,FF,00,00,FF,FF,FD,FF
"HaspTimeMemory"=hex:\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,\
3f,db,95,7d,00,00,00,00,00,00,00,00,00,00,00,00,\
00,00,00,00,00,00,00,00
"TimeShift"=hex:00,00,00,00,00,00,00,00

где: 3f,db,95,7d - серийный номер ключа записаный побайтно



=HL encrypt/decrypt=

Таблично эмулируются функции hasp_decrypt + hasp_encrypt, при отсутствии значений в таблицах
значения обрабатываются по внутреннему AES агоритму. При необходимости смены дефолтного
ключа AES алгоритма внести в рег-файл его значение:

"AesKey"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00

Таблицы располагаются в подветках основного расположения дампа:
Decrypt: [HKEY_LOCAL_MACHINE\System\CurrentControlSet\MultiKey\Dumps\12345604\DTable];
Encrypt: [HKEY_LOCAL_MACHINE\System\CurrentControlSet\MultiKey\Dumps\12345604\ETable].


Формат записей в таблицах для мультикея версии < 18.1 (все значения шестнадцатеричные):
"10:00112233445566778899AABBCCDDEEFF"=hex:FF,EE,DD,CC,BB,AA,99,88,77,66,55,44,33,22,11,00
"20:00112233445566778899AABBCCDDEEFF"=hex:FF,EE,DD,CC,BB,AA,99,88,77,66,55,44,33,22,11,00
"30:00112233445566778899AABBCCDDEEFF"=hex:FF,EE,DD,CC,BB,AA,99,88,77,66,55,44,33,22,11,00

*****************************************************************************************
!!!для мультикея версии >=18.1 в имена запросов 20h и 30h следует брать 32 байта запроса !!!

"10:0123456789ABCDEF0123456789ABCDEF"=hex:12,34,56,78,90,AB,CD,EF,12,34,56,78,90,AB,CD,EF
"20:5500A934CDE5D7B619568515F74D323695EC75E8C48F6B5D9880F6A88B251C48"=hex:4F,8A,A7,A1,26,55,61,B3,1A,77,B4,A2,19,B3,34,FD
"30:9A2B6F7F80A2F2E36334D3258BAFD06FBB7286766A24910911648D98D8C56628"=hex:12,71,B7,B5,3D,47,B4,2B,DC,93,4F,00,00,1C,2C,4E

*****************************************************************************************

где

- "10:00112233445566778899AABBCCDDEEFF" - запрос в ключ
"10(20,30)" - длина запроса в байтах
"00112233445566778899AABBCCDDEEFF" - ПЕРВЫЕ 16 байт самого запроса

- hex:FF,EE,DD,CC,BB,AA,99,88,77,66,55,44,33,22,11,00 - ответ ключа, берутся только
первые 16 байт реального ответа.

Например:

==================================================================
2008/10/10 07:13:25.109 <== HaspHL_decrypt: Length = 0x10
2008/10/10 07:13:25.109 <== HaspHL_decrypt: Input Data =
2008/10/10 07:13:25.109
2A E1 F0 A2 | E1 B2 F1 F9 | 9F C8 72 F6 | CA 4B 01 49

2008/10/10 07:13:25.171 ==> HaspHL_decrypt: Output Data =
2008/10/10 07:13:25.171
53 9D 4D 03 | 00 00 00 00 | CB D2 6B 04 | 00 00 00 00

2008/10/10 07:13:25.171 ==> HaspHL_decrypt: Status = 0x00
==================================================================
2008/10/10 07:13:23.484 <== HaspHL_decrypt: Length = 0x20
2008/10/10 07:13:23.484 <== HaspHL_decrypt: Input Data =
2008/10/10 07:13:23.484
7B 6E 8C DF | D6 51 A3 0C | 47 E1 FA 60 | 51 6C 79 71
2E 0E 0C 38 | C6 99 FE 97 | B2 C2 E1 37 | 7F 61 CD 7A

2008/10/10 07:13:23.546 ==> HaspHL_decrypt: Output Data =
2008/10/10 07:13:23.546
02 B0 3C 6E | DA 88 46 BA | 4C 7E 5A 12 | 8E D6 DE 76
2E 0E 0C 38 | C6 99 FE 97 | B2 C2 E1 37 | 7F 61 CD 7A

2008/10/10 07:13:23.546 ==> HaspHL_decrypt: Status = 0x00
==================================================================
2008/10/10 07:13:23.609 <== HaspHL_decrypt: Length = 0x30
2008/10/10 07:13:23.609 <== HaspHL_decrypt: Input Data =
2008/10/10 07:13:23.609
7B 6E 8C DF | D6 51 A3 0C | 47 E1 FA 60 | 51 6C 79 71
2E 0E 0C 38 | C6 99 FE 97 | B2 C2 E1 37 | 7F 61 CD 7A
9C F3 2A BD | A4 DA 3B 78 | 97 CC 44 ED | 42 47 42 E6

2008/10/10 07:13:23.671 ==> HaspHL_decrypt: Output Data =
2008/10/10 07:13:23.671
77 64 61 62 | 63 5F 60 61 | A2 B9 AC 60 | 61 62 63 5F
2E 0E 0C 38 | C6 99 FE 97 | B2 C2 E1 37 | 7F 61 CD 7A
9C F3 2A BD | A4 DA 3B 78 | 97 CC 44 ED | 42 47 42 E6

2008/10/10 07:13:23.671 ==> HaspHL_decrypt: Status = 0x00
=================================================================

Получаемая таблица:

[HKEY_LOCAL_MACHINE\System\CurrentControlSet\MultiKey\Dumps\12345604\DTable];
"10:2AE1F0A2E1B2F1F99FC872F6CA4B0149"=hex:53,9D,4D,03,00,00,00,00,CB,D2,6B,04,00,00,00,00
"20:7B6E8CDFD651A30C47E1FA60516C79712E0E0C38C699FE97B2C2E1377F61CD7A"=hex:02,B0,3C,6E,DA,88,46,BA,4C,7E,5A,12,8E,D6,DE,76
"30:7B6E8CDFD651A30C47E1FA60516C79712E0E0C38C699FE97B2C2E1377F61CD7A"=hex:77,64,61,62,63,5F,60,61,A2,B9,AC,60,61,62,63,5F

Если в протоколе встречается одиночный запрос длиной в 32 (20h) байта, за которым сразу
нет запроса длиной 48 (30h) байт (или если сказать по другому, в котором вторые 16 байт запроса
НЕ РАВНЫ вторым 16 байт ответа) , то такой запрос необходимо сохранять в таблицу как
два запроса по 16 (10h) байт



= SRM =

Для эмуляции SRM помимо данных как HL ключа необходимы дополнительные данные.
На даный момент это приватная информация.


//
// List of supported functions for hasp key
//
enum KEY_FN_LIST {

//HL
KEY_FN_SET_CHIPER_KEYS = 0x80,
KEY_FN_CHECK_PASS = 0x81,
KEY_FN_READ_3WORDS = 0x82,
KEY_FN_WRITE_WORD = 0x83,
KEY_FN_READ_ST = 0x84,
KEY_FN_READ_NETMEMORY_3WORDS = 0x8B,
KEY_FN_HASH_DWORD = 0x98,
KEY_FN_GET_TIME = 0x9C, // Get time (for HASP time) key
KEY_FN_PREPARE_CHANGE_TIME = 0x1D, // Prepare to change time (for HASP time)
KEY_FN_COMPLETE_WRITE_TIME = 0x9D, // Write time (complete) (for HASP time)
KEY_FN_PREPARE_DECRYPT = 0x1E, // qwestions
KEY_FN_COMPLETE_DECRYPT = 0x9E, // answers
KEY_FN_ECHO_REQUEST = 0xA0, // Echo request to key
KEY_FN_ECHO_REQUEST2 = 0xA1, // Echo request to key

//srm
KEY_FN_SRM_A2 = 0xA2, //чтение таблицы фич
KEY_FN_SRM_26 = 0x26, //26/A6 - чтение значений фич ключа и памяти
KEY_FN_SRM_A6 = 0xA6, //
KEY_FN_SRM_AA = 0xAA, //логин в ключ
KEY_FN_SRM_AB = 0xAB, //логаут ключа
KEY_FN_SRM_AC = 0xAC, //hasp_get_rtc - получение времени с ключа
KEY_FN_SRM_AE = 0xAE, //хз, вроде с 3.25 появилось
KEY_FN_SRM_27 = 0x27, //27/A7 - запись в память ключа
KEY_FN_SRM_A7 = 0xA7, //
KEY_FN_SRM_29 = 0x29, //29/A9 - крипт-декрипт
KEY_FN_SRM_A9 = 0xA9, //
KEY_FN_SRM_28 = 0x28, //28/A8 - чтение ключа без шифровки протокола с подписью(update)
KEY_FN_SRM_A8 = 0xA8, //
KEY_FN_SRM_38 = 0x38, //38/B8 - обновление ключа и прошивы
KEY_FN_SRM_B8 = 0xB8 //
};

********************************************************************************************************************************



*** HARDLOCK ******************************************************************************************************************


"ID"=dword:xxxxxxxx - серийный номер

"withMemory"=dword:0000000x - ключ с памятью или без нее

"Seed1"=dword:0000xxxx
"Seed2"=dword:0000xxxx
"Seed3"=dword:0000xxxx

"HlkMemory"=hex: - ячейки памяти


//
// List of supported functions for HARDLOCK key
//
enum HARDLOCK_KEY_FN_LIST {
HDK_KEY_FN_SET_CHIPER_KEYS = 0x80,
HDK_KEY_FN_CHECK_PASS = 0x81,
HDK_KEY_FN_READ_WORD = 0x82,
HDK_KEY_FN_WRITE_WORD = 0x83,
HDK_KEY_FN_HL_VERKEY = 0x87,
HDK_KEY_FN_READ_ID = 0x8B,
HDK_KEY_FN_HL_CODE = 0x8C,
HDK_KEY_FN_HL_CRYPT = 0x8D,
HDK_KEY_FN_HL_CODE_PAR = 0x0C,
HDK_KEY_FN_HL_CRYPT_PAR = 0x0D,
HDK_KEY_FN_HL_CALC = 0x89
};

********************************************************************************************************************************



*** SENTINEL ******************************************************************************************************************


...MultiKey\Dumps\0000xxxx] - xxxx - Developer ID

"Type"=dword:00000000 - модель, 0-SuperPro, 1-все другие типы ;
"sntMemory"=hex: - ячейки памяти, для "Type"=0 - 64 cell, для "Type"=1 в зависимости от типа ключа
"CellType"=hex: - типы ячеек ; для "Type"=0 - 64 байт, для "Type"=1 в зависимости от типа ключа


"Type"=0 - полное внутреннее алго для спро, рег-файл старого образца

"Type"=1 - только табличная эмуляция для всех типов ключей, в рег файл добавляются новые поля:

"Option"=hex:02,00,03,80,7F,00,00,00 (пример для СПРО с поддержкой аес-тунеля)
где : [0]...[3] - значение типа ключа, получаем функой GET_KEYINFO
[4] - величина физически читаемой памяти ключа, обычно 7F или FF
[5]...[7] - резерв

"AesKey"=hex:00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00 - aes ключ для аес-тунеля(пока так, доставать из проги)

!!!!! Для формирования правильного рег-файла рекомендуется использовать дампер SSUMD v1.1 !!!!!
Spro по умолчанию дампится в старом режиме ("Type"=0).


Формат таблиц :

...MultiKey\Dumps\0000xxxx\cell_yy] - yy - номер cell, для которого таблицы, для каждого селла свои таблицы
"12345678"=hex:22,33,44,55
"1122334455667788"=hex:11,12,13,14,15,16,17,18
"11223344556677888877665544332211"=hex:88,77,66,55,44,33,22,11,11,22,33,44,55,66,77,88


//
// List of supported functions for Sentinel key
//
enum SENT_KEY_FN_LIST {
SENT_KEY_FN_FIND_FIRST_UNIT = 0x10,
SENT_KEY_FN_READ = 0x11,
SENT_KEY_FN_QUERY_SHORT = 0x12,
SENT_KEY_FN_QUERY_LONG = 0x13,
SENT_KEY_FN_WRITE_0 = 0x14,
SENT_KEY_FN_WRITE_1 = 0x15,
SENT_KEY_FN_WRITE_2 = 0x16,
SENT_KEY_FN_WRITE_3 = 0x17,
SENT_KEY_FN_OVERWRITE_0 = 0x18,
SENT_KEY_FN_OVERWRITE_1 = 0x19,
SENT_KEY_FN_OVERWRITE_2 = 0x1A,
SENT_KEY_FN_OVERWRITE_3 = 0x1B,
SENT_KEY_FN_ACTIVATE = 0x1C,
SENT_KEY_FN_DECREMENT = 0x1D,
SENT_KEY_FN_GET_KEYINFO = 0x00,
SENT_KEY_FN_SET_PARAMETER = 0x03,
SENT_KEY_FN_GET_PARAMETER = 0x02,

USENT_KEY_FN_GET_LOGIN = 0x05, //for ULTRA and new SPRO
USENT_KEY_FN_LOGIN_21 = 0x21,
USENT_KEY_FN_AES_TUNNEL = 0x07,
USENT_KEY_FN_2F = 0x2F
};

********************************************************************************************************************************



*** GUARDANT ******************************************************************************************************************


...MultiKey\Dumps\xxxxxxxx] - xxxxxxxx - pwRead - пароль ключа на чтение;

"DongleType"=dword:00000004
"pWrite"=dword:23232323 >>>пароль на запись, необязательный параметр, если прога не использует запись
"Data" =hex:\
... (256 байт - полный дамп с дескрипторами)


Формат таблиц :

если дескриптор алгоритма равен 0 в рег-файле, тогда ищем данные в таблице

...MultiKey\Dumps\xxxxxxxx\algo_yy] где yy - номер алгоритма

"1122334455667788"=hex:11,12,13,14,15,16,17,18

Используются упрощенные таблицы - запрос в рег файле ограничен 8 байтами, т.е. если длина
запроса на трансформ превышает 8 байт, в имя запроса в реестр берем только первые 8 байт, ответ пишется полный.

********************************************************************************************************************************



*** DINKEY ********************************************************************************************************************


...MultiKey\Dumps\12345678]

где 12345678 - dinkSerial

"DongleType"=dword:00000005
"dinkValue" =dword:xxxxxxxx
"dinkMemory"=hex:\

********************************************************************************************************************************