CRACKL@B Оригинальный CD-ROM крэкера: CRACKL@B GIGABYTE
Домой | Статьи | Форум | Программирование | Скачать | CD & DVD
CRACK | Новичку | FAQ | Ссылки | Интервью | Архив | Новости | Связь

Программирование в OllyDbg

Автор: AndyMov <Andy_Mov@Mail.ru>

Наверное, прочитав название этой статьи Вы подумали «Да чё это с тем парнем, неужели он пишет свои проги в OllyDbg !!!», но если серьезно то бывает и такое!:), попадается какая-то прога которую ну очень нужно «подправить», вот тут то OllyDbg самое то!!!
Эту статью я написал для новичков, независимо кракеров или программистов, так как ее цель дать необходимую информацию для встраивания своего кода в exe, dll файлы. Первоначально я ориентировался на кракеров, но в процессе написания решил дать больше общей информации, по той простой причине что ее очень не хватает.
Дабы не растягивать сию статью применять эту технику я собираюсь на собственной проге (кракми), продемонстрировав таким образом в одной статье ряд тех приемов которыми я часто пользуюсь.
Итак, скоренько я набросал кракмис с наг-скрином, и проверкой количества оставшихся запусков в реестре.

1. Снимаем ограничение количества запусков.

Кракмис хранит количество запусков в ветви реестра HKEY_CURRENT_USER\AndyMov\runs типа integer и когда такой отсутствует то прога его создает думая что она запущена впервые(часто встречающиеся решение), иначе при каждом запуске значение этого параметра уменьшается на 1, когда значения этого параметра меньше 1 то прога просто отказывается запускаться, значит нужно до того как программой будет осуществляться проверка этого параметра просто удалить его.
Вот отрывок листинга из Regmon.exe в подтверждение:

OpenKey HKCU\AndyMov SUCCESS Key: 0xE1785188
QueryValue HKCU\AndyMov\runs SUCCESS 0x1E
QueryValue HKCU\AndyMov\runs SUCCESS 0x1E
SetValue HKCU\AndyMov\runs SUCCESS 0x1D
CloseKey HKCU\AndyMov SUCCESS Key: 0xE1785188


Итак, теперь нам нужно найти немного незадействованного места в .ЕХЕ ф-ле программы для размещения своего кода, одно из таких мест находится начиная с адреса 00452518 и до 004525F0(как видно ниже, из отрывка дизассемблерного листинга значения байтов в этих адресах = 00, и обычно такое встречается в конце секций, то есть если например в конце секции кода вы увидите нули то это и есть пространство для размещения вашего кода, проверим, откройте файл calc.exe в PE – editor’e LordPE, нажмите на кнопку [sections], в окне что появилось выделите секцию [.text]- это и есть секция кода и в контекстном меню пункт [hex edit section...], в конце выделения(то есть секции(у меня 00012AED)) вы увидите байты 00) :

00452518 . 0000 ADD BYTE PTR DS:[EAX],AL
0045251A . 0000 ADD BYTE PTR DS:[EAX],AL
0045251C . 0000 ADD BYTE PTR DS:[EAX],AL
0045251E . 0000 ADD BYTE PTR DS:[EAX],AL
00452520 . 0000 ADD BYTE PTR DS:[EAX],AL
00452522 . 0000 ADD BYTE PTR DS:[EAX],AL
00452524 . 0000 ADD BYTE PTR DS:[EAX],AL
... ... ...
004525F0 . 0000 ADD BYTE PTR DS:[EAX],AL


Удалить нужный ключ реестра можно с помощью АПИ функции RegDeleteKey:

LONG RegDeleteKey(

HKEY hKey, // хэндл откр. ключа
LPCTSTR lpSubKey // адрес строки с именем ключа
);

Delphi пример : RegDeleteKey(HKEY_CURRENT_USER, ’AndyMov’);


