Ассемблер. Математические и логические инструкции. Крэкинг ч.5

Обсудить статью на форуме


Очень удобно, когда все крэкерские инструменты, книги и статьи в одном месте. Используйте сборник 2020 года от EXELAB - вот тут.

МАТЕМАТИЧЕСКИЕ ИНСТРУКЦИИ



INC И DEC

Эти инструкции увеличивают или уменьшают значение операнда, прибавляя к нему один в случае с INC или, соответственно, отнимая один в случае с DEC.

Идём в Олли и, как обычно, открываем крэкми CrueHead'и и в первой строке пишем:

Взлом программ отладчиком OllyDbg

На моей машине EAX изначально равен нулю. Если у вас это не так, вы можете изменить это вручную.

Взлом программ отладчиком OllyDbg

Затем нажимаем F7 и выполняем инструкцию INC EAX, увеличивая его на один.

Взлом программ отладчиком OllyDbg

Таким же образом можем ввести DEC сразу под предыдущей инструкцией.

Взлом программ отладчиком OllyDbg

Нажимаем F7 и выполняем инструкцию INC EAX, которая уменьшает значение регистра на 1, после чего он принимает предыдущее значение - 0.

Взлом программ отладчиком OllyDbg

Также можно увеличивать или уменьшать значение ячейки памяти.

Взлом программ отладчиком OllyDbg

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

Взлом программ отладчиком OllyDbg

Что было бы, если бы у секции было выставлено разрешение на запись? Идём в DUMP по адресу 405000.

Взлом программ отладчиком OllyDbg

Содержимое, если его прочитать наоборот, будет равно 00001000, значит, если бы оно было увеличено, то было бы 00001001

Взлом программ отладчиком OllyDbg

В данном случае для DWORD прибавление 1 производилось к 4 байтам содержимого.

Для WORD суммирование будет применено только к двум последним байтам.

Взлом программ отладчиком OllyDbg

И при BYTE суммирование будет применено только к последнему байту.

Взлом программ отладчиком OllyDbg

ADD

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

ADD EAX, 1 похоже на INC EAX.

Также можем складывать регистры.

Идём в Олли.

Взлом программ отладчиком OllyDbg

До выполнения инструкции:

Взлом программ отладчиком OllyDbg

На моейм машине EAX содержит 00000000, а EAX - 12FFB0. У вас данные регистры могут содержать другие значения, также вы можете, если хотите, их изменить, но когда вы нажмёте F7, оба значения будут сложены, а результат помещён в EAX. Смотрим:

Взлом программ отладчиком OllyDbg

Здесь EAX стал красного цвета, потому что он был модифицирован и содержит результат суммирования.

Также можем сложить регистр с содержимым ячейки памяти.

Взлом программ отладчиком OllyDbg

В данном случае нет проблем с правами на запись, так как меняется и сохраняет результат регистр EAX, а содержимое [405000] остаётся неизменным. Соответственно, не генерится и никакого исключения.

До нажания F7 видим, что EAX содержит 0, а по адресу 405000 находится значение 00001000.

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Нажимае F7, после чего вычисляется сумма.

Взлом программ отладчиком OllyDbg

Так как EAX = 0, то в EAX сохраняется результат, равный 1000.

Если хотим, чтобы результат сохранился в памяти, то пишем:

Взлом программ отладчиком OllyDbg

В этом случае результат сохранится в 405000, и так как это модифицирует память, то в нашем случае при нажатии на F7 будет сгенерировано исключение об отсутствии прав на запись.

Взлом программ отладчиком OllyDbg

ADC (ADD С ПЕРЕНОСОМ)

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

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Здесь видим, что здесь будет суммирован EAX, содержащий 21, со числом 3, а также вычислен флаг C, который сейчас равен нулю. Нажимаем F7.

Взлом программ отладчиком OllyDbg

