Всякий диалог выводится не сам по себе (это ведь не кошка), а отображается некоторой API-функцией. Перехватив API-функцию, выводящую NAG, мы сможем дизассемблировать защитный код, который ее вызывает, и проанализировать условия, определяющие появление NAG'а на экране.
Существует множество API-функций, связанных с диалогами: CreateDialog, DialogBox, MessageBox и т.д. Какую из них использовал разработчик RAR'а? Чтобы не гадать, воспользуемся API-шпионом. Он все покажет. Только сначала настроим фильтр, чтобы Kerberos отбрасывал малоинформативные API-вызовы, захламляющие файл отчета. Откроем ke_spy.txt и закомментируем следующие функции: TlsGetValue, DefWindowProcA, DispatchMessageA, GetFocus, GetMessageA, SendMessageA, SendMessageW, TranslateAcceleratorA, TranslateAcceleratorW и TranslateMessage (чтобы закомментировать функцию, перед ее именем вставляется знак ';'). Для усиления фильтрации имеет смысл зайти в Опции (кнопка "options") и взвести флажок "report only .exe calls", чтобы собирать API-вызовы только из winrar.exe, но не из загружаемых им DLL. Если этого не сделать, ничего страшного не произойдет, но файл отчета получится слишком большой и удручающе ненаглядный.
Рисунок 2.Настройка фильтра перед запуском шпиона.
Теперь нажимаем Browse, указываем путь к RAR'у и давим Inject. Дождавшись появления NAG'а на экране, выходим из RAR'а и открываем файл отчета WinRAR.rep, находящийся в одном каталоге с RAR'ом.
Рисунок 3.API-шпион kerberos, готовый к работе.
Изучение файла-отчета (см. листинг 1) лучше начинать с конца (ведь NAG-screen появляется в последнюю очередь, когда основной интерфейс уже инициализирован). Только слепой не обнажит вызов функции DialogBoxParamA, выводящей диалог с грозным именем "REMINDER" (то есть, "напоминатель"). Она-то этот противный диалог и создает. Да... с фантазией у разработчиков защит всегда были напряги.
Kerberos (вот умница!) даже сообщает адрес возврата из функции - 440А73h, ведущий прямо к защитному коду. Заглянем сюда дизассемблером? Загружаем winrar.exe в IDA PRO и давим <G> (Jump to address), "440A73", <Enter>.
Рисунок 4.Защитный код, исследуемый в дизассемблере IDA PRO.
Отчетливо виден вызов DialogBoxParamA, выше которого находится следующий дизассемблерный код:
Как мы видим, функция DialogBoxParamA вызывается, когда выполняется условный переход: cmp eax, 28h/jg loc_440F4F (прыжок, если eax > 28h). В десятичной системе 28h равно 40. Это и есть срок демонстрационного периода, положенный нам по праву. Теперь становится понятен "физический" смысл переменной dword_004B43C8, содержащей количество дней, прошедших с момента установки программы.
Открываем свежее пиво! Штаб-квартира защитного механизма найдена! Как мы будем действовать? Чтобы заблокировать NAG, можно, например, изменить cmp eax,28h (83 F8 28) на xor eax,eax/nop (33 C0/90), тогда eax всегда будет равен нулю независимо от того, какой день сейчас за окном, ну а команда nop понадобилась нам для того, чтобы скомпенсировать уменьшение длины инструкции (cmp занимает три байта, а xor - только два).
Запускаем hiew, загружаем winrar.exe, дважды нажимаем на <ENTER> чтобы перейти в ассемблерный режим, давим <F5> (goto) и пишем ".440F46" - адрес инструкции cmp, ну а точка здесь затем, чтобы сообщить hiew'у, что это именно адрес, а не смещение в файле. Нажимаем <F3> для перехода в режим редактирования (edit), а затем <ENTER> для ввода ассемблерной инструкции. В появившемся диалоговом окне пишем "xor eax,eax" <ENTER> "nop" ESC>. Сохраняем все изменения в файле нажатием <F9> и выходим.
Рисунок 5.Три байта, блокирующие NAG.
Запускаем winrar. Теперь NAG уже не выводится! Весь взлом не занял и десяти минут! Как вариант, можно заменить mov eax, dword_004B43C8 (A1 C8 43 4B 00) на mov eax, 6 (B8 06 00 00 00) и тогда RAR будет считать, что с момента регистрации всегда прошло ровно шесть дней. Почему именно шесть? Ну, не шесть, так девять. Какая нам разница?! Главное, чтобы не больше 40! А еще можно заменить jg short loc_440F4F (7F 04) на jmp short loc_440F73 (EB 28), тогда безусловный переход будет перескакивать диалог независимо от текущего времени.
Наиболее красивым считается решение, требующее минимальных исправлений. Лучшие из вышеупомянутых решений хачатся двумя байтами, но можно захачить программу и с помощью одного. Поиск этого байта и будет нашим домашним заданием, ок?