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

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
Загрузчик

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

Мы будем анализировать его части и характеристики, большая часть того, что мы видели до настоящего времени, будут применимы и к ЗАГРУЗЧИКУ и для ОТЛАДЧИКА. В случае, если что-то будет отличаться или не похоже на общий случай, я упомяну это.

Очевидно, то, что в ЗАГРУЗЧИКЕ программа абсолютно не выполняется, но она анализируется, и создаётся база данных с информацией этого файла, и это значительное отличие относительно ОТЛАДЧИКА.

В ЗАГРУЗЧИКЕ нет ни окна РЕГИСТРОВ, ни окна СТЕКА, ни списка модулей, которые загружены в память. Это вещи, существуют при выполнении и отладке программы.

После загрузки Cruehead Crackme (CRACKME.EXE), если мы посмотрим на список процессов , то увидим, что он не работает и никогда не выполняется, пока мы не откроем отладчик IDA.

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

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

Что же такое регистры и для чего они используются?

Хорошему процессору нужны помощники в его задаче по выполнению программ.

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

32-разрядные регистры, которые используются - это: EAX, ECX, EDX, EBX, ESP, EBP, ESI, EDI и EIP . В конце курса будет часть, посвященная 64-битным.

120d7778af9f45ac8225a349cf3b1bf7._.png

Регистры общего назначения

EAX (Аккумулятор): Аккумулятор используется для таких инструкций как деление, умножение и некоторых инструкций формата, и также как регистр общего назначения.

EBX (База): Он может непосредственно работать с памятью, используется как база и также как регистр общего назначения.

ECX (Счетчик): ECX регистр общего назначения, который может использоваться в качестве счетчика для различных инструкций. Он также может иметь адрес смещения данных в памяти. Инструкции, которые используют счетчик, являются - цепочечные инструкции, инструкции смещения, ROR инструкции(циклические) и LOOP/LOOPD.

EDX (Данные): Это регистр общего назначения, который содержит часть результата умножения или деления. Он может также работать непосредственной с данными памяти.

EBP (Указатель на базу стека): EBP указывает на место в памяти. Почти всегда как база для аргументов и переменных функции, кроме того, он также регистр общего назначения.

EDI (Указатель на назначение): Часто, он указывает на адрес назначение результата в строковых цепочечных инструкциях. Он также регистр общего назначения.

ESI (Указатель на источник): Часто, он указывает на адрес источника в строковых цепочечных инструкциях. Как и EDI, ESI также работает как регистр общего назначения.

EIP: Указатель, который указывает на следующую инструкцию, которая будет выполнена.

ESP: Указатель, который указывает на верхушку части стека или пачку.

Подведём итог того, что я сказал.

Восемь регистров - EAX (аккумулятор), EBX (база), ECX (счетчик), EDX (данные), ESP (указатель на вершину стек), EBP (указатель на базу стека), ESI (указатель на источник данных ) и EDI (указатель на назначение данных).

Также там существуют 16-битные и 8-битные регистры , которые являются частями предыдущих регистров.

Если EAX равно 12345678

AX
это последние четыре цифры (16 бит)

5b9fb5bc5e1e12f5a9450dfd54f20de1._.png

AH это 5-я и 6-я цифра и AL две последние цифры (8 бит каждая)

d896df1f7b42b9c80bb17fabfea7b1e5._.png

Есть 16-разрядный регистр для младшей части регистра EAX называющийся AX и два 8-разрядных регистра называющихся AH и AL. Не существует специальных регистров для старшей части .

Эти регистры существуют в той же формы для EBX (BX, BH и BL), для ECX (CX, CH и CL) и это применимо почти ко всем регистрам (только у ESP есть 16-бит SP, но не SL из 8 битов)

f181b8b4948073a32bf7ec2f8fa89ffa._.png

Здесь Вы можете видеть регистры, такие как EAX, EDX, ECX, и EBX, которые имеют регистры из 16 и 8 битов и EBP, ESI, EDI и ESP, которые имеют 16-битные подрегистры.

eaba0eec6dec88e7d30f0f1aac9dbf46._.png

