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

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Ок, продолжаем как обычно. Мы уже нашли украденные байты, и у нас теперь есть скрипты для того, чтобы легко попасть в OEP и чтобы починить IAT, так что осталось сделать дамп.

06dd530658a5d68a4a475e9ef78a08ed.png

Открываем программу в OllyDbg и устанавливаем два BP, необходимых для работы скриптов, и стираем BPX, которые могли остаться от прошлого раза.

954be124e86686d7411e2defe2d1002e.png

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

c23ec8bfa361ae54877373a59d6e0354.png

8a92eb33cd5e246f39cc9e42974c8201.png

Отвечаем, что нет и находимся в OEP.

f38fdb0160f0893edb7aa3f0ae21cd19.png

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

40c88ef68f7a342f06fcea9c9892c18d.png

806f22ed4430237468a3f3a221d9bb66.png

Снимаем галку и сохраняем как dumped.exe или другое имя, которое мы хотим. Теперь перезапускаем OllyDbg и используем скрипт для того, чтобы работать с починенной таблицей.

2d71cff9456584b41db40659416dcd63.png

Здесь уже всё работает, так что открываем IMPORT RECONSTRUCTOR и ищем нужный нам процесс в списке процессов в выпадающем меню.

Теперь ищем данные OEP, RVA и РАЗМЕР IAT, как мы это делали в прошлой части.

OEP=271b5
НАЧАЛО=60818
РАЗМЕР= 460f28-460818= 710
Видим, что все API-функции правильны кроме одной. Я её пропустил?

Можем посмотреть, что случится, если бы эта ошибка не была показана. Рестартуем OllyDbg и устанавливаем на этот элемент MEMORY BREAKPOINT ON WRITE.

db8ab98e3c84f085dc01a5f433438ea1.png

И делаем RUN, чтобы оказаться в месте, где сохраняется плохое значение.

c8e7a0eea048c190d0e3daaec67ad730.png

Здесь видим, что будет сохраняться значение и в ESP-0C нет никакой API-функции.

05b4c26adf219fe145e4f607ea053dda.png

Видим, что скрипт изменил его на значение, которое в данном случае равно 46E5CB, так что видим значение, которое сохраняется в IAT без использования скрипта. Нажимаем F7.

d5a6bea5977f1fa0f9704fa1955dd89c.png

Значение, сохраняющееся без использования скрипта, будет плохим, так что смотрим, куда оно ведёт. Идём в 46BD5B.

584b5b22ee278212d9bbdbcf17efb908.png

Хорошо, как видели раньше, выполняется PUSH константы, и над ней совершается XOR с другой константой, а результатом этой операции становится адрес API-функции. Считаем.

942c0892 xor 946aed59

Если нет желания использовать калькулятор, может использовать то, что OllyDbg выполнит сама эти строки и получит результат, хе-хе.

0058ee1505feb6219e858f376565ef9a.png

99cd6b55708b9eeaaefc56b45cf7b9b5.png

Видим, что результатом XOR является 46E5CB – это значение, которое скрипт поместит в элемент, поэтому скрипт не ошибается. Дело в том, что этот элемент особенный, так что рестартуем и прибываем в OEP, что посмотреть, найдём ли то, к чему динамически относится API-функция, то есть, откуда она запускается.

f2e5c279d10c2eb7e4f4940c466ddb27.png

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

a995a1904648d9277de24e088e2649a7.png

Останавливаемся, трассируем.

b68a49cda37604f2c1397978fbc90fad.png

Конечно, доходим до RET и отсюда прыгаем:

ea4a27eb40c045f5fb8db3e02f952d7d.png

Посмотрим, ведёт ли это к какой-нибудь API-функции. Начинаем трассировать с помощью F7 и видим, что это ведёт в большой кусок кода, так что применяем метод pushad. Вот эта инструкция в начале, и останавливаемся на POPAD, до куда нужно оттрасировать некоторое количество строк.

a2cc1bbae963514917589ee251871a12.png

И видим, что API-функция, с которой у нас проблемы – это MessageBoxA.

Другой, более быстрый метод – это сделать RUN TRACE с условием, что необходимо остановиться, когда EIP станет, например, больше 500000, то есть когда произойдёт выход из секции в API-функцию. Смотрим:

8f226b101dfc9cec7a164ba46139249f.png

Здесь останавливаемся, когда EIP выходит за пределы 0-500000. Пробуем, сработает ли.

239acc9db2b1a6633764640b1b214e55.png

2f4516a149f63845112eca265e1d1fce.png

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

4ce09327aa78b214f3655785a0762add.png

Адрес возврата – это 40E51B. Если пойдём туда:

5728c6d1a63df280c7be71eaf4d02ab1.png

Возвращаемся прямо на следующую строку вызванного call’а, так что у нас уже есть все данные. Перезапускаем процесс с помощью скрипта для IAT и устанавливаем данные как в прошлый раз в IMP REC.

d97cb396c22a2244bb5f87caf539cbca.png

Делаем двойной щелчок по неправильному элементу и меняем его на MessageBoxA.

8a647c9840a4f73b0fccf00f8fa4792c.png

Теперь, если всё правильно, починим дамп с помощью FIX DUMP. Ищем файл дампа.

42791e6c33ade9963c320ba9e12a4226.png

