allasm.ru |
|
Это первая часть последней главы из цикла о SentinelLM, но уже после её прочтения вы должны быть в состоянии "зарегистрировать" и/или отучить от заглушки в порту (aka донгл) некоторые простенькие программы, продавшие душу Rainbow Tech. Итак, на данный момент имеем установленный SentinelLM SDK 7.1, эксклюзивно настроенный на наш таргет, т.е. в нём жёстко прописан VId нашей жертвы. Для того, чтобы изменить этот VId можно просто переустановить SDK или найти и пропатчить эти значения в бинарниках, что вовсе не тривиально. После нескольких неудачных попыток поменять VId, я решил всегда переустанавливать SDK и вам советую так поступать. Пока я усердно работал над этой главой, вы уже прочитали объёмные PDF'ы из документации и узнали, что генератор лицензий SLM (он же WlscGen.exe) так просто нас не наградит халявными лицензиями для нашей жертвы. Оказывается, что он сам защищён SLM и требует наличия донгла! Смешно и обидно... Но не отчаивайтесь -- сегодняшний практикум многому вас научит и поможет устранить защиту SLM даже в патологически сложных случаях, в которых кроме ратификации лицензионного файла программа активно использует EEPROM-память донгла. У меня даже есть готовый патч для "исправления" WlscGen, но я настаиваю на необходимости хотя бы один раз поработать над этим вручную. Чем не ритуал посвящения в Sentinel? :-) Кроме двух PDF'ов, входящих в комплект поставки SDK, вам нужно прочитать ещё один ОЧЕНЬ важный документ: "SentinelSuperPro 6.0 Developers Guide" (6,4 Мб), который можно скачать на сайте www.rainbow.com. Документ посвящён API Sentinel SuperPro, с помощью которой SLM "общается" с донглами семейства SuperPro. Особого внимания заслуживает глава 14: "API Function Reference". Перед штурмом WlscGen, хочу добавить пару слов о принципе работы этой программы (особенно для тех лентяев, которые -- как и я в своё время -- не прочитали документацию ;-) Маркетинговая политика радужной компании основана вовсе не на продаже CD с SentinelLM SDK в красивых упаковках. Эти капиталисты взимают дань со своих клиентов за КАЖДУЮ выпущенную лицензию. Справедливости ради стоит заметить, что многие другие компании тоже так поступают... В общем, вместе с SDK компания выдаёт (вроде, первый раз бесплатно) своеобразный электронный счётчик, который автодекрементируется при каждом употреблении. При создании постоянных лицензий для одного PC, счётчик уменьшается на определённое количество единиц; при выпуске корпоративных лицензий для нескольких PC -- теряется соответственно большее количество единиц. Всё зависит от типа лицензии, срока годности и т.д. Эти единицы теряются безвозвратно, даже если пользователь по ошибке создаст бракованную лицензию. При полном истощении счётчика, приходится идти к Rainbow и покупать новый. Вам это не напоминает картриджи для принтеров HP? Так вот, счётчик этот реализован в виде нескольких ячеек памяти в ранее упомянутом донгле и WlscGen "видит" эти ячейки через API, которая общается с донглом через драйвер. На следующем изображении упрощённо показана зависимость WlscGen от донгла.
На большее у нас с Paint'ом не хватило воображения :-) Обратите внимание на ячейку "Vendor Id" (или "Developer Id") -- это тот самый VId!!! Таким образом, каждый лицензионный донгл "привязан" к своему хозяину и отказывается работать на "чужих" владельцев. Так, по крайней мере, считают в Rainbow. Ячейка "Уникальный S/N" -- это вовсе не то, о чём вы сразу подумали. Нам данный S/N абсолютно безразличен (не путать с серийником для SDK). Область "N/A" не доступна приложениям и, в основном, представляет собой зарезервированные ячейки. В области "Произвольные данные" находится, например, вышеупомянутый счётчик. SLM API в данном случае реализована статически, т.е. нужные функции внедрены в WlscGen.exe. Наличие lsapiw32.dll не должно сбивать вас с толку. Наша задача -- пропатчить генератор лицензий, вернее пропатчить SLM API для того, чтобы генератор "видел" несуществующий донгл и признавал его своим. Потом мы "заполним" счётчик и получим неистощимый запас лицензий на зависть всем клиентам Rainbow! Единственный известный мне рабочий метод взлома WlscGen -- это метод описанный в статье CyberHeg "Removing need for dongle in Sentinel LM Wlscgen". Вообще, SentinelLM!WlscGen_CRK_1 можно считать частичным переводом статьи CyberHeg. Итак, запускаем WlscGen.exe и убеждаемся в его неработоспособности без донгла. Я настоятельно рекомендую вам сделать паузу в чтении этой статьи и помедитировать над кодом программы как в IDA (не забудьте наложить сигнатуру статической SLM API), так и под софтайсом. Можете запомнить текст сообщения об ошибке и попытаться оттрассировать его под отладчиком. Попробуйте угадать какие функции из SLM API могут/должны вызываться для обнаружения донгла. Сдаётесь? Так быстро? Ладно... в IDA > Names ищем те самые функции из "SentinelSuperPro 6.0 Developer's Guide". При помощи дизассемблера, отладчика и хекс-редактора мы постепенно заставим некоторые из этих функций работать с несуществующим донглом :-) По мере необходимости мы будем заглядывать в SoftIce (как обычно, MAP > SYM > NMS и т.д.) RNBOsproFindFirstUnit(packet, VendorID) Первым делом ставим BPX на RNBOsproFindFirstUnit(), так-как эта функция предназначена для поиска донгла с заданным VId. Для большей уверенности можете поставить бряк сразу на все 16 функций из этой API. Наше предположение оказывается верным и SoftIce выскакивает на входе в RNBOsproFindFirstUnit(). Трассируем до RETN и получаем 3 в аккумуляторе (EAX = 3), что означает отсутствие донгла и объясняет сообщение об ошибке. Не теряя времени, идём в IDA и правим это безобразие: 00435B00 _RNBOsproFindFirstUnit@8 proc near При успешном выполнении RNBOsproFindFirstUnit возвращает SP_SUCCESS, т.е. ноль. Блиц-патч: 00435B00 _RNBOsproFindFirstUnit@8 proc near Элементарно, не правда ли? Вместо исправления кода внутри функции RNBOsproFindFirstUnit можно поправить условные переходы после каждого её вызова, но гораздо проще и быстрее поступить вышеописанным образом. По ходу дела, не забывайте осуществлять изменения в самом файле WlscGen.exe при помощи HIEW, WinHex или подобной утилиты. RNBOsproRead(packet, address, *data)После успешного "обнаружения" донгла с помощью RNBOsproFindFirstUnit, WlscGen пытается прочитать 16-битные ячейки донгловой памяти через RNBOsproRead. Второй параметр функции задаёт относительное местоположение запрашиваемой ячейки. Полученное значение возвращается через указатель в третьем параметре. Так-как данная функция возвращает принципиально различные значения через указатель, нам её так просто не пропатчить. Опираясь на статьи Goatass и CrackZ, CyberHeg предложил внедрить в конец RNBOsproRead массив из 128 байт для эмуляции памяти донгла. Естественно, код самой функции нужно исправить и заменить вызов драйвера донгла на чтение локального, так сказать, массива. "Правильные" значения ячеек в данном массиве определяются путём долгих мучений с отладчиком. В большинстве случаев, WlscGen проверяет значение считанной ячейки вскоре после возврата из RNBOsproRead и вы можете его перехватить и добавить в массив. Правда, иногда проверка значений происходит иным, менее элементарным образом. Далее представлен исправленный вариант RNBOsproRead: 00435CD0 _RNBOsproRead@12 proc near Обратите внимание на 4 ячейки с 0FFFFh и одну с 0700h. Эти значения были получены путём трассирования каждого вызова RNBOsproRead. Если снова запустить WlscGen, программа должна заметно тормознуть (!) и показать окно с приглашением "Please Login". Эта задержка при запуске служит явным признаком того, что нам ещё рано праздновать. Действительно, пора заняться RNBOsproQuery, RNBOsproFindNextUnit и RNBOsproDecrement. Хотя, стоп!!! Я по себе чувствую, что вы подустали :-) Поэтому оставим эти три API для следующей главы. Я вам даже больше скажу: с RNBOsproFindNextUnit и RNBOsproDecrement вы должны быть в состоянии разобраться сами! Это будет своеобразным домашним заданием :-) Отдыхайте. [C] Quantum |