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

# Часть 42

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

В 41 части, для практики было оставлено два упражнения. К сожалению, никто не прислал мне решения. Это заставляет меня задаться вопросом, стоит ли оно того, что я делаю. По крайней мере для меня это сейчас вопрос. Ни обратной связи, ни вопросов ко мне. Ничего нет.

Это заставляет меня переосмыслить вещи и спросить себя, стоит ли мне заходить с этим курсом так далеко, как я думал с самого начала. Мы увидим, какое решение мы примем в отсутствии обратная связь. Сейчас же, мы будем решать упражнение из главы **41**.

Нам необходимо обновить до новой версии плагин **KEYPATCH**, поскольку мы будем использовать его в конце.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjttkJvbq8Uocl4jWiJ%2F-Ljtu4kB7wVNawMXPED7%2F01.png?generation=1563265893553767\&alt=media) <https://github.com/keystone-engine/keypatch>

Я заменяю файл **.PY** новым скриптом.

[http://ricardo.crver.net/WEB/INTRODUCCION AL REVERSING CON IDA PRO DESDE CERO/EJERCICIOS/](http://ricardo.crver.net/WEB/INTRODUCCION%20AL%20REVERSING%20CON%20IDA%20PRO%20DESDE%20CERO/EJERCICIOS/)

Давайте откроем пример **41** в **IDA**.

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

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

Если мы посмотрим **STRINGS WINDOWS**, мы увидим строку **MYPEPE.DLL**. Поэтому, возможно, что необходимо поместить библиотеку в ту же папку. Это та же самая **DLL** из предыдущих упражнений.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5OvD8Sk-KzS3kmk%2F42-03.png?generation=1563225001905515\&alt=media)

Я помещаю библиотеку в нужную папку.

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

Я делаю двойной щелчок по этой строке.

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

Мы видим ссылку. Мы идем в неё с помощью нажатия **X** или **CTRL + X**.

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

Мы видим, что программа загружает библиотеку здесь. Поэтому всё хорошо. Это похоже на функцию **MAIN**. Поскольку это консольная программа, если это так, то она должна иметь функцию в качестве ссылки, которой передаётся такие аргументы как **ARGC**, **ARGV** и т.д.

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5PK1vvpKIHhF0X6%2F42-08.png?generation=1563225022022833\&alt=media)

Поэтому, по адресу **401090** находится функция **MAIN**. Мы переименовываем её.

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

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

Давайте начнем реверсить.

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

Здесь, мы видим, что программа читает запись **IAT SYSTEM**, которая находится в секции **IDATA**. Адрес указанной **API** помещается в регистр **EAX**.

Иногда, если вы испытываете некоторые сомнения в синтаксисе **IDA**, используйте **KEYPATCH**, чтобы увидеть простую альтернативу пока не привыкните к ней.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5PjYJIQHeOt22Za%2F42-11.png?generation=1563225030324388\&alt=media)

Здесь, Вы можете увидеть запись **IAT. IDA** логически говорит нам о типе **EXTRN**, потому что это внешняя **API** импортированного модуля.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5PsbewX1J6reK8s%2F42-12.png?generation=1563225011758141\&alt=media)

Конечно, в **IMPORTS** есть импортированные функции для модуля и адрес записи **IAT**, который показывает значение **4020A8**, поэтому у нас всё совпадает.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5Pzc4Ji1VKYYeW7%2F42-13.png?generation=1563225005247572\&alt=media)

Затем программа запишет в глобальную переменную **DWORD**\_**403088**, (которая является **DWORD)** значение регистра **EAX**.

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

Мы помним, что в **IDA** если существует префикс типа данных перед адресом, это означает, что содержимое этого адреса имеет тот же тип. В этом случае это **DWORD**. По крайней мере это **4** байта. Также программа записывает адрес **API** здесь.

Поэтому мы переименовываем глобальную переменную в **P**\_**SYSTEM**.

Мы знаем, что это переменная длиной **4** байта и так как она сохраняет адрес, то она должна быть типа указатель. Я изменяю её тип.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5QCLUtmi3sjq7St%2F42-15.png?generation=1563225028157257\&alt=media)

Поскольку я знаю, что это указатель на **API**, то могу легко сделать его указателем на что-то неизвестное.

```
VOID * P_SYSTEM
```

В любом случае, нет необходимости иметь слишком точные определения, потому что они лишние. Важно просто то, что это указатель на что-то.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5QIIDozFzgJ7grv%2F42-16.png?generation=1563225016319716\&alt=media)

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

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

