Введение в крэкинг с нуля, используя OllyDbg - Глава 20

  • На форуме работает ручное одобрение пользователей. Это значит, что, если Ваша причина регистрации не соответствует тематике форума, а также Вы используете временную почту, Ваша учётная запись будет отклонена без возможности повторной регистрации. В дальнейшем - пожизненная блокировка обоих аккаунтов за создание мультиаккаунта.
  • Мы обновили Tor зеркало до v3!
    Для входа используйте следующий url: darkv3nw2...bzad.onion/
  • Мы вновь вернули telegram чат форуму, вступайте, общайтесь, задавайте любые вопросы как администрации, так и пользователям!
    Ссылка: https://t.me/chat_dark_time

AnGel

Администратор
Команда форума

AnGel

Администратор
Команда форума
27 Авг 2015
3,413
2,025
Следующий приём против отладки в OllyDbg, который мы рассмотрим, это обнаружение её по имени процесса, но прежде всего настроим OllyDbg так, как это необходимо в данном случае.

Если перейдём в DEBUGGING OPTIONS-SECURITY:

025f7ef325b3f1e2f40ecf17a3d47665.png

Здесь находится три галочки. Если мы их все отметим, то увидим, что установив BPX на API-функцию и если переинициализируем OllyDbg (Restart), то BPX останутся установленными, что позволяет нам избежать повторение всего процесса каждый раз, когда мы делаем рестарт.

Строго говоря, я не знаю, как именно работает OllyDbg «внутри», но на практике достаточно просто отметить эти три галочки, чтобы установленные на API-функции BPX оставались установленными после перезапуска.

601a2dcdcf1a4f0e6bc349719876a154.png

Именно так, как мне кажется, без особых проблем и хлопот, мы и начинаем изучение темы антиотладки по имени процесса.

Обнаружение OllyDbg по имени процесса

Запустив OllyDbg, мы можем посмотреть список процессов с помощью CTRL + ALT + SUPR.

e1b625722037f24be6ef030987462214.png

Видим, что имя процесса находится среди остальных, что позволяет программе пробежаться по их списку, и если она встретит называющийся OllyDbg, она закрывается, оставив противника ни с чем, ха-ха!

Крэкми, который мы используем, решать пока не будем, так как он находится на более продвинутом уровне, чем материал, изученный ранее – мы сделаем это в другой раз, но на его примере мы изучим то, как программы находят OllyDbg по имени процесса, как этого избежать вручную и автоматически, хе-хе.

Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
называется DAXXOR. Если запустим его и OllyDbg по отдельности, то увидим, что крэкми запускается, но закрывает отладчик, а если загрузим программу в OllyDbg, то закроются оба.

Изучим, как это происходит. Откроем крэкми в OllyDbg.

3e795d1d685dbb0c7c904c37d96e7c0b.png

Оказавшись в точке входа, посмотрим, какие API-функции используются.

30d97e22c3039caf879af308cf4c2dfe.png

Ок, их тут немало, но дело в том, что они используются защитой, а не самим крэкми, который сам в начале не грузится, поэтому API-функции, используемые для обнаружения OllyDbg, мы сможем посмотреть только в середине выполнения. Заодно я объясню этот способ защиты, который не позволяет нам увидеть список API-функций. С другой стороны, теперь мы точно знаем, что эти среди них есть важные API-функции, раз программа их скрывает и они не появляются в списке.

Почти в каждом таком случае, когда программа не запакована, как здесь, используется API-функция GetProcAddress.

6a4b941b429c20458d0b70446b0af9eb.png

Она используется программой, чтобы загружать другие API-функции, которые не находятся в списке используемых. Мы более подробно рассмотрим GetProcAddress в главе, посвящённой распаковке, но пока просто установим на неё BP.

e6110cd55724e145a515a61bb36c580e.png

И делаем RUN.

babe3340e9e8465d295efcbc74413a38.png

Каждый раз, останавливаясь на ней, видим, что именно запрашивается, в данном случае первой запрашивается функция __CPPdebugHook, не связанная с защитой, которую мы изучаем, поэтому снова жмём RUN.

d02891dd45b6d8e4218929e4d235fb84.png

Таким образом, с помощью F9 доходим до API-функций, относящихся к защите. Здесь видим, что используется функция EnumProcesses, так что после того, как дойдём до RET в GetProcAddress, в EAX будет возвращен адрес функции, действительный для конкретной машины, и туда мы установим BPX, после чего выполним RET с помощью EXECUTE TILL RETURN.

ad543feda5f87471b9d02cf7600896f6.png

