"… ибо его оружие - мозг - не требовало особого
ухода, спецхранения и работало в любых условиях."
В. Головачев "Схрон"
Автор: Volodya
Итак, я предполагаю, что читатель имеет твердое представление об ассемблере, неплохо владеет Си, прекрасно разбирается в том, как компилировать и линковать программы. Также, очевидно, необходимо уметь пользоваться 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-файлами и слинковать с соответствующими библиотеками.
Только в качестве иллюстрации:
#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 |
FLEXlm Client |
MSVC++ |
|
Standard |
lm_new.obj |
lmgr.lib |
libcmt.lib(/MT) |
|
Add for |
libcrvs.lib |
||
|
Add for |
flock.lib |
||
|
For /MD |
Replace |
Replace Standard |
Replace Standard |
|
For CRO |
Add to Standard: |
Replace Standard |
Видно, что здесь есть много интересного. Сразу появляется желание скачать этот самый 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. Код выглядит так:
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
_text:0040178B jnz loc_0_4019A3 ;заменить на jz
Можно считать, что с первой линией обороны мы справились. Заметьте, что защита 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, "исходники").
Так или иначе:
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: flexlm.c,v 1.10.2.1 2002/10/18 20:06:49 mtoguchi Exp $
Offset 0x6e781 - yyyyyyyyyyyy@(#) FLEXlm v7.2i (liblmgr.a),
Copyright (C) 1988-2001 Globetrotter Software, Inc.
Верхняя строчка оставлена для хохмы, это вообще одуреть. Строки отчета cvs попали в бинарник! Это ж какое качество компилятора! Ладно, зато теперь нам точно известно, какая версия использовалась. Это дает возможность использовать средства FLAIR для получения файла сигнатур, который поможет элементарно найти нужные строки кода в дизассемблированном листинге. Ниже приведен пример создания файла сигнатур для FlexLM SDK 8.0.
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. Теперь уже нам с вами нужно решать, что с ними делать (ставить "-" для появления имени функции в виде комментария, "+" для обычного вида, не ставить ничего для полного исключения функции из файла сигнатур). Я предпочитаю включать ту, что выполняет более общее действие. Пример:
+_l_swap 58 734E
558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6
_swap 58 734E
558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6
Здесь поставлен знак «+» перед функцией _l_swap, так как думается мне, что эта функция более напоминает при анализе бинарника функцию flexlm SDK. Аналогично расставляются знаки и для других пар (или большего количества) функций, вызвавших коллизии.
После редактирования .exc файла просто повторите:
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). У меня было опознано свыше девятисот(!) библиотечных функций. Теперь мы сравнительно легко придем к нужному результату:
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
; думаю, название снимает все вопросы
_text:0040106E call sub_0_404C0E ;mov eax,0
_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
_text:0040306E call sub_0_40837E ;mov eax,0
_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. Вот часть дампа со случайно взятого файла:
Уже сейчас мы можем выяснить размер процедуры, количество переданных параметров, количество локальных переменных и т.п. Если Вы не очень уютно себя чувствуете с кадром стека - почитайте Рэндалла Хайда и проиграйтесь с отладчиком - многое прояснится. Может (и справедливо!) возникнуть еще один вопрос: "Хорошо, я знаю адрес процедуры, количество параметров и прочую ерунду. А КАК мне сделать, чтобы это узнал и Soft-Ice?" Ответ см. ниже - он есть, а пока методику поняли? Ищем секцию отладки в PE-файле (F8,F6 в HIEW) - если есть, она будет называться как-нибудь вроде .debug. Далее извлекаем ее (см. ниже), переводим в понятный S-Ice'у формат (см. ниже ) и работаем дальше. |
Результат:
W_VT_P_61_0011.EXE - закачать с intel.com, размер - свыше 100 мб.
AnProdInfo.dll
.text:602341C0 call sub_60232466 ->xor eax,eax
.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), чтобы узнать их порядковый номер. Пример:
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:10024387 push 7Bh ; uID
.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 и "спускается" к
?IsFeatureEnabled@CTahoeLicenseMgr@@QAE_NW4SPFeatureEnum@@@Z
.text:1002D780 mov eax, [ecx+4]
.text:1002D783 mov ecx, [esp+arg_0]
.text:1002D787 and eax, ecx
; Очень изящный и приятный код. Это пример хорошей оптимизации. Смотрите, вообще нет
; условных переходов, которые для современных CPU не представляют собой ничего хорошего.
; Вместо этого используется инструкция вычитания с заемом - более подробно см. статьи
; Касперски. А здесь, недолго мороча голову:
.text:1002D789 neg eax --> mov eax,1; nop
.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 в результате, либо использующие пакеры/криптовщики, но это уже совсем другая песня…
Патч:
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
_text:00407F4A call sub_0_4E20F0 ; funny proc - mov eax,1
_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
_text:00428C3A call sub_0_4911C0 ; funny proc - mov eax,1
_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
_text:0040578A call sub_0_489890 ; funny proc - mov eax,1
_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.
[C] Volodya