> 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-34.md).

# Часть 34

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

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

**ЧТО ТАКОЕ DEP** ?

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0svsOHZP7ewvyXT%2F34-01.png?generation=1563221058327931\&alt=media)

Предотвращение выполнения данных (**DEP**) представляет собой набор аппаратных и программных технологий, который выполняет дополнительные проверки в памяти, чтобы помочь избежать запуска в системе вредоносного кода. В **SERVICE PACK 2** (**SP2**) **MICROSOFT WINDOWS XP** и в **MICROSOFT WINDOWS XP TABLET PC EDITION 2005**, как аппаратное, так программное обеспечение применяют **DEP**.

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

Давайте оставим определение **DEP** компании **MICROSOFT'у**. На самом деле, существует несколько способов задействовать **DEP**. Один из таких способов, сделать это через Свойства Системы.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0t4UTQpBKb89fnC%2F34-02.png?generation=1563221058234060\&alt=media)

Сейчас я нахожусь в **WINDOWS 10** и **DEP** включен для основных программ и сервисов. Это настройки по умолчанию. Это означает, что существуют программы, у которых **DEP** выключен по умолчанию.

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

Помимо этой конфигурации системы, каждая программа можем активировать функцию **DEP** самостоятельно, используя **API**, который **MICROSOFT** предоставляет для этого.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1G0hhHkL3YIfuLd%2F03.png?generation=1563265875130253\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tDj9BWEWFkSzRV%2F34-04.png?generation=1563221059444534\&alt=media)

В общем, скажем, что, защита **DEP** изменяет разрешения страниц, где хранятся данные, стек, куча и т.д. Чтобы избежать этого, мы можем исполнить код там.

Поскольку **DEP** управляется процессом, то у него есть несколько способов запуститься и это можно сделать прям во время выполнения. Мы можем увидеть список процессов с помощью утилиты **PROCESS EXPLORER**, у которой есть столбец, показывающий статус **DEP** для каждого процесса.

<https://technet.microsoft.com/en-us/sysinternals/processexplorer.aspx>

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tG1-5scl4nfQsh%2F34-05.png?generation=1563221068290268\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tI_VKMBMK_f0jU%2F34-06.png?generation=1563221056679955\&alt=media)

Вот нужная нам настройка. Мы должны запустить утилиту под пользователем Администратор. Мы добавляем столбец, сделав правый щелчок в панели и выбрав пункт **SELECT COLUMNS**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Gtr6NsEeGyu_ua%2F07.png?generation=1563265875905642\&alt=media)

Мы видим, что у большинства процессов режим **DEP** активирован, а у некоторых других процессов он отключен.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1H5HrIahrUuZSYi%2F08.png?generation=1563265877116356\&alt=media)

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

Хорошо, основной момент здесь такой, что даже если **DEP** включен, он не имеет большого значения, потому что его можно обойти. **DEP** усилится, когда он объединяется с другими защитами, которые мы увидим позже.

Один из основных способов обхода **DEP** является **ROP** или возвратно-ориентированное программирование.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tPon30wPEh3lpQ%2F34-09.png?generation=1563221058378039\&alt=media)

> Четверо исследователя из Калифорнийского Университета опубликовали статью под названием "**RETURN**-**ORIENTED PROGRAMMING**: **SYSTEMS**, **LANGUAGES AND APPLICATIONS**" где они показали способ обхода этой защиты. Грубо говоря, он заключается в выполнении фрагментов кода, которые уже существуют в самом коде программы. Таким образом нет необходимости инжектировать свой собственный код. Я постараюсь кратко описать технику и сделать пример приложения. Хотя я советую Вам прочитать оригинальную статью, где это все хорошо объясняется.
>
> Необходимо получить маленькие фрагменты кода, оканчивающиеся инструкцией **RET**. В идеале, с одной ассемблерной инструкцией (в дополнении к **RET**), внутри программы, которую мы хотим использовать. Эти маленькие фрагменты кода называются гаджетами. С помощью этих фрагментов мы должны как с конструктором **LEGO**, создать код эксплоита или шеллкод. Как только эти фрагменты получены и правильно упорядочены, мы можем запустить их в установленном порядке. Как мы это сделаем? То, что эти гаджеты заканчиваются инструкцией **RET** не являются случайными. Этот метод заключается во вводе адресов гаджетов в стек в правильном порядком исполнения, так чтобы при выходе из исполняющейся функции адрес возврата возвращался в регистр **%EIP**, где эти гаджеты вызывались бы один за другим в правильном порядке.

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

Но основная идея **ROP** заключается в том, что вместо перехода на инструкцию **JMP ESP**, происходит переход на кусочки кода, называемые гаджетами, которые являются исполняемым кодом программы, которые завершаются инструкцией **RET** (гаджеты являются частью некоторого модуля, вот почему мы можем их запускать) и с помощью которых, вы можете по чуть-чуть делать вызовы некоторых **API**, например такие как **VIRTUALPROTECT** или **VIRTUALALLOC**, которые изменяют и дают разрешение на выполнения кода в стеке или куче, т.е там, где находится мой код и наконец происходит переходит на его выполнение.