Здесь в EAX возвращается адрес указанной функции для конкретной машины, в моём случае это 76BB3A9A (он может отличаться у вас).

4bd3175767f45cfc7f222a02cca6d45d.png

С другой стороны, видим, что OllyDbg не обнаружила эту API-функцию, и её нет в списке NAMES, поэтому мы не можем установить BP напрямую по имени функции, и поэтому устанавливаем точку останова на адрес.

69d3d0a0ce2ca133495970ee7c0c720d.png

Вот она установилась.

412559c9b41dc1dde5fcff861d3fd29c.png

Итак, мы установили BP на подозрительную API-функцию, продолжаем выполнять программу в OllyDbg, чтобы увидеть, загружается ли ещё что-нибудь.

f8ed57ddbf0a2bdbfa09f317d3d97f66.png

Хм, перебираются модули процесса, дойдём до RET и установим BPX на адрес, который будет возвращён в EAX.

Чтобы много не печатать, то находясь на RET, можем сделать так:

27460fac38ad8a16941ddccdcd0b7582.png

Так я устанавливаю BPX на все API-функции, когда нахожусь на RET.

6507858ad258db653f410178b5865ae1.png

Ещё одна подозрительная API-фукнция, устанавливаем на неё BP таким же образом, что и в прошлые разы, делаем и останавливаемся на EnumProcesses.

18ea74827750f20cd3f74d3f96ab5c97.png

Комментарий справа, содержащий имя API, был добавлен мной. Комментарии можно добавлять с помощью двойного щелчка на нужной области.

819fd3a662e38a5b274676dcd959fca7.png

30ddc642c8d0746501dc7f9b8f3e4955.png

9e09a7cfb1fd1967d82b4abd5bf87f4d.png

Все эти функции, загруженные программой, не были увидены OllyDbg и не были отражены в списке, также она не даёт по ним какую-либо информацию.

Поищем в гугле, что это за функция “EnumProcess”.

98a5a5f455525f318647f2b14cb17538.png

Находим её на сайте Микрософта, адрес страницы:

Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!


86bfef96f0622749b2b811dd3e7cfa64.png

Хорошо, здесь говорится, что вышеупомянутая функция возвращает нам идентификатор или PID каждого запущенного процесса, ок, рассмотрим что такое этот PID, хе-хе.

Каждому запущенному процессу присвоен идентификатор – число, меняющееся каждый раз при запуске процесса. Посмотрим на список процессов.

740adaefc983079fda8c5669c3f722d1.png

Видим, что в данном случае OllyDbg присвоен PID 724 – в десятеричной системе счисления, так как программа просмотра процессов работает именно с ней. Переведём вышеуказанное число в шестнадцатиричную систему с помощью калькулятора Windows.

0b51bd79e0167d72215bb9670f9e87a0.png

Нажимаем на кнопку HEX, чтобы перейди в шестнадцатеричную систему.

2391ace24a40b8bf16c73d734da65aef.png

PID OllyDbg в шестнадцатеричной системе равен 2D4. Можем закрыть и запустить по новой OllyDbg, и увидим, что PID изменился. Каждый раз, когда процесс запускается заново – PID меняется.

Также нам не повезло с отображением параметров функции, так как для OllyDbg она не существует.

51272d28ea5cefc9130f7298eac3fc3d.png

Из страницы на сайте Микрософта, знаем, что у неё три параметра.

f810dad30425d2b3b39cdcff5bb6d249.png

То есть в 12EDE4 сохраняется список PID’ов всех процессов, запущенных на моей машине, делаем EXECUTE TILL RETURN, чтобы вернуться из API-функции и смотрим через DUMP, что там лежит.

bff17dbb508c89c3f8c0e865bc39f1d6.png

Там находится список PID’ов, а среди них и PID OllyDbg, хнык, хнык.

Ставим здесь BPM ON ACCESS, чтобы посмотреть, где он используется.

f691bb27952c76dc7c59c8bf38897bde.png

Теперь делаем RUN.

dce86a0e21358fbbc5fbcd2bb9e3f50e.png

Видим, что остановились там, где будет применена функция OpenProcess, которая проверяет, работает ли процесс, и если да, то возвращает его хэндл (логический номер).

Какая разница между PID и хэндлом? Это очень просто – PID – это общий идендификатор – на всей машине, в какой угодно программе PID OllyDbg остаётся одним и тем же, пока процесс не будет перезапущена, в моём случае это 2d4, а хэндл – это номер, который позволяет позволяет вашей программе управлять процессом и который будет отличаться в другой программе. Это своего рода заявка на контролирование процесса, без номера не сможете им управлять, а чтобы получить номер, нужно попросить систему, которая вернёт вам хэндл. Тогда сможете и управлять и подстроить какую-нибудь гадость, хе-хе.

