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

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

AnGel

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

AnGel

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

Для этого снова идём OEP.

b8acb8258e23dc83c88ddbe3585a5c8e.png

Ок, теперь идём в фальшивую OEP, ищем вызовы API-функций и с помощью клика на правую кнопку мыши смотрим SEARCH FOR-ALL INTERMODULAR CALLS.

4da2bec9602d5b306f5372e9cf3bde91.png

3b9db65ac320a7e3e269e75c9084dd6d.png

Вот они, выбираем один и делаем двойной щелчок на нём, чтобы посмотреть листинг.

8ae218a8986d131cb2bd26ae53eee876.png

Это значит вызов API-функции принимают значение 460d38, что является адресом элемента IAT.

5147d9664c75c966d9244d9b62e4844a.png

Вот IAT и видим, что все элементы – правильные, поднимаемся наверх, чтобы найти начало IAT.

05c57d2291f54ad24503f78959347ee3.png

Видим, что начало IAT находится в 460818, так как если отметим какие-нибудь элементы выше и нажмём FIND REFERENCES, то не будет найдено никаких ссылок, ведущих в секции кода DLL. К сожалению, вся IAT правильная, поэтому нам не нужно искать волшебные переходы. Ищем конец IAT.

Вот и он.

6d53576aecabb2d871c5d7ffed588c8a.png

До части выделенной серым нет проблем, есть ссылки а вот элемент 460f24 сомнителен, для него нет ссылок. То, что мы отметили серым это элементы, ведущие в секцию кода ole32.dll.

81f5b8eb23c9354eeb1472da36f4d358.png

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

fed5d811bca75da5ce04f4bdf3c56b71.png

Если снова посмотрим на OEP, увидим, что редкий JMP, который на моей машине переходит в секцию по адресу Axxxxx, которая относится к секциям самого исполняемого файла (на вашей машине она может находиться по другому адресу). Посмотрим на карту памяти:

90b30094baed6132c7798c875ccacf88.png

Видим, что программа переходит в эту секцию и что оригинальная программа, запускающаяся из OEP не может перейти в секцию, находящуюся вне exe-файла до того, как она будет создана с помощью VirtualAlloc или другой подобной функцией, поэтому делаем вывод, что эта секция была создана упаковщиком и не является часть оригинального кода программы, так же как и JMP, которые туда переходят, как, например, тот, который стоит в фальшивой OEP и многие другие.

Поэтому возможно, что в эту секцию упаковщик поместил вызовы и переходы, которые берут значения из IAT. Откроем конфигурацию OllyDbg.

56d44d402459691aa6a4b0bf985df11b.png

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

Пробуем искать ссылки в других секциях.

22acd2102e99ec3fb1025f463f0d55a6.png

f0a3ba1be36c6451478b0efae6d26d07.png

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

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

129a50fba4f2432e3034059ffdea9f2a.png

a3ea2edcd95e2dae0223002455f1e097.png

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

7256d2f8afdd81d321850779f5488525.png

623dd6727f03c7a008d3ac5c6c750314.png

Теперь ищем ссылки.

Ничего, но у нас несколько секций, и знаем, что вызов, читающий значения из элемента 460f24 будет выглядеть как:



CALL [460f24]
а байты, из которых состоит эта команда:

FF 15 24 0f 46 00

Например, если посмотрим другой вызов одной из API-функций:

ba6de812b62e196bebfeb8ea74290d52.png

Видим, что последовательность байтов вызова равна «FF 15», а затем идёт адрес элемента в обратном порядке, так что можем поискать эти байты по всей памяти и таким образом выяснить, есть ли эта ссылка где-либо, что позволить нам избежать посекционного поиска.

8cf52f8b6fb9f93afd49ee4bc2398367.png

Идём в карту памяти и нажимаем на правую кнопку мыши.

64e1ec4ed4e848afbc58ba9ebfcdd19b.png

2f3d6b771bf9c4e8c20fff0fdd805d2a.png

И пишем в поле «HEX» последовательность байтов, которую мы хотим найти. Нажимаем OK и не получаем результатов (грр), но так как мы настойчивые ребята, и есть множество возможностей вызвать API-функцию, не использующие косвенные вызовы, стираем «FF 15» и ищем в памяти только адрес.

9239e030f52e547573ce726cf4859483.png

118cacdea469977312d658afe4159d2b.png

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

b77896802237a84c164df95f4ed43ad3.png

Здесь находим эту чудесную ссылку, очевидно что мы пытались искать «FF 15» (косвенный вызов), но не «FF 25» (косвенный JMP), но ладно, проведя поиск по этому образцу мы получим ссылки на любую команду, которая вызывает API-функцию.

Таким образом, мы установили, что это элемент IAT.

99210577b8f43519b65f79c442f14e18.png

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

Ок, данные из IAT равны:

LARGO=FINAL -INICIO= 460f28 - 460818= 710

aa70c9c91b7b561b3fe987ee1b544033.png

Так что у нас получается следующее:

OEP=271B0 RVA o INICIO=60818 SIZE O LARGO=710

Теперь видим, что IAT правильная, так что нужно снова пойти в фальшивую OEP, добавить украденные байты и сделать дамп.

Идём в фальшивую OEP.

Украденные байты равны:

55 8B EC 6A FF 68 60 0E 45 00 68 C8 92 42 00 64 A1 00 00 00 00 50 64 89 25 00 00 00 00 83 C4 A8 53 56 57 89 65 E8

Прикрепляем их в дампе после 4271b0, как мы это делали в главе 39.

302566f10fba0acbe83c0ac5a3f773f4.png

Теперь сдампим, изменив OEP на 4271b0.

c759906588f1e5eb2aec03cf26897de5.png

Здесь изменяем OEP, снимаем галочку с «REBUILD IMPORTS» и нажимаем «Dump», чтобы сделать дамп.

5691a442df9c78e4936356042d09dd08.png

Сохраняем его как «dumpeado pelock», можем сейчас починить IAT, так как мы определили OEP. Открываем IMP REC.

9f8c7c29667ea0156543aed9c6b236ac.png

Устанавливаем данные IAT, найденные нами и нажимаем GET IMPORTS.

f13e785255ea6909729b556125d87871.png

Говорит, что «NO», но давайте вспомним, что переадресовочных элементов нет. Проблема заключается в том, что упаковщик заменил нули, отделяющие элементы друг от друга на разный мусор. Давайте посмотрим.

3b2ddf5eea5df24b6ae1f1e8837e7234.png

Здесь ясно видно, что вместо нулей, отделяющих элементы для каждой из DLL, находится мусор. IMP REC легко это исправит, нажимаем SHOW INVALID.

5ec3c2d7ec46a5efbf48dfd00cf14e8d.png

Вот подтверждение того, о чём мы говорили – элементы advapi32.dll и comctl32.dll отделены мусором, так что помечаем весь этот мусор, нажав SHOW INVALID, затем делаем правой кнопкой мыши выбираем CUT THUNKS, тем самым обнуляя все эти элементы.

d15ab71483baee74bdfb712132cd6e52.png

e0e0c1ec51d08957834d914ea2487505.png

Как видим, после обнуления мусорных элементов, IMP REC показывает, что всё правильно и таблица починена.

Теперь нажимаем FIX DUMP для того, что починить дамп.

2a2f6d98dfac78152d72ec9542cb6d3b.png

Создаётся «dumpeado pelock_.exe» с починенной IAT, и теперь, если запустим исправленный файл, то выдаст ошибку. Открываем его в OllyDbg без закрытия другого, который должен быть остановлен на OEP.

Так как выдал ошибку формата, передаём его LORDPE с опцией REBUILDPE, чтобы починить заголовок, и теперь можем видеть в Ollydbg результаты исправлений.

6f4fdfa95e32e0b9cf57dca6034688f6.png

Видим, что остановлен на EP в правильном виде. Смотрим IAT.

a88ab19cc156df1cc1efc69f387b8bfd.png

Здесь видно, что IAT была правильно починена IMP REC'ом. Видим, что он заменил мусорные значения нулями, для того, чтобы было нормальное разделение между различными DLL. Несомненно, что запустив программу тут же в OllyDbg, получим ошибку, что и происходит.

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

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

5120f2ee5593e3f0f4afe384223e3085.png

Программа запускается, но когда доходит до JMP, выдаёт ошибку. Трассируем досюда.

d9aac79d8aae45f9f009e5521dd16d59.png

Видим, что если нажмём F7, то перейдём на несуществующую секцию.

38edcf8134823108322b8da04ffe8e23.png

И не можем продолжать. Если посмотрим на исходный файл, то увидим, что JMP ведёт в область, созданную упаковщиком во время выполнения.

41c8ceab2a3ff33a7506a1cd095eb13e.png

Делаем щелчок правой кнопкой мыши – FOLLOW, и отображается, куда ведёт JMP.

90b6b9faaf1d4a76dbde8112353ade0d.png

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

Смотрим отсутствующую секцию в исходной программе. Сначала добавим ту, из-за которой происходит ошибка в начале, потом, если будут снова ошибки, добавим другие.

Необходимо сдампить только ту секцию, из-за которой происходит ошибка, для чего используем “PUPE” -

6fb4f52dfb4e82337ef3b1db9761a20c.png

Делаем щелчок правой кнопкой мыши - CAJA DE HERRAMIENTAS.

35e57f1ea8f76d78a5857b4d702551be.png

Открываем в ней нужный процесс, идём в карту памяти, чтобы сдампить отсутствующую секцию, для этого нажимаем кнопку MAPA (“карта” по-испански – прим. пер.)

Вспоминаем, что отсутствующая секция начиналась в A80000, так что ищем этот адрес в карте памяти PUPE.

3cc84b5888e0e7e4c1f61b6e93dd0606.png

Теперь нажимаем VOLCAR и сохраняем под именем “секция”.

2e62bbe1eccd44195f819e8a9eba09ec.png

