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

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Мне попросили, чтобы прежде, чем начинать рассказ об исключениях, я рассказал о том, как запустить в OllyDbg крэкми «antisocial», которое было приложено к предыдущей статье.

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

Сначала загрузим её в переименованную OllyDbg со всеми плагинами, чтобы посмотреть, почему не крэкми не выполняется и попытаться это исправить.

Итак, запускаем antisocial в переименованном и пропатченном OllyDbg со всеми доступными плагинами.

5f602c0aab664d6b401bc76390c93e5a.png

Это уже даёт нам идею о том, что программа может быть запакована. Оказываемся на точке входа.

7cd37ce57c7163a88347aa83d30952fb.png

Здесь видим что-то странное, а именно инструкцию POPAD, которая служит для получения значений из стека, помещённых туда ранее с помощью PUSHAD, а никаких PUSHAD до этого нет, что весьма подозрительно.

Запускаем, чтобы посмотреть, до куда дойдёт.

498e436b5bb5d3ee50e3e8aa511ae505.png

Досюда.

7dcae5bd33af6eff9c0b96c60314736f.png

То есть, когда крэкми пытается сделать PUSH, выдётся ошибка, что нет прав писать в стек, но права писать в стек должны быть всегда. Взглянем на стек.

a731ffc693d5c970f393830e21083689.png

То есть, значение наверху стека равно 130000, и если рестартуем программу:

2503a43f9d89b8a2c2e7255976b86be6.png

Посмотрим секции и увидим, что стек на моей машине идёт с 12c000 до 12ffff, ошибка возникает, потому что стек выше за пределы своей секции на другую, которая начинается с 130000, а туда-то писать как раз прав и нет.

Вернёмся обратно в место, где произошла ошибка.

63570ba483ed98a2c918ec709e286c13.png

Видим, что программа выполняет ещё один popad и совершает JNZ-переход на PUSH, который также вызывает ошибку. Установим BPX на этот popad до того, как произойдёт ошибка.

c6f462cad8b143f5563382394deb028a.png

Теперь перезагрузим программу, сделаем RUN и остановимся здесь.

2073f2c4870396baa57966580368d1c6.png

Смотрим стек.

b2d0be390d3b3fcc894f17be25ac2707.png

Находимся в правильной секции. Запускается POPAD.

baa782e1021065e10177be50061731bb.png

Здесь заканчивается секция, так что проблему можно решить, забив POPAD NOP’ами, но вообще, POPAD должен предшествоваться PUSHAD, которая сохраняет начальные значения регистров в стек, а этот POPAD тогда будет получать их обратно, поэтому давайте посмотрим, что будет, если заменить POPAD на PUSHAD. Рестартуем программу.

Нажимаем пробел.

dfa574c0a838c75e1d623325a7998ba3.png

Пишем PUSHAD.

267648bc4b6c7683e76e22941ef6ea1d.png

2738b63c76e473dac7d0bd27f911cf90.png

Теперь нажимаем RUN и останавливаемся на второй POPAD.

91e253008d4714b573746ff069c0b795.png

Но в этот раз стек в порядке.

7fa9cf7e651ce74ef818e87bc5435553.png

Поэтому POPAD не выходит за границу секции стека, и мы можем миновать это место с помощью F8.

779827a3f198bb0614c3eccec815bd14.png

Видим, что всё прошло без проблем.

f96b547085bf2110c1325db6f5c631d8.png

Доходим до PUSH и RET, трассируем и, нажимая на F8, доходим до RET.

87842310336d73e6ca954e7b5f5d4242.png

Хорошо, здесь есть проблема с анализированием.

2b211b6a22014c5510346c9b9318fada.png

3413dd238100475acebe9ce9ea38c957.png

Здесь это особенно видно.

Посмотрим, что случится, если сделаем RUN.

a196426e8e4cc81fb1a49e2cabbc5af1.png

2ed60516e4e5fd7fb5b77684188a97ae.png

Так как программа завершилась, посмотрим в LOG’е OllyDbg, есть ли там что-нибудь интересное.