Видим, что результат равен 24. Теперь повторим эту операцию, но с флагом C равным 1, значение которого мы можем изменить, если дважды кликнем по нему мышью.

Взлом программ отладчиком OllyDbg

Сделав это, повторяем выполнение инструкции, изменив значение флага C.

Взлом программ отладчиком OllyDbg

Нажимем F7 и вуаля - результат равен 25.

Взлом программ отладчиком OllyDbg

Так как сумма EDX (21) с 3 и флагом C, равном 1, равна 25.

SUB

Это операция является обратной по отношению к ADD - она вычисляет остаток от вычитания второго операнда от первого и сохраняет в последнем полученный результат.

Взлом программ отладчиком OllyDbg

На моей машине регистры до выполнения инструкции содержали следующее:

Взлом программ отладчиком OllyDbg

По нажатию F7 инструкция вычтет от EAX, который содержит ноль, значение 2.

Взлом программ отладчиком OllyDbg

Результатом является -2, что в шестнадцатеричной системе выглядит как FFFFFFFE, в чём мы можем убедиться, если кликнем два раза мышью на данном значении:

Взлом программ отладчиком OllyDbg

Видим, что в десятеричной системе это равно -2.

Также можно отнимать значение регистров и ячеек памяти примерно таким же образом, как и при использовании инструкции ADD.
SUB EAX,ECX<


То есть EAX-ECX с сохранением результата в EAX.

И
SUB EAX,DWORD PTR DS:[405000]<


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

Обратный случай:
SUB DWORD PTR DS:[405000],EAX<


Так как результата сохраняется .в первый операнд, то, поскольку у нас нет прав на запись в секцию, то получим исключение.

SBB

Это операция является обратной к ADC: она вычисляет разность между операндами, отнимает от того, что получилось, значение флага переноса (флаг C) и сохраняется окончательный результат в первый операнд.

Взлом программ отладчиком OllyDbg

До выполнения в EDX находилось 21, а флаг переноса был равен 0.

Взлом программ отладчиком OllyDbg

Нажатие на F7 вычтет из EDX число 3, а затем ноль, которому равен флаг C.

Взлом программ отладчиком OllyDbg

Теперь повторим операцию, присвоив флагу C значение 1.

Взлом программ отладчиком OllyDbg

Нажимает на F7 и теперь из EDX вычитается 3, а затем единица, которой равен флаг C.

Взлом программ отладчиком OllyDbg

В данном случае результат равен 1D.

MUL

Ок, есть две инструкции для выполнения умножения. Первой из них является MUL, которая не учитывает знаки чисел. Она использует только один операнд, а другим всегда является EAX Результат сохраняется в EDX:EAX.

Например:
MUL ECX<


Здесь ECX умножается на EAX без учёта знаков их значений, а результат сохраняется в EDX:EAX.

Рассмотрим следующий пример с помощью OllyDbg:

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Поместим в EAX число FFFFFFF7, в ECX - 9, а затем посчитаем результат с помощью стандартного калькулятора Windows:

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Получится:

Взлом программ отладчиком OllyDbg

Это не поместится в EAX. Посмотрим, что будет в Олли и нажмём на F7.

Взлом программ отладчиком OllyDbg

EDX и EAX выделены красным, так как их значение было изменено, и, как видим, в EAX было сохранено то, что поместилось, а остальное в EDX. В данном случае 8-рка, которую не смог вместить EAX, попала в EDX, поэтому в таких случая говорят, что результат содержится в EDX:EAX, то есть два регистра используются как один двойного размера.

В случае с
MUL DWORD PTR DS:[405000]<


Происходит умножение ячейки памяти по адресу 405000 на EAX, а результат, как обычно, помещается в EDX:EAX без учёта знаков операндов.

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

Взлом программ отладчиком OllyDbg

