# Часть 12

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

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

Если мы запустим программу вне **IDA**, то мы увидим.

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

Нас просят ввести имя пользователя и затем пароль, а потом программа говорит нам, что мы проиграли, и она смеётся над нами.

Давайте откроем её в **IDA**, чтобы увидеть программу в статическом виде.

Поскольку я не использую символы, всё оказывается слегка уродливым.

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

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

Один из способов, который мы уже видели, чтобы попасть в "горячую часть программы" - найти строки, мы уже знаем как это делать, также в этих консольных программах на **C++**, это один из способов найти **MAIN**, который почти всегда работает.

Мы знаем, что в функцию передаются аргументы **ARGC**, **ARGV** и т.д. Это аргументы консоли.

**INT MAIN(INT ARGC, CHAR \*ARGV\[])**

Мы уже видели в предыдущем примере, что даже если аргументы не используются, они всё равно **ПОМЕЩАЮТСЯ** в стек, иногда это действует по умолчанию для консольных исполняемых файлов, поэтому мы можем искать их во вкладке **NAMES**, чтобы увидеть, есть ли они там или нет.

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

Отсюда и далее, когда я говорю - "На вкладке **XXX**", Вы уже должны знать, что это открывается в меню **VIEW → OPEN SUBVIEW → XXX**, чтобы не повторять это более.

Здесь с помощью комбинации **CTRL + F** мы фильтруем ввод, введём например **ARG** и мы увидим записи, давайте сделаем двойной щелчок по **\_P\_ARGC**.

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

Ища ссылки с помощью **X** мы находим

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

Здесь мы видим как программа вызывает функции **\_P\_ARGV** и **\_P\_ARGC** и то, что она передает содержимое результата в функцию **MAIN**, адрес которой в этом случае - **0x401070**.

Если я посмотрю ту же самую функцию в моей **IDA**, в версии с символами.

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

И мы видим ссылку.

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

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

Давайте переименуем этот вызов в **MAIN**.

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

**IDA** автоматически переименовывает **АРГУМЕНТЫ** узнав, что вышеупомянутая функция – это **MAIN**.

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

Сейчас, это больше похоже на версию с символами.

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

Мы видим в этом случае, что переменные и аргументы более нумерованы чем в предыдущем примере.

Если мы сделаем двойной щелчок на любой переменной или аргументу, мы увидим статическое представление стека.

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

Мы смотрим снизу вверх и видим, что логически первыми идут аргументы функции, которые будут всегда под адресом возврата **R**, так как они передаются через **PUSH** и они сохраняются в стек перед вызовом функции с помощью **CALL**, которая затем сохраняет адрес возврата в стек.

Затем у нас идёт **S** или что, то же самое, что и **STORED EBP**, который является **EBP** функции, которая вызывается функцией **MAIN**, он сохраняется в стек, когда начинает выполняться функция с помощью инструкции **PUSH EBP**.

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

Затем программа помещает **ESP** в **EBP**, помещая значение в **EBP**, которое оно будет иметь в этой функции, чтобы быть **БАЗОЙ** откуда берутся аргументы, которые ниже **БАЗЫ** и локальные переменные, которые выше неё, и наконец инструкция **SUB ESP, 0x94** сдвигает **ESP** выделяя место для переменных и локальных буферов, поэтому они выше, в этом случае размер для буфера будет равен **0x94**, потому что компилятор вычисляет, размер который ему нужен, чтобы зарезервировать место для переменных и буферов, в соответствии с тем, как мы запрограммировали нашу функцию.

**ESP** остается со значением выше этого зарезервированного пространства для локальных переменных и **EBP** указывает на **БАЗУ** или **ГОРИЗОНТ**, который делит стек на локальные переменные, которые выше и **СОХРАНЕННЫЙ EBP**, **АДРЕС ВОЗВРАТА** и **АРГУМЕНТЫ**, которые ниже него.

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