Но проблема в том что подопытная прога не импортирует такой функции!!!
Конечно можно узнать адрес необходимой АПИ функции например с помощью команды ‘EXP имя функции’ SoftIce’a, и потом сделать джамп или кол на этот адрес, но адреса АПИ ф-ций могут быть не одинаковые даже в двух одинаковых ОС но разных билдов, тоесть если у Вас на WinXP proff RU прога работает это еще не значит что прога будет работать на всех WinXP, что уж говорить о других осях! Потому придется каждый раз узнавать адрес нужной функции динамически программным путем(добавлять нужную АПИ автоматически с помощью разных инструментов я не хотел так как это просто, добавлять импорт вручную – тяжеловато, а с помощью АПИ как раз то что нужно). И сделать это можно с помощью АПИ функции GetProcAddress которая в качестве результата возвращает адрес нужной функции, или NULL в случае неудачи, вот ее прототип:

FARPROC GetProcAddress(

HMODULE hModule, // хэндл модуля DLL
LPCSTR lpProcName // имя функции (RegDeleteKey)
);

Где взять хэндл модуля DLL? Конечно у функции GetModuleHandle :)
У этой функции всего один параметр, смотрим ее прототип:

HMODULE GetModuleHandle(
LPCTSTR lpModuleName // адрес с именем модуля хэндл которого
); // требуется узнать


Теперь у нас есть вся необходимая информация для успешного осуществления задуманного!
Вот пример дельфи кода который возвращает адрес ф-ции RegDeleteKey:

GetProcAddress(GetModuleHandleA(’AdvApi32.dll’), ’RegDeleteKeyA’);

Теперь остается только запрограммировать этот код в OllyDbg.
Итак, грузим кракмис в олли, ставим курсор по адресу 00452518 (думаю вы без особых проблем отыщите немного места для своего кода в любом екзешнике, иначе может пока не стоит читать далее), делаем дабл-клик по этой строке листинга дизассемблера(но не на поле адресов иль автоанализа), и в окне что появилось начинаем вводить такой код(в конце каждой строки жмем ENTER):
Push 004525D8 // адрес строки AdvApi32.dll
Call GetModuleHandleA // получаем в еах хэндл AdvApi32.dll
Push 004525E5 // адрес строки RegDeleteKeyA
Push EAX // хэндл модуля AdvApi32.dll
Call GetProcAddress // получаем в еах адрес вызова RegDeleteKeyA
Push 004525F3 // адрес строки AndyMov(удаляемый ключ)
Push 80000001 // HKEY_CURRENT_USER
Call EAX // Удалить ключ :)

Mov EAX, 004522F0 // команда спертая с ОЕР, на месте этой // команды я поставил переходник по // которому передается управление с ОЕР на // мой код : JMP адрес_начала_моего_кода.

Jmp 004524DB // передача управления на ОЕП,
// программа продолжает нормальную работу


Вот и все! Теперь осталось только разместить текстовые строки в .EXE нашего кракми. Это можно сделать многими способами даже в OllyDbg, но я предпочитаю такой:
Помещаем курсор по адресу 00452518 (для Delphi прог почти всегда немного ниже ОЕР), должны быть такие строки:

00452518 . 0000 ADD BYTE PTR DS:[EAX],AL
0045251A . 0000 ADD BYTE PTR DS:[EAX],AL
0045251C . 0000 ADD BYTE PTR DS:[EAX],AL
0045251E . 0000 ADD BYTE PTR DS:[EAX],AL
00452520 . 0000 ADD BYTE PTR DS:[EAX],AL