Существует другая переменная того же типа, которая хранит адрес **API SETPROCESSDEPPOLICY**. Я делаю то же самое.

Я изменяю тип также в декомпиляторе **HEXRAYS** с помощью **F5**. Изменение типа ни на что не влияет.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5QQ-6nCh8ZxkZoa%2F42-18.png?generation=1563225028919273\&alt=media)

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

Это не имеет большого значение. Это просто нужно, чтобы показать Вам больше вариантов.

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

Мы видим, что глобальная переменная **P\_SYSTEM** используется повторно и сохраняет указатель (используется инструкция **LEA** для поиска адреса) на переменную **SIZE**, которая является **DWORD**. Очевидно, it will cast it to do it **C++**(**??? Опять куча itов. Не понял как тут правильно будет**), но здесь это не имеет значения. Они обе являются указателями.

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

Что-то вроде этого:

> **P\_SYSTEM\_\_\_\_\_P\_SIZE**

В сложных функциях они много раз повторяется и мы должны следовать этому.

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

Затем программа сравнивает переменную **ARGC**, которая представляет собой число аргументов с числом **2**. Таким образом это имя исполняемого файла + аргумент, т.е. всего два аргумента. Если нет двух аргументов, программа пропускает всё и выходит из функции напрямую.

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

Мы видим, что **ARGV** это массив и что в позиции **0** он хранит строку имени исполняемого файла и если мы добавим в нему **4**, то программа получит адрес строки первого аргумента.

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5R1Z2IrvUEcD_OO%2F42-24.png?generation=1563225008591468\&alt=media)

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

После возврата из функции **ATOI** это значение сохраняется в переменную **SIZE**, которая находится в стеке.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5RIRz3KsLI2gFyl%2F42-26.png?generation=1563225018818610\&alt=media)

Не путайте её с глобальной переменной **P\_SYSTEM\_\_\_\_\_P\_SIZE**, которая имеет сохраненный **АДРЕС** этой же переменной **SIZE**.

Программа сравнивает это значение размера, которое пришло из **ARGV** со значением **0x300** и если оно больше, программа переходит и возвращается в функцию **MAIN**. Конечно, этот **SIZE** является знаковым, потому что сравнение с использованием инструкции **JLE** говорит нам об этом.

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

Поскольку переменная является знаковой, когда мы передаем ей отрицательное значение, она будет меньше **0x300**. Например, если я передам ей значение **-1**, это значение будет меньше **0x300**, потому что рассматривается знак и переменная пройдет сравнение.

Очевидно, если эта переменная **SIZE** используется как размер в **API** функции, которая принимает переменную как беззнаковую, то в программе может случиться переполнение, потому что для этой **API** функции значение не будет отрицательным, но без знака. Например, если значение равно **-1**, для **API**, которая принимает это значение как положительное, максимальным положительным будет значение **0xFFFFFFFF**. Т.е. **-1** равно **0xFFFFFFFF**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5RUZ7KWbtSRokAa%2F42-28.png?generation=1563225020555979\&alt=media)

Мы видим функцию, ей аргументом является переменная **SIZE**. Мы ещё не переименовывали её. Давайте посмотрим что она делать. Пойдем туда и посмотрим.

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

Мы видим, что есть здесь есть функция **GETS\_S** для ввода данных. Поэтому я даю функции имя **INGRESO**.

Эта функция **GETS\_S** имеет переменную **SIZE**, которая принимается как беззнаковая и может вызвать переполнение буфера.

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

Здесь мы видим, что тип переменной **SIZEINCHARACTERS** является типом **SIZE\_T**.

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

И этот **SIZE\_T** является беззнаковым. Поэтому я уверен, что мы можем переполнить буфер. Давайте посмотрим насколько он большой. Хотя мы уже видели, что я сделал его плохим, но программы пытается фильтровать **SIZE** больше чем **0x300** байт. Поэтому очень вероятно, что размер буфера таков.

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

Мы видим, что буфер находится в секции **DATA** и **IDA** говорит мне, что его размер равен **0x64** байт. Чуть ниже буфера мы видим глобальные переменные **P**\_**SETDEP** и **P\_SYSTEM**\_\_\_\_**P**\_**SIZE**. Поэтому здесь нет ошибки. Максимальная проверка позволяет нам переполнить даже этот **0x64** байтный буфер (**100** десятичных байт), без требования быть отрицательным. Только с размером больше чем **0x64** байта.

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

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