Вот почему в функциях основанных на **EBP**, как только программа вызывает функцию, она сохраняет с помощью инструкции **PUSH EBP** значение **EBP** функции, которую вызывает программа, затем программа помещает **ESP** в **EBP** и это считается теперь как горизонт, вот почему в статическом представлении стека, **IDA** показывает **000000000** как горизонт, а выше видно знаки минус (**-**), а ниже знаки плюс (**+**).

Вот почему **VAR\_4** имеет значение **- 00000004**, потому что переменная берет **EBP** как **БАЗУ** или как **0** и математическим адресом переменной будет **EBP - 4**.

И ниже **ARGC** будет равен **EBP + 8**, это видно по колонки слева.

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

Это можно проверить это в листинге, внутри функции **MAIN** где программа использует переменную **VAR\_4**, если мы сделаем правый клик на ней.

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

Вернемся к статическому представлению стека.

Когда мы видим здесь пустое пространство где нет смежных переменных, возможно это потому что выше есть **БУФЕР** (позже мы увидим случаи, в котором пустое пространство является структурой). Сейчас давайте немного поднимемся.

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

Здесь мы видим переменную **BUF**, которая является первой переменной над пустой зоной, мы делаем правый клик и выбираем **ARRAY**.

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

Мы видим, что размер **МАССИВА** равен **120** байт, потому что он состоит из **120** элементов по **1** байту.

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

Сейчас представление стека стало лучше.

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

Мы видим базу **EBP** и мы помним, что как только **EBP** и **ESP** равны это равносильно инструкции **MOV EBP, ESP**, затем программа вычитает из **ESP** значение **0x94** и **ESP** теперь начинает работать выше зоны для локальных переменных.

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

Здесь мы видим область в которой **ESP** будет после инструкции **SUB ESP, 0x94**.

Здесь в левой стороне видно значение **-00000094** или что также равно **ESP = EBP – 094**, очевидно затем значение будет продолжать расти по мере работы программы, между другими подпрограммы и т.д., но всегда пока значение находится внутри этой функции **MAIN** и пока значение не выйдет из этой области, оно будет продолжать работать в области не выше **0x94** зарезервированную часть для переменных, чтобы не наступить на них.

Хорошо, однажды мы уже видели статическое представления стека, давайте отреверсим переменные, поскольку аргументы нам известны (**ARGC**, **ARGV**, и т.д.)

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

Мы уже видели, что **VAR\_4** это переменная **COOKIE\_SEGURIDAD** или **CANARY**, мы видим, что инструкция считывает это значение, затем **XORит** его с помощью **EBP** и сохраняет его в стек, чтобы защитить стек от **ПЕРЕПОЛНЕНИЯ**, поэтому давайте переименуем эту переменную.

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

Равно как и в предыдущем примере **API** функция **PRINTF** не имеет символов и она не отображается, но я наблюдаю строки для неё, которые она печатает в консоли и мы видим эту функцию по адресу **0x4011B0**.

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

И здесь внутри по адресу **0x401040** мы видим.

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

Так что, давайте переименуем функцию по адресу **0x4011B0** в функцию с именем **PRINTF**.

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

Давайте идти дальше.

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

Мы видим, что размер переменной инициализируется с помощью числа **8** и больше это значение никогда не изменяется, есть только два чтения среди следующих ссылок, поэтому мы переименуем размер этой переменной в имя **\_CONST\_8**.

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

Затем мы видим вызов функции **GETS\_S**, которая является эволюцией функции **GETS**, но с ограничение по количеству вводимых символов, которые мы можем ввести(это такая защита), в этом случае максимальным значением будет **8**, которое помещается в **EAX** и передается как аргумент с помощью **PUSH EAX**, а затем **LEA** получает адрес переменной **BUF** или **BUFFER**.

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

Конечно, если мы введём больше символом чем **8** и нажмём **ENTER**, функция также будет обрезать ввод и случится возврат.