Как видно из этого листинга все пространство в этом промежутке адресов инициализировано нулями. В контекстном меню этой строки дизассемблера выбираем команду View -> Executable file, в окне дампа что появилось с помощью контекстного меню даем команду Hex -> Hex/ASCII(16 bytes), после чего данные в окне отображаются будто в обычном HEX редакторе, выделяете необходимую область для размещения данных, и давим Ctrl+E (как альтернативу используем команду Binary -> Edit контекстного меню), теперь можно ввести всю необходимую инфу, после чего сохранить модифицированный .EXE файл (при закрытии окна дампа олли спросит, нужно ли сохранять изменения – вот это отладчик! :).
Запускаем прогу... ОК ключ удаляет, ограничение количества запусков снято, но остался надоедливый наг-скрин :( ...

2. Снимаем наг-скрин.


Для снятия надоедливого окна наг-скрина можно воспользоваться разнообразными АПИ функциями, это дело вкуса, я здесь просто отправлю окну сообщение WM_CLOSE что заставит окно-получатель исчезнуть, конечно можно действовать и более радикальными методами например уничтожить надоедливое окошко, но в данном случае мы обойдемся без этого(безопаснее просто скрыть окно чем уничтожать его, тем более последнее связано с рядом трудностей и потому не всегда возможно), тем более что после прочтения п.1 этой статьи Вы имеете достаточно информации чтобы сделать это по-другому как сами захотите.
Итак, чтобы отослать наг-скрину сообщение WM_CLOSE которое его спрячет мы воспользуемся функцией SendMessageA вот ее прототип:

LRESULT SendMessage(

HWND hWnd, // хэндл окна-получателя
UINT Msg, // отсылаемое сообщение (WM_CLOSE)
WPARAM wParam, // первый параметр сообщения (0 или 1)
LPARAM lParam // второй параметр сообщения (0 или 1)
);


Остается узнать хэндл(дескриптор) окна которое надо скрыть, то есть нашего нага. Используя АПИ FindWindow мы без проблем вычислим наш наг-скрин:

HWND FindWindow(

LPCTSTR lpClassName, // указатель на имя класса окна
LPCTSTR lpWindowName // указатель на текст заголовка окна
);


Значит план действий такой:
- получаем хэндл наг-скрина
- отправляем окну сообщение WM_CLOSE

Как вводить код ассемблера в OllyDbg вы уже знаете(нет? Читайте сначала), потому повторять не буду и сразу привожу ассемблерный листинг:

Push 0 // заголовок окна - NULL
Push offset Wnd_Class_Name // 1-й параметр класс искомого окна
Call FindWindowA // получить хэндл окна Wnd_Class_Name
Push 0 // 2-й параметр (не используется )
Push 0 // 1-й параметр (не используется )
Push 10 // константа WM_CLOSE
Push EAX // хэндл окна для отправки сообщения
Call SendMessageA // отправляем сообщения WM_CLOSE
Mov EAX, 0045251C // эмуляция спертой команды (вместо // этой команды на ее оригинальном месте я поместил JMP на начало своего кода, теперь выполняю эту команду и передаю управление на следующую за ней, будто ничего не бывало)
Jmp XXXXXXXX
// передача управления программе

Вот и все! Хочу сказать что труднее чем записать этот код было отыскать нужное место для него, так как выполнять эго нужно после создания окна наг-скрина иначе никакого эффекта не будет(наш код просто не найдет нужного окна).

Напоследок


Программировать код на низком уровне не легко, особенно трудны первые шаги, надеюсь эта статья поможет Вам сделать этот первый шаг – в мир машинного кода. Я старался написать как можно проще, и дать наиболее необходимую информацию, имея которую можно самостоятельно продолжить эксперименты с кодом, хорошим заданием для вас теперь будет самостоятельно добавить в .ехе windows калькулятора(calc.exe, notepad.exe ... выбирайте по вкусу) код который выводил бы MessageBox, с вопросом запустить calc.exe или отменить запуск, после нажатия ОК соответственно запуская калькулятор, при нажатии CANCEL – закрывая прогу, разумеется, вам будет нужен M$ SDK.
Наиболее часто работоспособность кода нарушается из за несогласованности стека – ВНИМАТЕЛЬНО следите за тем чтобы ваш код извлекал из стека ровно столько параметров сколько помещал. Если вами будет затерта какая-то команда для передачи управления вашему коду, то настоятельно рекомендую восстанавливать ее при передачи управления, следите за этим и я уверен что большой части проблем с функционированием кода у вас не будет. Если места для размещения своего кода наидти не удастся то свой код можно вынести в отдельную секцию(создать новую секцию можно в том же PETools или LordPE, там есть еще много полезного для «перепрограммирования» .exe :).
Очень много материала осталось незатронутым, но даже в том его небольшом количестве возможны опечатки и/или ошибки, тем более это моя первая статья на Cracklab – заранее извините.
Приветы всему CrackLab’y, и всем кто прочел эту статью тесть Тебе!

Комментарии

Добавить
Ваше имя

Комментарий

Оценка


SLV ::: 14 Apr 2005 19:46:02 MSK
имхо так ломать проги слииишком геморно.. зачем допимывать свой код чтобы снять наг когда можно просто занопить какой-нить DialogBoxParamA и подправить стек...
----
ValdiS ::: 13 Apr 2005 23:59:25 MSK
А где ссылка на крякми? Странно...
----
red_mould ::: 15 Apr 2005 11:14:20 MSK
Ну гиморно или нет это уже другой вопрос. За-то заставляет мозги пошевелиться
----
AlexZ_CRC ::: 17 Apr 2005 09:01:11 MSK
Мне нравится свой код встраивать, нежели просто нопить что-то-там :) Кстати, я в пеХплорер байт 500 патча влепил (раньше он под ХР неработал, но потом профиксил).
----
SLV ::: 17 Apr 2005 14:50:02 MSK
и ещё.. метод автора \"адресозависим\", т.е. привязан к конкретным адресам его системы...
----
mysterio ::: 16 Apr 2005 23:27:47 MSK
Вот хорошая тулза к этой статье:
_http://www.jbfonline.net/sNd/index.php?dir=03.march/&file=snd-apiaddressesfinder.tool.zip

