Оригинальный DVD-ROM: eXeL@B DVD !
eXeL@B ВИДЕОКУРС !

ВИДЕОКУРС ВЗЛОМ
выпущен 12 ноября!


УЗНАТЬ БОЛЬШЕ >>
Домой | Статьи | RAR-cтатьи | 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, и всем кто прочел эту статью тесть Тебе!


Обсуждение статьи: Программирование в OllyDbg >>>


Комментарии к статье: Программирование в OllyDbg

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

---
tum 18.04.2005 14:57:03
по пункту 1:
Все понятно, но если прога не импортирует и ГетПросАдрес ?
---
WarrioR 18.04.2005 17:06:20
Можно заставить прогу импортировать :)
---
tum 19.04.2005 15:48:02
да. ;)
но тогда можно заставить импортировать
любую АПИ функцию, и ГетПрокАдрес
не потребуется..
---
Я 28.04.2005 10:30:42
кг/ам :P
---
John Freeman 30.04.2005 14:44:44
Это всё конечно хорошо, НО 2 ГРУБЕЙШИЕ ОШИБКИ(ламерские)
1) call FindWindowA - ЭТО БУДЕТ РАБОТАТЬ ТОЛЬКО НА КОМПЕ С ТОЙ ЖЕ ВЕРСИЕЙ advapi.dll
Надо call dword ptr.... [адрес в таблице импорта]
и отсюда же вытекает
2) в таком же нерабочем виде всё будет работать даже если прога не импортирует эту функцию и делать GetProcaddress НЕ НУЖЕН, другое дело что это нерабочее всё!
Надо ещё править(добавлять) импорт и легче всего сразу на нужные функции, и потом уже call dword ptr:[IAT address]
---
Romen 01.05.2005 17:06:23
Странно у меня все работает под разные ОС без проблем
---
COdEXpLOrER 06.05.2005 01:35:09
Поддерживаю высказывания John Freeman. Пример: данный код, введённый под Вин9х не работает (прога вылетает с ошибкой) под ВинХР.
---
WELL 06.05.2005 03:19:42
Статья хорошая. Тем более, что на эту тему статей мало (я не видел).
---
John Freeman 17.05.2005 17:23:24
2Romen:
А ты под другим SP попробуй... Или под 2003/nt4
---
John Freeman 19.06.2005 02:04:07
Наоборот всё логично, если бы он ПРАВИЛЬНО написал...
---
AndyMov 29.06.2005 18:18:11
Ошибка о которой говорил John Freeman действительно имеет место и GetProcAddr первый раз необходимо колить через таблицу импорта поскольку при компиляции модуля вместо call GetProcAddr подставляется реальный адрес ф-ции в даной системе, после через GetProcAddr можно колить другие АПИ. К сожалению ошибка обнаружилась только сегодня раньше попросту времени небыло
---
MINDLE$$ 30.06.2005 08:48:25
Да всё нормально, пусть человек пишет, побольше .А ошибки тут у всех практически. Главное- принцип, а начинающим это и надо
---
Mifodix 04.03.2006 21:54:02
Парень старался, а вы его обсираете. Статей на подобную тематику вообще нет! Хотя бы за индивидуальность и неповторимость тематики надо сказать риспект.
---
ZaZa 20.05.2006 22:57:34
Да, конечно! Обосрали парня...... Я сам так делал на примере защиты программы PasswordDoor 8.0, даже статью выложил, но скорее ее не будут публиковать, т.к. она ламерская! Для начинающих так сказать! Я сам такой же! Респект автору за статью, уважаю до глубины фибр своей души ) Все что написано выше канает и в Win2000 SP2, так что прислушаемся все к его советам и дружно пошлем все программы (распакованные конечно) к чертовой матери..... Пусть все сами удаляют и работают без границ на пользу нашего дела! ) )
---

Материалы находятся на сайте https://exelab.ru



Оригинальный DVD-ROM: eXeL@B DVD !


Вы находитесь на EXELAB.rU
Проект ReactOS