06b13dbd8dc2e7134d5a1149b4bc78f2.png

Видим, что возникло исключение после точки останова на POPAD. Рестартуем и повторим все шаги, чтобы оказаться там, где были.

dc0cfd0c7e8791da6b44741e9b7b58af.png

Уберём галочки со всех опций, которые относятся к исключениям.

dad74f7cf5f8f71dc59b05a928c90beb.png

Делаем RUN.

aee901ddabb1937c2b423bd76b3bd8f3.png

Останавливаемся на исключении, что отображается в LOG’е.

d9a04a433bb97647ca12856e0b91c783.png

INT68 – одно из немногих исключений, которое OllyDbg не может избежать, но можем забить его NOP’ами.

f46dbde2a05022468f4c0bf70676e206.png

b696d6230e84ee7d36a41c242ed049b7.png

С другой стороны, знаем, что могут быть ещё INT68, которые будут мешать, поэтому поищем их и также забьём NOP’ами.

42e45de17bb91b1af61277e7c03127fd.png

b822a1c4232606c29231e644dd32f6a0.png

e1143533f744065a194b43cbaef9bc46.png

Видим, что нашлось ещё одно исключение, забиваем его NOP’ами.

8c358431ecca414591266686c4bd7c3a.png

Ищем заново, находим, забиваем NOP’ами.

a8450fb4c1e161af839a377cf1a296c0.png

Если нажмём CTRL + L, то продолжим искать то, что искали в последний раз.

Когда ничего больше не находим, делаем RUN.

cc519f1b8b91ab91fc478c79c28670c1.png

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

84d1d7baa97cb157438b86fb49b5d215.png

Я распаковал OllyDbg без плагинов, всё, что есть – это command bar, так что никакой защиты. Для этого используем другую директорию и другой путь, указывающий на плагины.

b714bd8cfc20cc775eac6173d311b26f.png

ad894d6b609b8ab170352d87fdb81493.png

Как видим, здесь только один плагин. Запускаем OllyDbg.

eb89aca707493d30a3c1fe0b3996d8f8.png

Повторяем операции по замене popad.

dd6711aaa1a2e1515d215fdb9c6817aa.png

12c55847fed841f400c81647dfaae616.png

Устанавливаем BPX на POPAd, нажимаем RUN и смотрим, куда попадём.

a81ea584d211cadc80de8f6fc4c25102.png

Прибываем туда, где распаковывается код программы.

b7cc297fe7b44495e46e800e9afd5309.png

Можем забить INT68 или снять галочки с исключений, и каждый раз, останавливаясь на INT68, забивать его NOP’ами, а не идти дальше с помощью SHIFT+F9, как это мы обычно делаем с другими исключениями.

8d9171ef2195b39c34e28f7720cb4871.png

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

04040e3014abe218a2f686fcbf7079a1.png

Необходимо отметить её, чтобы отображалась информация о секции, в которой мы сейчас находимся.

57c5909fdb4d2853ba8b670377b09b7b.png

735b1b35532446d9d888bd91e45f5c44.png

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

344a4aa12a1c4d09d5298a79544eadb3.png

Жмём RUN.

d0eef2c12e47cc4fda6102f25831e0bf.png

Ничего подозрительного нет, продолжаем нажимать RUN, пока не встретится что-нибудь странное.

11e556b30c953be2fd37b67f01cd4495.png

Здесь нам повстречалась первая странность: API-функция, которая делает снимок состояния всех выполняющихся процессов. Доходим до RET и ставим BP EAX, так как EAX будет содержать адрес функции.

5ff8208348fe760a0766e208d2ccdf2c.png

11ebc5b23e393fc3fdbcf2c91588ca5c.png

13d9c401491078d287221720feef5a64.png

f2aaa1c16cbdaaaaec5b629ccb6cba2f.png

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

9b9e1da8a32e860dac72eb08ac4af809.png

Список продолжается.

10cd6e0a750b46dcc162d46cbba61099.png

Ещё что-то похожее на прошлый случай, на всякий случай поставим BP и сюда.

ba4465b08bdd35d0d5e8b02791ee6c95.png

