allasm.ru

    Меню

 


Логотип Intel Fortran Compiler

Ситуация с этим компилятором вкратце такова. В процессе работы над третьим томом "Образа мышления IDA" я исследовал большое количество компиляторов на предмет особенностей их кодогенерации и вытекающих отсюда трудностей восстановления исходного кода. Не избежал этой участи и "Intel Fortran Compiler", обнаруженный на диске "Научись сам программировать на FORTRAN". Краткая аннотация на буклете гласила "Intel FORTRAN Compiler 4.5 - новейшая версия знаменитого компилятора. Для регистрации программы смотрите поддиректорию CRACK". Ну, на счет "новейшего" составили диска явно приврали, т .к. на тот момент уже вышла седьмая версия, да и CRACK оказался некорректным. Вместо того, чтобы ломать защиту, он ломал сам компилятор, необратимо его гробя. К счастью, оригинальный ifl.exe на диске все-таки имелся и это давало возможность заставить работать компилятор мне самому. В конце концов использовать в коммерческих целях этот, бесспорно, замечательный программный продукт я все равно не собирался, а для серии тестовых прогонов не то, что месяца (положенного мне по праву) даже нескольких дней было вполне предостаточно, поэтому с этической точки зрения ничего кощунственного я не совершал (просто мне очень уж не хотелось тянуть ~160 метров из Интернета, с моим междугородним Интернетом это действительно проблематично).

Итак, запускаем оригинальный файл компилятора на выполнение и лицезрим как он спускает на нас Полкана (ругается в смысле):

KPNC$C:\Program Files\Intel\compiler45\bin>ifl1.exe >1
Intel(R) Fortran Compiler Version 4.5 000403
Copyright (C) 1985-2000 Intel Corporation.  All rights reserved.
Evaluation Copy
ifl1: error: The evaluation period has expired.

    The evaluation period for this trial version of the
    Intel(R) Fortran Compiler has expired.  For product ordering
    information, please refer to the product release notes or visit the
    Intel Developer web site at the following URL:

               http://developer.intel.com/vtune

Ни слова о FLEX lm! (см. "Компилятор Intel С++ 5.0.1") и файл LMGxxx.DLL отсутствует. Странно! Похоже, что Fortran Compiler защищен иначе, что, собственно и не удивительно, поскольку их делали разные группы.

Что ж, запускаем IDA и натравливаем на нее исполняемый файл, который, кстати, занимает всего 176,128 Кб, что с точностью до байта соответствует размеру Intel C++ 5.1 Compiler. Странно! Но, как бы там ни было, ASCII-строки "The evaluation period has expired" автоматический анализатор IDA в тексте дизассемблируемого файла так и не нашел. Что ж, тогда мы сделаем это сами. , , "The evaluation period" и…

.data1:0042A220  54 68 65 20 65 76 61 6C-75 61 74 69 6F 6E 20 70 "The evaluation p"
.data1:0042A230  65 72 69 6F 64 20 68 61-73 20 65 78 70 69 72 65 "eriod has expire"
.data1:0042A240  64 2E 0A 0A 20 20 20 20-54 68 65 20 65 76 61 6C "d.00    The eval"
.data1:0042A250  75 61 74 69 6F 6E 20 70-65 72 69 6F 64 20 66 6F "uation period fo"
.data1:0042A260  72 20 74 68 69 73 20 74-72 69 61 6C 20 76 65 72 "r this trial ver"
.data1:0042A270  73 69 6F 6E 20 6F 66 20-74 68 65 0A 20 20 20 20 "sion of the0    "

Теперь, вновь нажимаем для поиска последовательности "20 A2 42 00" - адрес начала строки, заданный в обратном виде. Результат не заставляет себя долго ждать:

.data:00419390  60 A3 42 00 4F 00 00 00-20 A2 42 00 50 00 00 00 "`гB.O... вB.P..."
.data:004193A0  00 A2 42 00 51 00 00 00-E0 A1 42 00 52 00 00 00 ".вB.Q...рбB.R..."
.data:004193B0  C0 A1 42 00 53 00 00 00-A0 A1 42 00 54 00 00 00 "LбB.S...абB.T..."
.data:004193C0  60 A1 42 00 55 00 00 00-40 A1 42 00 56 00 00 00 "`бB.U...@бB.V..."
.data:004193D0  20 A1 42 00 57 00 00 00-00 A1 42 00 58 00 00 00 " бB.W....бB.X..."

Переключаемся обратно в дизассемблер, трижды жмем для преобразования цепочки байт в двойное слово, затем для перевода его в смещение и… в результате таких манипуляций получаем приблизительно такую же таблицу, как и в нашем предыдущем случае с Intel C++

.data:00419390 dd offset aSNoteTheEvalua ; "%s: NOTE: The evaluation period for thi"
.data:00419394 dd 4Fh
.data:00419398 dd offset aTheEvaluationP ; "The evaluation period has expired.\n\n   "
.data:0041939C dd 50h
.data:004193A0 dd offset aCommandLineErr ; "Command line error"
.data:004193A4 dd 51h
.data:004193A8 dd offset aCommandLineWar ; "Command line warning"
.data:004193AC dd 52h