Как можно видеть, во втором ряду находится значение со знаком (в данном случае FFFFFFAF это -81, если учитывать знак), но в таких операциях как MUL все числа считаются БЕЗЗНАКОВЫМИ. Третья строка как раз и содержит десятеричное значение без знака. Сейчас видим, что число FFFFFFAF - это 4294967215, если рассматривать его как положительное, то есть беззнаковое.

IMUL (умножение без знака)

Инструция IMUL - это умножение со знаком и употребляется аналогично MUL.

IMUL ECX

Данная операция производит умножение ECX на EAX, а результат сохраняется в EDX:EAX с учётом знака операндов.

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

Из туториала CAOS'а:
Несмотря на использовальние регистров EAX и EDX по умолчанию, можно указать другие источники и приёмники данных вплоть до трёх операндов. Первый - место, куда необходимо поместить результат и которое всегда должно быть регистром, второй и третий - два значения, которые нужно перемножить. В этих примерах увидим применение этой инструкции с двумя или тремя операндами.
F7EB	imul ebx					EAX x EBX -> EDX:EAX<


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

696E74020080FF imul ebp, dword ptr [esi+74], FF800002 [ESI+74] x FF800002 -> EBP

Это второй пример, в котором три операнда: содержимое ESI+74 умножается на FF800002, а результат сохраняется в EBP. Мы можем посмотреть его в действии с помощью Олли.

Скопируем строку "imul ebp, dword ptr [esi+74], FF800002" в Олли.

Взлом программ отладчиком OllyDbg

Видим, что нажатие кнопки "ASSEMBLE" выдаёт ошибку. Это происходит из-за того, что в Олли к числам, которые начинаются с букв, нужно слева приписывать ноль. Исправляем:

Взлом программ отладчиком OllyDbg

Теперь нажатие на ASSEMBLE проходит без ошибок.

Взлом программ отладчиком OllyDbg

Изменяем значение ESI на 401000, чтобы быть уверенными, что адрес ESI + 74, из котого будет происходить чтение, существует.

Взлом программ отладчиком OllyDbg

Видим в пояснениях:

Взлом программ отладчиком OllyDbg

Здесь говорится, что ESI + 74 - это адрес 401074, содержимым которого является C7000000. Идём в DUMP с помощью "GOTO EXPRESSION 401074".

Взлом программ отладчиком OllyDbg

Это значение, которое, если прочитать его наоборот, равно C7000000, будет умножено на FF800002, а результат данной операции будет сохранён в EBP.
imul ebp, dword ptr [esi+74], FF800002<


Нажав F7, видим, что EBP стал красным, так как сейчас он содержит результат.

Взлом программ отладчиком OllyDbg

Калькулятор даёт нам следующий результат операции C7000000 * FF800002:

Взлом программ отладчиком OllyDbg

Но поскольку EBP не может вместить его полностью, то в нём остаётся только то, что поместилось, а остальное отбрасывается.

В третьем примере только два операнда, оба из которых перемножаются, а результат сохраняется в первый из них.
0FAF55E8	           imul edx, dword ptr [ebp-18]		EDX x [EBP-18] -> EDX<


Как видим, основной способ для умножения больших чисел - использовать IMUL только с одним операндом, так как в этом случае результат сохраняется в EDX:EAX, то есть он может быть двойного размера, чего нельзя добиться при использовании двух или трёх операндах, соответственно, данную возможность следует применять для маленьких чисел.

DIV (Unsigned Divide) / IDIV (Signed Divide)

Это инструкции, обратные по отношении к MUL и IMUL соответственно.

DIV имеет только один операнд, не учитывает знаки и сохраняет результат в EDX:EAX.

IDIV всегда учитывает знаки. Если используется один операнд, то, как и DIV, сохраняет результат в EDX:EAX, в случае двух - делит один на другой и сохраняет результат в первый, а при трёх операндах делит второй на третий и сохраняет то, что получилось, в первый.

Не думаю, что нужно приводить здесь примеры, похожие на те, что были в разделе, посвящённом MUL и IMUL.

