Обзор некоторых защит на основе FLEXlm SDK

Дата публикации 30 янв 2003

Обзор некоторых защит на основе FLEXlm SDK — Архив WASM.RU

"… ибо его оружие - мозг - не требовало особого
ухода, спецхранения и работало в любых условиях.
"
В. Головачев "Схрон"

Автор: 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):
  1.  
  2. #include "lmpolicy.h"    //компиляция с нужным файлом оглавления
  3.  
  4. LP_HANDLE *lp_handle;
  5.  
  6. status = lp_checkout(LPCODE, policy, feature, version, num_lic,  
  7.                            license_file_path, &lp_handle) //здесь зовем нужные функции
  8.  
  9.  

Библиотеки для разных случаев используются разные. Скажем, для линковки мультипоточного варианта (multithread) будут использоваться одни библиотеки, если приложение представлено одним единственным процессом – другие. Ниже дан пример из FlexLm SDK версии 8.0:



FLEXlm
Object File

FLEXlm Client
Libraries

MSVC++
Libraries

Standard

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.lib

Add for
CRO

libcrvs.lib
libsb.lib

Add for
static
FLEXlock

flock.lib

For /MD

Replace
lm_new.obj
with
lm_new_md.
obj

Replace Standard
lmgr.lib with
lmgr_md.lib

Replace Standard
libcmt.lib with
msvcrt.lib (/MD)

For CRO
/MD

Add to Standard:
libcrvs_md.lib
libsb_md.lib

Replace 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):
  1.  
  2. Setup.exe - 40,960 bytes
  3.  
  4. _text:0040175D loc_0_40175D:                           ; CODE XREF: _WinMain@16+744j
  5. ; явное связывание в наглядном варианте. В таблице импорта setup.exe следов вызова
  6. ; функции не будет, однако рапорт BoundsChecker покажет, что имел место вызов .dll и
  7. ; вызывалась соответствующая функция
  8. _text:0040175D                 push    offset aChklic_dll    ; lpLibFileName
  9. _text:00401762                 call    ds:LoadLibraryA
  10. _text:00401768                 mov     esi, eax
  11. _text:0040176A                 push    offset a_checkvalidlicense ; lpProcName
  12. _text:0040176F                 push    esi                ; hModule
  13. _text:00401770                 call    ds:GetProcAddress  
  14. _text:00401776                 cmp     esi, ebx
  15. _text:00401778                 jz      loc_0_40192E
  16. _text:0040177E                 cmp     eax, ebx
  17. _text:00401780                 jz      loc_0_40192E
  18. _text:00401786                 push    ebx
  19. _text:00401787                 call    eax  ; _CheckValidLicense
  20. _text:00401789                 test    eax, eax
  21. <STRONG>_text:0040178B                 jnz     loc_0_4019A3  ;заменить на jz</STRONG>
  22.  