Так что мы знаем, что в **BUF** будет помещаться имя **ПОЛЬЗОВАТЕЛЯ**, которое мы набрали и что оно будет иметь максимум **8** символов.

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

Здесь мы видим, что потом программа передаёт с помощью **PUSH EDX** адрес буфера снова, как аргумент к **API** функции **STRLEN**, чтобы получить длину строки, которая сейчас находится в **BUF** и соответствует введенному **ПОЛЬЗОВАТЕЛЮ**, и сохраняет длину в переменной **VAR\_90** через регистр-результат **EAX**, так что мы переименовываем **VAR\_90** в **LEN\_USER**.

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

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

Синяя стрелка всегда указывает на переход назад, который может быть **ЦИКЛОМ**, по адресу **0x4010CE** программа инициализирует счетчик **LOOP VAR\_84**, мы также видим, что по адресу **0x4010F5**находится условный переход, который оценивает условие выхода из цикла, счетчик начинается с **НУЛЯ**, и он будет увеличиваться в каждом цикле, и программа выйдет из цикла, когда счетчик будет больше или равен длине, которую мы ввели в **LEN\_USER**.

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

Счетчик увеличивается к концу **ЦИКЛА** здесь.

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

Здесь он помещает значение **СЧЁТЧИКА** в **EAX** увеличивая его и затем снова сохраняет.

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

Здесь программа помещает первый байт **БУФЕРА** из **EBP + EDX + BUF** в **EAX**, поскольку **EBP + BUF** складывается со **СЧЕТЧИКОМ**, который сейчас равен нуль, то он будет увеличиваться пока работает **ЦИКЛ**, мы видим, что здесь будет складываться все значения символов, которые я набираю, поэтому переменная **VAR\_88** которая начинается с нуля, будет складываться в каждом цикле **HEX**значения каждого символа строки **БУФЕРА**.

Мы видим инструкцию, которую мы до этого даже ещё не видели - **MOVSX**.

**MOVSX** И **MOVZX**.

Обе инструкции берут байт и помещают его в регистр, в случае с **MOVZX** заполняются с помощью нулей старшие байты, в то время как в случае с **MOVSX** учитывается знак байта, если он положительный или меньше или равен **0x7F** он заполняется с помощью нулей и если он отрицательный или равен **0x80** или больше заполняется с помощью **0xFF**.

**MOVZX EAX, \[XXXX]**

Если содержимое **XXXX** будет равно **0x40, EAX** будет равен **0x00000040**.

Также например существует инструкция **MOVZX EAX, CL**.

Этот случай похожий, инструкция будет брать значение байта и заполнит с помощью нулей старшие байты.

**MOVSX EAX, CL**

Инструкция принимает во внимание знак байта, если **CL** - например равен **0x40**, **EAX** будет равен **0x00000040** и если бы он был бы равен **0x85**, в этом случае, поскольку у него отрицательный знак и это значение отрицательное **EAX** будет равен **0xFFFFFF85**.

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

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

Мы видим, что **ЦИКЛ** - это сложение символов, мы покрасим их тем же цветом.

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

Также я немного увеличил их, перетащив и отпустив нижний блок немного выше.

Есть люди, которые, чтобы убрать блоки с экрана, если они хотят, чтобы они их не беспокоили, группируют их, с помощью нажатия **CTRL** и делая клик в верхнюю панель каждого блока.

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

Делаем правый клик и выбираем **GROUP NODES**, а затем вводим имя, например **LOOP**.

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

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

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

Затем программа выводит слово **ПОЛЬЗОВАТЕЛЬ** и говорит, что нужно ввести **ПАРОЛЬ**.

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

Затем программа вызовет снова функцию **GET\_S** используя тот же самый буфер и тоже максимальное значение вводимых символов.

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

