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

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
В 33-ей части мы рассмотрели, как работают IT и IAT. Кто-то мог бы подумать, что для починки IAT вовсе не необходимо знать, как она работает, так как есть инструменты, позволяющие это сделать автоматическим образом, но я вас уверяю – знание того, как и что работает – это очень хорошо, так как многие упаковщики вводят подобные инструменты в заблуждение, и те отказываются работать, и в этих случаях необходимо поразмыслить и подумать, как осуществить подобную правку собственноручно, и двигаться дальше.

Начнём с чего-нибудь лёгкого, например, с крэкми CrueHead’а, запакованного UPX. Сделаем полную распаковку, чтобы подготовить нас к главному, а потом починим IAT, чтобы она работала.

Как видим, первый шаг – это прибытие в OEP, для чего открываем крэкми в OllyDbg.

1e9be17966cbfa4984d9d0a71583e34b.png

Применяем метод PUSHAD, чтобы дойти до OEP, жмём F7, чтобы пройти PUSHAD.

d7fb69b71b0df519605099656a5ebefb.png

Теперь отмечаем ESP-FOLLOW IN DUMP.

И в дампе смотрим сохранённые регистры, отмечаем первые 4 байта и устанавливаем HARDWARE BPX ON ACCESS.

7860142c2ecbd751b915507aa9dc80fd.png

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

2e1b4e059c7fdadd43efd5b624c4da16.png

Хорошо, я нахожусь на переходе на OEP, нажимаю F7 и иду дальше.

40fea9e1653fa67975a83a94d255e512.png

Ок, прибыли в то место, где программа распакована в памяти. Теперь сдампим её.

В прошлой части я уже говорил, что существует много разных дамперов, в том числе и для OllyDbg существует плагин под названием OllyDmp, который очень хорошо дампит, но поскольку мы рассматривали ранее LORD PE, то будем использовать PE TOOLS, которые можно скачать по ссылке ниже:

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


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

Открываем PE-TOOLS без закрытия OllyDbg, где мы по-прежнему стоим на OEP.

4553a943b8dc9922aff0fa44136887f7.png

Ок, вот нужный нам процесс, который в данном случае называется crackme.exe, поскольку я потерял тот, что назывался crackmeUPX, пришлось сделать новый, но я забыл поменять имя, но это точно такой же крэкми, запакованный UPX’ом, что и в прошлый раз.

48bfc761be2806821343be5f8909c3f1.png

Делаем щелчок правой кнопкой мыши – DUMP FULL.

b020cf9bb6ffbab9af0e0461213d5974.png

38fb6d6b2028707a90a8b5d3d1c73ca2.png

Ок, сдампили, теперь переходим к починке IAT. Закрываем PE TOOLS, видим, что сдампленный файл сохранился в директорию PE TOOLS, так что ищем его и копируем в директорию, где находится упакованный UPX’ом крэкми CrueHead’а.

c06ef116228dd1bc04f877506fccf8b9.png

Попробуем запусть этот файл, хотя и знаем, что ничего хорошего из этого не выйдет. Делаем двойной щелчок на dumped.exe.

9c90a88a0b9abdc8bc3852b384b2ba7a.png

Ок, как видим, нужно починить IAT, чтобы файл мог работать на любой машине, а не только на нашей, для чего используем IMPORT RECONSTRUCTOR, конечно, не закрывая OllyDbg с загруженным крэкми CC, остановленным на OEP, так как IMP REC будет работать, используя его.

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


Программу можно скачать по ссылке выше.

ec68cfea43d169b12d03f82ab929bedd.png

Запускаем её и ищем процесс с крэкми CrueHead’а, упакованного UPX’ом, которое остановлено на точке входа.

Ок, сейчас встаёт проблема, которая озадачивает множество начинающих, а именно – как найти начало и конец IAT. Конечно, в крэкми, которое у нас остановлено на OEP, мы уже видели, что упаковщик разрушает IT, поэтому 4-ый и 5-ый указатели первого IID (Imaga Import Descriptor), т.е. имя DLL и адрес первого элемента её IAT, у нас нет, поэтому для её нахождения нужно использовать другие способы.

Конечно, знаем, что в общем случае вызовы API-функций реализуются с помощью косвенных JMP или CALL’ов.