Жмём RUN.

9d990a77cdddc395971f234ddb928dee.png

Ставим BP на неё.

eb6e2d9e3fd677913f96d030e2e41019.png

7747c954f96090ddb164d3bc46e0f985.png

То же самое.

575e0f3f916b6ba991eb490aa6788962.png

e016048c12920f7b01f0d59ab38f2f48.png

a79f9c933a2c4d3bb72f35e2cf177c80.png

8149f39e05435d2d441e21a395910fd9.png

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

f4be72536970f6ce2937e5e9c2a48b64.png



Видим пустые пробелы (NOP’ы), так что можем сделать EAX равным нулю, до того как его значение будет возвращено.

8b2b7d42e13a5dd8b9c1a3185df72c76.png

Так мы возвращаем ноль, и у программы нет логического номера, с помощью которого она могла бы обработать снимок или что-то узнать о процессах. Это один способ, а другой состоит в изменении кода самой программы. Выполним неизменённый RET функции.

7810382c7e0b96a52a397d2353cdc34c.png

Чуть пониже есть JNZ-переходы, а ещё чуть ниже их – вызов TerminateProcess, который закрывает OllyDbg, и перед которым есть OpenProcess, получающая логический номер программы.

9abcedeef74247bf2f0db83074dd6872.png

Если заменить все JNZ на JMP, можно избежать перехода на TerminateProcess и закрытия OllyDbg.

Первая часть защиты преодолена, теперь переходим ко второй части. Жмём RUN.

ca036ba38a5cb1d6e0b7b3ef10ac38de.png

Забиваем NOP’ами, запускаем выполнение программы, но она всё равно закрывается. Если поставить плагин HideDebugger, который защищает от FindeWindows/EnumWindows, то выполнится нормально, если повторить сделанные до этого шаги.

Место, где происходит закрытие, следующее:

bcb278f1993ccda32da782caeddfa8b1.png

Выполняем программу и когда останавливаемся на верхнем вызове,

d356b918b95982766cead46c6f0808bc.png

bd61950bc486f8d7867b30a8751e5e46.png

Видим, что здесь сравнивается.

f4def8bbc4de557dc852ab6dd70008a1.png

7b9ffab9ca9206a59d0a5d98b323f053.png

Вопрос в том, как избежать сравнения этих нехороших вещей, хе-хе, можно сделать это, заменив JNZ, который стоит после первого CALL, на JMP.

2ee76f441f5e928810021a1f00d37892.png

Этот загадочный переход заменяется на JMP.

864dceb09c0dea0948aea3322b4eadfb.png

Избегаем второго CALL, внутри которого находится следующее.

1aa378f1dc625340b4673def223fad6d.png

Здесь находится PostQuitMessage, который даст приложению сигнал о необходимости выхода из цикла обработки сообщений и завершения приложения.

Конечно, если спросите меня, как найти этот JNZ, то это легко.

Как только прошли первую часть защиты, устанавливаем BPX на PostQuitMessage.

bdfa89130e6c8127d6bc9e41a9e43f74.png

bceb3687073be58644e11f53ae92caed.png

Останавливаемся на API, смотрим на стек, чтобы узнать, откуда вызывается.

ad8f305cfbe717fe9845050c6634e267.png

Идём в 4532d7, так что стек расскажет, откуда происходит вызов.

6d65a9e2bc36f58352faecd4cece8393.png

Конечно, я попробовал изменить JE, стоящий перед PostQuitMessage, на обратный и не смог избежать закрытия окна, так что идём ко втором RETURN TO, который есть в стеке.

a57847b73ec3327ead7bef0b7c3cc684.png

Он ведёт в 4532СС.

460b49eb30673c2e84d464e9a1c6c0fc.png

Как видим, этот call можно избежать, обратив JNZ, и тогда не будет вызван и PostQuitMessage, и изменив JNZ на JMP видим, что крэкми выполняется без помощи каких-либо плагинов.

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

До встречи в 25-ой главе, где мы будем изучать исключения.
 

О нас

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

    Dark-Time 2015 - 2022

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

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

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