Можно считать, что с первой линией обороны мы справились. Заметьте, что защита 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):
  1.  
  2. 24/12/2002 5:33:52 PM
  3. Search String: flexlm
  4. Replace String:
  5. Path: C:\Downloads\comp\
  6. File Mask: *.*
  7.  
  8. Processing file : C:\Downloads\comp\chklic.exe
  9.  
  10. Offset 0x680dd - $Id: <FONT COLOR=
  11. "#ff0000">flexlm.</FONT>c,v 1.10.2.1 2002/10/18 20:06:49 mtoguchi Exp $
  12. Offset 0x6e781 - yyyyyyyyyyyy@(#) <STRONG>FLEXlm v7.2i (liblmgr.a)</STRONG>,
  13. Copyright (C) 1988-2001 Globetrotter Software, Inc.
  14.  

Верхняя строчка оставлена для хохмы, это вообще одуреть. Строки отчета cvs попали в бинарник! Это ж какое качество компилятора! Ладно, зато теперь нам точно известно, какая версия использовалась. Это дает возможность использовать средства FLAIR для получения файла сигнатур, который поможет элементарно найти нужные строки кода в дизассемблированном листинге. Ниже приведен пример создания файла сигнатур для FlexLM SDK 8.0.

Код (Text):
  1.  
  2. E:\flexlm\v8.0\i86_n3&gt;pcf lmgr.lib lmgr
  3. lmgr.lib: skipped 0, total 142
  4.  
  5. E:\flexlm\v8.0\i86_n3&gt;pcf lmgr_md.lib lmgr_md
  6. lmgr_md.lib: skipped 0, total 142
  7.  
  8. E:\flexlm\v8.0\i86_n3&gt;sigmake -n&quot;FlexLm Win32 v8.0
  9. Standard&amp;Multi-thread&quot; lmgr.pat+lmgr_md.pat lmgr.sig
  10.  

В первой строке запускается парсер для lib-файлов coff-формата (elf-формат идет под Linux). В результате имеем pat-файл. В данном случае запускаем парсер второй раз для получения мультипоточного варианта библиотеки. Потом используется утилита sigmake для объединения полученных pat-файлов в один sig-файл, ключ –n дает файлу название, под которым его видит конечный пользователь. Процесс опознавания библиотечных функций не безупречен, часто появляется файл коллизий. Опять таки, отсылаю к статье Ильфака. Файл коллизий редактируется очень просто. В этом файле представлены функции, которые имеют сходные CRC. Теперь уже нам с вами нужно решать, что с ними делать (ставить "-" для появления имени функции в виде комментария, "+" для обычного вида, не ставить ничего для полного исключения функции из файла сигнатур). Я предпочитаю включать ту, что выполняет более общее действие. Пример:

Код (Text):
  1.  
  2. +_l_swap                                             58             734E      
  3. 558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6
  4. _swap                                                58             734E
  5. 558B4C24108BEC83EC60538B450CC745FC0000000056578B34888B7C880485F6
  6.  

Здесь поставлен знак «+» перед функцией _l_swap, так как думается мне, что эта функция более напоминает при анализе бинарника функцию flexlm SDK. Аналогично расставляются знаки и для других пар (или большего количества) функций, вызвавших коллизии.

После редактирования .exc файла просто повторите:

Код (Text):
  1.  
  2. E:\flexlm\v8.0\i86_n3&gt;sigmake -n&quot;FlexLm Win32 v8.0
  3. Standard&amp;Multi-thread&quot; lmgr.pat+lmgr_md.pat lmgr.sig
  4.        
  5.  


Утилита сама поймет, что делать с файлом коллизий на этот раз. В завершение процесса нужно сжать файл сигнатур утилитой zipsig и поместить его в директорию /sig папки IDA.

Дизассемблируем файл icl.exe и ecl.exe. Применяем полученный файл сигнатур (я приложил sig-файлы для FlexLM SDK v6.0/7.2i/8.0). У меня было опознано свыше девятисот(!) библиотечных функций. Теперь мы сравнительно легко придем к нужному результату:

Код (Text):
  1.  
  2. icl.exe - 684,032 bytes
  3.  
  4.  
  5. _text:0040105A loc_0_40105A:                           ; CODE XREF: _main+350j
  6. _text:0040105A                 mov     eax, dword_0_488B24
  7. _text:0040105F                 call    sub_0_4083F4
  8. _text:00401064                 mov     eax, offset aFfrpsz  ; &quot;FFrpsZ&quot;
  9. _text:00401069                 mov     edx, 21h
  10. ; легко можно увидеть, что эта функция &quot;скатывается&quot; к FlexLMMainCheck
  11. ; думаю, название снимает все вопросы
  12. <STRONG>_text:0040106E                 call    sub_0_404C0E  ;mov eax,0</STRONG>
  13. _text:00401073                 test    eax, eax
  14. _text:00401075                 jnz     short loc_0_40107F
  15.  
  16.  
  17. ecl.exe - 692,224 bytes
  18.  
  19. _text:0040305A loc_0_40305A:                           ; CODE XREF: _main+350j
  20. _text:0040305A                 mov     eax, dword_0_48AB44
  21. _text:0040305F                 call    sub_0_40BD51
  22. _text:00403064                 mov     eax, offset aFfrpsz  ; &quot;FFrpsZ&quot;
  23. _text:00403069                 mov     edx, 21h  
  24. <STRONG>_text:0040306E                 call    sub_0_40837E  ;mov eax,0</STRONG>
  25. _text:00403073                 test    eax, eax
  26. _text:00403075                 jnz     short loc_0_40307F
  27.  

Теперь у нас есть компилятор. Самое время взломать профилировщик.

Используя методы, описанные выше, мы легко сможем обнаружить, что ругательство при запуске 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):
  1.  
  2. dumpbin.exe /FPO sh30w32.dll &gt;fpo.txt
  3. Dump of file sh30w32.dll
  4. File Type: DLL
  5. FPO Data (222)
  6.                                                     Use Has  Frame
  7. RVA      Proc Size   Locals  Regs   Prolog  BP  SEH  Type   Params
  8. 00001000        96        0     2        2   N   N    fpo        4  _MemPoolShrink@4
  9. 00001060       144        8     4       21   Y   N    fpo        0
  10.  