XADD (Обменять и сложить)

Как можно догадаться, это смесь XCHG и ADD, то есть если :
XADD EAX,ECX<


Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Видим, что ECX равен 1, а EAX - 9. По нажатию на F7 они обменяются значениям, т.е. в EAX попадёт 1, а в ECX - 9, после чего произойдёт сложение.

Взлом программ отладчиком OllyDbg

Видно, что результат затем был сохранён в первый операнд. Регистр ECX содержит число 9, которое находилось до выполнения операции в EAX.

NEG

Назначением данной инструкции является менять знак заданного числа на противоположный, т.е. если у нас есть число 32 в шестнадцатеричной системе, и мы применяем к ней NEG, то результатом будет его отрицательный аналог.

Пример:

Взлом программ отладчиком OllyDbg

Пишем в Олли NEG EAX и заносим в EAX число 32.

Взлом программ отладчиком OllyDbg

После нажатия на F7 в EAX окажется отрицательный вариант числа 32. Смотрим:

Взлом программ отладчиком OllyDbg

Взлом программ отладчиком OllyDbg

Во втором ряду видим, что результатом является -50 в десятеричной системе (это соответствует -32 в шестнадцатеричной).

Взлом программ отладчиком OllyDbg

Если напечатаем в CommandBar'е число -32 в шестнадцатеричной системе, чтобы выяснить, чему оно равно в десятеричной, то получим ответ, что это значение эквивалентно -50, а также пояснение, что это FFFFFFCE.

Так что видим, что NEG меняет знак операнда на обратный.

ЛОГИЧЕСКИЕ ИНСТРУКЦИИ



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

AND

Результатом этой операции над двумя битам является 1, если они оба равны 1, и 0 во всех остальных случаях. Посмотрим пример в OllyDbg:
AND EAX,ECX<


Взлом программ отладчиком OllyDbg

Делаем ECX=00001200, а EAX=3500.

Взлом программ отладчиком OllyDbg

Чтобы сделать эту операцию вручную, нужно перевести оба числа в двоичный вид:

Применим вышеприведённую таблицу операции AND побитно, например, к последней цифре:

Взлом программ отладчиком OllyDbg

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

Взлом программ отладчиком OllyDbg

Если нажмём F7 в Олли, то увидим, что в ECX находится результат 1000, что эквивалентно 01000000000000 в двоичном виде.

Взлом программ отладчиком OllyDbg

OR

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

Получается 1, если один или оба бита равны 1, и 0 во всех остальных случаях.

XOR

Здесь то же самое, только используем таблицу функции XOR.

Получается 1, если один и только один из двух битов равен 1, и 0 во всех остальных случаях.

NOT

Просто инвертирует значение:

Пример: not 0110 = 1001

Если у нас, например, EAX=1200, что в двоичном виде равно 1001000000000, то все нули превратятся в 1, а все 1 в 0.
00000000000000000001001000000000<


После применения NOT получим
11111111111111111110110111111111<


что в калькуляторе Windows в шестнадцатеричном виде отобразится как FFFFEDFF.

Взлом программ отладчиком OllyDbg

В Олли до нажатия на F7 сделаем EAX равным 1200.

Взлом программ отладчиком OllyDbg

Нажимаем F7.

Взлом программ отладчиком OllyDbg

Видим, что результат тот же самый.

Ок, здесь мы закончим пятую часть "Введения...". Пока подумайте над тем, что узнали в этой главе, а нам ещё предстоит рассмотреть инструкции сравнения, выходов, call и ret.

Шаг за шагом дорога приведёт нас к цели.



  [C] Рикардо Нарваха, пер. Aquila

Обсуждение статьи: Ассемблер. Математические и логические инструкции. Крэкинг ч.5 >>>


При перепечатке ссылка на https://exelab.ru обязательна.



Видеокурс ВЗЛОМ