Другими словами, если эксплоит, который перезаписывал адрес возврата для примера без **DEP** был:

"**A" \* 200 + АДРЕС\_JMP\_ESP + КОД ДЛЯ ВЫПОЛНЕНИЯ**

То, теперь с **DEP**, в том же случае, код должен быть таким:

"**A" \* 200 + ROP + КОД ДЛЯ ВЫПОЛНЕНИЯ**

Где **ROP** должен предоставить моему коду разрешение на выполнение.

Рассмотрим, пару примеров без защиты **DEP**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tTsMaAVdVRJBgH%2F34-10.png?generation=1563221053573536\&alt=media)

Здесь у нас есть программа. Она имеет буфер длиной **30** десятичных байт, и получает строку в качестве аргумента, которая копируется с помощью функции **STRCPY** в буфер без проверки длины. Следовательно, аргумент вызывает переполнение буфера.

Также, программа загружает модуль под названием **MYPEPE.DLL**. Позже увидим, нужен ли программе этот модуль или нет.

Давайте откроем программу в **ЗАГРУЗЧИКЕ IDA**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1HtHU6-yMLx7DhG%2F11.png?generation=1563265875842406\&alt=media)

Мы видим, что программа имеет только два аргумента в функции **MAIN** - **ARGC** и **ARGV**. Мы знаем, что переменная **ARGC** - это количество аргументов, которые мы вводим через консоль. Поэтому, если их не два (имя исполняемого файла + второй аргумент после него через пробел) программа будет закрываться, так как условие не выполняется.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1I1UeynYIzyk9UJ%2F12.png?generation=1563265875477964\&alt=media)

Если количество аргументов не равно **2**, программа будет переходить в красный блок, и выводить сообщение об ошибке, и придёт к возврату без каких либо действий. А если количество аргументов корректно, т.е. равно **2**, программа будет переходить в желтый блок, загрузит **DLL** и затем перейдёт в функцию **SALUDA**. Сейчас имена выглядят уродливо. Я иду в меню **OPTIONS→DEMANGLENAMES→NAMES**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1ILEcZxGHPKIwWL%2F13.png?generation=1563265875395195\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0tqnT2WsoYLcIjG%2F34-14.png?generation=1563221057459844\&alt=media)

Если кто-то не помнит, переменная **ARGC** - это число аргументов, а переменная **ARGV** - это массив указателей. Каждый элемент указывает на строку, которая является аргументом. Другими словами, в случае:

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Ig_eEEu7ZtvAhZ%2F15.png?generation=1563265876468880\&alt=media)

По адресу **0x0040109C** регистр **ECX** имеет значение переменной **ARGV**. Т.е. это массив указателей.

**ARGV** = \[указатель\_на\_имя\_исполняемого\_файла, указатель\_на\_аргумент1, указатель\_на\_аргумент2…]

В **IDA** мы видим, что программа исполняет инструкцию **SHL EAX**, **0**, другими словами сдвигает **0** байтов, оставляя регистр **EAX** равным, как и раньше, т.е. **4** в этом случае.

Затем выражение \[**ECX**+**EAX**] будет возвращать указатель на аргумент. Если регистр **EAX** равен нулю, программа будет возвращать указатель на имя исполняемого файла. Если он будет равен **4**, то поскольку каждый указатель имеет длину **4** байт, то программа будет читать указатель на следующий аргумент и так далее.

В этом случае, поскольку регистр **EAX** равен **4**, то указатель на второй аргумент, который мы ввели, будет в регистре **EDX**, который передаётся как аргумент в функцию **SALUDA**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1J2SSaz3mx-W3Yo%2F16.png?generation=1563265875253131\&alt=media)

В функции **SALUDA**, есть аргумент, который является указателем на аргумент и переменная, которая является буфером, куда будет скопирована строка.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0u-F3YtuI5Q0xtj%2F34-17.png?generation=1563221057242832\&alt=media)

Поскольку я скомпилировал программу с символами, **IDA** определяет текст как указатель, и что он указывает на строку (или массив символов).

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

Давайте посмотрим буфер.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1JMTY4UtatCJOPn%2F18.png?generation=1563265875093378\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Jb3LnZ8ceNzAE4%2F19.png?generation=1563265876787017\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Jo6a_wj1vyFi_-%2F20.png?generation=1563265881674641\&alt=media)

Поэтому давайте сделаем правый щелчок и выберем пункт **ARRAY**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uBK61KhdPm6gvm%2F34-21.png?generation=1563221058720325\&alt=media)

Здесь нет никаких сомнений. Ниже нет никаких переменных. Что есть ниже, так это переменные **СОХРАНЕННЫЙ EBP** и **АДРЕС ВОЗВАРАТА**. Таким образом, нет никаких сомнений, что буфер рассчитан **IDA** хорошо. (Кроме того, программа имеет символы, которые помогают **IDA** определить, что это буфер, даже без нашей помощи)

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

