|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 6, 2004 18:47:58 HarmEr Это виртульная машина, vIntel. Ана мне понравилась больше всего (так и не удалось оптимизировать ее разбор). Каждый переход это указатель на функцию эмуляции команды. Прокоментируй точки входа, и увидишь весь код. Первый раз я ее увидел в 3.95 haspnt.sys. Писали скрипт под ИДУ который перевел в удобночитаемый IA32 ассемблер. |
|
|
Дата: Авг 9, 2004 04:34:20 Я уже задал ему вопрос по той пиар компании которую он начал проводить получив от меня "Под нераспространение" часть информации о эмуляции 3C/3D, жду ответа... [url=]http://www.reng.ru/board/viewtopic.php?t=1725[/url] Там и отвечено |
|
|
Дата: Авг 14, 2004 13:02:58 · Поправил: _Chingachguk_ HarmEr Еще раз спасибо за ответ. С машиной вроде ничего сложного нет, надо только повозиться. Кстати, нечто подобное я видел и в приложении. Пока что я вроде окончательно выдернул transform2(аттач). Я полагал, что она модифицирует в структуре Key какие-то данные при каждом вызове и поэтому не получается ее эмулировать табличной заменой. Но нет. Она использует поля [+1Ch],[+1Eh],[+20h],[+4Ch],[+BAh],[+BCh] для работы с портами (ключом), но только на чтение... Можно предположить, что в ключе есть таблица подстановок, но есть и некоторый указатель(ли), которые модифицируются при каждом вызове transform2, например: transform2_InKey(Data) static Base; // Базовый указатель static Table[]; // Таблица подстановок res=Table[(Base+Data)%(sizeof...)]; Base=+func(Data); return(res); На это может указывать код transform2. Ведь при его вызове он обрезает переданный байт, оставляя 5 бит: Data' = ( ( ( Data[] and 18h ) shl 1 ) or ( Data[] and 7 ) ); Затем идет ветвление, например: if (!(ExtKey[0x4C]&0x02)) { if (ExtKey[0xBA]==1) { eax=(ExtKey[0x20]-(((ExtKey[0xBC]>>0x0B)|(ExtKey[0xBC]<<0x05))^0x85))^ 0x5120-0xAD; ... // Вывести в порт байт Data' eax раз out dx,al Те в зависимости от полей структуры ExtKey, но не от значения Data, переданного в transform2, мы выводим Data в порт, определенное число раз - возможно, это приводит к сдвигу указателей базы внутри ключа на каждом шаге... Ладно, пойду дальше смотреть. PS: Никто не знает, можно ли сделать dump такого ключа утилитой Sp0Raw ? |
|
|
Дата: Авг 14, 2004 13:06:16 |
|
|
Дата: Авг 15, 2004 04:39:39 Хм. Нашел любопытную вещь в коде transform2. В некоторых случаях возможна ситуация, когда ее результат зависит только от трех битов аргумента. Вот схематичный код transform2: bit transform2(byte b, *Key)
{
b= ((b&0x18)<<1)|(b&0x07); // Оставляем 5 бит из 8
P4B64C(b,Key);
P4B64C(b|0x10,Key);
P4B64C(b,Key);
return(P6153(Key));
}
void P4B64C(byte b, *Key);
{
if (Key[0x1C] == 0)
P59BCE((b&0xFE)|0x80,Key);
else
P59BCE(b|0x81,Key);
}
void P59BCE(byte b,*Key);
{
if ( (Key[0x4C]&2) != 0 )
{
if ( (b&0x80) == 0 ) return; // Never ?
byte outbyte = P2C938(b, Key);
P259F0(outbyte,Key); // Отправляем байт outbyte
// в порт
}
else
// Отправляем байт b в порт определенным образом
// вычисленное число раз, но все же 5 бит
...
}
// b на входе содержит только 5 бит исходного байта
byte P2C938(b, *Key);
{
b= ((b^0xC3)>>2) & 0x1F; // Оставить 3 бита ???
// Далее на основании только трех бит из 5
// формируется байт для вывода в порт.
...
}
Непонятно. Выходит, в случае Key[0x4C]&0x02 можно получить ответ от ключа, передавая в transform2 3 бита ? Могут быть следующие ситуации: 1) Такой вызов не происходит в случае 3d, а в каких-то иных случаях или же этот код универсален для разных типов ключей, но для данного ключа отрабатывает именно 5 бит; 2) Можно работать с ключом и через три бита, и через пять. Случай 2 наиболее интересен - часть зависимости вынесена в код драйвера и это можно изучить. Надо будет проверить, куда поступает параметр "2" в вызове InitDongle(2,Key)... |
|
|
Дата: Авг 16, 2004 09:37:52 Ага. Кажется, мою теорию с: transform2_InKey(Data) static Base; // Базовый указатель static Table[]; // Таблица подстановок res=Table[(Base+Data)%(sizeof...)]; Base=+func(Data); return(res); проверить будет несложно. В общем случае такой вариант с одним указателем базы можно представить как 39 битовых независимых таблиц подстановки (шагов ведь 39), каждая такая таблица содержит максимум 5 бит, минимум 3 бита. Т.е. получается, что нужно будет всего 39x32 бита = 39x4 байт = 156 байт. Это вроде немного. Как можно узнать битовые таблицы ?... Если удасться запустить код transform2 на выполненение, то получить все возможные отклики Transform2 на каждом шаге не должно вызвать трудностей... Пока у меня не хватает инициализатора InitDongle, где должно быть предъявление ключа... Попробую все же восстановить таблицы по известным мне парам входное/выходное значение ф-ции transform. Каждая пара при обращении по методу подбора crc дает 2^(39-32)=2^7=128 вариантов, и из них один верный. Из каждой пары можно будет извлечь примерно 32 бита таблиц подстановок. |
|
|
Дата: Авг 17, 2004 10:46:40 О, мудрейшие, объясните чайнику, как ф-ция transform может и криптовать и декриптовать? Ведь на первый взгляд она может либо одно, либо другое. Сдвиг только в одну сторону, да и биты зависят от предистории. Понимаю, что я что-то не понимаю. Посоветуйте литературу по теме |
|
|
Дата: Авг 17, 2004 16:26:12 wtch Поробую тебе объяснить по руски ;-) Вот маленький примерчик: *data++ ^= prng(); Эта функция и являтьеся средством 2 в 1. кроме сложения по модулю 2 ты можешь использовать и другие операции (+-), в этом случае PRNG остаться неизменным, а вот функции шифрования/дешифрования будут различными. Transform, в нашем случае и являеться генератором случайных чисел. _Chingachguk_ На счет размеров таблиц ты ошибаешся. |
|
|
Дата: Авг 17, 2004 17:02:47 · Поправил: _Chingachguk_ HarmEr Сенькс. Я уже накопил достаточно пар аргументов/ответов transform2 и проверил - действительно, пока не получается. Но ведь вначале же стоит: b= ((b&0x18)<<1)|(b&0x07); // Оставляем 5 бит из 8 Ладно, посмотрю еще. Главное, чтобы прокатило в принципе независимость Key на каждом шаге, те табличная эмуляция. Или же байт для transform2 - номер таблицы, а шаг - индекс в таблице (те таблицы из 39 элементов) ?... Надо будет проверить. PS: Ты не решал больше задачу crackme by Mike Zhuravlev ? (это там, где t=K1*0xAB+0x2BCD,...) |
|
|
Дата: Авг 18, 2004 11:18:06 _Chingachguk_ Думаю, что имеется всего 32 бита. В донгле спаян генератор псевдослучайных чисел на сдвиговом регистре из 32-х JK- или D- триггеров с ксором по входу. Мультиплексор выбирает 1 бит из 32 согласно адресу b= ((b^0xC3)>>2) & 0x1F. Где-то еще ксорятся и само ПСЧ и адрес - всего 37 бит о чем писа Харм. Если се это х***ня, готов получить выговор. |
|
|
Дата: Авг 18, 2004 12:15:30 · Поправил: _Chingachguk_ wtch Непонятно, почему ты оставил только часть маскирования b: b= ((b^0xC3)>>2) & 0x1F если сначала делается: bl = ( ( ( Data[] and 18h ) shl 1 ) or ( Data[] and 7 ) ), и bl<<=1; Насчет регистра сдвига. Ты хочешь сказать, что на первом шаге инициализируется регистр: b31,b30,...b0 = B На каждом запросе бита он сдвигается: b31'=b30 xor b29 xor ... b0, B=(B>>1)|b31, При запросе бита из B выбирается по индексу (индекс вычисляется из переданного байта Data[index]) нужный бит ? Тогда это можно эмулировать с помощью 39-и 32-х битных таблиц, ведь B пребывает в 39-и состояниях. Но у меня так не получается, по крайней мере на парах HASP_DECODE_DATA из того алгоритма, который первым отрабатывает в 3d: .data TestBytes db 0DBh,0FEh,01Eh,06Bh,0E4h,01Bh,0DBh,0B0h .data? Count dd ? .code mov dword ptr Count,0 mov esi,offset TestBytes @@Decrypt1: mov edi,[esi] mov edx,edi xor edx,05B2C004Ah mov ecx,dword ptr Count mov eax,0FFFFFFF9h sub eax,ecx and eax,1Fh mov ecx,20h mov ebx,edx sub ecx,eax shr ebx,cl mov ecx,eax mov eax,[esi+4] shl edx,cl mov [esi+4],edi or ebx,edx xor ebx,eax mov [esi],ebx add dword ptr Count,5 cmp dword ptr Count,1Eh jb @@Decrypt1 .data? Tmp dd ? .code mov esi,offset TestBytes mov eax,[esi] mov dword ptr [esi],eax xor HASP_DECODE_DATA mov [esi+4],eax ;; mov eax,ds:[0] xor edi,edi @@Decrypt2: mov edx,[esi] mov eax,0Ah sub eax,edi mov Tmp,edx and eax,1Fh xor edx,803425C3h mov ecx,20h mov ebx,edx sub ecx,eax add edi,2 shr ebx,cl mov ecx,eax shl edx,cl mov ecx,Tmp or ebx,edx mov edx,[esi+4] xor ebx,edx cmp edi,0Ch mov [esi],ebx mov [esi+4],ecx jb @@Decrypt2 ; Final mov esi,offset TestBytes mov eax,[esi] mov ebx,eax xor ebx,HASP_DECODE_DATA mov [esi],ebx mov [esi+4],eax |
|
|
Дата: Авг 18, 2004 12:34:06 · Поправил: wtch _Chingachguk_ Сам не понимаю почему... А как остальная идея? Возможно придется копать сорусы от Инферно и ЕДСтрукт, хотя возможно это неспортивно в ЕДСтрукт прсутствует 39 х 32 битная таблица По поводу регистров - первое, что нашел в сети - http://se.math.spbu.ru/Courses/Crypto/2001/lfsr.html |
|
|
Дата: Авг 18, 2004 12:47:56 wtch Какая остальная ? Твоя идея насчет регистра сдвига похожа на правду (я где-то в hardlock'е видел что-то похожее) - ты же это имел в виду ? Я могу проверить 64-х, и даже 128-ми битовые таблицы, данные есть - это означает, что регистр сдвига соответствующий... Пока ковыряю InitDongle для получения последовательностей in/out и выполнения transform "вживую" - так можно получить биты на каждом шаге. Кстати, в аттаче прилагаю код, которым я ищу варианты 39-ти битовых последовательностей для каждой пары. Соурсы Infern0 мне дали, но я не буду его ковырять. Я только убедился в том, что до transform2 все аналогично, те основная идея верная. У них transform2 сцеплен с собственным алгоритмом шифровки. Какой смысл его вскрывать, если HarmEr вскрыл ключ год назад ? Для меня интересно самому вычислить работу transform2... |
|
|
Дата: Авг 18, 2004 12:51:45 Аттач. В моем примере я имею два преобразования HASP_DECODE_DATA: dd 04fb3a179h -> 0c3f8ba22h dd 03abcd1bch -> 002735b06h По каждому из них я получил примерно по 2 пары битов из разных таблиц. _358694151__func3d_07.ASM |
|
|
Дата: Авг 18, 2004 13:00:06 ЕДСтрукт прсутствует 39 х 32 битная таблица Да, ты редактировал пост ? Теперь увидел. Я еще посмотрю свой код на предмет ошибок. Либо я беру не те пары. |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.055 |