InLine Patching Protected Applications by Hooking API Functions SUB Z3R0 | Spirit Of The Wind | Seek’n Destroy TeaM 2oo6 Не хотел постить, ибо я то это знаю. Но если реверсом интересуется хотябы 43 человека, что следует из "популярности" моей статьи, то почему бы и нет. =\\ За**ло бороться с фильтром!! Если у кого картинки не отображаются, то листайте оригинал http://www.tuts4you.com/download.php?view.320!!! InLine Patching давольно слабо освещён в рунете, что очень плохо... Ведь это довольно простой метод, который может сильно сохранить силы и время реверсера. Он позволяет исправлять код защищёной программы без ее распаковки. Может понадобиться если возникают проблемы с дампом или восставлением импорта.. Я решил заткнуть эту брешь и перевести этот tutorial. Это интересный тутор, специально для новичков. Профи не найдут ничего нового.. Я перевел только теорию и два примера, имхо с практикой можно разобраться самому. Тем более что в архиве лежат примеры. Кстати перевод получился давольно свободным.. Я мыcлю так - главное донести суть некоторых предложений, а это, думаю, будет проще сделать на великом и могучем. + небольшие комментарии Введение: Для понимания InLine Patching нам необходимо знать ответы на эти вопросы: Вопрос: Что делает пакер/протектор с программой? Ответ: Он сжимает (ASPack, UPX) или криптует (TheMida, tElock), либо и то и другое (ASProtect, Armadillo), настоящий код программы и добавляет свой код в конец файла. Затем перемещвет EP (точку входа) на свой код. Вопрос: Как работают пакеры? Ответ: 1. Выделить для себя память. (может не выделять) 2. Дешифровка и запись совего кода в выделенную память 3. Дешифровка и запись настоящего кода программы 4. В некоторых случаях протектор эмулирует API функции 5. Фиксирует таблицу импорта 6. Выполняет переход на оригинальный код программы OEP. Заметка: Вторая часть может происходить два и более раз, что затруднит создание InLine patch’a. Хорошо, теперь Вы знаете теорию пакеров, узнайте торию инлайн патчинга через ответы на эти вопросы: Вопрос: Что такое Inline patching? Ответ: Inline patching – это трюк исправления запакованной программы без её распаковки! Вопрос: Как такое может быть? Ответ: Чтобы это сделать, нам необходимо провести инекцию кода после восстановления/дешифровки/распаковки оригинального кода программы и перед выполнением оного. (тоесть когда программа уже распакована но перехода на OEP ещё небыло, либо было но программа далеко не ушла) Одна из серьёзных проблем Inline patching’а – это поиск CRC* значений часто высчитывающихся с помощью чтения файла через (CreateFile – ReadFile и тп) API. *CRC – проверка на целостность кода, обычно высчитывается хэш файла и производится сравнение с этолоном Вопрос: Как мы можем перехватить API функцию? Ответ: Я знаю два способа перехвата API функций: Простой путь: 1. Читаем первые 5/6 байт API функции и записываем их по адресу “X”. 2. Записываем переход** на адрес “X” вместо первых 5/6 байт API функции. 3. Записываем наш код по адресу “X”+5/6. 4. В конец записываем переход на адрес API функции + 5/6 байт. ** Вы можете использовать: jmp [xxxx] (6 byte) / jmp xxxx (5 byte) / push xxxx ret (6 byte) Наглядная иллюстрация данного метода: Это хорошо, но работает не на всех API и системах Windows. Трудный путь: 1. Чтение первых 5/6 байт API функции и сохранение их. 2. Запись перехода на адрес “X” вместо первых 5/6 байт API функции. 3. Запись нашего кода в X, затем добавление кода который сохранит и измененит адрес возврата*** на код Y. Востановление оригинальных 5/6 байт функции. 4. Код Y выполняет действие 2 и переходит на настоящий адрес возврата. *** адрес возврата – когда происходит выполнение комманды call, в стек кладётся адрес следущей комманды. Иначе как бы ret узнавал куда возвратить управление? Наглядная иллюстрация данного метода: Это чётко работает на всех API и всех Windows. От меня: На самом деле есть действительно трудный метод. Но для этого нужно будет разобраться с дизассемблерами длин. Сделать что то подобное, что делает PESPin для обфускации. Вопрос: Что у тебя за метод? Ответ: Мой метод научит Вас перехватывать API, обходить проверку CRC и патчить программу (после дешифрации оригинального кода программы) Вопрос: Как ты это делаешь? Ответ: Чтобы провести InLine Patching моим методом нам необходимо проделать следущие шаги: Первый шаг: Обход проверки CRC одним из этих методов a) Перехват ReadFile/MapViweOfFile и перезапись настоящих байт в буфер (можно использовать для ASProtect) b) Следующий метод - подмена настоящего CRC вместо того что посчитает функция Второй шаг: Перехват таких API как (GetModuleHandleA, GetVersion, ThunRTMain). Эти функции обычно находятся в каждой прорамме и выполняются недалеко от OEP. (В некоторых случаях придётся создать счётчик вызовов этих функций. Программа не будет исправляться/патчится до тех пор, пока функция не будет вызываться недалеко от OEP) ASProtect 2.xx InLinePatching By Hook Method Откроем наше приложение (JhonWho InLineMe) в ToPo … Хорошо, 815 байт будет достаточно! Чтож мы используем выбранную секцию ... Свободное место с 4898D1 … поменяем EP на 898D1. Давайте подумаем что мы имеем в этом случае: 1. Свободное место измененое ASPR, мы перейдем к выделеной памяти для установки нашего hook’а. 2. Запишем наш код в выделеную память и пофиксим адреса 3. Перехватим “MapViewOfFile”, чтобы “надуть” CRC Мы установим hook на MapViewOfFile... Измним AccessMode на 1 (File_Map_Copy)… изменим адрес возврата из MapViewOfFile на наш код (после выполнения MapViewOfFile мы перейдем к исправлению его буфера (buffer помещается в eax))… затем после сравнения EP Мапированного файла с нашей EP (898D1), мы перезапишем OEP (1000) пакера 4. Перехват “GetModuleHandle”, исправление nag screen: Первый вызов GetModuleHandle имеет параметр hModule равный нулю и расположен в секции кода. Значит это вызов из настоящего кода программы.. Скорее всего программа уже распакованна в памяти пакером, а следовательно самое время патчить =) Программа запускается! Yes! Наг скрин был удалён! tElock 0.98+ InLinePatching By Hook Method Во-первых создадим резервную копию файла, затем откроем наше приложение (SnD UnpackMe) в ToPo… Хорошо, добавим 400 байт в новую секцию файла... Изменим EP на адрес добавленых байт: 66BD6 Для начала мы имеем поиск CRC: Откроем файл в Olly… установите breakpoint на CloseHandle… Запустите и ждите пока olly не остановится... нажмите Ctrl-F9 для перехода к ret… затем жмите F8 и Вы увидете этот код: Установим breakpoint на 4659DE, запустим (F9)… запишите EAX – это CRC Давайте подумаем что мы имеем в этом случае: 1. tElock, защищая файлы, не использует GetProcAddress в создании своей таблицы импорта... он ищет адреса в таблице экспорта kernel32.. Вы можете также добавить GetProcAddress в таблицу импорта вручную или исползуя LordPE… 2. На рисунке выше можно заметить, что мы можем написать “mov eax,04e468f32 | jmp 4659DE” по адресу возврата CloseHandle. 3. Перехват GetModuleHandle и исправление нужных байт... Первый вызов GetModuleHandle имеет параметр hModule равный нулю и расположен в секции кода. Значит это вызов из настоящего кода программы.. Скорее всего программа уже распакованна в памяти пакером, а следовательно самое время патчить =) Код который найдет GetProcAddress и перехватит CloseHandle и GetModuleHandle… Hook Callbacks… Запускаем файл.. Готово!!