Введение в реверсинг с нуля используя IDA PRO. Часть 4

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Мы продолжаем рассматривать инструкции обмена данными в IDA.

XCHG A, B

Эта инструкция обменивает значение A со значением B, давайте рассмотрим пример.

e260ae6b5464149c1979ec3117df2fd1._.png

В файле VEVIEWER нет такой инструкции, поэтому я загружаю СRACKME.EXE Cruehead, и меняю инструкцию по адресу 0x4013D8.

Я помещаю курсор на строку адреса и перехожу в меню EDIT->PATCH PROGRAM->ASSEMBLE.

80aea60c9c0f4ffc737b68bff636b724._.png

Мы видим, что функция была повреждена, так как я работаю сейчас с ней.

79b06f41c3d33810491fe9760dfa3362._.png

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

Таким образом, если мы запишем инструкцию NOP, что означает NO OPERATION или инструкция заполнения, которая ничего не делает, то так заменим байт 0xC0.

e975d58ae093562caf3d0f08c68d405b._.png

Поставим по этому адресу NOP.

a7c2979fb268a2b90242fb5c732f20da._.png

Вполне очень симпатично, но функция повреждена. Если есть не распознанные части, подобно коду ниже, и IDA не распознаёт его, но когда с кодом всё ОК, мы щелкаем правой кнопкой мыши, где было начало функции 0x4013D8, и выбираем там пункт CREATE FUNCTION.

912ec4cb5ef6418d9922a24b6ae3ad90._.png

И это меняет префикс loc_, который означает “локальная метка” на префикс sub_, который означает, “начало подпрограммы или функции”.

f6f01740c1f8c7ceb8d302488be882d3._.png

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

5d219592de33dd275eee9171453af464._.png

Теперь намного лучше и сейчас здесь есть наш XCHG.

Мы видели, что если EAX равняется 12345678 и ESI равняется 55, то когда выполняется XCHG, регистр EAX будет равняться 55 и ESI будет равняться 12345678.

Мы видим, что в меню PATCH есть элемент под названием PATCHED BYTES, который показывает изменения, и он может вернуть к исходному неизменному коду.

487dcd00f9ffcd153b7c9d156a994c94._.png

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

beeacb28acee2e5dbd6ff099a4d85ad2._.png

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

Например, если значение EAX равно 55 и значение ESI равно 0x10000.

Инструкция будет проверять, что находится здесь, в этой ячейке памяти и если она доступна на запись, она сохранит туда значение 55 и прочитает значение по адресу памяти 0x10000 и сохранит его в EAX.

Что произойдет, если мы сделаем то же самое, но вместо того, чтобы использовать регистр мы используем адрес в памяти, как мы сделали в MOV ?

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

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


Во второй ссылке находится файл keypatch.py, который мы должны скопировать в каталог плагинов IDA и затем можно установить keystone-0.9.1-python-win32.msi.

Кроме того, необходимо установить Microsoft VC ++, библиотеку времени исполнения.

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


539511a8566a4ffab912c97240796fa6._.png
2b9cb3591e3d39d6d4764b315524d9b7._.png

В Keypatch выберите PATCHER.

Когда мы выбираем PATCHER, мы видим что, если запишем инструкцию в простой форме и со скобками, он запишет её и преобразует в синтаксис IDA.

1ede631ebfdd471f5ea91e375ebe5e5d._.png

И я получаю такой результат.

a7931bab8184f411742e743952ebf79d._.png

Как и в MOV, когда показывается префикс dword_ без СМЕЩЕНИЯ в начале, это будет означать, что обменивается содержимое 0x4020DC со значением EAX.

СПЕЦИАЛЬНЫЕ ИНСТРУКЦИИ ПЕРЕСЫЛКИ ОСНОВАННЫЕ НА РАБОТЕ СО СТЕКОМ

ЧТО ТАКОЕ СТЭК?


Стэк, это область в памяти, которая работает по принципу LIFO.

Для обработки данных предоставляется две основные операции: положить или PUSH, которая помещает объект в стек и обратная операция, чтобы забрать последнее значение или POP.

В каждый момент времени, есть доступ только к верхушке стека, то есть к последнему сохраненному объекту. Операция POP получает обратно этот элемент, который вытолкнут со стека, разрешая доступа к тому, который находится ниже (положен ранее) и он становится последним доступным объектом.

В CRACKME.EXE мы видим примеры обеих инструкций.

0e1fc3afd6007b7cdae2c0a2bc104003._.png

Обычно, в 32-битных приложениях, PUSH используется, чтобы передать аргументы функции в стек, прежде, чем вызвать функцию с помощью CALL, на картинке выше мы видим это по адресу 0x40104F.

PUSH 64 кладет dword 64 в верхнюю часть стека, затем PUSH EAX кладет значение EAX, на предыдущее значение в стеке, оставляя внизу это предыдущее значение, и поэтому оно будет последним на верхушке стэка.

ESP ->значение EAX
->
0x64

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

9d14e18c8c15a485efea2ccb7d63b4fb._.png

Мы видим слово СМЕЩЕНИЕ перед символьным ТЭГОМ, соответствующее строке символов, здесь будет положен в стэк адрес начала строки или строковый массив.