Уже сейчас мы можем выяснить размер процедуры, количество переданных параметров, количество локальных переменных и т.п. Если Вы не очень уютно себя чувствуете с кадром стека - почитайте Рэндалла Хайда и проиграйтесь с отладчиком - многое прояснится. Может (и справедливо!) возникнуть еще один вопрос: "Хорошо, я знаю адрес процедуры, количество параметров и прочую  ерунду. А КАК мне сделать, чтобы это узнал и Soft-Ice?" Ответ см. ниже - он есть, а пока методику поняли? Ищем секцию отладки в PE-файле (F8,F6 в HIEW) - если есть, она будет называться как-нибудь вроде .debug. Далее извлекаем ее (см. ниже), переводим в понятный S-Ice'у формат (см. ниже ) и работаем дальше.

Результат:

Код (Text):
  1.  
  2. W_VT_P_61_0011.EXE - закачать с intel.com, размер - свыше 100 мб.
  3.  
  4. AnProdInfo.dll
  5.  
  6. <STRONG>.text:602341C0                 call    sub_60232466 -&gt;xor eax,eax</STRONG>
  7. .text:602341C5                 xor     ebx, ebx
  8. .text:602341C7                 add     esp, 0Ch
  9. .text:602341CA                 cmp     eax, ebx
  10. .text:602341CC                 mov     [esi], eax
  11. .text:602341CE                 jz      loc_6023429D
  12. .text:602341D4                 mov     [ebp+0Ch], ebx
  13. .text:602341D7                 cmp     eax, 0FFFFFFEBh
  14. .text:602341DA                 mov     [ebp-4], ebx
  15. .text:602341DD                 jz      short loc_602341F2
  16. .text:602341DF                 cmp     eax, 0FFFFFFF6h
  17. .text:602341E2                 jz      short loc_602341EB
  18. .text:602341E4                 push    0D1h
  19. .text:602341E9                 jmp     short loc_602341F7
  20.  

«Однако за время пути собака могла подрасти». Пока писалась эта статья, я совершенно случайно накопал еще один update от Intel на тему Vtune –

ftp://download.intel.com/software/products/vtune/downloads/.

Что он делает, в двух словах и не рассказать. В своей статье о профилировщиках я его не описываю тоже, отчасти потому, что работать с ним страшновато. Это надстройка над JavaMachine, да еще к ней прибабахан MySQL-сервер. Для чего все это нужно, мне сказать сложновато. Естественно, все это дело тормозит жутко, а потому вдумчиво его ковырять на предмет радостных сообщений защиты мне было недосуг.

Поэтому здесь я скорее предпочту описать методики, как можно поймать интересующий код, чем давать готовые решения, хотя парочка решений, конечно же, будет.

Итак, немного поиграв с пакетом, имеем стандартный MessageBox со стандартными фразами. Что здесь можно сделать?

Вещь первая. Если строки сообщения защиты находятся в ресурсах PE-файла, то надо воспользоваться редактором ресурсов (например, Restorator 2.52 – wasm.ru), чтобы узнать их порядковый номер. Пример:

Код (Text):
  1.  
  2. 123      The GUI license for VTune(TM) Enterprise Analyzer for Web
  3.             Applications is invalid.  Please contact technical support.
  4.        
  5.  

Здесь, "123" – это произвольный (т.е. разработчик брал от фонаря) порядковый номер ресурса, который в дальнейшем будет использован функцией LoadString. Номер этот будет передан функции через стек (таков закон ). Т.е. будет использоваться инструкция push + шестнадцатеричное представление "123" (0x7B). Такой шаблон легко найти в HIEW – в режиме ассемблерного поиска надо ввести push ?7B (отметьте знак вопроса – он означает, что перед 7В может идти что угодно). Чаще всего, вхождений будет несколько, однако что стоит найти правильное?

Код (Text):
  1.  
  2. <STRONG>.text:10024387                 push    7Bh             ; uID</STRONG>
  3. .text:10024389                 mov     [esp+4Ch+var_4], esi
  4. .text:1002438D                 mov     ecx, [eax+8]
  5. .text:10024390                 push    ecx             ; hInstance
  6. .text:10024391                 lea     ecx, [esp+50h+var_34]
  7. .text:10024395                 call    sub_10010A10   ;к LoadString
  8.  
  9.        
  10.  