Мы будем рассматривать и другие регистры, один из них важный вспомогательный регистр EFLAGS, который активирует свои флаги, которые принимают значения на основе решений в разные моменты выполнения программы, которые мы рассмотрим позже, сегментные регистры указывают на другие части исполняемого файла, такие как CS=CODE, DS=DATA и т.д.

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

10bb230997109c12f60878541f2daf59._.png

IDA управляет большим количеством данных, которые мы будем видеть постепенно, чтобы не усложнять обучение, важная вещь состоит в том, чтобы знать, что BYTE равен 1 байту в памяти, WORD 2 байтам и DWORD составляет 4 байта.

ИНСТРУКЦИИ

IDA
работает с синтаксисом инструкций, который не является самым простым в мире, большинство же людей используют дизассемблер OLLYDBG, который более прост и без кофеина (проще понять), несмотря на то, что OLLYDBG дает нам меньше информации.

Инструкции перемещения данных

MOV


MOV dest,src: Она копирует содержимое источника операнда (src) в место назначения (dest).

Операция: dest ← src


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

MOV EAX, EDI

387a2beb33ac6884f5508fde19ecf84e._.png

В целом, мы можем перемещать из или в регистр непосредственно, принимая во внимание это EIP не может быть МЕСТОМ НАЗНАЧЕНИЯ или ИСТОЧНИКОМ в любой операции. Мы не можем сделать так

MOV EIP , EAX

Это не допустимо.

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

MOV EAX, 1

9725197d2db442097545e3dab4423333._.png

Другая возможность состоит в том, чтобы переместить значение адреса памяти, а не ее содержимое (Эти инструкции в изображении принадлежат другой программе, не CRACKME.exe, потому что они не были там, но есть в VEViewer.exe, файл приложен к этой части 3)

c06b464d11775ea807e7a9d81fed1670._.png

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

Или если нажмём Q , оно становится таким

2e5cb257bec33342466d398ba9068096._.png

MOV EAX, 46f038

Эта ещё одна инструкция как в OLLY, но она не дает нам информации о содержимом этого адреса. Если мы щелкаем правой кнопкой по адресу 46F038, мы можем вернуться к исходной инструкции.

5df004e38813eba3e9695f3608714602._.png

И она станет как прежде.

Что говорит мне эта дополнительная информация? Что IDA говорит мне о вышеупомянутом адресе памяти?

1ba57536a7489ec16b20f8c78cb26b9b._.png

Если я открываю окно HEX DUMP и поищу упомянутый выше адрес, я вижу, что первично он равен нулю. Я знаю, что это DWORD, но я действительно не знаю что это, потому что он зависит от того, где он использует это значение в программе, что определяет тип этой переменной.

2e398b9a8f8f9a9248f7c26209938be0._.png

Если я вернусь к списку и дважды щелкну в этом адресе.

f22ca13c422589204965dd3a1adc2687._.png

