> For the complete documentation index, see [llms.txt](https://yutewiyof.gitbook.io/intro-rev-ida-pro/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-37.md).

# Часть 37

[\[Используемые материалы\]](https://github.com/yutewiyof/intro-rev-ida-pro/tree/e1367e11cc661f3d69c02ae5f733b7dd168bc5ab/.gitbook/assets/files/37.zip)

Хорошо. Мы будем делать тот же пример, который мы делали в предыдущей части, но на этот раз используя плагин **MONA** внутри отладчика **WINDBG**. Мы знаем, что **MONA** не запускается в **IDA**. Поэтому мы открываем **WINDBG** вне **IDA**.

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

![](/files/-LjrE0tJMt7qyW7r8MUy)

Я мог бы запустить программу также и с помощью **WINDBG**. Это было бы те же самым. Нам просто нужно остановиться в том месте, где загружается **DLL**, в которую мы будем загружать **ROP**. Не имеет значения, что он не заработает.

В этом случае, мы находимся внутри функции **GETS\_S** и библиотека **MYPEPE** уже загружена.

![](/files/-Ljtu4oc-uQwWdXECvCe)

Я присоединяюсь к процессу через пункт **FILE** → **ATTACH TO PROCESS**.

![](/files/-Ljtu4opjI3eV0stmCjg)

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

![](/files/-Ljtu4ow9LaGLNIvXaLa)

Символы уже присутствуют.

Хорошо, давайте загрузим **MONA**.

![](/files/-Ljtu4p3a-ziMLUbQmx8)

Сейчас, давайте попросим её сделать нам **ROP** для библиотеки **MYPEPE.DLL**. Давайте посмотрим, какой результат получился у неё.

**!PY MONA ROP -M MYPEPE**

Давайте пойдем за кофе, пока **MONA** работает над поставленной задачей. Это займет немного времени.

Пока она заканчивается анализ, позвольте мне сказать, что у неё есть опции для поиска адресов без нулей, для фильтрации различных символов, и т.д. Это очень хорошо. Хотя она не всегда находит полную цепочку **ROP**. Иногда, **MONA** даёт нам почти полный **ROP** и говорит нам, чего ей не хватает, для того, чтобы найти цепочку вручную. Поэтому нам всегда приходится немного доделывать за неё работу.

![](/files/-Ljtu4pBTmti07aEIvla)

Тсссссссс...... Дайте ей время подумать.

![](/files/-Ljtu4pIz4PCBQ6__-3B)

Опция **-CP** даёт нам возможность фильтровать результаты **ROP** в соответствии с различными критериями. Мы видим, что у **MONA** есть опция **NONULL** для того, чтобы найти инструкции без нулей или другие. Также у неё есть возможность фильтровать численно с помощью опции **CPB**, для определенных символов.

![](/files/-LjrE0uFqDTkT7kMyD1A)

**MONA** закончила анализ. Посмотрим на результат. Она написала много текста. Если бы я запустил её как пользователь **ADMINISRATOR**, она сохранила бы результат в **TXT ФАЙЛ**, но у неё нет разрешений на запись. Поэтому я буду копировать здесь наиболее интересные части.

![](/files/-Ljtu4pYw22FQjcoJLo1)

Мы видим, что она показывает нам то, что регистры должны иметь перед гаджетом **PUSHAD - RET**, который мы использовали в предыдущей части. Она даёт нам ещё одну альтернативу для вызова функции **VIRTUALALLOC**. Также полезно сохранить то, что должны иметь регистры при использовании функции **VIRTUALPROTECT** которая также находится там.

![](/files/-LjrE0uQ3wXfE_xm71C3)

Хорошо это сохранить. В случае, если мы сделаем это вручную, мы сможем узнать, что назначить каждому регистру перед **PUSHAD** - **RET** для **VIRTUALALLOC** и **VIRTUALPROTECT**. Теперь, давайте посмотрим, нашла ли она **ROP** для функции **VIRTUALALLOC**.

![](/files/-LjrE0uX7uZysrkyTy5A)

Мы видим, что **MONA** нашла **ROP** и упростила его, потому что она использовала другой способ, который напрямую использует другую записать **IAT**, а не адрес **API**. Программа переходит косвенно и избегает передачи адресов **VA** между регистрами.

Здесь мы видим, что это уже код для **PYTHON**. Поэтому мы копируем и вставляем его в наш скрипт.

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

![](/files/-LjrE0ucRhhDYXiC49Qh)

И мы будем вызывать **ROP** с помощью функции

> **ROP\_CHAIN = CREATE\_ROP\_CHAIN()**

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

Давайте посмотрим, сработает ли этот код.

Что-то ничего не получилось. Это не странно. Мы будем трассировать **ROP** и увидим, что случится.

![](/files/-Ljtu4qRXq3X01UeQGRN)

Мы уже присоединились к процессу с помощью **IDA**. Теперь мы можем использовать её. Нам не нужна **MONA**.

![](/files/-Ljtu4qaL1cSwCZZNjqE)

Давайте посмотрим, что нам нужно присвоить каждому регистру.

![](/files/-LjrE0vM_sGon1kW0ina)

Это альтернативный подход, который используется и мы видим разницу легче, потому что **MONA** помещает инструкцию **JMP** \[**EAX**] в регистр **ESI** а тот, который я использовал, помещает адрес функции **VA** в регистр **ESI**.

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

Это наш первый гаджет.

![](/files/-LjrE0urXB3hvc2uC4Bu)

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

Последний адрес этого гаджета **POP EBP - RET** находится в регистре **EBP**.

Это хорошо.

![](/files/-Ljtu4qzqDxwgpN0n-7t)

Перейдем к следующему гаджетом.

![](/files/-Ljtu4r7hlZHbJIoJQgv)

Гаджет помещает в регистр **EBX** значение **1**, которое является **DWSIZE**. Поэтому он соответствует нашей модели. Давайте продолжим.

![](/files/-LjrE0uzSClj8vCinZRM)

Этот гаджет поместит в регистр **EDX** значение **0x1000** как говорит наша модель. Давайте продолжим.

![](/files/-Ljtu4rU7gFSgHlKOfcJ)

Этот гаджет поместит в регистр **ECX** значение **40**. Все нормально. Давайте продолжим.

![](/files/-LjrE0v3WrSWO5pOBSrO)

Дальше гаджет не заработал. Он переходит в любое место и не следует цепочке **ROP**, как и следовало ожидать, потому что следующий не существует. Это обычно происходит когда есть какой-то недопустимый символ, который мы не увидели, который отрезает запись байтов. Давайте посмотрим, что следует сделать.

![](/files/-LjrE0v7KuAedCATCAm2)

Здесь гаджет был урезан. У нас есть **0x1A**. Может быть, коду не нравится это значение? Давайте найдем другую инструкцию **POP EDI** у которой нет байта **0x1A** чтобы узнать что произойдет.

По адресу **0x78028756** находится инструкция **POP EDI**, которую я нашел в предыдущей части. Мы будем использовать это адрес.

![](/files/-Ljtu4s2T2pkJTJYsn4r)

Давайте потрассируем цепочку снова.

![](/files/-Ljtu4sBann4GvPkC1dO)

Цепочка отработала и вы видите **ROP**, который теперь в стеке. Сейчас она не была урезана. Давайте посмотрим, что гаджет сохранил в регистр **EDI**.

Это указатель на **C3** или **RET** как говорит наша модель.

![](/files/-LjrE0vItqtTYh5JDC7N)

Мы видим, что после инструкции **POP ESI**, **ESI** указывает на инструкцию **JMP** \[**EAX**] как говорится в нашей модели.

![](/files/-MX3mJf9-rLLxQyV3P92)

В регистре **EAX** должна остаться запись на **VA IAT**, а не адрес.

![](/files/-Ljtu4sYNJgMdPndxv98)

Это была корректная запись **VA IAT**, но если мы продолжим программа выдаст ошибку.

![](/files/-LjrE0setDKsgAhmDm24)

Если я продолжу, я увижу, что ошибка, в этом случае, создается из-за инструкции **ADD AL**, **80** которая добавляется к адресу **VA IAT**. Поэтому для компенсации мы должны вычесть **0x80** из адреса записи **IAT**.

![](/files/-LjrE0vXX9XgTDs9ycbm)

**Python>HEX(0x7802E0B0 – 0x80)**

**0x7802E030**

![](/files/-Ljtu4szSy0N1hvAoi10)

Сейчас гаджет должен сработать.

![](/files/-LjrE0vffPUZMRpcJOrP)

Мы увидели, как хорошо помогает нам **MONA**. Она даёт нам почти все верные ответы, но иногда нам нужно что-то подкорректировать вручную. Это не всегда идеально. В любом случае, когда у нас мало времени, мы обычно делаем это так. Хотя это и не так весело и интересно.

Автор оригинального текста — Рикардо Нарваха.

Перевод и адаптация на английский язык — IvinsonCLS.

Перевод и адаптация на русский язык — Яша Яшечкин.

Перевод специально для форума системного и низкоуровневого программирования - WASM.IN

25.03.2018

[**Источник: ricardonarvaja.info**](http://ricardonarvaja.info/WEB/IDA%20DESDE%20CERO/CURSO%20DE%20IDA%20TUTES/37-INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO.docx)