JMP [xxxxxxx] o CALL [xxxxxx]
Как мы рассматривали в предыдущей части, программа берёт адрес API-функции на нашей машине из IAT, которая является хранилищем адресов API-функций на нашей машине. Ищем переход на API-функцию в упакованном файле, для чего снова идём в OllyDbg с загруженным упакованным CC, остановленным на OEP.

551e1d5dac1acf5a46f172b862870ad3.png

Здесь на второй строке видим CALL, о котором OllyDbg нам говорит, что это API-функция, хотя на самом деле это подготовительный шаг косвенного перехода, так что отмечаем эту строку и делаем FOLLOW.

909df462d0c1932fd54c23e5d8742c58.png

c367d381eb8482ff8c7673d74795ba96.png

Здесь находим таблицу переходов, содержащую значения IAT, сюда мы попадаем при вызове каждой API-функции. Как видим, эти переходы начинаются с опкодов FF 25, поэтому во многих туториалах сразу делается поиск двоичной строки ‘FF 25’, чтобы попасть сюда гораздо быстрее.

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

Вот в примере JMP [403238]:

a7ce2343590052633e17fea3cf9d3970.png

Довольно очевидно, что 403238 – это элемент IAT, где сохранён адрес API-функции GetModuleHandleA, и таким же образом можно посмотреть в DUMP’е часть IAT, что необходимо для определения где она начинается и где заканчивается.

Конечно, можно посмотреть на все эти косвенные JMP и определить, у какого из них минимальный, а какого максимальный адрес, но это очень медленно, а лучше пойти в DUMP и подняться немного. Как мы знаем, в каждом элементе содержится адрес одной API-функции, в данном случае это 7C80B529, то есть если перевернуть, получится 29 B5 80 7C. Переключитесь в режим одновременно просмотра двух колонок, чтобы был обзор получше.

3acfc57448fe158518b1f421b9db3ce3.png

Здесь видим структуру IAT. В прошлой части мы рассматривали, что все элементы, относящиеся к одной DLL, идут последовательно, и перед началом следующей идёт элемент-разделитель, состоящий из одних нулей.

980678d47ba5b1c66f26f3b4892788a8.png

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



00403238 29 B5 80 7C 0E 18 80 7C )µ€|##€|
00403240 A2 CA 81 7C 00 00 00 00
три API-функции, которые указывают на адреса 7Cxxxxxx, а затем идёт нулевой элемент, который отделяет следующую DLL.

Если используем VIEW-M, то увидим, что секция CODE данной DLL-библиотеки соответствует этим адресами вида 7Cxxxxxx.

4acb8c51acb9a5c0e48a2bc5fca3d9ac.png

Итак, все эти адреса указывают на секцию кода kernel32.dll.

9455fc19d330d76e606f596423707410.png

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

b2a86e48ff89e16aa05087f014e3442c.png

Ок, рассмотрели все элементы, указывающие на kernel32.dll, видим нулевой разделитель, помеченный розовым цветам, а выше находятся элементы, которые ведут в другую DLL, в данном случае в её секцию CODE, среди них встречаются элементы, начинающиеся на 77Dxxxxx, так что смотрим в M, куда они ведут.

f824a2cb77180d06ebb2a2100e25a13b.png

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

03572ad53033ebe086c3ae0f6cfd65ca.png

Здесь видим все API-функции, которые находятся внутри секции CODE библиотеки user32.dll и разделитель, но выше ничего нет, это значит, что начало IAT – в 403184, и это первый действительный элемент.

4ea2813b0bc6add8f79e1cb39368cf93.png

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

Итак, в образе началом IAT является 403184, теперь идёт вниз, пока не найдём конец IAT, используя тот же метод, используя тот же метод: продолжаем, пока элементы указывают на секцию кода какой-либо DLL.

Позже мы также рассмотрим упаковщики, которые меняют элементы IAT и перенаправляют на свои процедуры, в свою очередь совершающие переход на API-функцию. В этом случае метод выше не сработает, и мы будем изучать дальше, что делать, а пока будем исходить из того, что элементы IAT – это адреса на API-функции, которые должны указывать на секцию кода DLL-библиотеки.

b5598b065e88f620d3839754c87aa6de.png

Здесь видим последние элементы IAT, которые ведут по адресам 76xxxxxx. Проверим, какой DLL они соответствуют.

831866d3f9ae47f2dc7107e7ec4fd08c.png