Вот более подробное определение OpenProcess в WinApis32, у неё тоже много параметров, но нам они не интересны.

067bb3b1cd71a0f1d4951b9022d681d1.png

То есть возвращается логический номер исполняющегося процесса, коротко говоря, это то, что программа в данном случае и хочет узнать.

Трассируем с помощью F8, пока не остановимся на API-функции.

28dcf924664f2e0415926991eb3ae9e5.png

Y en EAX devuelve el handle o manejador del OLLYDBG que en mi caso es 58.

В EAX возвращается логический номер OllyDbg, который в моём случае равен 58.

El mismo OLLYDBG nos muestra los HANDLES con los cuales esta trabajando el programa en la ventana H.

Тот же OllyDbg умеет показывать логические номера, с которыми программа работает в настоящее время, с помощью окна H.

3a4a14a742746b6ef3d4790ba2ba8f6f.png

Видим, что здесь есть 58 и TYPE или тип является PROCESS, т.е. процесс, таким образом, у программы есть логический номер 58, действительный в процессе OllyDbg.

Если другой процесс использует EnumProcess, чтобы получить PID, то для OllyDbg, если она не будет перезапущена, он будет равен 2d4, а если потом попросить логический номер данного процесса, то он будет каким-нибудь другим, так как хэндлы для каждого процесса, их запрашивающих, уникальны.

В данном случае, опасность для OllyDbg заключается в том, что у программы уже есть логический номер, с которым она может делать всё, что хочет. Хотя она и не знает, что выполняется из под OllyDbg, она может проверить имя процесса, чтобы определить, не называется ли он OllyDbg, и очевидно, что для этого будут перебираться все PID’ы, полученные в списке процессов, поэтому бросаем всё и отправляемся туда, где это будет происходить, для чего установим BPM ON ACCESS на соответствующий PID.

Продолжаем трассировать с помощью F8.

ec6cbe8de28bc5bc641b27cfae3e5dfa.png

Дошли до ещё одной API-функции, которую от нас пытались скрыть, – EnumProcessModules. Посмотрим её описание на том же сайте, что и ранее.

3a8ab912df6c06b2c60fc3e3ccac098b.png

То есть будет проводиться поиск в исследуемом процессе, получаем список модулей, используемых им. Продолжаем трассировать с помощью F7.

99458be594f5edb8297355824637a587.png

В стеке видим параметры:

bb19d43d8ece05f83d215ccae17834c2.png

Список хэндлов всех модулей сохранён по выделенному адресу, а первым параметром, как мы видим, является логический номер процесса OllyDbg.

Здесь нужно прояснить одну вещь: когда запрашиваем логические номера модулей, система возвращает нам адресную базу, или откуда начинается указанный процесс в памяти. В данном случае нам было возвращёно 400000, так как именного отсюда начинается процесс OllyDbg.

2c40cb8ae9f2e30bdb5f1c3b104557ed.png

Продолжаем трассировать и находим ещё одну API-функцию.

f859f96c15cfb2256f0b28bbbd8dba9d.png

GetModuleBaseNameA

ab2da02886b9c01f2d896bda205b3aa6.png

Т.е., что с помощью этой функции ходим найти имя модуля, так как эта API-функция помещает в буфер по адресу lpBaseName имя модуля, соответствующего адресу, выясненному ранее.

806b1f128727bb6a647696ffd456108d.png

В стеке следующие параметры:

007013f8184ac7c61b6771131a900abc.png

58 – это логический номер OllyDbg, 400000 – это база главного модуля, а буфер располагается по адресу 12ECE0, так что смотрим эту область памяти через дамп.

4d478ae55ea3c5884bf58f5b873c79e7.png

Хе-хе, уже понятно, что эта операция будет проведена для каждого процесса, который запущен в машине, чтобы узнать, не является ли его именем ‘OLLYDBG.exe’.

d95a99574ec705cb81dce69d6db2bb03.png

Доходим до CloseHandle, где закрывается логический номер, то есть 58 исчезает из их списка.

1e959c49cbc258e7558a124a3343666c.png

Ну да, теперь мы не можем делать никаких шалостей, так как логический номер закрыт, и мы больше не можем полагаться на него.

4b68f06eb3dec9e3e70424978f89f485.png

Дошли до CALL, входим в него, нажав F7.

eda91112d519cf25d5558524eb98535f.png

5e92564d8697a46633bd8dc3332f88f9.png