Теперь открываем PE EDITOR и добавляем её к дампу.

9b94338337b29407332dc655e8da6f98.png

Ищем починенный дамп и открываем его в PE EDITOR'е.

d85b08ab2d170e806c6ea3fa0a812f29.png

Нажимаем кнопку “sections”.

19a564409f2a82746f632460c98069be.png

Здесь видим секции дампа, которые перешли туда из исходного файла, ещё секцию mackt, которую присоединяет IMP REC, чтобы починить IAT, теперь, наконец, добавляем отсутствующую секцию.

Делаем щелчок правой кнопкой мыши и выбираем COPY A SECTION FROM HD TO EOF (конец файла).

676314dfaae1bc7ca1b241a9a1e18412.png

51c2496c95f8685bf6e79e07d2ffe4b6.png

e31b8be879bd42347ff444ff6bb7071f.png

Теперь нам осталось только поменял VIRTUAL OFFSET на 0A80000, чтобы она запускалась отсюда, как и в исходном файле.

461e90cb26616099849f5b1d94ccea7b.png

Меняем виртуальное смещение на 0A80000, отняв 400000, остаётся:

fefa98167ed21393ad73b8c477549612.png

680000 является адресом виртуального смещения новой секции.

a5bcbea5c20af872e1f43c2624d62ad4.png

Теперь остаётся один шаг – снова починить заголовок с помощью LordPE, используя опцию REBUILD PE.

dbded01cdda9bfd8497a0cede40effe4.png

2787ee9440c53b87bd105784b6455d93.png

Запускаем и видим, что работаем, если открыть в OllyDbg.

5f4cda810d93271a5f71a224e6afb7e7.png

Смотрим карту памяти.

4976187842dca7fdb4dcfd49c96c53fa.png

Видим, что LordPE, чтобы сделать дамп рабочим, увеличил предыдущую секцию, чтобы не было “провалов” между ней и той, которую добили с помощью PUPE.

22e6ae3bd826f53bc3e3795f3c99cd1c.png

Если посмотрим переход, то увидим, что сейчас у нас есть ранее отсутствовавший код.

dfc6f9e9eca3f22282b6b8933b7dede5.png

Если образ оказывается слишком велик, то можем пропатчить всё, что нам нужно, а потом упаковать с помощью UPX, который уменьшит файл, но оставит при этом работоспособным, а также может распаковать его обратно. Если запустим GUIPEX, то там есть опции упаковки и распаковки. В данном случае это не является необходимым, так как дамп после починки и с добавленными секациями занимает меньше 500k.

Другой возможностью для тех, кто хочет изучть другой способ исправления антидампа, является добавить отсутствующую секцию или секции в продолжение последней, что не слишком сильно увеличит размер exe-файла, а затем поменять OEP в дампе, сделать вставку, чтобы расположить её в позиции созданной с помощью VirtualAllocи скопировать байты, которые мы добавили туда. Этот метод очень хорошо изложен marcian'ом в одном из последних состязаний crackslatinos.

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

marciano применяет другой метод, заключается в том, чтобы присоединить отсутствующую секцию вместо изменения Virtual Offset. Я много раз применял этот метод и он очень хорош, хотя если отсутствующих секций много, то добавлять их одну за одной несколько утомительно. С помощью метода добавления, используя LordPE, задействуется вся память между последней и добавленной секциями.

Таким образом, с помощью метода PeEditor'а первой удобно добавлять самую дальнюю секцию, так как после починки с помощью LordPE, вся память между последней секции и началом вставленной секции будет выделена без каких-либо проблем. Затем мы можем скопировать байты из исходной программы, остановленной на OEP в дамп, а затем вносить и сохранить изменения в нём, если будет отсутствовать какяя-то из “серединных” секций.

Думаю, что это хорошо понятно на нашем примере. Если самая дальняя добавляемая секция начинается в 0A80000, то LordPE увеличит последнюю секцию дампа так, чтобы она заканчивалась как раз у 0A80000, поэтому если надо будет добавить секцию, находящую до этого места, можно будет легко скопировать и вставить её, а потом сохранить изменения.

ИСХОДНАЯ КАРТА ПАМЯТИ

cc99152c41987bea1b891f3d5f04e6f1.png

КАРТА ПАМЯТИ ДАМПА

ead497b22336eb95afd768a7447b403d.png

Здесь видно, какие секции исходной программы, предшествующие A80000, существуют в дампе, и для них найдётся место, так как LordPE увеличил секцию mackt до места, куда присоединили недостающую секцию. Суммарный размер затребованной памяти составил с 401000 до A80000 + 3C0000 (размер последней серции) = 0E40000.

b4af68b5379b3ffef772906e05bafbb8.png

То есть любую секция, которая находится между 401000 и E40000 мы, если необходимо, сможем добавить в дамп.просто скопировав и вставив её из исходной программы, остановленной на OEP, сохранив затем изменения.

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

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

О нас

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

    Dark-Time 2015 - 2022

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

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

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