В данном случае они соответствуют секции CODE в библиотеке COMDLG32.DLL, и после них больше нет элементов, так что это конец IAT, таким образом, адресом, отмечающим конец таблицы, будет 40328C, мы также могли бы принять, что концом является последний элемент 403288, и это бы было тоже самое, но для большей ясности рассмотрим, что конец в 40328C, и установим это как конец IAT.

Поэтому у нас теперь есть начало и конец IAT.



НАЧАЛО: 403184
КОНЕЦ: 40328C
IMPORT RECONSTRUCTOR запрашивает у нас сведения о следующих трёх вещах:

1)Начало IAT, но нужно сначала отнять от 403184 базу образа, которая в данном случае равна 400000, так что получится 3184.
2)Второе значение, которое у нас запрашивается — это размер IAT. Чтобы его узнать, нужно отнять КОНЕЦ от НАЧАЛА.

Размер=40328c-403184=108

Поэтому второе значение равно 108.

3) Третье – это OEP, также с вычтенной базой образа, то есть 401000-400000=1000

42b183b10afe99c7a50a02985ba3929c.png

Эти данные вводятся в IMP REC.

22886dbb902329de032728089887899a.png

Здесь видим данные, которые ввели в IMP REC, в OEP ввели 1000, то есть 401000 с вычтенной базой образа, в RVA начало таблицы, также с вычтенной базой, и в Size – размер IAT.

Здесь нажимаем GET IMPORTS.

837fc9da8946a3749a78bfa4fcecd7c6.png

Видим, что IMP REC, чья задача установить, какие API-функции относятся к каждому элементу IAT, и кроме их нахождения, он сообщает, правильны ли они, отмечая их словом YES. В случае, если элементы не ведут напрямую на API-функцию, как это бывает с некоторыми упаковщиками, он показывает NO, и в этом случае необходимо установить, куда этот элемент ведёт на самом деле. После того, как он приведён в порядок, IMP REC распознает его как корректный элемент и скажет «YES», и как только всё станет «YES», мы можем починить дамп.

Прежде, чем это делать, посмотрим на каждую DLL, развернув содержимое путём нажатия на +.

12d99d415510709925c702cd04e4f633.png

Тут у нас все элементы, к которым относятся API-функции, и если есть желание, то можно поместить первую из них (а это GetModuleHandleA) в IAT.

9ace086307c949dd469603781671ad3d.png

Если помните, это был первый элемент, который мы смотрели в IAT. Он соответствует 403238, но в IMP REC, конечно, все значения содержатся с вычтенной базой образа, поэтому ищем 3238. Кроме того, мы знаем, что он относится к Kernel32.dll.

7a351adefc827632556a07d9e5e9e240.png

Поэтому мы должны открыть kernel32.dll, для чего сделаем щелчок мышью на «+» слева от названия библиотеки.

1a0f2d507f07c36b8acac1f873b5e06c.png

Видим, что элемент 3238 соответствует GetModuleHandleA. Так что сейчас починим дамп, идём к кнопку FIX DUMP.

724a7ef994bfb5259f8e6d5a4748e26e.png

Ищем дамп и открываем его.

aae22feb52e865bee85f22338e1ccd47.png

Ок, видим, что IMP REC починил его, хотя сохранил изменённый файл не под именем DUMPED, а под именем DUMPED_.exe.

Смотрим, что находится в папке.

31176312ff80acb5da2d2d9e3f2d1c4b.png

Можем попытаться запустить его, чтобы узнать, нормально ли он работает.

9583fa5a1e97a02635f653deab0e23b7.png

Хе-хехе, похоже, что не работает. Не пугайтесь, такое часто происходит после починки IAT. В PE TOOLS есть решение этой проблемы.

92e6126970be68b0992b57f6f792e0d6.png

И идём в REBUILD PE, ищем DUMPED_.EXE, оно прекрасно срабатывает, а теперь запускаем его ииииии…

e8474fbaf3b7f3326b7d52c356d41ee5.png

Рабоооооотает! И теперь будет работать на любой машине, потому что IAT починен с помощью IMP REC, которые поместил правильные вызовы API-функций во все элементы IAT, заново записав туда имена API-фукций и приведя в порядк IT, чтобы она соответствовала тому, как должна быть, и что программа запускалась без ошибки.