Здесь считывается первая буква “OLLYDBG” (4F) и помещается в стек с помощью PUSH, затем идёт новый CALL, в который мы также заходим.

Видим, что в этом вызове не происходит ничего особенно важного, поэтому выходим и оказываемся рядом со следующим CALL'ом.

1d70d4d3bdeb4d4183df6d902d7f608c.png

Заходим в него.

1d361b452dac330fb87c47ca61dbd30f.png

c39811c21ffd959d96d8c83fcf34a15c.png

Ах, где-то здесь сравнивается полученное имя процесса с ‘OLLYDBG.EXE’, и если они равны, то всё, капут.. хе-хе, сейчас они равны, посмотрим, что случится. Возвращаемся через RET.

4dab845e406c7defabe36493e680f368.png

Если бы они не были равны, то EAX должен был бы отличаться от нуля, и был бы совершён переход, чего не происходит, если EAX равен нулю, как в данном случае.

a33ab8dbbf1415050ba7b8f8a47e4f53.png

Перехода не происходит, и снова вызывается OpenProcess, чтобы получить логический номер процесса и убить последний.

3405c1b3cf4c9bc5c819574bfc1e2259.png

24599b1e6d33fe5089fb6ce5ab71f396.png

Если выполним с помощью F8.

2af22cf1721e9990801f88c08ffb8c38.png

Система возвращает номер 58, так что продолжаем.

1937241b9248629948329d61d0ff0c4e.png

Как видим, API-функция TerminateProcess, которой передаётся логический номер 58, служит для того, чтобы убить OllyDbg.

798ed77bf0f1377366f4035e23887b64.png

И по нажатию F8 – до свиданья, Олли. Всё закрывается. Вот так мы и исследовали, как работает обнаружение по имени.

Ладно, я слегка устал от роли убийцы, хе-хе, перезапускаем OllyDbg и устанавливаем BP на OpenProcess.

ed2d8515bee0d1bc5132bb0f80feedf3.png

Останавливаемся тут, и если подредактируем API-функцию так, чтобы она всегда возвращала ноль, то программа будет думать, что никакие другие процессы не выполняются, и у неё не будет никаких логических номеров. Для этого можно изменить последние строки.

4840bd8f80761bd2d0bde3989a33c296.png

Вот так, теперь эта API-функция всегда возвращает ноль. Теперь убираем все точки останова, и так как программа генерирует кучу исключений, то, хотя мы ещё и не рассматривали данную тему, чтобы она нормально выполнялась, отметим все опции в DEBUGGING OPTIONS-EXCEPTION следующим образом:

d39c7ce02a9be8d858ef0140c1005d41.png

Пока что просто отметьте все опции, чтобы программы перепрыгивала через все исключения, так как их очень много (для прохождения через них надо нажимать SHIFT+F9, а вышеуказанная конфигурация позволяет миновать их автоматически). Делаем RUN.

480c853f0bd18521c39a6a23d6b74568.png

И вот, она выполняется без проблем, но вот ещё, что можно сделать:

b4f84fdb2bd5f9888aedc5a0fd225320.png

Меняем JNZ на JMP, чтобы избежать выполнения кода защиты.

Программа запускается и показывает нам окно, которое исчезает после нажатия на TRY.

2bfe0c0c48249d397bee287e25bdd3be.png

Выскакивает сообщение об ошибке. Прекрасно, потому что это говорит о том, что защита против отладки была побеждена.

Всё это не обязательно делать, чтобы обойти подобную защиту, достаточно скопировать OLLYDBG.exe под другим название, скажем, PIRULO.exe, работать отладчик после этого будет также, а вот отлаживаемая в нём программа не найдёт ни одного процесса под имени OLLYDBG, так как теперь он называется PIRULO.

62dcfbf462d456e0ce4cb421bbe2ec29.png

Важно помнить, что переименованный файл необходимо держать в той же папке, что и исходный, во избежание проблем с плагинами.

dba4cb6b680525fe62cf41aa2d77fca4.png

Может быть защита и такого рода, когда программа идёт на уступки, если вводим правильный серийный номер, а также использовать другие API для нахождения имён процессов. Всё это мы рассмотрим в следующих главах.
 

О нас

  • Наше сообщество существует уже много лет и гордится тем, что предлагает непредвзятое, критическое обсуждение различных тем среди людей разных слоев общества. Мы работаем каждый день, чтобы убедиться, что наше сообщество является одним из лучших.

    Dark-Time 2015 - 2024

    При поддержке: XenForo.Info

Быстрая навигация

Меню пользователя