Если мы дважды щёлкнем на этот тэг, который представляет название строки WindowName.

В исходнике на C увидим массив символов, который может быть определен таким образом:

char mystring[] = "Hello WASM.IN";

31c7a93621dcf974a9f5bdad76bb18ed._.png

Мы видим, что в этом случае используются строчки для описания переменной.

Здесь записано char WindowName[], потому что IDA обнаружила функцию API CreateWindow.

ff5cac266faebcb43a99124ec3378eb3._.png

В любом случае, это массив символов или байтов, только IDA добавляет немного полезной информации, которая получена от API функции, мы видим, что после адреса 0x4020E7 следующий адрес в списке 0x4020F4, здесь есть некоторая последовательность байт, которые принадлежат символам строки “Crackme v1.0” и ноль, который говорит о конце строки.

5bdb6365d31fb5f17f715f559dc95941._.png

Если мы нажмём кнопку D, чтобы изменить тип данных на WindowName.

Мы видим, что мы можем заставить IDA прекратить обнаруживать эту строку как символьный массив, и оставить её как DB или то же самое, что и байт.

526ad506594b4de1f086bbab703ea09e._.png

Это те же самые байты, которые соответствуют последовательности crackme v1.0.

Мы видим, что оригинальная инструкция изменилась, очевидно слово offset впереди говорит о том, что будет заталкиваться значение 0x4020E7, но сейчас, содержимое прекратило быть символьным массивом и теперь стало байтом и инструкция изменилась на

deb7d76a8f9735fee1de29fb01b154de._.png

push offset byte_4020e7

a4eeb4d8997829c09058586c4e80d823._.png

Нажмём кнопку A и строка из ASCII последовательности станет снова как и раньше.

3cd88cd3dcce3a7979b2bbbcad05a110._.png

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

04b8284ac8df43f2b32c6ed0099a9dd7._.png

Передвигаемся в начало последовательности байт и нажимаем A, теперь смотрится намного лучше.

e1975167bb98448272e1f6aead85d7f0._.png

В этом случае, мы видим, что эта строка не определена в двух строчках, как предыдущая, IDA даже не говорит, что она CHAR[], но она определена с помощью тэга, который начинается с буквы a, для того, чтобы быть ASCII строкой, в предыдущем случае IDA показывает дополнительную информацию, потому что IDA обнаружила, что это был аргумент API или функция системы и IDA предупредила, что аргумент должен быть CHAR[] и вот почему она добавил это там, но нормальная строка будет похожа на эту последнюю строку.

Здесь мы видим другую строку.

9393875ed2eb8e4303568f199e99a95a._.png

По адресу 0x402110 начинается первый байт строки, она может быть расщеплёна на байты, чтобы их видеть отдельно, просто нажатием клавиши D на строке aMenu.

7b65a1e8260b748fe9febb6cc57b8d01._.png
Если мы нажмём A, мы отменим сделанные изменения.

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

Мы видим, что тут сохраняется адрес 0x402110, потому что стоит слово СМЕЩЕНИЕ.

6fbf33b4f6ac1fef30e39c70986c4d18._.png

Обычно, когда аргументы передаются к функциям, мы всегда будем видеть PUSH offset xxxxx, потому что ищется адрес строки, чтобы передать его функции, если инструкция не имеет слово OFFSET, мы бы заталкивали содержимое адреса 0x402110, байты 55 4E 45 4D которого являются той же строкой и API не будет работает, API всегда передаётся указатель на начало или адрес где начинается строка.

В этом случае, в этой инструкции, которую мы видим выше, префикс DS:TAG указывает, что она собирается сохранить его в адрес памяти секции данных (DS=DATA), когда мы будем рассматривать структуры, мы изучим этот случай, сейчас важно запомнить, что инструкция сохраняет адрес начала строки в секции DATA.

POP

ca43b9a02bbfe4a6c641b884d298b617._.png

Эта операция, которая читает вершину стэка и перемещает значение с этой вершины в регистр назначения, в этом случае мы видим, что POP EDI будет читать первое значение или ВЕРШИНУ СТЭКА и скопирует его в EDI, а затем ESP будет указывать на значение, которое было ниже и теперь оно станет ВЕРШИНОЙ стэка.

Если мы ищем текст, а именно слово POP, мы видим, что вариантов используется не так много, несмотря на то, что там есть возможность вытолкунуть POPEAR(wtf amigos???) в адрес памяти вместо регистра, эта опция не является очень используемой.

6c187cf011804b097768dbbcbe3328c9._.png

Мы продолжим с другими инструкциями в пятой главе, чтобы быть готовыми изучать функционирование ЗАГРУЗЧИКА.

Пока пока.
Рикардо Нарваха

Источник:
Пожалуйста, Вход или Регистрация для просмотра содержимого URL-адресов!
AL REVERSING CON IDA PRO DESDE CERO/EN INGLES/
Перевод на английский - @IvinsonCLS
Перевод на русский — Яша_Добрый_Хакер
Перевод специально для форума системного и низкоуровневого программирования - WASM.IN
24.02.2017
 
  • Лайк
Reactions: _k0NsuL

О нас

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

    Dark-Time 2015 - 2022

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

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

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