И сохраняем его как dumped_.exe. Нам осталось исправить OEP на предмет украденных байтов, так что открываем файл в OllyDbg.

6b412a71c3ec0d82113aeaae50afc5f6.png

Нам нужно скопировать украденные байты и поменять OEP.

00485AF3 Main PUSH EBP
00485AF4 Main MOV EBP,ESP ; EBP=0012FFC0
00485AF6 Main PUSH -1
Вот украденные байты, которые мы можем ввести с помощью функции «Assemble».

159def6520f8295eec89e78ea5d0df39.png

b8fc0c9ecfb0fab49abbcd8e39512ed6.png

Видим введённые байты, которых ровно пять, так что теперь считаем: 4271b5 (фальшивая OEP) минус пять байт дают нам правильный OEP, то есть 4271b0.

0fc1cb7fd9ff5ba9797557d99cca63de.png

Теперь, если сохраним изменения с помощью COPY TO EXECUTABLE – SAVE FILE, мне останется поменять OEP. Перезапускаем и идём в заголовок дампа с помощью GOTO EXPRESSION 400000.

f514f1093d3ff761658f7f085a1bdd7f.png

Переходим в режим SPECIAL-PE HEADER, ищем значение ADDRESS OF ENTRY POINT, меняем его и сохраняем изменения.

9b1c2a7b763dff84952cf10a760de17d.png

672351dbeb6ce62f2e76ac0e9a9a6fd4.png

Ок, если запустим файл после починки, то будет показана ошибка. Снимаем все галочки с исключений и смотрим, какой ещё трюк был применён против нас.

8697c0650c66ebdb8c259b6cbd492609.png

Видим в LOG’е, что произошла ошибка, смотрим CALL STACK, то есть нажимаем кнопку с буквой «K», показывающую последние исполненные call’ы (можем также посмотреть в стеке RETURN TO…).

e48c5cf552cfad44dca8a405271d79ce.png

Последний CALL был выполнен из 429806, идём туда.

ac1714d2e705b898b06da51f8fe519c5.png

b7789dc64d53aaabd4b682c48cebe706.png

Продолжаем с помощью FOLLOW, чтобы посмотреть куда идёт CALL.

1b7e9757c38140ba0fd171df8691b7dd.png

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

Запускаем оригинальный файл в другом OllyDbg и доходим до OEP с помощью скрипта, стирая старые HBP и устанавливая два необходимых BP.

d7ac0a7f6369c7888136e78c1cb6bf6a.png

Alli llegamos vamos a mirar la zona de esos saltos indirectos aquí

Доходим до сюда, смотрим область этих косвенных переходов.

4f6e7ebeedf61a433df1a9f006fd735a.png

Если пойдём в DUMP, то там табличка, откуда берутся значения для перехода.

e903196e2c56c71eb5594203269af1e6.png

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

Ищем первый переход в 46c0f5.

56fb6bd9ec2102179d6773783f253913.png

Он занимает 6 байт – инструкция JMP, ведущая в 178250, где также проиходит выполнение 6 байт и возврат.

93b6682fbf78c7c65b258b35e31654e4.png

Идея заключается в том, чтобы заменить 6 байтов косвенного перехода на 6 байтов, которые действительно что-то делают.

0c2d63c302ff54353a2f512b155c62a9.png

Отмечаем три строки и делаем BINARY COPY.

Возвращаемся к переходу и делаем BINARY PASTE.

d7523712ac78a6156bf01c5ecaf21f50.png

0b50739370ede9c1053ad9fc9f13199a.png

Должно работать. Эти косвенные переходы вызываются call’ами из программы, так что выполняется шесть байт, и при срабатывании RETN будет происходить возврат туда, откуда произошёл вызов.

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

b9aa73d6f23b3ec0c51c00d1c6bd7cd1.png

Байты начинают выполняться с 178256 – это первый элемент таблицы, а последний заканчивается в 1799ba.

4b06f71b85ea478c72e8ee6f3ef6241e.png

Так что копируем с помощью BINARY COPY всю область с нужными нам байтами и заменяем переходы с помощью BYNARY PASTE.

c47dc88dfa3185583b269e6a5b6d2998.png

Видим, что получилось, также видим, что некоторые переходы в конце ведут к частям, у которых нет RET.

031daf738b82bf800ddb03707a82e86d.png

Я предположил, что эти переходы не используются, так что, по идее, проблем возникнуть не должно. Ок, починили секцию. Теперь может сделать BINARY COPY всей секции и скопировать её в файл дампа с помощью BYNARY PASTE.

7b1d48b06d9dbee0407959c68a63613a.png

Теперь сохраняем изменения в дамп с помощью COPY TO EXECUTABLE и так далее.

911fe22f0051361ad2d8c7f13841afe0.png

Чтобы сохранить их и нам не было сказано, что не можем этого сделать, делаем так: от конца секции поднимается до последней строки, где есть данные.

646bfa020434466a4418a13cfbdbfa3f.png

Отмечаем отсюда и до начала секции вверх и сохраняем изменения. Перезапускаем и пробуем.

3a77718c35bffff537d6fa9f1fef4d7d.png

Работает превосходно. Мы победили украденные байты, переадресовочную IAT, антидампы, и защиту против HBP.
 

О нас

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

    Dark-Time 2015 - 2022

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

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

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