Здесь я буду видеть, что IDA говорит мне, что содержимое вышеупомянутого адреса DWORD, в окне дизассемблера IDA, когда мы видим область памяти, которая не является кодом, поскольку в этом случае принадлежит секции данных, конечно, первая колонка это адрес`а.

IDA говорит мне dword_46F038, это означает, что содержимое ячейки памяти равно DWORD, это похоже на разъяснения адреса слева, здесь есть тип данных dd, который является знакомым нам DWORD и потом значение, которое содержит вышеупомянутая ячейка памяти, является нулём.

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

b45f1880e660015a502f42eb57ab09fd._.png

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

a6c3c0ba7eb4358728d740503eff3f0b._.png

Первая, где читается адрес, где мы были ранее, вторая, записывает DWORD по адресу 0x46F038, вот почему IDA в первой инструкции говорит нам, что тот адрес указывает на DWORD, потому что тут была другая ссылка, которая получает доступ к ней и записывает этот DWORD и сейчас все чисто.

02b81140ce5ab2e69f7bfa0613cb9588._.png

Так что, IDA в первоначальной инструкции не только сообщила мне, что собирается поместить адрес в регистр, но она также сказала мне, что этот адрес содержит DWORD, это что-то вроде бонуса.

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

Как ранее мы видели.

mov eax, offset dword_46F908

Эта инструкция поместит адрес 0x46F908 в EAX

mov eax, dword_46F908


Эта инструкция поместит содержимое или значение, которое расположено в вышеупомянутой памяти.

48f7cf0ff5ce153733fcb79bf1390668._.png

Эта инструкция, которую помним по OLLY с квадратными скобками для, тех кто привык к этому отладчику.

MOV EAX,DWORD PTR DS:[46f908]

Или когда адрес имеет впереди слово OFFSET, он ссылается на этот самый адрес, а когда этого слова нет, то ссылается на значение полученное по этому адресу.

Это просто случается, когда мы обращаемся к числовым адресам, если мы работает только с регистрами.

ff25912071cdb9e3ebe842e80a86a285._.png

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

Конечно, в этом случае, если EDI указывает например на 0x10000, упомянутая выше инструкция будет искать содержимое адреса памяти и оно будет скопировано в ECX.

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

4a1b6652268f23df377b38324e193624._.png

Тут мы видим, что в EAX помещается значение 0x45f4d0, потому что впереди есть слово OFFSET и также она говорит мне, что упомянутый выше адрес содержит stru_, который является структурой.

7b64e89c395383607d9802ab657c6aee._.png

В другом случае, в первой помеченной инструкции, перемещается содержимое 0x46fc50, которое DWORD ,а во второй, просто адрес, который равен числу 0x46FC50.

Мы видим, что значение вышеупомянутого адреса будет помещено в 0x42f302, если мы кликнем в 0x46fc50, давайте посмотрим, что там есть.

64bc5f3dd03bcfa7d8bbb9c38c3a4ade._.png

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

С помощью нажатия на X на ссылки, мы видим все ссылки, видим, что инструкция сохраняет DWORD по адресу.

6c8d140177f2967456a9ab1c80b7513a._.png

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

Конечно, константы можно также поместить в 16-ные и 8-ные регистры, которые мы видели ранее.

375e11309efa211ae0873200383b4acc._.png

Эта инструкция помещает 1 в AL, оставляя остальную часть EAX со значением, которое было прежде. Тут просто изменяется самый младший байт.

fd744c663dbf19477ae622d8dade187d._.png

Здесь, инструкция перемещает содержимое адреса памяти 0x459C24 в AX и говорит нам, что это WORD.

b04bf0e127205fb81eca2d8fd4a27d7d._.png

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

707939475b48d0dea7f78164541269ec._.png

Здесь AX помещается в содержимое EBX, т. к. это регистр, то не знаем какое значение имеет регистр AX, IDA не может сказать больше, она использует квадратные скобки, чтобы указать что, записывается в содержимое адреса EBX.

626857b770494207bf47b8d34d81f335._.png

Здесь, инструкция запишет значение AX в содержимое ESI+8.

Другой пример

2fdf8db05317ebd30af7a9f856d94eef._.png

Если я щелкну на страшное имя, оно приведет меня сюда

6ef6d590fb6dd69adfcb54119a33fa8c._.png

Мы знаем, что это IAT (таблица, которая сохраняет импортированные адреса функции, когда запускается программа), она почти всегда находится в разделе idata.

Если я ищу этот адрес в окне HEX DUMP, у него всё еще нет указателя на функции, потому что IAT заполняется, когда процесс запускается, а тут он ещё не запустился.

096d83a528823d6cfb905dfe2ca2ffde._.png

Если я пойду в OPTIONS->DEMANGLE NAMES и выберу NAMES будет намного лучше.

56c1d02b8bfb6a12f450202879f26830._.png

Префикс EXTRN подразумевает, что это ВНЕШНЯЯ импортированная функция.

Если мы прокрутим выше, мы видим, что программа говорит, что есть импортированные функции, которые принадлежат модулю DVCORE.dll и выше есть другие, которые принадлежат различным функциям.

7582008ddbc2f01bfdab757f1f48300b._.png

Мы видели различные примеры MOV, которые Вы можете практиковать и видеть в IDA , в той программе, которую я приложил к уроку.

В 4-той части, мы продолжим и разберём больше инструкций.

Пока.

Рикардо Нарваха
Перевод на английский @IvinsonCLS
Перевод на русский Яша_Добрый_Хакер
Перевод специально для форума системного и низкоуровневого программирования - WASM.IN
18.02.2017
 
  • Лайк
Reactions: _k0NsuL

О нас

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

    Dark-Time 2015 - 2022

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

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

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