Если откроем DUMPED_exe в OllyDbg.

872c078754ce5e1c1ebf3449a639ccbd.png

30232e43b8f949d2b4fee114eea4fe0a.png

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

ccbd980ac967161e1904f01e03693b10.png

Прибываем в точку входа и идём смотреть заголовок с помощью GOTO EXPRESSION=400000.

eaa2a21ae4cfe2a0fa0e1aca1e6c7dbb.png

c304c41592d5d35ff1c8ca4bbf3ecd4e.png

Меняем режим на SPECIAL-PE HEADER.

ce43325254e47af1646d3ea14ad8ac2d.png

609e54ef458dd5504cd285de8f7a2faf.png

Чуть ниже:

40ab4054086aec7d13b22add5aea6ec7.png

Видим, что сигнатура PE начинается в 80, идём туда (400080).

cb59fbdd22b8fc06cf4d7b4edf11ecf0.png

Здесь находится этот негодный указатель, означающий BASE OF CODE=9000, а мы хотим, чтобы первая секция была секцией кода, которая начинается в 401000, так что меняем 9000 на 1000.

450643560b390762abe7a4e8c7780b41.png

Отмечаем и идём в MODIFY INTEGER.

343b9878b48cfd75f72aff639b694389.png

8ab0bb848b319fcfb8e84118ba916fd4.png

Теперь сохраняем изменения как обычно с помощью щелчка правой кнопки мыши – COPY TO EXECUTABLE, в открывшемся окне опять правый щелчок и SAVE FILE.

5b098dc9b81ea6ff8a3eb74ee96c405b.png

fff463230ef4115415d8b07b19133f18.png

5e86e8dfd93df8c9d8c48dca7b5945d7.png

Теперь рестартуем крэкми в OllyDbg и увидим, что назойливое окошко исчезло, так как OllyDbg больше не считает ту секцию секцией кода.

cefd78b01aa1c01f24f29b2927b448ba.png

Если посмотрим секции сдампленного файла, то увидим, что для его починки IMP REC добавил новую секцию, названную mackt, где находится новая IT. Проверим её. В том же заголовки в режиме SPECIAL посмотрим указатель на IT.

c1a6790ad35b2bbe8e6dfc70c66bb6ec.png

Vemos que la IT esta ahora en B000 o sea 40B000 que es la direccion de la seccion que agrego el IMP REC vayamos a ver alli quitando el modo SPECIAL.

Видим, что IT сейчас находится в B000, то есть в 40B000, являющимся адресом секции, которую добавил IMP REC. Идём туда, выходя из режима SPECIAL.

Видим, что IT находится в B000, то есть 40B000, что является адресом секции, которая добавляет IMP REC. Идём посмотреть, что там, выходя из режима SPECIAL.

e1605fb44f8fbf0eef0a2e3e9d9e56dc.png

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

a0032eb72486c33714c53e25d6e70bb0.png

Здесь у нас первый IID, относящийся к первой DLL, и его 4-ый DWORD указывает на имя DLL, и в данном случае имя этой DLL находится по адресу B078, то есть 40B078.

3d890c691454fc92d33fe9c20115c94e.png

Это user32.dll.

И 5-ый указатель, как мы знаем из предыдущей главы, - это 3184, поэтому первый элемент реконструированной IAT находится в 403184, т.е. её начало.

e7f6a662bf73dbaab3375df1c1df1fde.png

И, конечно, первый элемент IAT у нас сейчас содержит значение API-функции, но если посмотрим в исполняемый файл, то до того, как быть перезаписанным адресом API-функции на моей машине, он должен был содержать указатель на имя API-функции.

ddced65fa3130d253e371e29d4264d1e.png

9f92e9875392d97b17bb064b224b13aa.png

В этом элементе IAT в исполняемом файле есть значение B084, которое соответствует 40B084, где должно находится имя API-функции, чей адрес будет помещён в этот элемент.

b0dbd4ccbc7bc83b1d16a8dfb91c348e.png

И это KillTimer.

Видим, что IMP REC провёл изумительную работу, обнаружил все API-функции, сконструировал новую IT, в которую добавил все указатели, и реконструировал список имён всех API-функций, чтобы система знала при запуске программы, какому элементу IAT какая функция соответствует. Настоящее чудо.

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

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

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

О нас

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

    Dark-Time 2015 - 2022

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

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

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