PDA

Просмотр полной версии : InLine Patching Protected Applications


taha
27.04.2007, 01:03
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)

Наглядная иллюстрация данного метода:

http://img86.imageshack.us/img86/764/inline1hi8.gif

Это хорошо, но работает не на всех API и системах Windows.

Трудный путь:
1. Чтение первых 5/6 байт API функции и сохранение их.
2. Запись перехода на адрес “X” вместо первых 5/6 байт API функции.
3. Запись нашего кода в X, затем добавление кода который сохранит и измененит адрес возврата*** на код Y. Востановление оригинальных 5/6 байт функции.
4. Код Y выполняет действие 2 и переходит на настоящий адрес возврата.
*** адрес возврата – когда происходит выполнение комманды call, в стек кладётся адрес следущей комманды. Иначе как бы ret узнавал куда возвратить управление?

Наглядная иллюстрация данного метода:

http://img180.imageshack.us/img180/1457/inline2ww2.gif

Это чётко работает на всех 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 …

http://img180.imageshack.us/img180/1250/inline3rr9.gif

Хорошо, 815 байт будет достаточно! Чтож мы используем выбранную секцию ... Свободное место с 4898D1 … поменяем EP на 898D1.

Давайте подумаем что мы имеем в этом случае:
1. Свободное место измененое ASPR, мы перейдем к выделеной памяти для установки нашего hook’а.
2. Запишем наш код в выделеную память и пофиксим адреса

http://img108.imageshack.us/img108/7469/inline4yq4.gif

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 равный нулю и расположен в секции кода. Значит это вызов из настоящего кода программы.. Скорее всего программа уже распакованна в памяти пакером, а следовательно самое время патчить =)

http://img252.imageshack.us/img252/1923/inline5hr8.gif

Программа запускается! Yes! Наг скрин был удалён!

tElock 0.98+ InLinePatching By Hook Method
Во-первых создадим резервную копию файла, затем откроем наше приложение (SnD UnpackMe) в ToPo…

Хорошо, добавим 400 байт в новую секцию файла...

Изменим EP на адрес добавленых байт: 66BD6

Для начала мы имеем поиск CRC:
Откроем файл в Olly… установите breakpoint на CloseHandle… Запустите и ждите пока olly не остановится... нажмите Ctrl-F9 для перехода к ret… затем жмите F8 и Вы увидете этот код:

http://www.img2you.by.ru/ilp/inline6.gif

Установим 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…

http://www.img2you.by.ru/ilp/inline7.gif

Hook Callbacks…

http://www.img2you.by.ru/ilp/inline8.gif

Запускаем файл..

http://www.img2you.by.ru/ilp/inline9.gif

Готово!!