Обзор некоторых защит на основе FLEXlm SDK — Архив WASM.RU
© Volodya"… ибо его оружие - мозг - не требовало особого
ухода, спецхранения и работало в любых условиях."
В. Головачев "Схрон"
Автор: VolodyaОбзор некоторых защит на основе FLEXlm SDK
Итак, я предполагаю, что читатель имеет твердое представление об ассемблере, неплохо владеет Си, прекрасно разбирается в том, как компилировать и линковать программы. Также, очевидно, необходимо уметь пользоваться Visual Studio.
Данная статья написана как довесок к моей основной статье о профилировщиках. Здесь рассказывается, как устранить некоторые проблемы инсталляции и работы программ , использующих для своего функционирования набор API-функций, предоставляемых пакетом FlexLm. Так уж получилось, что подавляющее большинство профилировщиков, средств покрытия кода (т.е. средств, показывающих, сколько веток if и других циклов выполняется при нормальном течении хода проги, это очень полезно, т.к. показывает, насколько ваша прога "готова" к нестандартным изменениям ситуации, как тщательно вы подготовились к неприятностям, т.к. если ветки, которые получают управление редко, небрежно написаны, то в результате можно получить ой-ой-ой!) и выявления утечек памяти используют именно FlexLm. Среди них – Intel Compiler/Vtune environment, все продукты семейства DevPartner от Numega, и все опробованные мной продукты от Rational.
Рассмотрим сперва Intel Compiler, единственный реальный конкурент MS cl.exe. Закачать его можно с ftp://download.intel.com/software/products/. Последняя версия на момент написания -W_CC_P_7.0.073.exe. «Вес» пакета – 74 Мб.
Итак, закачиваем и инсталлируем (помните, в обязательном порядке должно иметь место наличие присутствия Visual Studio 6/Net). При попытке инсталляции получаем что-то вроде FlexLm license error. Теперь мы и подобрались к сути проблемы.
Итак, FlexLm – это творчество компании GLOBEtrotter Software. Фиговина эта требует присутствия .lic файла (действие которого может быть ограниченным во времени), без которого работать не хочет ну никак. Компания, как это модно сейчас, выпускает FlexLm SDK, где имеются API-функции для работы с lic-файлом, которые надо втиснуть в исходный код, скомпилировать с соответствующими .h-файлами и слинковать с соответствующими библиотеками.
Только в качестве иллюстрации:
Код (Text):
#include "lmpolicy.h" //компиляция с нужным файлом оглавления LP_HANDLE *lp_handle; status = lp_checkout(LPCODE, policy, feature, version, num_lic, license_file_path, &lp_handle) //здесь зовем нужные функцииБиблиотеки для разных случаев используются разные. Скажем, для линковки мультипоточного варианта (multithread) будут использоваться одни библиотеки, если приложение представлено одним единственным процессом – другие. Ниже дан пример из FlexLm SDK версии 8.0:
FLEXlm
Object FileFLEXlm Client
LibrariesMSVC++
LibrariesStandard
lm_new.obj
lmgr.lib
libcmt.lib(/MT)
oldnames.lib
kernel32.lib
user32.lib
netapi32.lib
advapi32.lib
gdi32.lib
comdlg32.lib
comctl32.lib
wsock32.libAdd for
CROlibcrvs.lib
libsb.libAdd for
static
FLEXlockflock.lib
For /MD
Replace
lm_new.obj
with
lm_new_md.
objReplace Standard
lmgr.lib with
lmgr_md.libReplace Standard
libcmt.lib with
msvcrt.lib (/MD)For CRO
/MDAdd to Standard:
libcrvs_md.lib
libsb_md.libReplace Standard
libcmt.lib with
msvcrt.lib (/MD)
Видно, что здесь есть много интересного. Сразу появляется желание скачать этот самый SDK и маленько с ним разобраться. Ничего невозможного - http://linux20368.dn.net/crackz/Flexlm.htm, т.к. с родного сайта компании вы уже ничего не скачаете - доступ закрыт, однако.
Теперь о том, как это ломать. Варианта два – 1-й - разобраться с форматом .lic файла, подправить оригинальные API-функции, словом вдумчиво ковырять FlexLm SDK (это уже и было проделано и в сети есть много англоязычных статей на эту тему), 2-й – лично мне больше по душе – ковырять конкретное приложение, которое неумело использует функции FlexLm. Есть идиоты, которые вообще выносят эти API-функции в отдельную .dll, вместо статической линковки, и это несмотря на предупреждения, красным по белому:
Caution: Use of the FLEXlm DLL on Windows remains strongly discouraged
А ведь если функции вынесены в dll, то кракеру поймать их ничего не стоит. Пример не за горами.
Итак, теперь к делу.
Выкачиваем компилятор. Пробуем запустить – ругается, нужен lic-файл. Его, ессно, нет. Начинаем копать. Существует достаточно много подходов ко взлому конкретного приложения. Кто к каким привык. Стандартом, как правило, считается постановка bpx на что-нибудь вроде MessageBoxExW или DialogBoxIndirectParamA, затем исследуется дизассемблированный код ВЫШЕ точки «всплыва» отладчика и определяется, какой из условных переходов, привел к таким ругательствам со стороны проги.
MessageBoxExW
Для постановки точки останова следует всегда выбирать MessageBoxExW вместо MessageBoxA или тому подобных. Дизассемблируйте user32.dll и увидите, что MessageBoxA, W, ExA являются просто переходниками к ExW. Такое имеет место быть только в чисто юникодовских системах, таких как Windows NT, 2000, XP. К 95/98 это не относится, а если что-то такое и имеет место быть, то с точностью до наоборот. Данное правило подходит не только к MessageBox, оно соблюдается и для многих других WinAPI функций – ASCII-варианты являются просто переходниками к юникодовским
Еще один вариант – это прогонять программу под каким-нибудь API-монитором, вроде BoundsChecker от NuMega. Реальных конкурентов у него нет, одни слишком медленные и тупые, вторые, может и быстрые, но для хакера совершенно непригодны. На этом этапе, если приложение использует какие-то API-функции из определенного рода библиотек (например, flexlm-библиотек ), то это все станет очевидным.
Можно даже и не пользоваться API-монитором, т.е. динамическим анализом программы. Вполне хватит и статического, если не используется явное связывание (explicit linking). Для статического анализа лучше всего использовать dumbin или dependency walker. Оба от MS.
Explicit linking
Динамическую библиотеку можно вызывать двумя способами – явным и неявным связыванием. Неявное связывание – наиболее широко используемый способ. Здесь с самого начала компилятору строго говорится, что вот так-то и так-то, вот это вот считать dll и поступать с ней вот так, а не иначе. Явное связывание – это явная задача в исходном коде инструкций вида LoadLibraryA для загрузки конкретной библиотеки (например, kernel32.dll), а потом GetProcAddress для возвращения адреса конкретной функции (например, IsDebuggerPresent ), а потом что-то вроде call [адрес, возвращенный GetProcAddress]. Ясно, что неявное связывание оставляет следы в таблице импорта, которые легко обнаружить, например, dumpbin. Явное связывание в таблице импорта не отображается. Подробнее – Джеффери Рихтер «Windows для профессионалов»
Очевидно, что любой из видов анализа рано или поздно приведет вас к анализу дизассемблированного кода. Лучше всего использовать IDA. Аналогов ей нет все равно. Вообще, я лично с презрением отношусь ко всяким заявлениям типа «следует юзать только HIEW, потому что настоящие кульные хацкеры юзают только HIEW и ничего больше». Надо уметь пользоваться всем, что под руку попадается.
Так вот, не важно, какой из вышеперечисленных методов используется, так или иначе, мы с вами вышли на файл ChkLic.dll, который экспортирует одну, ну жутко интересную функцию - _CheckValidLicense. Дальше выбора два – либо делать патч непосредственно в dll, либо в зовущем файле – setup.exe. Код выглядит так:
Код (Text):
Setup.exe - 40,960 bytes _text:0040175D loc_0_40175D: ; CODE XREF: _WinMain@16+744j ; явное связывание в наглядном варианте. В таблице импорта setup.exe следов вызова ; функции не будет, однако рапорт BoundsChecker покажет, что имел место вызов .dll и ; вызывалась соответствующая функция _text:0040175D push offset aChklic_dll ; lpLibFileName _text:00401762 call ds:LoadLibraryA _text:00401768 mov esi, eax _text:0040176A push offset a_checkvalidlicense ; lpProcName _text:0040176F push esi ; hModule _text:00401770 call ds:GetProcAddress _text:00401776 cmp esi, ebx _text:00401778 jz loc_0_40192E _text:0040177E cmp eax, ebx _text:00401780 jz loc_0_40192E _text:00401786 push ebx _text:00401787 call eax ; _CheckValidLicense _text:00401789 test eax, eax <STRONG>_text:0040178B jnz loc_0_4019A3 ;заменить на jz</STRONG>Можно считать, что с первой линией обороны мы справились. Заметьте, что защита flexlm пакету не помогла вообще, мы даже и не узнали, есть ли она там. Авторам надо было хоть немного читать то, что написано в SDK. А ведь ситуация могла бы и изменится, если бы использовалась статическая линковка. Но на каждую хитрую жопу есть хрен с винтом. Выход очень прост. Далее, в файлах icl.exe (интеловский компилятор для IA-32) и ecl.exe (IA-64 вариант) уже никакие dll не используются, и, все равно, это ничем не помогло разработчикам. Здесь можно работать по следующей методике. Сперва нам надо узнать, какая версия flexlm используется, использовать технологию IDA FLAIR, исследовать код вблизи мест проверки lic-файла и взломать прогу.
IDA FLAIR
Ильфак Гюильфанов написал замечательную статью о том как в IDA реализован механизм определения библиотечных функций – «Как IDA распознает стандартные функции?». Статью можно найти на pilorama.com.ru, повторяться не хочу.
Для определения версии flexlm можно использовать любой текстовый фильтр, либо тот, который найдет требуемое слово в бинарнике (Search and Replace – kickme.to/FOSI), либо тот, который вывалит все текстовые строки бинарника (мой собственный, например – wasm.ru – filter, "исходники").
Так или иначе:
Код (Text):
24/12/2002 5:33:52 PM Search String: flexlm Replace String: Path: C:\Downloads\comp\ File Mask: *.* Processing file : C:\Downloads\comp\chklic.exe Offset 0x680dd - $Id: <FONT COLOR= "#ff0000">flexlm.</FONT>c,v 1.10.2.1 2002/10/18 20:06:49 mtoguchi Exp $ Offset 0x6e781 - yyyyyyyyyyyy@(#) <STRONG>FLEXlm v7.2i (liblmgr.a)</STRONG>, Copyright (C) 1988-2001 Globetrotter Software, Inc.Верхняя строчка оставлена для хохмы, это вообще одуреть. Строки отчета cvs попали в бинарник! Это ж какое качество компилятора! Ладно, зато теперь нам точно известно, какая версия использовалась. Это дает возможность использовать средства FLAIR для получения файла сигнатур, который поможет элементарно найти нужные строки кода в дизассемблированном листинге. Ниже приведен пример создания файла сигнатур для FlexLM SDK 8.0.
Код (Text):
E:\flexlm\v8.0\i86_n3>pcf lmgr.lib lmgr lmgr.lib: skipped 0, total 142 E:\flexlm\v8.0\i86_n3>pcf lmgr_md.lib lmgr_md lmgr_md.lib: skipped 0, total 142 E:\flexlm\v8.0\i86_n3>sigmake -n"FlexLm Win32 v8.0 Standard&Multi-thread" lmgr.pat+lmgr_md.pat lmgr.sigВ первой строке запускается парсер для lib-файлов coff-формата (elf-формат идет под Linux). В результате имеем pat-файл. В данном случае запускаем парсер второй раз для получения мультипоточного варианта библиотеки. Потом используется утилита sigmake для объединения полученных pat-файлов в один sig-файл, ключ –n дает файлу название, под которым его видит конечный пользователь. Процесс опознавания библиотечных функций не безупречен, часто появляется файл коллизий. Опять таки, отсылаю к статье Ильфака. Файл коллизий редактируется очень просто. В этом файле представлены функции, которые имеют сходные CRC. Теперь уже нам с вами нужно решать, что с ними делать (ставить "-" для появления имени функции в виде комментария, "+" для обычного вида, не ставить ничего для полного исключения функции из файла сигнатур). Я предпочитаю включать ту, что выполняет более общее действие. Пример:
Код (Text):
+_l_swap 58 734E 558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6 _swap 58 734E 558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6Здесь поставлен знак «+» перед функцией _l_swap, так как думается мне, что эта функция более напоминает при анализе бинарника функцию flexlm SDK. Аналогично расставляются знаки и для других пар (или большего количества) функций, вызвавших коллизии.
После редактирования .exc файла просто повторите:
Код (Text):
E:\flexlm\v8.0\i86_n3>sigmake -n"FlexLm Win32 v8.0 Standard&Multi-thread" lmgr.pat+lmgr_md.pat lmgr.sig
Утилита сама поймет, что делать с файлом коллизий на этот раз. В завершение процесса нужно сжать файл сигнатур утилитой zipsig и поместить его в директорию /sig папки IDA.
Дизассемблируем файл icl.exe и ecl.exe. Применяем полученный файл сигнатур (я приложил sig-файлы для FlexLM SDK v6.0/7.2i/8.0). У меня было опознано свыше девятисот(!) библиотечных функций. Теперь мы сравнительно легко придем к нужному результату:
Код (Text):
icl.exe - 684,032 bytes _text:0040105A loc_0_40105A: ; CODE XREF: _main+350j _text:0040105A mov eax, dword_0_488B24 _text:0040105F call sub_0_4083F4 _text:00401064 mov eax, offset aFfrpsz ; "FFrpsZ" _text:00401069 mov edx, 21h ; легко можно увидеть, что эта функция "скатывается" к FlexLMMainCheck ; думаю, название снимает все вопросы <STRONG>_text:0040106E call sub_0_404C0E ;mov eax,0</STRONG> _text:00401073 test eax, eax _text:00401075 jnz short loc_0_40107F ecl.exe - 692,224 bytes _text:0040305A loc_0_40305A: ; CODE XREF: _main+350j _text:0040305A mov eax, dword_0_48AB44 _text:0040305F call sub_0_40BD51 _text:00403064 mov eax, offset aFfrpsz ; "FFrpsZ" _text:00403069 mov edx, 21h <STRONG>_text:0040306E call sub_0_40837E ;mov eax,0</STRONG> _text:00403073 test eax, eax _text:00403075 jnz short loc_0_40307FТеперь у нас есть компилятор. Самое время взломать профилировщик.
Используя методы, описанные выше, мы легко сможем обнаружить, что ругательство при запуске VTune выдает AnProdInfo.dll, опираясь на ресурсы из AnProdInfoRes.dll. Дополнительно, чтобы облегчить себе жизнь, нужно использовать команду Soft-Ice – stack – она покажет последовательность вызовов функций и мы сможем вычислить искомую.
STACK – проход стека, FPO и т.п.
Кадр стека (т.е. адресация по ebp либо инструкции enter/leave) - великая вещь, своим появлением он обязан относительно "скудным" возможностям адресации процессоров до 386-го (тогда с адресацией было туговато, не всякий регистр подходил), где в качестве индексного регистра разрешалось использовать только si,di,bx,bp. Теперь в качестве индексного можно использовать любой 32-разрядный регистр, например esp. Тогда кадр стека становится ненужным (т.к. используется адресация переменных по esp ± xxh - такой подход называется frame pointer omission (FPO)), а это есть хорошо для прикладных программистов и не есть хорошо для нас с Вами, т.к. при esp-подходе теряется большая часть символьной информации (например, команда S-Ice stack становится бесполезной, если в функции отсутствует кадр стека). Если разработчик программы - лопух и забыл убрать отладочную информацию, то мы сможем выловить с помощью dumpbin /FPO информацию о количестве переданных параметров и т.п.
Пример: с помощью Search&Replace я задал искать слово .debug (есть иногда такая секция в PE-файле) в директории Windows\system. Нашлось файлов 5. Вот часть дампа со случайно взятого файла:
Код (Text):
dumpbin.exe /FPO sh30w32.dll >fpo.txt Dump of file sh30w32.dll File Type: DLL FPO Data (222) Use Has Frame RVA Proc Size Locals Regs Prolog BP SEH Type Params 00001000 96 0 2 2 N N fpo 4 _MemPoolShrink@4 00001060 144 8 4 21 Y N fpo 0Уже сейчас мы можем выяснить размер процедуры, количество переданных параметров, количество локальных переменных и т.п. Если Вы не очень уютно себя чувствуете с кадром стека - почитайте Рэндалла Хайда и проиграйтесь с отладчиком - многое прояснится. Может (и справедливо!) возникнуть еще один вопрос: "Хорошо, я знаю адрес процедуры, количество параметров и прочую ерунду. А КАК мне сделать, чтобы это узнал и Soft-Ice?" Ответ см. ниже - он есть, а пока методику поняли? Ищем секцию отладки в PE-файле (F8,F6 в HIEW) - если есть, она будет называться как-нибудь вроде .debug. Далее извлекаем ее (см. ниже), переводим в понятный S-Ice'у формат (см. ниже ) и работаем дальше.
Результат:
Код (Text):
W_VT_P_61_0011.EXE - закачать с intel.com, размер - свыше 100 мб. AnProdInfo.dll <STRONG>.text:602341C0 call sub_60232466 ->xor eax,eax</STRONG> .text:602341C5 xor ebx, ebx .text:602341C7 add esp, 0Ch .text:602341CA cmp eax, ebx .text:602341CC mov [esi], eax .text:602341CE jz loc_6023429D .text:602341D4 mov [ebp+0Ch], ebx .text:602341D7 cmp eax, 0FFFFFFEBh .text:602341DA mov [ebp-4], ebx .text:602341DD jz short loc_602341F2 .text:602341DF cmp eax, 0FFFFFFF6h .text:602341E2 jz short loc_602341EB .text:602341E4 push 0D1h .text:602341E9 jmp short loc_602341F7«Однако за время пути собака могла подрасти». Пока писалась эта статья, я совершенно случайно накопал еще один update от Intel на тему Vtune –
ftp://download.intel.com/software/products/vtune/downloads/.
Что он делает, в двух словах и не рассказать. В своей статье о профилировщиках я его не описываю тоже, отчасти потому, что работать с ним страшновато. Это надстройка над JavaMachine, да еще к ней прибабахан MySQL-сервер. Для чего все это нужно, мне сказать сложновато. Естественно, все это дело тормозит жутко, а потому вдумчиво его ковырять на предмет радостных сообщений защиты мне было недосуг.
Поэтому здесь я скорее предпочту описать методики, как можно поймать интересующий код, чем давать готовые решения, хотя парочка решений, конечно же, будет.
Итак, немного поиграв с пакетом, имеем стандартный MessageBox со стандартными фразами. Что здесь можно сделать?
Вещь первая. Если строки сообщения защиты находятся в ресурсах PE-файла, то надо воспользоваться редактором ресурсов (например, Restorator 2.52 – wasm.ru), чтобы узнать их порядковый номер. Пример:
Код (Text):
123 The GUI license for VTune(TM) Enterprise Analyzer for Web Applications is invalid. Please contact technical support.Здесь, "123" – это произвольный (т.е. разработчик брал от фонаря) порядковый номер ресурса, который в дальнейшем будет использован функцией LoadString. Номер этот будет передан функции через стек (таков закон ). Т.е. будет использоваться инструкция push + шестнадцатеричное представление "123" (0x7B). Такой шаблон легко найти в HIEW – в режиме ассемблерного поиска надо ввести push ?7B (отметьте знак вопроса – он означает, что перед 7В может идти что угодно). Чаще всего, вхождений будет несколько, однако что стоит найти правильное?
Код (Text):
<STRONG>.text:10024387 push 7Bh ; uID</STRONG> .text:10024389 mov [esp+4Ch+var_4], esi .text:1002438D mov ecx, [eax+8] .text:10024390 push ecx ; hInstance .text:10024391 lea ecx, [esp+50h+var_34] .text:10024395 call sub_10010A10 ;к LoadStringА дальше, опять таки нужно воспользоваться командой stack в Soft-Ice, чтобы понять, какая последовательность вызовов функций привела к столь плачевному результату.
Вещь вторая. Коль уж вхождение найдено, часто оказывается необходимым ставить bpx не на MessageBox и ему подобные, а на конкретные адреса. Т.к. VTune – продукт, содержащий множество .dll, это автоматически означает, что будет производится перерасчет адресов загрузки .dll (подробнее – моя статья о профилировщиках или многочисленные статьи Мэтта Питрека и Джона Робинса в сети). А это, в свою очередь, означает, что адреса, которые мы увидим в IDA/WDasm/HIEW и т.п. НЕ будут соответствовать адресам в памяти, а предсказать адрес, по которому dll будет загружена, достаточно сложно, т.к. точно не известен порядок, в котором приложение загружает эти dll. Однако выход здесь прост. Старый кракерский трюк с int 3. int 3 имеет опкод 0CCh. Влепите этот опкод в требуемое место программы (не забыв выровнять количество байт и выписать эти самые байты, потому что потом их придется восстанавливать в Soft-Ice). Теперь для того, чтобы Sof-Ice отловил этот опкод, надо активировать опцию i3here on.
i3here on
Soft-Ice является отладчиком класса last-chance notification. Это означает, что он предоставляет отладчикам класса first-chance notification (таким, как отладчик VisualStudio) шанс обработать исключительную ситуацию, перед тем как брать бразды правления в свои руки. Что такое "последнее предупреждение" и "первое предупреждение" в двух словах не рассказать, это связано с реализацией SEH (structured exception handling) в Windows и знакомо специалистам по C++ как блоки try/catch. Да, кстати, почитайте в документации к Soft-Ice, что такое опция faults off. Она во многом определяет поведение Soft-Ice во время исключительных ситуаций. Есть также неплохая книжка Джеффери Рихтера – “Windows для профессионалов”. Там тоже очень неплохо рассказывается об исключениях. Интересующихся низкоуровневой организацией SEH в Windows (на уровне внутренних структур данных) отсылаю к статьям Мэтта Питрека.
После срабатывания точки останова и «всплыва» Soft-Ice необходимо поправить EIP (r eip = требуемое значение) так, чтобы он показывал ПРЯМО на int 3, а не на инструкцию ПОСЛЕ нее (там, где, собственно, и произошел всплыв). После того как поправили EIP, с помощью инструкции "a" или "e" поправьте байты по тому адресу (на те самые, которые выписывали, помните?).
Рано или поздно, исследуя внутренности VTune Enterprise можно наткнуться на функцию ?IsJavaEnabled@CTahoeLicenseMgr@@QAE_NXZ. Это одна из функций защиты приложения. Функция экспортируется библиотекой VTEGUIShared.dll и "спускается" к
Код (Text):
?IsFeatureEnabled@CTahoeLicenseMgr@@QAE_NW4SPFeatureEnum@@@Z .text:1002D780 mov eax, [ecx+4] .text:1002D783 mov ecx, [esp+arg_0] .text:1002D787 and eax, ecx ; Очень изящный и приятный код. Это пример хорошей оптимизации. Смотрите, вообще нет ; условных переходов, которые для современных CPU не представляют собой ничего хорошего. ; Вместо этого используется инструкция вычитания с заемом - более подробно см. статьи ; Касперски. А здесь, недолго мороча голову: <STRONG>.text:1002D789 neg eax --> mov eax,1; nop</STRONG> .text:1002D78B sbb eax, eax .text:1002D78D neg eax .text:1002D78F retn 4Вроде все методики расписаны. Единственная вещь, которая может вызвать легкое смущение – это странный вид имени импортируемой функции. Это – наглядный пример искажения ("замангления") имен.
Искажение имен (mangling)
Также иногда встречается термин "украшение".
Искажение имен применяется компилятором для разрешения своих внутренних конфликтов. Часто сложно отличить имена функций друг от друга. Проблема становится особенно актуальной в ООП-языков программирования, где становится возможной перегрузка функций (когда функции имеют одинаковое название, но выполняют более-менее разные действия) и даже операторов. Вот компилятор и изворачивается. Каждый компилятор (даже одного и того же языка) имеет собственную схему искажения имен. Схема искажения имен компилятора Borland сравнительно неплохо описана П.В. Румянцевым в своей "Работа с файлами в Win32". Схема искажения имен компилятора от MS, насколько я знаю, нигде особо не описывалась (хотя, может, стоит статьи Питрека поглядеть?) Однако есть утилита undname.exe, входящая в состав VisualStudio. Вся эта утилита, позволяющая, как и IDA, "разманглять" символьные имена, является переходником к функции UnDecorateSymbolName из imagehlp.dll. Функция вполне документирована, однако, представляет собой всего лишь переходник к уже недокументированной функции __unDName из msvcrt.dll. Советую изучить код функции, если вас интересует проблема искажения имен.
Теперь можно поговорить о взломе продуктов компании Rational Software (www.rational.com). Это ближайшие конкуренты фирмы NuMega, однако продукты их подходят только для программиста, а не для хакера. Но ведь и мы с вами не только тем занимаемся, что программы ломаем?
Основной пакет – PurifyPlus. Состоит из Purify/Quantify/PureCoverage. Все они тесно интегрируются с VS.NET. Purify – средство выявления утечек памяти и других мелких гадостей, Quantify – весьма неплохой профилировщик, PureCoverage – средство покрытия кода. Всем этим программам есть аналоги от NuMega (TrueTime, TrueCoverage и т.п.), однако в последнее время нужный инструмент от NuMegaне всегда легко найти. С сайта скачать невозможно ничего (в отличие от rational.com, пока!), в сети выловить тоже тяжеловато.
PurifyPlus активно использует flexlm (на момент написания статьи – версия 7.0f), о чем сам и говорит. Взломать эту защиту не составляет никакой сложности. Нетрудно установить, что ругательство ведется из rscommonui.dll. Вообще забавно наблюдать, как все FlexAPI-функции засовываются в одну-единственную на всю программу несчастную функцию, да еще и возвращающую результат типа bool. А потом еще говорят, что flex криво написан. Он-то, может, и криво написан, но используют его еще кривее! Что ж стоит подделать ответ функции, поменять нолик на единичку или наоборот? Да ничего! И никаких больше проверок! А ведь метод, который я предлагаю здесь, неверен в принципе! Здесь мы боремся со следствием, а причина (.lic-файл) остается нетронутой. А борьба со следствием чревата тем, что всегда есть риск проворонить где-нибудь какой-нибудь подлый call и получить уже полные старания фантазии разработчика, вплоть до самоуничтожения программы. Однако сейчас код код пишется настолько неаккуратно, что многие защиты можно взломать, не прилагая особых умственных усилий. В самом деле, все чаще встречаются программы, использующие для защиты либо примитивнейшие самопальные алгоритмы, возвращающие 1 или 0 в результате, либо использующие пакеры/криптовщики, но это уже совсем другая песня…
Патч:
Код (Text):
RationalPurify.2002.05.20.468.000.exe purifyw.exe - 3,240,020 bytes _text:00407F33 loc_0_407F33: ; CODE XREF: sub_0_407F20+Aj _text:00407F33 call sub_0_4E2060 _text:00407F38 call sub_0_5DBD5F _text:00407F3D test eax, eax _text:00407F3F jz short loc_0_407F68 _text:00407F41 call sub_0_4E26C0 _text:00407F46 test eax, eax _text:00407F48 jz short loc_0_407F55 <STRONG>_text:00407F4A call sub_0_4E20F0 ; funny proc - mov eax,1</STRONG> _text:00407F4F test eax, eax _text:00407F51 jnz short loc_0_407F68 _text:00407F53 pop esi _text:00407F54 retn RationalQuantify.2002.05.20.468.000.exe quantifyw.exe - 2,621,528 bytes _text:00428C23 loc_0_428C23: ; CODE XREF: sub_0_428C10+Aj _text:00428C23 call sub_0_491130 _text:00428C28 call sub_0_56E8EF _text:00428C2D test eax, eax _text:00428C2F jz short loc_0_428C58 _text:00428C31 call sub_0_4917D0 _text:00428C36 test eax, eax _text:00428C38 jz short loc_0_428C45 <STRONG>_text:00428C3A call sub_0_4911C0 ; funny proc - mov eax,1</STRONG> _text:00428C3F test eax, eax _text:00428C41 jnz short loc_0_428C58 _text:00428C43 pop esi _text:00428C44 retn RationalPureCoverage.2002.05.20.468.000.exe coveragew.exe - 2,527,320 bytes _text:00405773 loc_0_405773: ; CODE XREF: sub_0_405760+Aj _text:00405773 call sub_0_489800 _text:00405778 call sub_0_559E7F _text:0040577D test eax, eax _text:0040577F jz short loc_0_4057A8 _text:00405781 call sub_0_489EA0 _text:00405786 test eax, eax _text:00405788 jz short loc_0_405795 <STRONG>_text:0040578A call sub_0_489890 ; funny proc - mov eax,1</STRONG> _text:0040578F test eax, eax _text:00405791 jnz short loc_0_4057A8 _text:00405793 pop esi _text:00405794 retnВот, собственно, и все о защите FlexLm. То есть, о защите писать еще можно долго и нудно, однако о крайне бездарном ее применении в приложениях, я думаю, вы уже имеете весьма неплохое представление. За сим разрешите откланяться.
Volodya
wasm team.
P.S. Автор выражает искреннею благодарность всем членам wasm team за пинки по делу и вылавливание мелких и крупных блох. Персональное спасибо alexela и cybermaniac.
Обзор некоторых защит на основе FLEXlm SDK
Дата публикации 30 янв 2003