Из всех существующих для Windows-платформы
отладчиков, наибольшей популярностью вполне заслуженно пользуется SoftICE фирмы
Numega. Чем же SoftICE отличается от остальных подобных ему программ?. Наиболее
важным отличием является то, что SoftICE работает в 0-м кольце защиты. Не
пугайтесь, если Вы пока ничего не знаете о кольцах защиты, существующих в
архитектуре 32-разрядных процессоров фирмы Intel и предназначенных для
ограничения взаимодейстия выполняющихся программ между собой и с операционной
системой. Обычно ОС имеет права полного доступа ко всем остальным выполняемым
программам, т.к. она работает в 0-м кольце защиты (наиболее привелигерованном),
системные задачи выполняются в 1-м и 2-м кольцах, а приложения - в 3-м (наименее
привелигерованном). Частично осуществлять управление запущенными приложениями
можно из 1-го и 2-го кольца защиты, именно так работает большинство отладчиков
из крупных пакетов для разработки программ. Разработчики из Numega подошли к
делу более профессионально и создали SoftICE - отладчик, который работает в 0-м
кольце защиты (для этого он загружается до загрузки ядра ОС Windows) и позволяет
полностью контролировать не только все выполняемые системой задачи, но и саму ОС
Windows.
При установке SoftICE, когда программа спросит о типе Вашего видеоадаптера, Вы
можете указать Standard Display Adapter (VGA) и обязательно установите галочку
напротив пункта Universal Video Driver (в нижней части экрана), это позволит вам
работать с SoftICE в окне, не переходя на другое разрешение и видеть большую
часть того, что выводится на экран Windows (очень удобно).
В следующем окне выберите порт, к которому у Вас подключена мышь. Потом
программа установки спросит Вас, что она должна делать с файлом autoexec.bat.
Укажите самый верхний пункт (Let Setup modify AUTOEXEC.BAT).
После того как завершится копирование файлов и программа установки попросит
перегрузить компьютер, выберите пункт I restart my computer later. Сейчас мы
произведем некоторые изменения в файле конфигурации SoftICE (winice.dat).
Открываем его любым текстовым редактором. Находим строчку:
INIT="X;"
и заменяем ее на
INIT="wl; color f a 4f 1f e; code on; lines 60; wc 32; wd 4; wr; faults off; "
INIT="ww 4;dex 1 ss:esp;altkey ctrl d;watch es:di;watch eax;watch *es:di;set
mouse 3;cls;X;"
В самом конце файла найдем также следующий фрагмент:
; ***** Examples of export symbols that can be included for Windows 95 *****
; Change the path to the appropriate drive and directory
;EXP=c:\windows\system\kernel32.dll
;EXP=c:\windows\system\user32.dll
;EXP=c:\windows\system\gdi32.dll
;EXP=c:\windows\system\comdlg32.dll
;EXP=c:\windows\system\shell32.dll
;EXP=c:\windows\system\advapi32.dll
;EXP=c:\windows\system\shell232.dll
;EXP=c:\windows\system\comctl32.dll
;EXP=c:\windows\system\crtdll.dll
;EXP=c:\windows\system\version.dll
;EXP=c:\windows\system\netlib32.dll
;EXP=c:\windows\system\msshrui.dll
;EXP=c:\windows\system\msnet32.dll
;EXP=c:\windows\system\mspwl32.dll
;EXP=c:\windows\system\mpr.dll
во всех строчках, начинающихся со слова EXP убираем стоящий перед ним знак ";".
Теперь сохраните сделанные в файле изменения и перегружайте компьютер.
Если Вы все сделали правильно, то теперь при нажатии сочетания клавишь Ctrl+D
должно появится черное окно SoftICE (при разрешении 1024х768 оно занимает
половину экрана). Теперь нажав сочетание Ctrl+Alt+C вы переместите окно SoftICE
в центр экрана.
Выход из SoftICE в Windows можно осуществить повторным нажанием Ctrl+D, но мы
советуем для этих целей использовать клавишу F5 - это более корректно (клавиша
F5 соответствует команде X).
Распределение памяти
Используемая в ОС Windows 95 модель (способ) распределения памяти называется
непрерывной. В такой модели не существует строгого деления на сектора и сегменты
(что было присуще DOS и Windows 3.x), т.е. программа может свободно обращаться к
любому адресу всего адресного пространства (4 Гб, ограничение накладывается
32-разрядной адресной шиной компьютера). ОС считается многозадачной, если
работающие параллельно программы не могут воздействовать друг на друга. Для
этого Windows использует следующий механизм: каждой задаче предоставляется свое
личное адресное пространство размером около 2-х Гб. За границы своего адресного
пространства задача выйти не может, также как никакая другая задача не может
работать с данным пространством - этим и определяется автономность программы.
Предоставлением адресного пространства и загрузкой в него программы занимается
менеджер памяти Windows. У каждой программы существует два важных параметра:
Адрес загрузки. Это адрес, начиная с которого программа будет распологаться в
памяти. Запомните, программы в Windows всегда загружаются по одному и тому-же
адресу - адресу загрузки, это сильно облегчит нам работу в будущем. Как было
сказано выше каждой программе предоставляется свое адресное пространство
размером около 2-х Гб, начиная с адреса 40000000h (символ h означает, что число
записано в шестнадцатеричной системе счисления). Именно поэтому большинство
программ имеют адрес загрузки 40000000h.
Точка входа в программу. Это адрес, с которого начинается выполнение программы.
Он может находится в любой части программы, а не обязательно в ее начале; даже
наоборот в большинстве случаев он расположен практически в самом ее конце.
И под конец еще одна очень важная для нас вещь. ОС Windows не позволяет
программе производить изменения в области кода (т.е. программа не способна
изменять свой код), единственное, что она может - производить изменения в
области данных. Это ограничение очень важно, т.к. запрещает программистам делать
самомодифицируещиеся программы, что в свою очередь сильно облегчает работу нам,
Исследователям Программ.
Используемая в ОС Windows 95 модель (способ) распределения памяти называется
непрерывной. В такой модели не существует строгого деления на сектора и сегменты
(что было присуще DOS и Windows 3.x), т.е. программа может свободно обращаться к
любому адресу всего адресного пространства (4 Гб, ограничение накладывается
32-разрядной адресной шиной компьютера). ОС считается многозадачной, если
работающие параллельно программы не могут воздействовать друг на друга. Для
этого Windows использует следующий механизм: каждой задаче предоставляется свое
личное адресное пространство размером около 2-х Гб. За границы своего адресного
пространства задача выйти не может, также как никакая другая задача не может
работать с данным пространством - этим и определяется автономность программы.
Основы работы с SoftIce
Так как SoftICE работает в 0-м кольце защиты, получить изображение интерфейса
программы практически невозможно. Поэтому все описание будет чисто текстовым.
Если при установке программы Вы следовали нашим указаниям, то сейчас интерфейс
отладчика состоит из следующих частей (назовем их окнами, потому, что с ними
действительно можно работать как с окнами - включать, выключать, изменять
размер):
Самое верхнее окно - окно регистров (wr - сокращенное обозначение, используемое
в SoftICE). В этом окне отображается содержимое регистров процессора. Отдельно
от остальных в правом углу отображается состояние регистра флагов (каждого флага
в отдельности). Наибольшее значение для нас имеет флаг нуля (изображается
символом z). Заглавная буква Z означает, что флаг установлен, строчная - флаг
сброшен. Под содержимым регистра флагов отображается также очень полезная для
нас информация, но подробно я расскажу о ней в следующих статьях. Окно регистров
включается и выключается командой wr.
Следующее - окно данных. В нем мы можем наблюдать содержимое интересующего нас
участка памяти. Существует несколько различных форм представления информации в
этом окне:
db - информация отображается в виде байтов (byte)
dw - информация отображается в виде слов (word)
dd - информация отображается в виде двойных слов (double word - dword)
Информация в этом окне меняется при изменении содержимого участка памяти, т.е.
Вы всегда видите именно то, что находится в данный момент в памяти. Окно
включается и выключается командой wd. Ниже расположено окно кода. В нем
отображается дизассемблированный текст исследуемой программы. Курсор (красная
строка для рекомендованных настроек) указывает на команду, которая будет
выполнена на следующем шаге. В нижней части окна (на желтой полоске) показано, в
каком модуле мы в данный момент находимся. Переключается окно с помощью команды
wc.
Самое нижнее окно - окно команд SoftICE. Здесь Вы вводите команды и получаете
некоторую полезную информацию о работе SoftICE. Т.к. выводимая информация
целиком зависит от введенных команд, то описывать ее мы будем для каждой команды
отдельно.
Работа всех Windows-приложений основана на вызове API-функций. Это очень удобно
и выгодно. Например, для вывода окна сообщения с некоторым текстом, достаточно
вызвать функцию MessageBoxA с адресом выводимой строки в качестве аргумента.
Замечательной особенностью SoftICE является то, что Вы можете устанавливать
точки прерывания на вызовы API-функций. Установив точку прерывания на некоторую
строку программы, Вы сообщаете SoftICE, что при достижении этой строки программа
должна прервать свое выполнение и возвратить управление отладчику. Например, Вы
установили точку прерывания на выполнение команды по адресу 40А00020, а затем
запускаете программу с адреса 40А00000. Дойдя до строки с адресом 40А00020,
программа прервется, управление вновь вернется в SoftICE, и Вы сможете узнать
содержимое регистров процессора, участков памяти, а также, при необходимости,
что-то изменить.
Точка прерывания на вызов API-функции устанавливается точно так же, как и не
выполнение команды по определенному адресу. При вызове функции программа
прерывается в самом ее начале, и после этого Вы можете выполнить необходимые Вам
действия. Обычно точку прерывания на вызов API-функции устанавливают, когда
хотят узнать, из какого места программы она вызывается. Допустим, в программе
имеется следующий фрагмент:
некоторый код
...
40200100 call MessageBoxA
40200105 cmp eax, 01
...
продолжение программы
Вы точно знаете, что вызывается функция MessageBoxA, но не знаете, что это
происходит по адресу 40200100h. Для того, чтобы это выяснить мы должны проделать
следующее:
Активизируем SoftICE (Ctrl+D)
Устанавливаем точку прерывания на вызов функции MessageBoxA (bpx MessageBoxA,
советуем всегда писать общепринятые имена функций с заглавными и строчными
буквами, SoftICE их не различает, а Вы так быстрее запомните). При этом
происходит следующее: SoftICE устанавливает точку прерывания на выполнение
первой команды указанной функции
Выходим в Windows (F5)
Выполняем те действия, в результате которых произойдет вызов функции MessageBoxA
При вызове этой функции (сообщение в окне команд) программа прерывается в модуле
USER (указано в низу окна кода) и активизируется SoftICE, при этом курсор
установлен не первой команде функции MessageBoxA. Чтобы узнать, из какого места
произошел ее вызов, используем команду p ret (быстрая клавиша F12) - продолжение
программы до выполнения команды ret (команда возврата из подпрограммы)
После этого, программа вновь прерывается по адресу 40200105 (на этой строке
установлен курсор), а на предыдущей строке мы видим, что происходит вызов
MessageBoxA. Вот мы и нашли то место, откуда вызывается функция MessageBoxA
Мы описали лишь незначительную часть команд SoftICE. Остальные подробно
рассмотрим по мере их использования в наших следующих исследованиях конкретных
программ. Что ж, мы уже немного освоились в SoftICE и вплотную подошли к
необходимости использования дизассемблера. Без него никакого серьезного
исследования программы Вам провести не удастся.
Исследования
Временные защиты.
PcANYWHERE 8.0
Эта программа ДОЛЖНА быть установленна на каждом компьютере. Она предназначена
для связи компьютеров с помощью модема, прямого соединения, локальной сети и
Интернета. Она позволяет переносить файлы, управлять удаленным компьютером,
запускать на нем программы, и т.д. Найти эту программу можно по адресу http://www.symantec.com.
Ищите ее в Американском отделении Symantec.
Программа имеет 30-ти дневный Trial period, доступная регистрация – только
online.
Открыв программу (Winaw32.exe) в WinDASM, я посмотрел импортируемые функции, и
наткнулся там на функцию под названием TimeBombCheck@4 , импортируемую из модуля
AWCOMM32.DLL . По-моему, уже само название наводит на размышления. Вот как
выглядит место вызова этой функции в листинге программы:
* Reference To: AWCOMM32._TimeBombCheck@4, Ord:00BAh
|
:004066D9 FF1510314900 Call dword ptr [00493110]
:004066DF 85C0 test eax, eax
:004066E1 0F8521000000 jne 00406708
Видимо, после вызова "бомюы" программа проверяет содержимое регистра ЕАХ, и если
оно равно 0, то программа закрывается. Я перевел часы на год вперед, чтобы
просрочить период, поставил в SoftIce bpx 004066E1, и запустил программу. Попав
в SoftIce, вы увидите, что регистр ЕАХ=0. Изменив флаг процессора ( нажмите
мышкой на "Z" в правом верхнем углу SoftIce, а потом нажмите <Enter>), нажимаем
F5, и видим, что программа запускается. Прекрасно, меняем JNE 00406708 на JMP
00406708, и запускаем программу. Запускается, но потом закрывается. Причина одна
– эту "временную бомбу" используют и другие файлы. Значит, необходимые изменения
нужно вносить в саму .DLL . Ставим в SoftIce BPX 004066D9 (на вызов "Бомбы"), и
запускаем программу. Попав в SoftIce трассируем программу в поисках процедуры (CALL)
вызова окна с информацией о том, что наше время истекло. Делать это можно с
помощью клавиши F7: щелкаем мышкой по нужной линии, чтобы установить на нее
курсор, и нажимаем F7. Через десяток-другой CALLов попадаем в нужное место:
:0669DABD E8BE2E0000 Call 066A0980 <= вызов нужного нам окошка
:0669DAC2 C78568F1FFFF00000000 mov dword ptr [ebp+FFFFF168], 00000000 <= запись
0 в память
:0669DACC C645FC02 mov [ebp-04], 02
:0669DAD0 E8CE030000 call 0669DEA3
:0669DAD5 C645FC01 mov [ebp-04], 01
:0669DAD9 E819040000 call 0669DEF7
:0669DADE C645FC00 mov [ebp-04], 00
:0669DAE2 E81C040000 call 0669DF03
:0669DAE7 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:0669DAEE E81C040000 call 0669DF0F
:0669DAF3 8B8568F1FFFF mov eax, dword ptr [ebp+FFFFF168] <= 0 из памяти попадает
в ЕАХ
:0669DAF9 E927040000 jmp 0669DF25 <= переход на возврат в Winaw32.exe
Как видно, достаточно вместо вызова окна по адресу 0669DABD поставить пять NOPов,
и поменять mov dword ptr [ebp+FFFFF168], 00000000 на mov dword ptr
[ebp+FFFFF168], 00000001. Вносим наши изменения,и... Все! Программа работает без
ограничений времени, и окно с напоминаниями исчезло. Спасибо дядюшке Нортону за
отличную программу. Помещать блок защиты во внешнюю DLL означает вообще не
защищать программу – это для сведения программистов.
Opera 3.50
Эта программа – браузер интернета – образец того, как должны писаться программы.
Маленькая (1.3 Мб), удобная, по скорости работы не сравнимая с Нафигатором и
Internet Explorer-ом, с возможностью отключения "на лету" изображений или
текста... прекрасная замена браузерам-монстрам.
Программа ограниченна 30-ти дневным "trial period"-ом, и просит для регистрации
регистрационный код. Попытки найти место, где происходит проверка введенного
кода затянулись, и я решил просто избавиться от окна с напоминанием о
регистрации и от временных лимитов.
Ставим в SoftIce bpx DialogBoxParamA (ловим окошко с предложением
зарегистрироваться), и запускаем программу. Попав в SoftIce, нажимаем F12,
возвращаясь по цепочке вызовов обратно, пока не попадем вот в это место:
:0045BF18 8B0E mov ecx, dword ptr [esi]
:0045BF1A E8D07D0500 call 004B3CEF
:0045BF1F 8B0E mov ecx, dword ptr [esi]
:0045BF21 E815790500 call 004B383B
:0045BF26 898628040000 mov dword ptr [esi+00000428], eax
:0045BF2C 837C240800 cmp dword ptr [esp+08], 00000000
:0045BF31 740C je 0045BF3F
:0045BF33 FF352C595000 push dword ptr [0050592C]
:0045BF39 E809110300 call 0048D047 <= здесь вызывается нужное нам окно
:0045BF3E 59 pop ecx
:0045BF3F 833D2C59500000 cmp dword ptr [0050592C], 00000000
:0045BF46 7414 je 0045BF5C
Как видно из приведенного листинга, условный переход по адресу :0045BF31 обходит
процедуру вызова окна. Давайте изменим je 0045BF3F на jmp 0045BF3F, и запустим
программу. Окно исчезло. Теперь переведите время, скажем, на пару месяцев
вперед, и вы убедитесь, что программа по-прежнему запускается. Как оказалось
после, через это место программа проходит при запуске несколько раз, очевидно,
проверяя года, месяца, и дни.
Модификация FreeMem Pro
Эта программа показывает напоминание о регистрации при каждом запуске, и имеет
довольно интересный механизм ввода рег.номера – находится на вкладке "About" -
сравнение введенных вами знаков производится "на лету", нет кнопок регистрации.
Обычно такие операции ловятся в SoftIce с помощью bpx HmemCPY, но мы пойдем
другим путем.
Итак, откройте Fmempro.exe с помощью WinDasm, и поищите сслыки на строки типа "Registration
successful", "Thank you…" и т.д. Довольно скоро вы наткнетесь на строку "Thank
you for your Registration". Дважды щелкнув по ней мышкой, мы окажемся в
следующем месте:
* Referenced by a CALL at Addresses:
|:0044A114 , :0044D0DA
|
:0044D158 53 push ebx
:0044D159 8BD8 mov ebx, eax
:0044D15B 80BB6E05000000 cmp byte ptr [ebx+0000056D], 00
:0044D162 7451 je 0044D1B5 <= если [ebx+0000056D]= 00, то не зарегистрированны
:0044D164 33D2 xor edx, edx
:0044D166 8B8380030000 mov eax, dword ptr [ebx+00000380]
:0044D16C E8371CFDFF call 0041EDA8
:0044D171 33D2 xor edx, edx
:0044D173 8B8390030000 mov eax, dword ptr [ebx+00000390]
:0044D179 E82A1CFDFF call 0041EDA8
* Possible StringData Ref from Code Obj ->"Thank you for your Registration"
|
:0044D17E BAC0D14400 mov edx, 0044D1C0
:0044D183 8B8344020000 mov eax, dword ptr [ebx+00000244]
:0044D189 E8EE1CFDFF call 0041EE7C
:0044D18E 33D2 xor edx, edx
:0044D190 8B834C020000 mov eax, dword ptr [ebx+0000024C]
:0044D196 E80D1CFDFF call 0041EDA8
:0044D19B 33D2 xor edx, edx
:0044D19D 8B8358020000 mov eax, dword ptr [ebx+00000258]
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0044D13C(C)
|
:0044D1A3 E8001CFDFF call 0041EDA8
:0044D1A8 33D2 xor edx, edx
:0044D1AA 8B8384030000 mov eax, dword ptr [ebx+00000384]
:0044D1B0 E8F31BFDFF call 0041EDA8
:0044D1B5 5B pop ebx
:0044D1B6 C3 ret
Как видно из приведенного участка кода, по адресу :0044D15B осуществляется
проверка содержимого [ebx+0000056D], и если содержимое равно 0, то это означает,
что программа незарегистрированная (происходит переход на конец этой функции).
Самое простое решение – изменить cmp byte ptr [ebx+0000056D], 00 на mov byte ptr
[ebx+0000056D], 01("регистрируем" программу) и je 0044D1B5 (код 7451) на два NOP
(два - для соблюдения числа байт, код NOP - 90) - и … Все! Программа работает,
окно с напоминанием исчезло, и на вкладке "About" появилась надпись,
благодарящая нас за регистрацию.
CpuIdle - временная защита
Программа CpuIdle предназначена для охлаждения процессора путем посылки команды
HALT, и очень полезна для "разогнанных" процессоров. Срок ее действия без
регистрации ограничен 30-ю днями. Перед нами стоит задача снять временную
защиту. Итак, загружаем программу в SoftIce и устанавливаем bpx GetLocalTime,
нажимаем F5, и через пару секунд вновь оказываемся в SoftIce. Нажимаем F12 для
возврата в вызывающую программу, и видим следующий код:
:00407940 E83BDDFFFF CALL KERNEL32.GETLOCALTIME
:00407945 668B4C240E MOV CX, WORD PTR [ESP+0E] <= день записывается в СХ
:0040794A 668B54240A MOV DX, WORD PTR [ESP+0A] <= месяц записывается в DX
:0040794F 668B442408 MOV AX, WORD PTR [ESP+08] <= год записывается в AX
:00407954 E86BFFFFFF CALL 004078C4
:00407959 DD1C24 FSTP QWORD PTR [ESP]
:0040795C 9B WAIT
:0040795D DD0424 FLD QWORD PTR [ESP]
:00407960 83C418 ADD ESP, 00000018
:00407963 C3 RET
Самы пройстой CRACK – записать в регистры CX, DX и AX текущие значения, чтобы
программа определяля одно и то же время. Модифицируем строки:
:00407945 668B4C240E MOV CX, WORD PTR [ESP+0E]
:0040794A 668B54240A MOV DX, WORD PTR [ESP+0A]
:0040794F 668B442408 MOV AX, WORD PTR [ESP+08]
на:
MOV CX,0009 <= мой текущий день – 9-е число
NOP <=для выравнивания числа байт
MOV DX, 000C <= мой месяц – 12-й
NOP <= для выравнивания числа байт
MOV AX, 07CE <= мой год – 1998-й
NOP <= для выравнивания числа байт
Вот и все, CRACK готов...
Регистрация NJWIN
Не так давно наткнулся я на программу под названием Njwin, которая опознает и
перекодирует японские, корейские и китайские иероглифы в их "первозданный" вид.
Найти программу Njwin 1.6 можно по адресу http:/www.njstar.com/ .
У программы интересная сильная защита, которая все-таки имеет свои слабости, и
при правильном подходе довольно быстро сдается.
Во-первых, программа при закрытии проверяет сама себя на изменения кода, и если
Вы изменили в теле программы хоть один байт, программа самоуничтожается. Вторая
защита – 30-ти дневный "trial period". Итак, сначала нам необходимо отключить
механизм самоуничтожения, а после заняться ее регистрацией.
ОТКЛЮЧЕНИЕ МЕХАНИЗМА САМОУНИЧТОЖЕНИЯ:
Скопируйте файл Njwin.exe в другое место на случай неудач и запустите программу.
Установите в SoftIce bpx getmodulefilename, нажмите F5 и закройте Njwin. Вы
попадаете в SoftIce. Нажмите F11 и вы окажетесь в модуле Njwin.exe:
44E9 CALL KERNEL!GETMODULEFILENAME
44EE PUSH 1A7F
44F1 PUSH 7688
44F4 LEA AX,[BP+FEEA]
44F8 PUSH SS
44F9 PUSH AX
44FA CALL 1A7F:0856
44FF ADD SP,08
4502 MOV SI,AX
4504 MOV [BP-0C],DX
4507 OR DX,AX
4509 JNZ 450C
450B JMP 4698
450E PUSH 02
Протрассируйте код, используя F10, и записав все переходы JZ и JNZ. Теперь,
используя любой HEX редактор, измените что-нибудь в файле Njwin.exe. Откройте
его, установите точку прерывания на ту же функцию (bpx getmodulefilename), и
закройте Njwin. Попав в SoftIce, снова трассируйте код, отыскивая различия.
Очень скоро вы наткнетесь на место:
461C JNZ 467A <= расхождение
MOV WORDD PTR[BP-12],CFC4
MOV WORD PTR[BP-10],7BBC
PUSH 112F
PUSH 768C
LEA AX,[BP+FEEA]
PUSH SS
PUSH AX
CALL 112F:0856 <= вот он, самоубийца
ADD SP,08
MOV SI,AX
MOV [BP-0C],DX
OR DX,AX
JZ 4698
И убедитесь, что неизмененная программа не делает перехода по адресу 461С (JNZ
467A), и делает его по команде JZ 4698. Измените JNZ на JMP 4698, и вы увидите,
что программа перестала самоуничтожаться. Теперь можно внести эти изменения в
тело оригинальной программы. Кстати, взглянув повнимательнее на первый кусочек
кода, вы увидите знакомый переход по адресу 450В. Можно просто изменить JNZ 450C
по адресу 4509 на JMP 4698, и вы снова отключите защиту. Теперь можно переходить
к регистрации программы.
РЕГИСТРАЦИЯ ПРОГРАММЫ
У меня программа не выдавала окна для ввода регистрационной информации, но
друзья говорили, что даже после ввода правильной регистрационной информации при
перезапуске программы она снова видела себя незарегистрированной, т.е. снова
появлялось окошко с напоминанием о необходимости регистрации и т.д. Как
избавиться от этого окошка?
Программа использует при запуске файл Njwin.ini , расположенный в каталоге
Windows.
Значит, следует трассировать изменения, происходящие при чтении .ini файла.
Ставим bpx GetPrivateProfileString и запускаем программу. Останавливаемся мы в
следующем месте:
:0001.3B83 9AB93B0000 call KERNEL.GETPRIVATEPROFILESTRING
:0001.3B88 80BEF6FD3F cmp byte ptr [bp+FDF6], 3F
:0001.3B8D 752E jne 3BBD
:0001.3B8F FF36DC05 push word ptr [05DC]
:0001.3B93 FF36DA05 push word ptr [05DA]
:0001.3B97 FF36E005 push word ptr [05E0]
:0001.3B9B FF36DE05 push word ptr [05DE]
:0001.3B9F FFB6ECFB push word ptr [bp+FBEC]
:0001.3BA3 FFB6EAFB push word ptr [bp+FBEA]
:0001.3BA7 8D86F6FD lea ax, [bp+FDF6]
:0001.3BAB 16 push ss
:0001.3BAC 50 push ax
:0001.3BAD 680001 push 0100
:0001.3BB0 FF36F405 push word ptr [05F4]
:0001.3BB4 FF36F205 push word ptr [05F2]
:0001.3BB8 9AE53B0000 call KERNEL.GETPRIVATEPROFILESTRING
:0001.3BBD FF36DC05 push word ptr [05DC]
Трассируем программу, пока не дойдем до следующего места:
:0001.33EB 9AFA360334 call 0001.36FA <= вызов считывания данных из реестра
:0001.33F0 83C402 add sp, 0002
:0001.33F3 0BC0 or ax, ax
:0001.33F5 7503 jne 33FA <= проверка на регистрацию
:0001.33F7 E9BF01 jmp 35B9 <= переход, если зарегистрирована
:0001.33FA FF36F005 push word ptr [05F0]
:0001.33FE FF36EE05 push word ptr [05EE]
:0001.3402 680934 push SEG ADDR of Segment 0001
Как видно, по адресу 001.33F5 осуществляется проверка регистра ах, с последующим
переходом через адрес 0001.33F7, если программа не зарегистрирована. Значит, нам
необходимо изменить jne 33FA на jmp 35B9 – и CRACK готов.
XARA 3D
Эта программа, предназначенная для создания анимированных .GIF изображений,
имеет ограничение по времени работы (30 дней) , и регистрируется с помощью
рег.номера.
При вводе неправильного номера программа выдает окно сообщения о том, что введен
неправильный рег.номер. При ближайшем рассмотрении мы видим, что это типичный
MessageBox. Ставим в SoftIce bpx MessageBoxA, запускаем программу, и пытаемся
зарегистрироваться. После выдачи сообщения об ошибке мы жмем "ОК" и попадаем в
SoftIce:
:0048C30D FF15B86B5100 Call dword ptr [00516BB8] <=MessageBoxA
:0048C313 891E mov dword ptr [esi], ebx
:0048C315 837DFC00 cmp dword ptr [ebp-04], 00000000
:0048C319 89450C mov dword ptr [ebp+0C], eax
:0048C31C 740B je 0048C329
:0048C31E 6A01 push 00000001
:0048C320 FF75FC push [ebp-04]
:0048C323 FF15146E5100 Call dword ptr [00516E14]
:0048C329 6A01 push 00000001
:0048C32B 8BCF mov ecx, edi
:0048C32D E822FFFFFF call 0048C254
:0048C332 8B450C mov eax, dword ptr [ebp+0C]
:0048C335 5F pop edi
:0048C336 5E pop esi
:0048C337 5B pop ebx
:0048C338 C9 leave
:0048C339 C20C00 ret 000C
Как видно из приведенного листинга, процедура вызова окна является вложенной,
т.е. вызывается еще откуда-то. Видно это из-за наличия всего несколькими
строками ниже команды RET . Давайте протрассируем программу дальше с помощью
клавиши F12, пока не дойдем до места:
:0041477B E820A2FFFF call 0040E9A0 <= процедура проверки ???
:00414780 84C0 test al, al <= мы очутились здесь
:00414782 7522 jne 004147A6
:00414784 8D4DEC lea ecx, dword ptr [ebp-14]
:00414787 C745FCFFFFFFFF mov [ebp-04], FFFFFFFF
:0041478E E8D6FC0600 call 00484469
:00414793 33C0 xor eax, eax
:00414795 8B4DF4 mov ecx, dword ptr [ebp-0C]
:00414798 64890D00000000 mov dword ptr fs:[00000000], ecx
:0041479F 5F pop edi
В регистре AL в данный момент находится 0. Поменяйте test al,al на mov al,01 , и
программа будет открываться всегда, даже при неправильном коде и просроченном
времени. Однако от надоедливого окна с напоминанием о регистрации мы еще не
избавились. Давайте исследуем call 0040E9A0 по адресу :0041477B :
:0040EB82 3BC5 cmp eax, ebp
:0040EB84 7522 jne 0040EBA8
:0040EB86 8D4C2414 lea ecx, dword ptr [esp+14]
:0040EB8A C60598644C0000 mov byte ptr [004C6498], 00
:0040EB91 C78424B4040000FFFFFFFF mov dword ptr [esp+000004B4], FFFFFFFF
:0040EB9C E8C8580700 call 00484469
:0040EBA1 B001 mov al, 01
:0040EBA3 E9F70A0000 jmp 0040F69F
- - - - - - - - - - - - -
:0040F69F 8B8C24AC040000 mov ecx, dword ptr [esp+000004AC]
:0040F6A6 5F pop edi
:0040F6A7 5E pop esi
:0040F6A8 5D pop ebp
:0040F6A9 64890D00000000 mov dword ptr fs:[00000000], ecx
:0040F6B0 5B pop ebx
:0040F6B1 81C4A8040000 add esp, 000004A8
:0040F6B7 C3 ret
По адресу 40EBA8, как несложно убедиться, и вызывается вышеозначенное окно с
напоминанием. Протрассировав этот CALL вы увидите, что критичным для нас
является сравнение по адресу :0040EB82. Измените jne 0040EBA8 на NOP, NOP, и
запустите программу.
Все, окна исчезли, и программа работает. Переведите время, и вы убедитесь, что
она продолжает работать и после истечения срока.
Защиты паролем.
Регистрация WinWip 7.0
Загружаем WinZip32.exe в Softice , устанавливаем bpx GetDlgItemTextА и нажимаем
F5. В окне регистрации вводим свое имя и любой набор цифр в окне пароля (я
использую 12121212 для удобства), жмем "ОК" и попадаем в SoftIce. Bingo!
Нажимаем F12, и видим в SoftIce следующий листинг:
- - - - - - - - - - - - - - - - - - - - -
00408091 call [USER32!GetDlgItemTextA] <= имя для регистрации
00408097 push ebx
- - - - - - - - - - - -
- - - - - - - - - - - -
004080B3 call [USER32!GetDlgItemTextA] <= введенный вами рег.номер
004080B9 push esi
Очевидно, что происходит считывание введенных вами данных, и запись их адресов в
соответствующие регистры. Набрав d ebx мы увидим введенное нами имя, а в
регистре esi – введенный нами рег.номер. Выпишем значения регистров ebx
(0047DBA8) и ecx (0047DBD8) – они нам пригодятся в дальнейшем.
Смотрим код дальше:
- - - - - - - - - - - -
004080c6 cmp byte ptr[0047dba8],00
004080cd pop ecx
004080ce jz 0040812f
004080d0 cmp byte ptr[0047dbd8],00
004080d7 jz 0040812f
004080d9 call 00407bc8
004080de test eax,eax
004080e0 jz 0040812f
- - - - - - - - - - - -
Здесь тоже все ясно. По адресам 004080С6 и 004080D0 происходит проверка,
заполнены ли поля для имени и рег.номера. Если нет – то по адресу 0040812F
вызывается безобразное окно с надписью, что информация некорректная или
неполная. По адресу 004080D9 мы видим CALL, после которого производится
процедура сравнения, и если программу что-то не устраивает, вызов знакомого
безобразного окна. Видимо, в этом CALLе все и происходит. Чтож, взглянем на него
поближе. Просмотрев листинг, я среди кучи всякого непонятного хлама наткнулся на
следующие строчки:
00407bf9 mov edi,0047dba8
00407bfe push eax
00407bff push edi
00407c00 call 00407eae
- - - - - - - - - - - - -
00407c99 mov esi,00407dbd8
00407c9e pop ecx
00407c9f lea eax,[ebp-0140]
00407ca5 push esi
00407ca6 push eax
00407ca7 call 004579e0
- - - - - - - - - - - - - -
Очевидно, что в первом кусочке вызывается функция, использующая в качестве
одного из аргументов введенное вами имя, а во втором случае вызываемая функция
использует в качестве одного аргумента введенный вами рег.номер, а в качестве
второго – содерживое регистра еах. Дойдя до адреса 00407СА7 введите d eax, и вы
увидите заветный рег.номер. Осталось записать его на бумажку, закрыть SoftIce, и
зарегистрировать программу.
Кстати, поэкспериментировав в разными именами, вы увидите, что рег.номер
генерируется самой программой на основе вашего имени. Именно это и делает первый
кусочек приведенного листинга. Второй же кусочек использует сгенерированный код
для сравнения с введенным вами. Как оказалось, защита у этой программы очень
слабенькая, точнее, практически отсутствует.
Регистрация Multi-Edit 7.0
Найти Multi-Edit 7.0 можно на сервере компании American Cybernetics -
www.multiedit.com.
Для начала я покажу как решить проблему с сообщениями, появляющимися каждые 15
минут. Для этого стоит внимательно изучить функции Win32 API связанные со
временем. Исход из того, что программа отсчитывает промежутки в 15 минут,
наиболее подходящей функцией является GetTickCount. Эта функция возвращает
количество тиков со времени запуска Win95. Исходя из этого, проделаем следующее
- запустим SoftICE, за ним наш Multi-Edit. Закроем появившееся красивое окно с
сообщением, о том, что это демо-версия. Теперь мы в редакторе. Используя bpx
gettickcount я установил контрольную точку. Выйдя из SoftICE практическеи
мнгновенно попадаем обратно - в функцию GetTickCount.
Нажимаем F12. Теперь мы здесь:
sub_40F164 proc near
call j_GetTickCount
mov ecx, 37h
cdq
idiv ecx
retn
sub_40F164 endp
По виду этого куска кода не трудно догадаться,
что осуществляется пересчет тиков в более удобные(?)
единицы. Нажмем F12 еще раз. Теперь мы здесь:
sub_411748 proc near ; CODE XREF: sub_440430+43C
call sub_40F164 ; это и есть та самая функци
mov ds:dword_449388, eax ; сохраним текущее значение времени
mov eax, ds:dword_449388 ; бесполезная команда
cmp eax, ds:dword_44938C ; сравним
jz short loc_41176F ; равны - ничего не делаем
mov eax, ds:off_449A38 ; кол-во тиков равное (некоторое значение+15 минут)
mov edx, ds:dword_449388 ; текущее значение
call sub_40F1AC ; вредоносная процедура :)
loc_41176F: ; CODE XREF: sub_411748+15
mov eax, ds:dword_449388
mov ds:dword_44938C, eax
retn
sub_411748 endp
Особых пояснений требует только call sub_40F1AC. я не привожу эту процедуру
из-за ее громоздкости. Достаточно лишь понять основные ее функции. В общих
чертах, эта процедура проверяет, прошло-ли 15 минут со времени появления
предидущего демо-окна, и если прошло, показывает то самое окно. Теперь можно
подумать, как именно взламывать. Есть несколько вариантов, но что бы не копаться
во внутренностях программы, можно использовать простейший - вместо инструкции
call sub_40F1AC (кстати - ее длина 5 байт) использовать что-то вроде
xor eax,eax
xor eax,eax
nop
Таким образом мы успешно избавились от занудных напоминаний со стороны авторов.
Но еще есть над чем поработать! Не очень то хочется каждый раз при запуске
программы видеть то самое окно, от которого мы уже успешно избавились. Моя
первая мысль была - поставить что-то вроде bpx dialogboxparama, bpx
dialogboxindirectparama и запустить эту штуку. Попробуете сами. Никакой реакции.
Ну и ладно. Есть еще createdialogparama,
createdialogindirectparama и showwindow. Теперь
уже есть какой-то результат! Мы снова в SoftICE. А теперь попробуйте найти, что
же вызвало к жизни этот код. Если хотите чему-то научиться - не читайте дальше,
а попробуйте сами.
Нашли?
Теперь остается только изменить нужное условный/безусловный переход или вызов
функции. Остается найти и изменить это место в файле(mew32.dll). Сделаем это и
запустим все снова. В лучшем случае - у вас больше никогда не вызовется не одно
окно диалога и вообще никакое другое. В худшем - получите GPF of death... А вот
теперь и следует сесть и как следует подумать. Подумать очень хорошо. Какая
возможность позволяет неограниченно наращивать возможности Multi-Edit? Тот кто
его знает, ответят быстро - наличие внутреннего, очень мощного языка макросов.
Которые кстати компилируются в некоторое подобие исполняемого кода(в Multi-Edit
8.0 eval copy компилятор отсутствует - для этого то и нужен Multi-Edit 7.0 - там
он есть). Уже этого достаточно, чтобы найти решение. Если еще не нашли, то вот
вам несколько подсказок - для начала посмотрите файл Src/startup.s в том
каталогое где установлен Multi-Edit 7.0. Поле этого посмотрите в обоих
программах такой пункт меню - macro/list all macros... Я лично изучал этот
список около часа - из простого любопытства. Исходя из полученных сведений можно
сделать вывод о том, что ВЕСЬ интерфейс этих программ написан именно на
внутреннем языке макросов. Кроме этого есть там и такие замечательные макросы
как setserial, setdosserial, serial_test. Теперь выберите Macro/run... и введите
setserial. Никакого эффекта. Теперь Serial_test. То же самое. А теперь
setdosserial. А вот и окошечко для регистрации пользователей, обладающих старыми
версиями под Дос. Если у кого есть старый серийный номер - вводите. У кого нет -
идем дальше. Я подумал, что пытаться вычислить пароль не имеет смысла. Кто не
согласен - пусть попробует. Если получиться - буду очень рад об этом услышать
(сами пароли кстати очень простые). Помните, я говорил посмотреть файл Src/startup.s?
Если посмотрели, то какие идеи вам приходят в голову? Если у кого этого файла
нет (его нет в Multi-Edit 8.0) ,то вот его содержимое:
// #define MEWDEMO
macro STARTUP DUMP {
// The following code used only for the demo
#ifdef MEWDEMO
rm('mewdemo^calclag');
rm('mewdemo^nagevent');
#endif
}
Здесь rm обозначет run macro. Все еще нет идей? Тогда попробуйте поискать
строчки mewdemo^calclag и mewdemo^nagevent в файле mac/mew.mcl в директории с
MEW8. Если нашли - то попробуйте заменить их на что-то вроде sdfffwgbssbsqepa.
Как вы вероятно догадолись, а вычитал в файлах помощи, скомпилированный файл
может содержать несколько макросов, и поэтому в теле файла хранятся имена
содержащихся макросов. А в том, что теперь будет вызываться макрос, которого
якобы не существует нет ничего страшного - об этом никто никого не уведомляет.
Более того - это более эффективный взлом, чем тот, что мы использовали для
подавления 15-минутных напоминаний. Если избавиться от этих двух макросов с
самого начала, то и напоминания не дадут о себе знать.
Регистрация Xmcoder
Программа - Xmcoder - www.xingtech.com
Для того чтоб зарегистрировать программу ее следует изучить т.е. посмотреть ее
реакцию на введение s/n, unlocking code или reg.no. Сообщения которые выдает
программа на введение неверных ключевых данных лучше запомнить или записать -
они нам еще понадобятся.
Используемые инструменты: SoftICE,WDasm89
Запускаем xmencoder. Жмем кнопку Buy now.Попали в экран User Registration -
заполняем все поля информацией т.к. программа очень требовательна и не допускает
пустых полей ;) Ok! Заполнили. Идем дальше. Предлагают купить Item(s) -
проверяем кошелек если есть лишние $89 дальше лучше не читайте, а просто
заплатите и все . Идем далее. Предлагают выбрать способ оплаты. Мне понравилась
Visa (т.к. не надо лишний раз тыкать мышой) Пишете ваш номер кредитки если есть,
если нет то попробуйте подобрать любой подходящий ежели лень, то подсказываю: 13
шестерок проходит на УРА! Далее попадаем в форму для комментариев - вот где душу
можно отвести и клаву потоптать! Но помните, скорее всего никто не прочтет ваши
излияния . После комментариев проходим еще один экран последнего подтверждения
информации и ...
Попадаем в экран выбора способа оплаты Выберите OREDER BY PHONE и дальше. Теперь
спрашивают unlocking code. Введите любой бред. Получите сообщение типа Sorry,
that unlocking code .... что-ж, не угадали . Теперь поищем эту строку в
директории с Xing MPEG Encoder'ом. Вуаля - Есть вхождение в rsagnt32.dll
Дизассемблируем его, и находим 4 ссылки на эту строку
* Reference To: USER32.GetDlgItemTextA, Ord:00F5h
:1000466A FF15A4850310 Call dword ptr [100385A4] ;читаем unlocking code
:10004670 B9FFFFFFFF mov ecx, FFFFFFFF
:10004675 2BC0 sub eax, eax
:10004677 F2 repnz ;вычисляем длину
:10004678 AE scasb
:10004679 F7D1 not ecx
:1000467B 49 dec ecx
:1000467C 83F90A cmp ecx, 0000000A ;если не равно
:1000467F 743E je 100046BF ;10 то выдаем
:10004681 A164F20210 mov eax, dword ptr [1002F264] ;сообщение
* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is "
->"not valid for this program."
:10004686 6818150210 push 10021518
(такая же конструкция находится по адресу 10001F03; какая исполняется очевидно
зависит от выбранного способа оплаты) Нам надо поменять условный переход на
безусловный т.е.
:1000467F EB3E jmp 100046BF
и параллельно
:10001F25 7440 je 10001F67
на
:10001F25 EB40 jmp 10001F67
Можно конечно и не менять а ввести любую белиберду из 10 знаков Оппа! Вторая
часть полученного сообщения наводит на мысль о том, что программа защищена
Release Software Agent Но первая часть осталась неизменной Sorry, that unlocking
code ...
Что-ж, смотрим далее
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:10001FCA(C)
:10002288 A164F20210 mov eax, dword ptr [1002F264]
* Possible StringData Ref from Data Obj ->"Sorry, that unlocking code is"
->"not valid for this program."
:1000228D 6818150210 push 10021518
(аналогичная конструкция по адресу :1000474D).
Посмотрим на условный переход, который нас сюда
приносит с адреса 10001FCA
:10001FBA 6860FE0210 push 1002FE60 ;заносим в стек
:10001FBF 51 push ecx ;параметры ф-ции
:10001FC0 E89BDC0100 call 1001FC60 ;вызывается ф-ция
:10001FC5 83C408 add esp, 00000008 ;корректируется стек
:10001FC8 85C0 test eax, eax ;проверяется возвращаемое знач-е
:10001FCA 0F85B8020000 jne 10002288 ;если не 0
то выдаем уже знакомое нам сообщение
Если посмотреть на ф-цию по адресу
1001FC60, то там можно увидеть
:1001FC60 55 push ebp ;сохраняем индексный регистр
:1001FC61 8BEC mov ebp, esp ;сохраняем позицию стека
:1001FC63 57 push edi
:1001FC64 56 push esi
:1001FC65 53 push ebx
:1001FC66 8B750C mov esi, dword ptr [ebp+0C] ;берем один параметр ф-ции
:1001FC69 8B7D08 mov edi, dword ptr [ebp+08] ;берем другой параметр ф-ции
:1001FC6C 8D05688C0210 lea eax, dword ptr [10028C68]
:1001FC72 83780800 cmp dword ptr [eax+08], 00000000
:1001FC76 753B jne 1001FCB3 ;по этому переходу мы тоже будем проверять
строки, но немножко по-другому,
очевидно, это зависит от продукта к-рый
регистрируем
:1001FC78 B0FF mov al, FF ;загружаем в eax
:1001FC7A 8BC0 mov eax, eax ;начальные данные
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:1001FC88(C), :1001FCA8(C)
:1001FC7C 0AC0 or al, al ;начало цикла сравнения
:1001FC7E 742E je 1001FCAE ;если нечего сравнивать уходим
:1001FC80 8A06 mov al, byte ptr [esi];берем символ из одной строки
:1001FC82 46 inc esi ;увеличиваем счетчик первой строки
:1001FC83 8A27 mov ah, byte ptr [edi];берем символ из другой строки
:1001FC85 47 inc edi ;увеличиваем счетчик второй строки
:1001FC86 38C4 cmp ah, al ;сравниваем
:1001FC88 74F2 je 1001FC7C ;если равно, то на
начало цикла
:1001FC8A 2C41 sub al, 41 ;преобразуем в нижний регистр
:1001FC8C 3C1A cmp al, 1A ;один символ
:1001FC8E 1AC9 sbb cl, cl
:1001FC90 80E120 and cl, 20
:1001FC93 02C1 add al, cl
:1001FC95 0441 add al, 41
:1001FC97 86E0 xchg al, ah
:1001FC99 2C41 sub al, 41 ;а теперь другой
:1001FC9B 3C1A cmp al, 1A
:1001FC9D 1AC9 sbb cl, cl
:1001FC9F 80E120 and cl, 20
:1001FCA2 02C1 add al, cl
:1001FCA4 0441 add al, 41
:1001FCA6 38E0 cmp al, ah ;сравним и если равно
:1001FCA8 74D2 je 1001FC7C ;то на начало цикла
:1001FCAA 1AC0 sbb al, al ;если нет, то очищаем
al
:1001FCAC 1CFF sbb al, FF ;заносим в al 1
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:1001FC7E(C)
:1001FCAE 0FBEC0 movsx eax, al
:1001FCB1 EB6F jmp 1001FD22 ;на выход (в
eax результат сравнения)
Нам надо, чтоб ф-ция
выдавала всегда 0 в eax, для
этого есть много способов, я выбрал следующий:
:1001FCAC 33C0 xor eax, eax
В результате ф-ция всегда вернет нам
0 в eax - что нам и надо :))
Патчим rsagnt32.dll, запускаем
xmcoder и ... получаем сообщение
Application Error : Important application files are missing or corrupted :((
Значит программа вычисляет контрольную сумму
rsagnt32.dll. Поищем эту строку в каталоге программы.
Нашли в xmcoder.exe Дизассемблируем его и
увидим 2 обращения к этой строке в одной и той же ф-ции,
вот ее текст
:004033D0 56 push esi
:004033D1 6A00 push 00000000
:004033D3 6A00 push 00000000
:004033D5 E816FAFFFF call 00402DF0
:004033DA 83C408 add esp, 00000008
:004033DD 83F801 cmp eax, 00000001 ;проверка значения возвращаемого
:004033E0 7433 je 00403415 ;ф-цией если не
1 то получаем MessageBox
:004033E2 6810200000 push 00002010
* Reference To: USER32.MessageBoxA, Ord:0195h
|
:004033E7 8B3548C54200 mov esi, dword ptr [0042C548] ;заносим адрес
MessageBoxA в esi и в стек параметры вызова
* Possible StringData Ref from Data Obj ->"Application Error"
|
:004033ED 6884844100 push 00418484
* Possible StringData Ref from Data Obj ->"Important application files are "
->"missing or corrupted."
|
:004033F2 6834844100 push 00418434
:004033F7 6A00 push 00000000
:004033F9 FFD6 call esi ;непосредственно вызов
MessageBoxA
:004033FB A100F14100 mov eax, dword ptr [0041F100]
:00403400 50 push eax
:00403401 E86A450000 call 00407970
:00403406 83C404 add esp, 00000004
:00403409 6A00 push 00000000
:0040340B E880870000 call 0040BB90
:00403410 83C404 add esp, 00000004
:00403413 EB06 jmp 0040341B
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004033E0(C)
|
* Reference To: USER32.MessageBoxA, Ord:0195h
|
:00403415 8B3548C54200 mov esi, dword ptr [0042C548] ;в
esi заносим адрес MessageBoxA
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403413(U)
|
:0040341B E8B0E8FFFF call 00401CD0 ;вызов ф-ции
:00403420 85C0 test eax, eax ;проверка возвращаемого значения
:00403422 752B jne 0040344F ;и если eax=0
получаем MessageBox с ошибкой если
eax=0 идем на ret
:00403424 6810200000 push 00002010 ;в стек параметры вызова
MessageBox'а
* Possible StringData Ref from Data Obj ->"Application Error"
|
:00403429 6884844100 push 00418484
* Possible StringData Ref from Data Obj ->"Important application files are "
->"missing or corrupted."
|
:0040342E 68E4834100 push 004183E4
:00403433 6A00 push 00000000
:00403435 FFD6 call esi
:00403437 A100F14100 mov eax, dword ptr [0041F100]
:0040343C 50 push eax
:0040343D E82E450000 call 00407970
:00403442 83C404 add esp, 00000004
:00403445 6A00 push 00000000
:00403447 E844870000 call 0040BB90
:0040344C 83C404 add esp, 00000004
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:00403422(C)
|
:0040344F 33C0 xor eax, eax
:00403451 5E pop esi
:00403452 A3D8F24100 mov dword ptr [0041F2D8], eax
:00403457 A3A0C94100 mov dword ptr [0041C9A0], eax
:0040345C A3DCF24100 mov dword ptr [0041F2DC], eax
:00403461 C3 ret
Изменим 2 условных перехода на безусловные и
запустим xmcoder
:004033E0 EB33 jmp 00403415
:00403422 EB2B jmp 0040344F
Уверенно жмем Buy now, проходим уже знакомые
экранные формы и .... получаем поздравительное
рукопожатие (одна из этих рук на картинке точно моя
;)))! Поздравляю! После минутного процесса получаете полнофункциональный
XING MPEG Coder. Правда я не проверял - не моя специфика, но все вроде выглядит
достоверно :)) 2Release Software Agent: Фуфло гоните ребята! Хоть бы строки
зашифровывали!
Подводим итоги :
Xing MPEG Coder cracked by Gas
rsagnt32.crk
1325 74 EB
3A7F 74 EB
1F0AC 1C 33
1F0AD FF C0
xmcoder.crk
27E0 74 EB
2822 75 EB
Есть еще один метод взлома этой программы. В ассемблерном листинге есть код,
загружающий библиотеку RSAGENT32.DLL. Эта библиотека служит для 'защиты'
программы. Достаточно найти в листинге вызов, возвращающий статус программы -
зарегистрирована/незарегистрирована и поменять соответсвующие переходы так,
чтобы программа считала, что она зарегистрирована. Этот метод более общий, а
также более простой - изменяем один файл, не надо искать схему, проверяющую
целостность файлов.
Регистрация Phone Book Pro 97
Эта программа показывает окно с надписью "Незарегистрированная версия", которое
не исчезает очень долго. Механизм ввода пароля Тоже сам по себе интересен: в нем
отсутствуют кнопки, из чего можно сделать вывод, что проверка правильности
введенного пароля происходит "на лету", в процессе ввода. Введя информацию в
регистрационные поля, запускаем SoftIce, ставим bpx Hmemcpy, и нажимаем F5.
После чего вводим еще одну цифру в поле для рег.номера... мы оказываемся в
SoftIce. Нажимаем F12 , пока не окажемся в следующем месте:
:004726EA E89104FBFF call 00422B80 <= процедура считывания, сюда мы попали
:004726EF 8B45FC mov eax, dword ptr [ebp-04]
:004726F2 50 push eax
:004726F3 8D55F8 lea edx, dword ptr [ebp-08]
:004726F6 A13CF84D00 mov eax, dword ptr [004DF83C]
:004726FB 8B8000020000 mov eax, dword ptr [eax+00000200]
:00472701 E87A04FBFF call 00422B80
:00472706 8B4DF8 mov ecx, dword ptr [ebp-08]
:00472709 8BD3 mov edx, ebx
:0047270B 8BC3 mov eax, ebx
:0047270D E8BAFAFFFF call 004721CC
:00472712 84C0 test al, al <= явно процедура проверки. Если al<>1, то не
зарегистрирован
:00472714 7456 je 0047276C
:00472716 B201 mov dl, 01
:00472718 8B83F4010000 mov eax, dword ptr [ebx+000001F4]
Итак, по адресу 472712 происходит проверка содержимого al, и если оно равно 0,
то переход на продолжение этого цикла. Чтож, поправим программу. Заменим
test al,al на or al,01. Вносим изменения в
файл, запускаем его, и пытаемся зарегистрироваться. Есть! У нас появилась еще
одна кнопка с надписью "Register PB Pro 97". Нажимаем
ее, программа говорит "Спасибо за регистрацию", и закрывается для внесения
соответствующих изменений. Запускаем ее снова, и видим, что от окошка
регистрации мы так и не избавились. Значит, существует еще одна проверка.
Открываем файл с помощью WinDASM, и ищем строку типа
"Unregistered..." и т.д.
Натыкаемся на строку "This is an Unregistered
version...". Дважды щелкаем по ней мышкой, и попадаем в участок кода, где
эта строка находится. Прокрутив код наверх, видим следующее:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:004C3AF6(C)
|
:004C3BEA 8B0DC0DE4D00 mov ecx, dword ptr [004DDEC0]
:004C3BF0 8B09 mov ecx, dword ptr [ecx]
:004C3BF2 B201 mov dl, 01
:004C3BF4 A174694700 mov eax, dword ptr [00476974]
:004C3BF9 E83EA5F6FF call 0042E13C
:004C3BFE 8B1594DD4D00 mov edx, dword ptr [004DDD94]
:004C3C04 8902 mov dword ptr [edx], eax
:004C3C06 A194DD4D00 mov eax, dword ptr [004DDD94]
:004C3C0B 8B00 mov eax, dword ptr [eax]
:004C3C0D 8B80DC010000 mov eax, dword ptr [eax+000001DC]
:004C3C13 BA9F400000 mov edx, 0000409F
:004C3C18 E88BBAF7FF call 0043F6A8
:004C3C1D A194DD4D00 mov eax, dword ptr [004DDD94]
:004C3C22 8B00 mov eax, dword ptr [eax]
:004C3C24 8B80DC010000 mov eax, dword ptr [eax+000001DC]
:004C3C2A 8B5024 mov edx, dword ptr [eax+24]
:004C3C2D D1EA shr edx, 1
:004C3C2F 8B0D94DD4D00 mov ecx, dword ptr [004DDD94]
:004C3C35 E86EBAF7FF call 0043F6A8
:004C3C3A A194DD4D00 mov eax, dword ptr [004DDD94]
:004C3C3F 8B00 mov eax, dword ptr [eax]
:004C3C41 8B80E0010000 mov eax, dword ptr [eax+000001E0]
* Possible StringData Ref from Code Obj ->"This is an unregistered version, "
->"please consult "REGISTER.TXT" "
->"for more details."
|
:004C3C47 BA68414C00 mov edx, 004C4168
:004C3C4C E85FEFF5FF call 00422BB0
Ясно, что попадаем мы сюда из перехода по адресу 004C3AF6 . Смотрим на этот
адрес:
:004C3AEF E8D8E6FAFF call 004721CC
:004C3AF4 84C0 test al, al
:004C3AF6 0F84EE000000 je 004C3BEA <= тот самый переход
:004C3AFC 8B83C4050000 mov eax, dword ptr [ebx+000005C4]
Снова меняем test al,al на or al,01, и CRACK готов.
Регистрация Portscan
Эта программа при запуске показывает окно с предложением зарегистрироваться,
которое не исчезает с экрана в течении 30 секунд. Также незарегистрированная
версия программы ограниченна по возможностям сканирования. Мало того, тоже самое
окно с напоминанием появляется и при закрытии программы.
Итак, начнем. Запускаем программу, вводим требуемые данные, входим в SoftIce (Ctrl
– D), и набираем следующее: S DS:0 LFFFFFFFF "введенный номер" – это команда
поиска указанной строки (в данном случае введенного номера) в памяти. SoftIce в
ответ указывает, где он нашел эту строку. Ставим точку прерывания на этот адрес
(BPMB DS:НАЙДЕННЫЙ АДРЕС RW (по чтению и записи), выходим из SoftIce (F5), и
нажимаем кнопку "ОК". Немедленно мы оказываемся в SoftIce в модуле KERNEL.
Нажимаем F12 несколько раз, пока мы не окажемся в теле нашей программы. А далее
с помощью кнопки F12 двигаемся к выходу по каскаду вызовов до тех пор, пока не
попадем в следующее место:
: 12D6 9A531DF812 call 0011.1D53 <= вот отсюда мы вышли
: 12DB 9AC737C117 call 0002.37C7 <=явно процедура проверки
: 12E0 08C0 or al , al <= если al = 0, то незарегистрированны
: 12E2 7479 je 135D
: 12E4 8DBE00FD lea di, [bp+FD00]
:.12E8 16 push ss
Заходим в процедуру проверки по адресу 12DB . Первый раз нас выкидывает из
проверки на следующем участке:
:.37FF 50 push ax
:.3800 55 push bp
:.3801 FF36980E push word ptr [0E98]
:.3805 8926980E mov [0E98], sp
:.3809 80BEFEFD19 cmp byte ptr [bp+FDFE], 19 <= сравнение длины введенного
номера с 25
:.380E 7319 jnb 3829 <= если меньше, то выход из проверки
:.3810 80BE10FE2D cmp byte ptr [bp+FE10], 2D
: 3815 7412 je 3829
: 3817 80BE14FE2D cmp byte ptr [bp+FE14], 2D
Поправляем длину введенного номера, и пробуем снова. Трассируем программу, пока
не дойдем до следующего участка:
:.383E 9A8B398238 call 0002.398B
:.3843 8886FCFD mov [bp+FDFC], al
:.3847 8A86FDFD mov al , [bp+FDFD]
:.384B 3A86FCFD cmp al , [bp+FDFC] <=сравнение содержимого al c [bp+FDFC]
:.384F 7506 jne 3857 <= если не равны, то в [bp-01] пишется 0 по адресу 3857
:.3851 C646FF01 mov byte ptr [bp-01], 01 <= если равны, то в [bp-01] пишется 1
:.3855 EB04 jmp 385B <= переход на конец процедуры
:.3857 C646FF00 mov byte ptr [bp-01], 00 <= запись 0 в [bp-01]
:.385B 8F06980E pop word ptr [0E98]
:.385F 83C406 add sp, 0006
:.3862 EB25 jmp 3889
:.3864 C646FF00 mov byte ptr [bp-01], 00
:.3868 EB1A jmp 3884
:.386A 8986F8FD mov [bp+FDF8], ax
:.386E 8996FAFD mov [bp+FDFA], dx
:.3872 BFA237 mov di, 37A2
:.3875 0E push cs
:.3876 57 push di
:.3877 FFB6FAFD push word ptr [bp+FDFA]
:.387B FFB6F8FD push word ptr [bp+FDF8]
:.387F 9A0936A038 call 0002.3609
:.3884 9AA50FAB38 call 0015.0FA5
:.3889 8A46FF mov al , [bp-01] <= запись в al содержимого [bp-01]
:.388C C9 leave
:.388D CA0800 retf 0008
Как видно, нам требуется всего лишь поменять JNE 3857 по адресу 384F на JMP
3851, и CRACK готов.
FlexEd v3.2 - Delphi программа
При установке программа выводит окно с надписью "Unregistered" и предложением
зарегистрироваться. Без регистрации программа работает только 30 дней.
Программы, написанные на Delphi, отличаются тем, что имеют очень много вложенных
вызовов, и прослеживать все цепочки довольно трудно. Поэтому мы пойдем другим
путем.
Нажимаем кнопку "Register", вводим в поля требуемую информацию, нажимаем Ctrl-D,
и в SoftIce набираем
s ds:0 lffffffff "введенный рег.номер" (поиск в памяти введенного нами
рег.номера). SoftIce выводит сообщение типа "Pattern found at ............" .
Теперь ставим точку прерывания на этот участок памяти:
bpmb ds:<адрес, найденный SoftIce> rw, и нажимаем F5. В программе нажимаем
кнопку "ОК", и немедленно попадаем в SoftIce в модуль Kernel32. Жмем F12, пока
не попадем обратно во FlexEd32, и повторяем первые две процедуры – ищем в памяти
введенный нами номер, и ставим точку прерывания на этот участок памяти. Нажимаем
F5, и оказываемся в следующем месте:
MOV ECX, [ESI] <= запись правильного номера в ECX
MOV EBX, [EDI] <= запись введенного нами номера в EBX
CMP ECX,EBX < = здесь мы остановились
JNZ 0040399D
Здесь программа записывает правильный рег.номер, вычисленный из нашего имени, в
ЕCХ, потом заносит введенный нами рег.номер в ЕВХ , и сравнивает. В регистре ESI
мы и увидим вычисленный для нас рег.номер.
Защита лицензией или внешним .EXE
Silverrun ERX
Итак, при запуске программа выводит сообщение:
"No license. The application will run in restricted mode."
Как от этого избавиться?
Первое: окно нестандартное, значит ловить его чем-то типа bpx showwindow и т.д.
бесполезно.
Второе: окон для регистрации нет.
Третье: программа определяет "лицензию" при загрузке: значит, она берет ее из
какого-то файла или реестра.
Загружаем программу в WinDasm и ищем ссылку на строку
"The application will run in restricted mode".
Находим:
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0051B283(C)
|
:0051B29D 8D856CFEFFFF lea eax, dword ptr [ebp+FFFFFE6C]
:0051B2A3 50 push eax
:0051B2A4 E853170100 call 0052C9FC
:0051B2A9 83C404 add esp, 00000004
:0051B2AC 898564FEFFFF mov dword ptr [ebp+FFFFFE64], eax
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0051B259(C)
|
* Possible Reference to String Resource ID=00091: "The application will run in
restricted mode."
|
:0051B2B2 6A5B push 0000005B
:0051B2B4 B890010000 mov eax, 00000190
:0051B2B9 2B8564FEFFFF sub eax, dword ptr [ebp+FFFFFE64]
:0051B2BF 50 push eax
:0051B2C0 8B8564FEFFFF mov eax, dword ptr [ebp+FFFFFE64]
:0051B2C6 8D84056CFEFFFF lea eax, dword ptr [ebp+eax-00000194]
:0051B2CD 50 push eax
:0051B2CE E89DAA0000 call 00525D70
:0051B2D3 83C40C add esp, 0000000C
Видим, что вызов нужного нам окна
осуществляется по адресам 0051B283 и
0051B259. Загружаем программу в SoftIce и ставим bpx на эти точки. Жмем
F5.
:0051B255 837DFC00 cmp dword ptr [ebp-04], 00000000
:0051B259 0F8453000000 jz 0051B2B2 <= первое попадание
:0051B25F B890010000 mov eax, 00000190
:0051B264 2B8564FEFFFF sub eax, dword ptr [ebp+FFFFFE64]
:0051B26A 50 push eax
:0051B26B 8B8564FEFFFF mov eax, dword ptr [ebp+FFFFFE64]
:0051B271 8D84056CFEFFFF lea eax, dword ptr [ebp+eax-00000194]
:0051B278 50 push eax
:0051B279 E842050000 call 0051B7C0
:0051B27E 83C408 add esp, 00000008
:0051B281 85C0 test eax, eax
:0051B283 0F8414000000 jz 0051B29D <= второе попадание
:0051B289 C70594EB530000000000 mov dword ptr [0053EB94], 00000000
Итак, мы видим, что по адресу 51b283 осуществляется переход на процедуру вызова
нужного нам окна, если eax=0.
Два варианта решения:
1) Исследовать Call 0051b7c0, и найти место, где eax становится нулем.
2) Изменить jz 0051b29d на jmp <следующая строка>
Оба решения работают, но я предпочитаю первое, как более элегантный crack.
Делается это так: в WinDASM идем в конец нужного нам call
и видим следующее:
:0051BA82 FF1570665400 Call dword ptr [00546670]
:0051BA88 8B8510FFFFFF mov eax, dword ptr [ebp+FFFFFF10]
:0051BA8E E900000000 jmp 0051BA93
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:0051B81F(U), :0051BA8E(U)
|
:0051BA93 5F pop edi
:0051BA94 5E pop esi
:0051BA95 5B pop ebx
:0051BA96 C9 leave
:0051BA97 C3 ret
Можете поставить bpx 51ba88 и убедиться, что в еах записывается значение 0 из
[ebp+FFFFFF10].
Значит, нам следует найти место, где в этот адрес записывается 0. Заходим в
начало нужного нам CALL и видим:
* Referenced by a CALL at Address:
|:0051B279
|
:0051B7C0 55 push ebp
:0051B7C1 8BEC mov ebp, esp
:0051B7C3 81ECF4030000 sub esp, 000003F4
:0051B7C9 53 push ebx
:0051B7CA 56 push esi
:0051B7CB 57 push edi
:0051B7CC C78510FFFFFF00000000 mov dword ptr [ebp+FFFFFF10], 00000000
Вот оно! Меняем mov dword ptr [ebp+FFFFFF10], 00000000 на mov dword ptr
[ebp+FFFFFF10], 00000001, запускаем программу с проделанными изменениями.
Окно исчезло, GENTLE CRACK готов!
Как отучить игры от проверки CD-ROM
(на примере Hellfire)
Использованные программы: Hellfire v2.0, W32Dasm v8.9, Dos Navigator v1.5
В статье рассматриваются следующие вопросы:
1. Заменяем в программе HellFire v2.0 проверку с диска CD-ROM на сетевой диск
2. Пишем Fake-CD для OS Windows 95
Заменяем в программе HellFire v2.0 проверку с диска CD-ROM на сетевой диск
Суть проблемы состоит в том, чтобы доказать программе, что винчестер на самом
деле совсем не винчестер, а CD-ROM. Или скажем - как в данном случае - в выдаче
за локальный CD сетевого, ну один CD на работе, а играть-то всем охота!
Приступим. Цель - Функция GetDriveType(). Она возвращает тип диска, имя которого
ей передали. Вот ее прототип:
UINT GetDriveType(LPCTSTR lpRootPathName);
Функция возвращает следующие значения:
Числовое значение Идентификатор Описание диска
0 - Невозможно определить тип
1 - Диск не найден
2 DRIVE_REMOVABLE Гибкий (возможна замена)
3 DRIVE_FIXED Жесткий (замена невозможна)
4 DRIVE_REMOTE Сетевой диск
5 DRIVE_CDROM CD-ROM
6 DRIVE_RAMDISK RAM - Диск
Стандартно программа получает список всех дисков, проверяет их на "CDромность" и
по нахождению проверяет наличиенужных файлов. Для проверки, необходимо,
очевидно, сравнить возвращаемое значение с 5. Найдем этот момент программы,вот
как он выглядит после дизассемблирования HellFire с помощью W32Dasm :
Reference To: KERNEL32.GetDriveTypeA, Ord:00DFh
|
:0041D976 FF151CA56F00 Call dword ptr [006FA51C]
:0041D97C 83F805 cmp eax, 00000005
:0041D97F 752A jne 0041D9AB
В принципе можно использовать любой другой дизассемблер, или SoftICE, в
последнем случае для нахождения нужного куска необходимо написать:
bpx GetDriveType
bpx GetDriveTypeA
В самом же W32Dasm можно воспользоваться списком использованных функций. Ищем
KERNEL32.GetDriveTypeA и два раза щелкаем по функции мышью. В IDA такой список
есть в конце отдизассемблированного файла. Листинг полученный Sourcer'ом
придется исследовать обычным текстовым поиcком.
Запишем HEX-DUMP этого куска и найдем его в шеснадцатеричном редакторе. Например
в DN: откроем файл hellfire.exe по F3, далее F4 (переход в HEX режим), F7
(поиск), в строке ввода HEX строки введем записанное ранне и вперед (т.е. ENTER).
Вместо 83F805 введем 83F804 и любой из подключенных сетевых дисков теперь будет
восприпринят прораммой за CD, иначе введем 83F803 - тогда жесткие диски будут
приниматься за CD. Фантазия может развиваться по-любому, можно изменить условие
перехода после сравнения, тогда не придется заботится о типе диска.
Пишем Fake-CD для OS Windows 95
Для DOS существовала прекрасная утилита - FakeCD, которая подменяла MSСDEX и
эмулировала таким образом CD-диск который, на самом деле, был каталогом на
винчестере. Для Win95 такую программу найти не просто, поэтому необходимо ее
сделать самим. Этим мы и займемся, тем более, что это будет прекрасная практика
по копанию в недрах 95'ого.
Посмотрим на проблему, обсуждавшуюся раннее, с другой стороны. Заменим не
использование функции, а саму функцию. Если в DOS для замены функций необходимо
только было изменить обработчик прерываний, то в Windows такой финт уже не
поможет. Выясним, где "живет" GetDriveType(). И - о ужас - это главная
библиотека Win95 KERNEL32.DLL. Что делать? Как всегда, запастись кофе и
напуcтить на KERNEL32.DLL дизассемблер. OK, ждем окончания процесса и смотрим
список экспортируемых функций. Вот нужная нам:
Exported fn(): GetDriveTypeA - Ord:013Fh
:BFF777C4 57 push edi
:BFF777C5 6A21 push 00000021
...
...
...
:BFF777E1 F2 repnz
:BFF777E2 AE scasb
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:BFF777DA(C)
|
:BFF777E3 648F02 pop dword ptr fs:[edx]
:BFF777E6 83C408 add esp, 00000008
:BFF777E9 5F pop edi
:BFF777EA E9E5D4FFFF jmp BFF74CD4
Делаем переход в конце(кнопка Jump to на панели W32Dasm) и видим продолжение.
Функция, оказывается-то, длинная! Не будем в ней разбираться, а лучше вспомним
как происходит возврат значения из функции. Т.о. ищем строку типа
mov eax,03000000
Нашли? Далее, как и при любом взломе, запомним последовательность HEX кодов
нужной команды (а лучше нескольких следующих, так как загрузка в аккумулятор
числа 3 не самая редкая операция) и найдем этот блок в копии библиотеки (в копии
- потому что файл используется системой и не может быть изменен). Все, осталось
лишь в режиме DOS подменить KERNEL32.DLL. Перезагрузимся и в Проводнике
насладимся результатом - все ваши жесткие диски представленны в виде кругленьких
пластинок ранее обозначавших CD.
А теперь - для ленивых - кусок кода, который возвращает 3:
* Possible Reference to String Resource ID=00003: "....."
| :BFF74E0F B803000000 mov eax, 00000003 //Возвращаемое значение
:BFF74E14 EB05 jmp BFF74E1B //Переход на возврат
* Referenced by a (U)nconditional or (C)onditional Jump at Addresses:
|:BFF74DEB(C), :BFF74DFC(C), :BFF74E0D(C)
|
* Possible Reference to String Resource ID=00006: "..."
Да - лучше сохранить старый KERNEL32, так как некоторые программы могут не
оценить ваш юмор, и решить, что несколько CD и ни одного винчестера - это
слишком. А вообще идеально было бы изменить функцию коренным образом. Скажем
сделать CD дисками все, начиная с T. Тогда можно было бы подключать subst'ом
каталоги, которые были бы CD, а винчестеры остануться винчестерами. Но это уже
задание на дом. Удачи!
SRULER - наш инструмент
В этом примере мы разберем новый инструмент, Sruler, модифицируем его, и увидим
один из способов его применения.
Одно из замечательных свойств этой программы – это способность показывать в
пикселах ширину и высоту окна, что можно применять при исследовании. Покажем это
на примере самой этой программы. Запустите вторую копию этой программы, и
щелкните по линейке правой кнопкой мыши. В появившемся меню выберите пункт "About",
и первой копией измерьте размеры окна. Получится 290х378 пикселов (122х17С в
16-тиричной системе). Теперь в листинге Srulerа найдите ссылку на 17С, и вы
найдете следующее:
:00403C6C 6A00 push 00000000
:00403C6E 687C010000 push 0000017C
:00403C73 6822010000 push 00000122
:00403C78 6A32 push 00000032
:00403C7A 6A32 push 00000032
:00403C7C FF7508 push [ebp+08]
* Reference To: USER32.MoveWindow, Ord:0190h
|
:00403C7F FF159CE34000 Call dword ptr [0040E39C]
Вот вы и нашли вызов требуемого окна. При этом не зависит, какой процедурой
вызывается окно, то ли MessageBox, то ли ShowWindow, то ли CALL EAX....
Теперь модифицируем наш инструмент:
Во-первых, если год более 1998, то программа выдает сообщение, что она устарела.
Поищем в WinDASM ссылку на эту строку:
:0040300A 89C1 mov ecx, eax
:0040300C 09C9 or ecx, ecx
:0040300E 7414 je 00403024
* Possible StringData Ref from Data Obj ->"This is an old version of Screen "
->"Ruler. Get an updated version."
|
:00403010 6812A54000 push 0040A512
:00403015 8D85ACFEFFFF lea eax, dword ptr [ebp+FFFFFEAC]
:0040301B 50 push eax
:0040301C E81B140000 call 0040443C
:00403021 83C408 add esp, 00000008
* Referenced by a (U)nconditional or (C)onditional Jump at Address:
|:0040300E(C)
|
:00403024 6A0A push 0000000A
Сразу ясно, что достаточно поменять
je 00403024 на jmp 00403024 (в
Hiew jmps для соблюдения числа байт), и это
сообщение перестанет появляться.
Во-вторых, периодически программа выводит сообщение "Please register
Ruler", а после определенного количества запусков еще и "Used ... times". Опять
ищем ссылки на эти строки, и находим:
* Possible StringData Ref from Data Obj ->"Please register Screen Ruler."
|
:00402FA7 BE02A44000 mov esi, 0040A402
:00402FAC B900010000 mov ecx, 00000100
:00402FB1 F3 repz
:00402FB2 A4 movsb
:00402FB3 8B45F0 mov eax, dword ptr [ebp-10]
:00402FB6 83B8CC0100001E cmp dword ptr [eax+000001CC], 0000001E <=если
более 30 запусков
:00402FBD 763A jbe 00402FF9 <= то идем дальше
:00402FBF 8D7DB0 lea edi, dword ptr [ebp-50]
:00402FC2 BE90804000 mov esi, 00408090
:00402FC7 B940000000 mov ecx, 00000040
:00402FCC F3 repz
:00402FCD A4 movsb
:00402FCE FFB0CC010000 push dword ptr [eax+000001CC]
* Possible StringData Ref from Data Obj ->" Used %i times."
|
:00402FD4 6802A54000 push 0040A502
:00402FD9 8D45B0 lea eax, dword ptr [ebp-50]
:00402FDC 50 push eax
Меняем jbe 00402FF9 на jmp
00402FF9, и от второй надписи мы избавились.
Как видно, первая надпись появляется на экране в течение определенного
промежутка времени (3 секунды), поэтому давайте поищем ссылку на функцию
SetTimer:
:004025FB E8EA100000 call 004036EA <= выработка псевдо-случайного числа
:00402600 83C404 add esp, 00000004
:00402603 89C1 mov ecx, eax
:00402605 83F901 cmp ecx, 00000001
:00402608 752B jne 00402635 <= выводится сообщение или нет
:0040260A 6A00 push 00000000
:0040260C 68B80B0000 push 00000BB8 <= 3000 мсек, задержка таймера
:00402611 6880000000 push 00000080
:00402616 8B45F0 mov eax, dword ptr [ebp-10]
:00402619 FF7008 push [eax+08]
* Reference To: USER32.SetTimer, Ord:01FEh
|
:0040261C FF15E0E34000 Call dword ptr [0040E3E0]
:00402622 56 push esi
Поменяйте jne 00402635 на jmp 00402635, и мы навсегда избавимся и от первого
сообщения, и от задержки.
Теперь давайте модифицируем наш инструмент, чтобы он показывал значения в
шестнадцатеричной системе, что избавит нас от пересчетов. В HEXeditorе перейдите
в режим DATA, и в конце листинга вы увидите следующее:
:0040A398 65 5F 56 5F 42 69 74 6D e_V_Bitm
:0040A3A0 61 70 00 25 69 00 20 50 ap.%i. P
:0040A3A8 69 78 65 6C 00 20 50 69 ixel. Pi
:0040A3B0 78 65 6C 73 00 25 69 00 xels.%i.
:0040A3B8 50 69 78 00 25 69 00 25 Pix.%i.%
Значения %i Pixel и %i Pixels выводятся на линейку, а %i означает
десятичные единицы. Поменяйте %i на %x, что означает HEX исчисление перед Pixel
и Pixels:
:0040A3A0 61 70 00 25 78 00 20 50 ap.%x. P
:0040A3A8 69 78 65 6C 00 20 50 69 ixel. Pi
:0040A3B0 78 65 6C 73 00 25 78 00 xels.%x.
Теперь значения будут выводиться в HEX исчислении.