----
tum ::: 18 Apr 2005 14:57:03 MSK
по пункту 1:
Все понятно, но если прога не импортирует и ГетПросАдрес ?
----
WarrioR ::: 18 Apr 2005 17:06:20 MSK
Можно заставить прогу импортировать :)
----
tum ::: 19 Apr 2005 15:48:02 MSK
да. ;)
но тогда можно заставить импортировать
любую АПИ функцию, и ГетПрокАдрес
не потребуется..
----
Я ::: 28 Apr 2005 10:30:42 MSK
кг/ам :P
----
John Freeman ::: 30 Apr 2005 14:44:44 MSK
Это всё конечно хорошо, НО 2 ГРУБЕЙШИЕ ОШИБКИ(ламерские)
1) call FindWindowA - ЭТО БУДЕТ РАБОТАТЬ ТОЛЬКО НА КОМПЕ С ТОЙ ЖЕ ВЕРСИЕЙ advapi.dll
Надо call dword ptr.... [адрес в таблице импорта]
и отсюда же вытекает
2) в таком же нерабочем виде всё будет работать даже если прога не импортирует эту функцию и делать GetProcaddress НЕ НУЖЕН, другое дело что это нерабочее всё!
Надо ещё править(добавлять) импорт и легче всего сразу на нужные функции, и потом уже call dword ptr:[IAT address]
----
Romen ::: 01 May 2005 17:06:23 MSK
Странно у меня все работает под разные ОС без проблем
----
COdEXpLOrER ::: 06 May 2005 01:35:09 MSK
Поддерживаю высказывания John Freeman. Пример: данный код, введённый под Вин9х не работает (прога вылетает с ошибкой) под ВинХР.
----
WELL ::: 06 May 2005 03:19:42 MSK
Статья хорошая. Тем более, что на эту тему статей мало (я не видел).
----
John Freeman ::: 17 May 2005 17:23:24 MSK
2Romen:
А ты под другим SP попробуй... Или под 2003/nt4
----


Материалы находятся на сайте http://cracklab.ru/art/





Вы находитесь на CRACKLAB.RU, сегодня 20 мая 2005 года 13:15:01 MSK
SpyLOG liveinternet.ru: показано число просмотров за 24 часа, посетителей за 24 часа и за сегодня