Сейчас, после того как Вы перезапишите указатели, будет ли программа использовать эти указатели?

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

Я вижу в ссылках на **P**\_**SETDEP**, что есть вызов с использованием этого указателя на функцию и что, если я перезаписываю его с помощью переполнения, он может отклонить выполнение программы.

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

Это происходит сразу после функции **GETS**\_**S**. Это прекрасно. Давайте сделаем скрипт.

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

Я изменяю скрипт, который был достаточно похожий и устанавливаю размер равным **-1**. Он будет проходить проверку. Я помещаю **0x64** байта символов **A** чтобы заполнить буфер, и затем я помещаю значение **0x99989796**, которое предположительно должно перезаписать указатель, который находится чуть ниже.

Поскольку **ROP** для библиотеки **MYPEPE.DLL** уже создан, я оставляю его. Я увижу, как я расположу **ROP**. Сейчас я запускаю скрипт и присоединяю **IDA** к процессу, помещаю **BP** сразу после функции **GETS**\_**S**, для того, чтобы остановится там.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5SBrVcY-AhwRRBg%2F42-37.png?generation=1563225020549504\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-Lkxk3QV3VqJ1BB40Ie7%2F-Ljtu4rcA-uxA5NszXJk%2F40.png?generation=1564404215640681\&alt=media)

Мы видим, что буфер выглядит почти полным. Давайте пойдем туда, чтобы увидеть его.

Если я нажму **U** для **UNDEFINE**, мы увидим много символов **A**. Давайте посмотрим перезаписался ли указатель.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5SYq7X_SvECkTaF%2F42-40.png?generation=1563225020021673\&alt=media)

Мы должны увидеть, перезаписали ли мы указатель.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5Sd3Hkgk8u_QaZI%2F42-41.png?generation=1563225012579299\&alt=media)

Я нажимаю **D** до тех пор пока не получу **DWORD** и вижу что это всё хорошо перезаписалось. Установлено значение, которое я хотел.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5SoFJtOfLblSqbW%2F42-42.png?generation=1563225021466657\&alt=media)

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5Svwd6UAibmNv0m%2F42-43.png?generation=1563225025809407\&alt=media)

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

Я мог бы искать вызов **CALL EAX** в библиотеке **MYPEPE**, который не содержит защиту **ASLR**. Я использую новый **KEYPATCH** с опцией **SEARCH** и ввожу инструкцию **CALL EAX**.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5T-zXCtcgjqaGZN%2F42-44.png?generation=1563225013611956\&alt=media)

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5T48Z3rjeTN1Fq_%2F42-45.png?generation=1563225017849297\&alt=media)

Мы видим в результатах, что есть несколько, которые принадлежат библиотеке **MYPEPE**. Я выбираю некоторые для примера.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5T984L5x-GgGfKt%2F42-46.png?generation=1563225014562084\&alt=media)

Когда я иду туда, я нажимаю **C** для преобразования его в код, потому что я его не дизассемблировал.

По адресу **0x7802C16E** будет инструкция **CALL EAX**, которую я выбрал. Я добавляю этот адрес в скрипт.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5TEVmMNkrzY89pI%2F42-47.png?generation=1563225024076099\&alt=media)

Я помещаю шеллкод вперед, потому что он переходит в начало буфера и не меняет длину перед указателем. Оставшаяся часть шеллкода вычитается из общего количества букв **A**. Мне больше не понадобится **ROP**. Поэтому я удаляю его.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjrSx7vPF_6hdeduZel%2F-LjrT5TM45-9lg87QNUY%2F42-48.png?generation=1563225020912194\&alt=media)

Наша курочка готова. Шеллкод запускает калькулятор. Я надеюсь, что кто-то сделает меня счастливым, решив задачку **41B** или, по крайней мере, просто попробует её на вкус.

`\#8eqw0uExIPQMo0hlG2SMbg.kWxA60qd204.wQ0f6qnVEDF3sTM4kUnjA82Jgnlue8Wsgi0LIXEGPRLM89DcLVaUVNH29WUFmLizrcwP9OtNDlc4wPiQ6DtpTgbIFIhKqOATEW8MBxHDk2Uvz/8H8BgX5L2XHkS/zfDWlnPEVsMXsg`

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

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

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

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

22.04.2018

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