А посему и действовать мы будем точно так же: поставим бряк на адрес 0419390h и дождемся пока отладчик не получит управления. Кстати, на счет отладчика. В момент написания этих строк у автора как раз закачивалась седьмая версия компилятора Intel C++ и от использования soft-ice пришлось воздержаться (в момент своей активации soft-ice полностью "замораживает" операционную систему, что пагубно влияет на Интернет, а точнее на установленные TCP/IP соединения). И вместо soft-ice автор решил для разнообразия использовать Microsoft WDB, который кстати, справился со своей задачей ничуть не хуже.

Запускам WDB на выполнение, нажимаем , указываем имя загружаемого файла, переходим в окно команд ("Command Window") и устанавливаем точку остановка на адрес 0419398h для чего отдаем команду "BA r4 0x0419398" (что расшифровывается как: "Break on Access of Read 4 bytes long"). Затем для продолжения выполнения программы пишем "G" и с полсекунды ждем…


Внешний вид отладчика MS WBD в процессе ломания программы

Ага, отладчик говорит "Hard coded breakpoint hit" ("сработала аппаратная точка останова") и приостанавливает выполнение отлаживаемой программы. Сама же отлаживаемая программа к этому моменту уже успела вывести на экран:

Intel(R) Fortran Compiler Version 4.5 000403
Copyright (C) 1985-2000 Intel Corporation.  All rights reserved.
Evaluation Copy
ifl1: error:

Обратите внимание на строки, выделенные жирным шрифтом! Очевидно, они свидетельствуют о том, что мы попали не в самое начало защитной процедуры, а где-то в ее середину. Кстати, а что у нас там лежит на стеке? Смотрим (~Viewа Stack, см. рис. 0х003). Всего три адреса, - довольно неглубокий уровень вложения не так ли? Причем (обратив свой взор к окну дизассемблера), сейчас уровень вложения еще понизится, т. к. следующей командой мы выходим из этой процедуры:

0040C4CC 8B00             mov         eax,dword ptr [eax]
0040C4CE 83C414           add         esp,14                   _
0040C4D1 C3               ret

Теперь неспешно трассируем код, попеременно поглядывая то на дизассемблированный листинг, то на консоль отлаживаемой программы. Следующая трассируемая функция (внутрь которой мы не заходим, а "заглатываем" ее одним нажатием ) выводит на экран "The evolution period has expired", но не завершает программу, а продолжает ее выполнение. Что ж! Тогда и мы продолжим (трассировку)! Вызов функции 040F5FEh проходит без каких либо внешних проявлений и, так и не поняв, зачем она собственно нужна, мы поднимается на еще один уровень вверх, куда нас забрасывает завершающий функцию RET.

00403C7C E833880000       call        0040C4B4
; отсюда ^^^^^^^^^^^^^^^^^^^^^ мы только что вышли

00403C81 89442404         mov         dword ptr [esp+4],eax
00403C85 891C24           mov         dword ptr [esp],ebx
00403C88 896C2408         mov         dword ptr [esp+8],ebp
00403C8C E8A8BB0000       call        0040F839
; эта процедура выводит "The evaluation period has expired."

00403C91 C70424C04C4200   mov         dword ptr [esp],424CC0h
00403C98 895C2404         mov         dword ptr [esp+4],ebx
00403C9C E85DB90000       call        0040F5FE
; эта процедура ничего не делает

00403CA1 83C414           add         esp,14h
00403CA4 5B               pop         ebx
00403CA5 5D               pop         ebp
00403CA6 C3               ret
…и таким Макаром мы трассируем код до тех пор, пока не наткнемся на следующую конструкцию:

0040105A E8E1800000       call        00409140 ; отсюда мы только что вышли по RETN
0040105F 0FB6C0           movzx       eax,al
00401062 85C0             test        eax,eax
00401064 0F84C4000000     je          0040112E

что в ней необычного? А то, что это первая встретившаяся нам материнская процедура, которая анализирует код возврата дочерней функции. В нашем случае регистр EAX содержит значение "ноль" и, стало быть, следующий условный переход выполняется. Но не тот ли это переход который нам нужен? Что ж, сейчас мы это узнаем - нажимаем клавишу еще несколько раз… Опля! Наш условный переход перебрасывает нас на ту ветку программы, которая спустя несколько команд скоропостижно сдыхает, захлопывая окно программы. А что произойдет, если команду "JE" в строке 401064h заменить на противоположную (или, как вариант, просто удалить этот условный переход)? Пробуем…

Компилятор по прежнему смачно ругается на "evaluation expired", но… он работает! Работает!! Работает!!! По соображением экономии экранного места (в самом деле, ругательство занимает чуть ли не половину экрана и смотрится крайне некрасиво) мы забиваем вызов процедуры 0409140h командами NOP. Проверяем - сработало ли? Ну… это смотря как посмотреть. Трехэтажный мат действительно исчез, но вот лаконичная строка "Evaluation Copy" так и осталась. Найдем что за код ее выводит? Зачем? - лучше найти саму эту строку и тем же HIEW'ом ее переписать во что ни будь более привычное, например: "hacked by mother-fucker guy". Переписываем, и… пользуемся компилятором в свое удовольствие, не забывая, однако о том, что по истечении 30-дневного срока вы будете должны его стереть, в противном случае вы поступите очень и очень нехорошо, да и незаконно.

  [C] Крис Касперски