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

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

AnGel

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

AnGel

Администратор
Команда форума
27 Авг 2015
3,411
2,025
ИНСТРУКЦИИ УПРАВЛЕНИЯ ПОТОКОМ ВЫПОЛНЕНИЯ ПРОГРАММЫ

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

Следующие инструкции управляют потоком выполнения программы. Мы знаем, что EIP указывает на следующую инструкцию, которая будет выполнена, и когда это произойдёт, EIP будет указывать снова на следующую инструкцию.

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

JMP A

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

234b65a28fa33c730c86b85171b7bb73._.png

JMP SHORT - это короткий переход, который состоит их двух байт и он имеет возможность переходить вперед и назад, направление задаётся значением второго байта, первый байт это ОПКОД перехода, мы не можем переходить очень далеко.

bdee5e58e3b10fce920909a451d50aed._.png

Если мы установим в IDA опцию, чтобы видеть байты, из которых состоят инструкции, мы увидим опкод 0xEB, который соответствует инструкции JMPи которая будет совершать переход на 5 байт вперед от места, где заканчивается инструкция, адрес назначения может быть рассчитан следующим образом.

a11a4be29eb8d40b5de3b0a40723106d._.png

Начальный адрес инструкции + 2, что является количеством байт, которые составляют инструкцию и затем добавляется число 5, что является вторым байтом.

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

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

a11a4be29eb8d40b5de3b0a40723106d._.png
4103912eac0da3ea8521e62d9e4dc69e._.png

Здесь нас спросят имя.

В VIEW->DATABASE SNAPSHOT MANAGER

bc788eb35650c2dd8ef71fd7ec720c72._.png

Это позволит нам увидеть список всех снимков и дату, когда они были сделаны и с помощью кнопки RESTORE, мы можем вернуться к состоянию, которое мы хотим, которое мы сохранили ранее.

Давайте посмотрим, что произойдёт, если поменять байт 0x05 на 0x7F.

fab2adfe549a8274b2d04df46efa4ffc._.png

Используя PATCH BYTE в IDA, я меняю байт 0x05 на 0x7F.

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

e1ffbb6a339ca3840c934547340e15dd._.png

77aa5ef86e6c85d9f726cc3f4b93ae03._.png

Мы видим, что всё нормально и этот переход ведёт к адресу 0x4013A5вперёд, давайте посмотрим, что произойдёт, если мы изменим байт 0x7F на 0x80.

Вернёмся в графический режим с помощью пробела и изменим байт на 0x80.

d64afee1cc4e08c42d8ee81f003bb8e6._.png

Мы видим, что сейчас мы делаем самый большой переход назад, здесь изменяя значение 0x7F на +1, что является самым большим переходом вперёд, мы изменили его на 0x80, что является теперь самым большим переходом назад.

59904137b1fd36af68b74fa1956f078a._.png

В этом случае, когда мы возвращаемся назад, чтобы подогнать всё под формулу и только для математических целей, потому что PYTHON не знает, что переходы могут идти вперед или назад от инструкции, мы должны записывать -0x80 в его 16-ное значение, в DWORD, что равно значению 0xFFFFFF80, а затем, как мы видели при выполнении инструкции, применить логическое AND 0xFFFFFFFF к результату, этим мы очищаем все биты, большие, чем необходимо для 32-битного числа, и у нас получается тот же самый адрес 0x4012A6.

Если я использую 0xFF в качестве второго байта, это будет минимальный переход, который равен -1 в 16-том представлении. Я добавляю к нему 0xFFFFFFFF, чтобы соответствовать нужной разрядности. Помните, что мы всегда добавляем размер инструкции, в данном случае, два байта. Это позволит нам совершить переход назад, потому что 2 байта, которые мы добавили, заставляют считать это как начало вычисления. Инструкция будет переходить по адресу 0x401325.

Если мы продолжим переходить назад ещё на одну позицию, то вторым байтом будет 0xFE, что означает переход назад на -2 байта от конца инструкции, в формуле это будет добавление значения 0xFFFFFFFE.

844464e9da4a703b15e8f611b716fdb6._.png