А дальше, опять таки нужно воспользоваться командой 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):
  1.  
  2.    ?IsFeatureEnabled@CTahoeLicenseMgr@@QAE_NW4SPFeatureEnum@@@Z
  3. .text:1002D780                 mov     eax, [ecx+4]
  4. .text:1002D783                 mov     ecx, [esp+arg_0]
  5. .text:1002D787                 and     eax, ecx
  6. ; Очень изящный и приятный код. Это пример хорошей оптимизации. Смотрите, вообще нет
  7. ; условных переходов, которые для современных CPU не представляют собой ничего хорошего.
  8. ; Вместо этого используется инструкция вычитания с заемом - более подробно см. статьи
  9. ; Касперски. А здесь, недолго мороча голову:
  10. <STRONG>.text:1002D789                 neg     eax  --&gt; mov eax,1; nop</STRONG>
  11. .text:1002D78B                 sbb     eax, eax
  12. .text:1002D78D                 neg     eax
  13. .text:1002D78F                 retn    4
  14.        
  15.  

Вроде все методики расписаны. Единственная вещь, которая может вызвать легкое смущение – это странный вид имени импортируемой функции. Это – наглядный пример искажения ("замангления") имен.

Искажение имен (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):
  1.  
  2. RationalPurify.2002.05.20.468.000.exe
  3.  
  4. purifyw.exe - 3,240,020 bytes
  5.  
  6. _text:00407F33 loc_0_407F33:                           ; CODE XREF: sub_0_407F20+Aj
  7. _text:00407F33                 call    sub_0_4E2060
  8. _text:00407F38                 call    sub_0_5DBD5F
  9. _text:00407F3D                 test    eax, eax
  10. _text:00407F3F                 jz      short loc_0_407F68
  11. _text:00407F41                 call    sub_0_4E26C0
  12. _text:00407F46                 test    eax, eax
  13. _text:00407F48                 jz      short loc_0_407F55
  14. <STRONG>_text:00407F4A                 call    sub_0_4E20F0    ; funny proc - mov eax,1</STRONG>
  15. _text:00407F4F                 test    eax, eax
  16. _text:00407F51                 jnz     short loc_0_407F68
  17. _text:00407F53                 pop     esi
  18. _text:00407F54                 retn
  19.  
  20.  
  21. RationalQuantify.2002.05.20.468.000.exe
  22.  
  23. quantifyw.exe - 2,621,528 bytes
  24.  
  25. _text:00428C23 loc_0_428C23:                           ; CODE XREF: sub_0_428C10+Aj
  26. _text:00428C23                 call    sub_0_491130
  27. _text:00428C28                 call    sub_0_56E8EF
  28. _text:00428C2D                 test    eax, eax
  29. _text:00428C2F                 jz      short loc_0_428C58
  30. _text:00428C31                 call    sub_0_4917D0
  31. _text:00428C36                 test    eax, eax
  32. _text:00428C38                 jz      short loc_0_428C45
  33. <STRONG>_text:00428C3A                 call    sub_0_4911C0 ; funny proc - mov eax,1</STRONG>
  34. _text:00428C3F                 test    eax, eax
  35. _text:00428C41                 jnz     short loc_0_428C58
  36. _text:00428C43                 pop     esi
  37. _text:00428C44                 retn
  38.  
  39.  
  40. RationalPureCoverage.2002.05.20.468.000.exe
  41.  
  42. coveragew.exe - 2,527,320 bytes
  43.  
  44. _text:00405773 loc_0_405773:                           ; CODE XREF: sub_0_405760+Aj
  45. _text:00405773                 call    sub_0_489800
  46. _text:00405778                 call    sub_0_559E7F
  47. _text:0040577D                 test    eax, eax
  48. _text:0040577F                 jz      short loc_0_4057A8
  49. _text:00405781                 call    sub_0_489EA0
  50. _text:00405786                 test    eax, eax
  51. _text:00405788                 jz      short loc_0_405795
  52. <STRONG>_text:0040578A                 call    sub_0_489890 ; funny proc - mov eax,1</STRONG>
  53. _text:0040578F                 test    eax, eax
  54. _text:00405791                 jnz     short loc_0_4057A8
  55. _text:00405793                 pop     esi
  56. _text:00405794                 retn
  57.        
  58.  

Вот, собственно, и все о защите FlexLm. То есть, о защите писать еще можно долго и нудно, однако о крайне бездарном ее применении в приложениях, я думаю, вы уже имеете весьма неплохое представление. За сим разрешите откланяться.

Volodya
wasm team.



P.S. Автор выражает искреннею благодарность всем членам wasm team за пинки по делу и вылавливание мелких и крупных блох. Персональное спасибо alexela и cybermaniac.

© Volodya

0 3.412
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532