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

# Часть 24

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

Решение для упражнения **IDA2.EXE** довольно похоже на предыдущее, только здесь присутствуют две переменные или мы можем назвать их **кукисами**. Для того, чтобы перенести Вас в область хорошего сообщения, теперь сравниваются две переменные, а не одна.

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGVXkh-W810vXQa-%2F24-01.png?generation=1563215339553169\&alt=media)

Давайте посмотрим, существует ли место, где Вы можете изменить эти переменные? Мы переименовываем переменные в **COOKIE** и **COOKIE 2**, так как сама **IDA** называет их такими именами.

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

Мы видим, что единственные места, где есть доступ к этим переменным, находятся там, где вызывается функция **PRINTF**. Через инструкцию **LEA** программа получает адреса этих переменных, чтобы напечатать значения этих переменных, но не может сама изменить их значения.

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

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

Так что, если мы не можем изменить значение этих переменных, то как мы можем добраться до хорошего сообщения, чтобы прибыть к нему, если обе переменные должны иметь определенные значения?

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

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

Здесь мы видим переменную **VAR\_10**. Давайте посмотрим, что это за переменная и для чего она нужна. Видно, что она инициализируется нулём. Теперь, с помощью **X**, будем искать другие места где используется эта переменная.

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

Видим три места, в которых программа использует эту переменную. Первое место - когда программа инициализирует переменную в нуль.

Давайте посмотрим на две другие переменные, но прежде, согласуем аргументы, которые будут передаваться в **API**. Так что, всё это не так уродливо, используя технику, которую мы видели в моём предыдущем туториале с примером **IDA1**. Делая правый щелчок на этих переменных и изменив альтернативное представление в стеке, которое **IDA** показывает нам здесь, увидим такой код.

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

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

Давайте посмотрим, где программа использует эту переменную.

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

Здесь, с помощью инструкции **LEA**, программа получает адрес переменной и затем увеличивает её содержимое. Другими словами, увеличивается значение переменной.

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

Поскольку комментарий **IDA** говорит мне **flag %x**, мы можем переименовать переменную на то же имя. Видно, что это ни на что не влияет.

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

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

Посмотрев на статическое представление стека, мы увидим:

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

Делая двойной щелчок на буфере, мы видим статическое представление стека в **IDA**.

Очевидно, что буфер - это место зарезервированное в памяти, для того, чтобы сохранять в него то, что напечатано в консоли, так как программа передаёт адрес как аргумент в функцию **GETS**.

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

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

Чтобы увидеть размер этого буфера в статическом представлении стека, мы делаем правый щелчок и выбираем пункт **ARRAY**. Теперь видно размер, который **IDA** предлагает нам.

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

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

![](https://333516620-files.gitbook.io/~/files/v0/b/gitbook-legacy-files/o/assets%2F-Ljp8Kl9OQ2AqdU_D0G8%2F-LjqtEP2kV1qNtJHVrED%2F-LjqtGVz-3aijmvD3FPy%2F24-12.png?generation=1563215345684531\&alt=media)

Здесь мы видим буфер и кроме того видя это статическое представление, мы знаем, что заполняя буфер **68** символами он будет почти переполнен и так как функция **GETS** не имеет никаких ограничений, мы можем переполнить буфер и перезаписать его с помощью **4** байтов + переменную **COOKIE**, которая находится рядом. Затем с помощью других четырёх байтов я перезаписываю флаг, который является **DWORD** (**DD**) и с помощью других **4**-х байт я перезаписываю переменную **COOKIE 2**

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

С помощью этих знаний, мы могли бы уже создать скрипт. Те данные, которые мы бы послали программе, были бы такие.

**FRUTA = 68 \* "A" + COOKIE + FLAG + COOKIE2**

> **from** subprocess **import** \*
>
> **import** struct
>
> p = Popen(\[**r'C:\Users\ricna\Desktop\23-INTRODUCCION AL REVERSING CON IDA PRO DESDE CERO PARTE 23\IDA2.exe'**, **'f'**], stdout=PIPE, stdin=PIPE, stderr=STDOUT)
>
> cookie=struct.pack(**"\<L"**,0x71727374)
>
> cookie2=struct.pack(**"\<L"**,0x91929394)
>
> flag=struct.pack(**"\<L"**,0x90909090)
>
> **print "ATACHEA EL DEBUGGER Y APRETA ENTER\n"**
>
> raw\_input()
>
> primera=68 \***"A"**+ cookie + flag + cookie2
>
> p.stdin.write(primera)
>
> testresult = p.communicate()\[0]
>
> **print** primera
>
> **print**(testresult)

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

Вот наш цыпленок и готов. Мы устанавливаем в **кукисы** соответствующие значения, а в флаг значение **0x90909090** или любое другое, которое не влияет на исполнение.

И получаем нужный нам результат.

До встрече в следующей части. Для практики, Вы можете разобрать сами примеры **IDA3.EXE** и **IDA4.EXE**, которые прикреплены к данному туториалу.

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

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

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

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

02.12.2017

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