> 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)


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://yutewiyof.gitbook.io/intro-rev-ida-pro/chast-37.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