Я выбираю область, которую я собираюсь заполнить начиная с буфера, оставляя **АДРЕС ВОЗВРАТА**, делаю правый щелчок и выбираю пункт - **ARRAY** без соглашения, просто, чтобы увидеть размер, который должна иметь срока для переполнения.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uF1YEYDnV0HYTI%2F34-22.png?generation=1563221062203184\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uINE3CaotCXamF%2F34-23.png?generation=1563221057198223\&alt=media)

Предположительно, строка **0xCCCCCCCC** просто должна перезаписать адрес возврата. Я мог бы попробовать эту строку. Для этого я устанавливаю **IDA** как **JUST IN TIME DEBUGGER**. Я открываю консоль с правами администратора и иду в папку, где находится исполняемый файл **IDA**.

**-I#** установит **IDA** как отладчик времени исполнения (**0** - для выключения и **1** - для включения)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1KaZ-BmgQsmKjjs%2F24.png?generation=1563265875259331\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uOI6pdEaULXNYd%2F34-25.png?generation=1563221063167939\&alt=media)

При запуске скрипта, я вижу, что он переходит к выполнению кода, по адресу **0xCCCCCCCC**, который я помещаю в него же. Этим я перезаписываю адрес возврата.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1Kq0FltS7FE1_9b%2F26.png?generation=1563265875430205\&alt=media)

Здесь, я вижу, что сейчас регистр **ESP** указывает чуть ниже значения **0xCCCCCCCC**. Поэтому, если я добавлю больше кода ниже, и вместо перехода на адрес **0xCCCCCCCC**, программа будет переходить на инструкцию **JMP ESP**, чтобы начать выполнять указанный код (Какие же хорошие были времена, когда не было **DEP**)

Я ищу в списке модулей библиотеку **MYPEPE.DLL**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uTTiERJqZsJtMz%2F34-27.png?generation=1563221064028763\&alt=media)

Мы сделаем щелчок правой кнопкой, чтобы проанализировать нашу библиотеку и загружаем символы для неё. Тем временем, в любом месте кода мы запускаем плагин **KEYPATCHER** и не принимая соглашение, мы видим, что инструкции **JMP ESP** соответствует последовательности байтов **FF E4**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uWhcS-ARyPCD9c%2F34-28.png?generation=1563221073239755\&alt=media)

Когда анализ закончится, мы увидим, что в списке функций появляется функция **MYPEPE**. Я иду к одной из них.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0u_gAWchK94rW1t%2F34-29.png?generation=1563221053520707\&alt=media)

Модуль выглядит хорошо. Давайте посмотрим, есть ли здесь инструкция **JMP ESP?**

Выбираем пункт **SEARCH FOR→ SEQUENCE OF BYTES** и вводим значение **FF E4**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1LP88Kf5fzp1wxL%2F30.png?generation=1563265878649427\&alt=media)

Здесь, по адресу **0x004010BA** есть инструкция **JMP ESP**. Мы не можем использовать нуль, но поскольку система добавляет нуль в конце, когда программа исполняет функцию **STRCPY**, мы не будем добавлять нуль.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1LWqIYa6CgbYVec%2F31.png?generation=1563265875999591\&alt=media)

Проблема заключается в том, что инструкция **JMP ESP** служит только для перехода если мы добавим ещё код ниже. Но мы не можем добавить больше кода из-за того, что адрес инструкции **JMP ESP** заканчивается нулем. Так что мы будем переходить на инструкцию **RET**. Чуть ниже это указатель на нашу строку, которая была передана нами как аргумент.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uj5Bqx9jpkf3DF%2F34-32.png?generation=1563221061040594\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1LkAGOLEXWn8dfj%2F33.png?generation=1563265875456416\&alt=media)

Скажем так - "Это хороший **RET**". Давайте добавим его.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0upiIf2cNIyxE1Z%2F34-34.png?generation=1563221062101688\&alt=media)

Давайте теперь попробуем с ним.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu1LupezWu7NzB5X4%2F35.png?generation=1563265875072504\&alt=media)

Я вижу, что программа уже совершает переход, чтобы выполнить мой код **CCCCCCCC**, который я добавил как шеллкод. Сейчас, я бы мог перестроить код, который я хотел бы туда поместить, и выполнить то, что захочу я захочу, потому что здесь нет **DEP**. Единственное, что у программы мало свободного места, потому что я выделил буфер только длиной **30** байт, который мешает мне делать большие вещи.

Я подготовил шеллкод, который запустит калькулятор:

**import** struct shellcode = **"\xB8\x40\x50\x03\x78\xC7\x40\x04"** + **"calc"** + **"\x83\xC0\x04\x50\x68\x24\x98\x01\x78\x59\xFF\xD1"**

fruta = shellcode + **"A"** \* (36-len(shellcode)) + **"\x3a\x10\x40"**

\#0x40103a ret

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrDv_m4LAycSFMBnkh%2F-LjrE0uvPH7Dl2T7lcNN%2F34-36.png?generation=1563221067648105\&alt=media)

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

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

До встрече в 35 части.

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

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

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

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

12.03.2018

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