Программа может повторно использовать тот же **БУФЕР** для **ПАРОЛЯ**, в любом случае программа полностью рассчитала **СУММУ HEX** значений символов **ПОЛЬЗОВАТЕЛЯ** и она больше не будет использовать строку **ПОЛЬЗОВАТЕЛЬ**.

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

Сейчас она возьмёт **ПАРОЛЬ** и преобразует его в **HEX** как в предыдущем примере используя **ATOI**.

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

Здесь передаётся значение **VALOR\_PASSWORD** с помощью инструкции **PUSH EDX** и суммируется с помощью **PUSH EAX**, это будут два аргумента, которые передаются в функцию по адресу **0x401010**, давайте введём их.

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

Здесь мы видим два аргумента, очевидно, что тот, который ниже будет **VALOR\_PASSWORD** так как передается с помощью **PUSH** в стек первым и второй, который кладется следующим, будет суммой, и он будет выше.

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

Я переименовываю их согласно этому, и затем, чтобы проверить нормально ли всё, сделайте правый щелчок по адресу **SUB\_0x401010** и выберите **SET\_TYPE**.

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

При этом **IDA** попытается объявить функцию со своими аргументами, чтобы показать их в ссылке и мы переименуем также это в функцию **CHECK**.

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

И если мы пойдём к ссылке.

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

Мы видим, что **IDA** распространят имена и говорит мне, что у **EAX** есть **СЛОЖЕНИЕ** и **EDX** - это **VALOR\_PASSWORD**.

И что сделает функция **CHECK** с этими двумя аргументами?

Мы видим, что она сравнивает их, но сначала она берет значение **PASSWORD** и делает с ним операцию **SHL EAX, 1**

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

Мы знаем, что **SHL** сдвигает биты влево, заполняя нулями те, которые исчезают на другой стороне, но в частности **SHL REG, 1 -** это равносильно умножению на **2**.

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

Программа берет значение пароля, умножает его на **2** и сравнивает его с суммой символов слова **ПОЛЬЗОВАТЕЛЬ**.

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

При этом мы получаем числовое значение символа, мы можем сделать формулу, которая суммирует все символы строки **pepe**, которую я использую как **ПОЛЬЗОВАТЕЛЬ**.

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

Мы видим, что сумма равна **0x1AA**, с другой стороны значение, которые мы ввели как пароль будет умножено на **2** перед сравнением с этим **0x1AA**, поэтому правильный пароль должен быть значением, которое при умножении на два даёт нам **0x1AA**.

**X\*2 = 0x1AA**

Давайте проясним, что эта программа имеет ограничения, если сложение даёт нечетное число, то невозможно, чтобы существовало значение x, которое при умножении на 2 даёт нам результат нечетное число, поэтому эти имена пользователей не имеют решений , в этой программе имеют решения только имена пользователей, чья сумма при сложении чётная.

Мы очищаем строку и вводим.

**X = 0x1AA / 2** и ответ поступает в десятичной системе счисления, очевидно, что с помощью **ATOI** он переводится из десятичной системы счисления в **HEX**.

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

Если я введу **ИМЯ ПОЛЬЗОВАТЕЛЯ** как **pepe**, а **ПАРОЛЬ** как **213**, что произойдёт?

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

Конечно, я вижу, когда сравнение одинаково внутри функции проверки.

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

Если они не равны, программа идёт в красный блок и возвращает **НУЛЬ**, а если они равны программа идёт в зелёный блок и возвращает **ЕДИНИЦУ**, давайте посмотрим, что произойдёт с этим возвращаемым значением.

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

Программа сохраняет его здесь, давайте переименуем это значение в **FLAG\_EXITO**.

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

Так что, поскольку, если мы видим **0**, то тогда пойдём к **BAD REVERSER**, а если **AL** равно **1**, то идём к **GOOD BOY** как это и случается у нас здесь.

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

До встречи в **13**-й главе.

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

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

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

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

02.09.2017

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