Этот переход к той же самой начальной инструкции, которая именуется БЕСКОНЕЧНЫМ ЦИКЛОМ, она всегда возвращается к повторению и Вы не можете вырваться из него.

И так далее, переход на -3 где заканчивается инструкция перехода назад, будет равен 0xFD и он совершит переход по адресу 0x401323.

7ad50256c1bf7f6fc64966d4a1b0648c._.png

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

7239df8e35e09c48c26a61244b595bc8._.png

Здесь, мы видим пару длинных переходов, помните, что loc_ говорит нам, что эта инструкция является локальной(любой, основной) инструкцией.

f9b5f19904b143094992c1c53d5fc32a._.png

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

f4134aa478d13cd5e1effa81dbc5b7b6._.png

Здесь мы видим, что расстояние вычисляется с помощью следующей формулы: конечный адрес - начальный адрес – 5. 5 - это размер инструкции. Это даёт мне результат 0x300, что является DWORD и он стоит рядом с опкодом длинного перехода 0xE9.

09d7dae3b1ef3736629dd919a1c3d281._.png

348648223cdb0bff10a81493a466eaee._.png

Если с помощью KEYPATCH я изменяю адрес назначения этого перехода на адрес перехода назад, например на адрес 0x400000, мы видим ...

45b91f9493e0335cbb0959e56268d093._.png

Хотя он помечен мной в красный, потому что он не является действительным адресом в данный момент, Я буду видеть, смогу ли я сделать формулу в PYTHON, чтобы сделать переход назад.

8610ac29ff9a1f4fec3f25c73e33f356._.png

Это даёт мне расстояние равное -0x26B3, используя ту же самую предыдущую формулу.

b76209095a32e33088e0c4ea84a51694._.png

Эти байты в 16-ном представлении равны 0xFFFFD94D, которые стоят рядом с опкодом 0xE9, но только инвертированы справа налево.

fbb580983a047b7da865cdb44400c333._.png

УСЛОВНЫЕ ПЕРЕХОДЫ

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

Давайте возьмём например инструкцию CMP A, B.

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

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

bc735bd9661ea2a38a41a84e4f87fa3f._.png

Здесь мы видим, пример условного перехода JZ, он также совершает переход, если флаг Z или нуль активирован. Это происходит, когда в предыдущем примере CMP EAX и EBX равны, так как CMP похожа на инструкцию SUB, но она без сохранения результата.

CMP вычитает оба регистра и если они равны, результатом будет 0, что активирует ФЛАГ Z или нуль, который проверяет переход JZ, чтобы совершить переход, если ФЛАГ Z активирован, программа переходит к зелёной стрелке и если нет, то переходит к красной стрелке, если они разные.

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

cea40d3a607413d921e836fe0710ea72._.png

Хорошо, за исключением JMP и NOP, которые не принадлежат таблице, остальные - это условные переходы, которые оценивают различные состояния сравнения, если первый аргумент из них больше, или если больше или равен, или если меньше и т.д., есть несколько возможностей работы с ними, которые мы увидим позже более подробно, когда будем рассматривать ОТЛАДЧИК.

ИНСТРУКЦИИ CALL И RET

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

759856a4a3ac56e709eca6ae68f526e8._.png

Здесь мы видим пример инструкции CALL, который переходит по адресу 0x4013D8 для выполнения этой функция (мы видим приставку sub_ перед адресом 0x4013D8, которая говорит нам об этом).

Инструкция CALL сохраняет на ВЕРШИНЕ стэка значение, куда будет возвращаться выполнение или адрес возврата, в нашем случае это адрес 0x40123D, я могу войти во внутрь этой функции просто нажав ENTER на инструкции CALL.

65f05d0a5af3afe56c0c4e213cbe9ad0._.png

После того, как эта функция завершится, она также достигнет инструкции RET, который берёт адрес возврата сохранённый в стэке,а именно адрес 0x40123D и перейдёт туда, продолжая выполнение после CALL.

5711d63cc7f9aa152408c4054755afc2._.png

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

До встрече в 8-ой части.

Рикардо Нарваха
 

О нас

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

    Dark-Time 2015 - 2022

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

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

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