
- •Лабораторная работа №6 «Команды работы с данными»
- •Раздел 1
- •«Команды перемещения данных»
- •1 Nop (No Operation)
- •2 Push (push operand onto stack)
- •3 Pop (pop operand from the stack)
- •4 Pushad (push All general Double word registers onto stack)
- •5 Popad (pop All general Double word registers from the stack)
- •6 Mov (moVe operand)
- •9 Lea (Load Effective Address)
- •10 Xchg (Exchange Register/Memory with Register)
- •Раздел 2 «Математические команды»
- •1 Inc (inCrement operand by 1)
- •2 Dec (deCrement operand by 1)
- •3 Add (adDition)
- •4 Adc (aDdition with Carry)
- •5 Sub (suBtract)
- •6 Sbb (SuBtract with Borrow)
- •7 Mul (muLtiply)
- •8 Imul (Integer muLtiply)
- •9 Div (diVide unsigned)
- •10 Idiv (Integer diVide)
- •11 Xadd (eXchange and add)
- •12 Neg (neGate operand)
7 Mul (muLtiply)
Команда MUL выполняет целочисленное умножение операндов без учета их знаковых разрядов. Для этой операции необходимо наличие двух операндов-сомножителей, размещение одного из которых фиксировано (регистр EAX), а другого задается операндом в команде.
Для разбора команды требуется открыть в программе OllyDbg файл Crackme.exe. В открывшейся программе в окне Disassembler window в самом начале находится команда PUSH 0. При помощи окна Assemble необходимо заменить эту команду на команду MUL ECX.
До выполнения команды MUL значение регистра ECX = 00000009, EAX = FFFFFFF7, как показано на рисунке 1.15.
Рисунок 1.15 – Registers window
Затем нужно выделить строку с командой MUL ECX щелчком левой кнопкой мыши и нажать F7. Значение регистра ECX 00000009 умножится на значение регистра EAX FFFFFFF7 без учёта знаков их значений, а результат 8FFFFFFAF сохранится в EDX:EAX. В данном случаи регистр EAX не смог вместить все значение и поэтому 8 попала в регистр EDX, как показано на рисунке 1.16, в таких случая говорят, что результат содержится в EDX:EAX, то есть два регистра используются как один двойного размера.
Рисунок 1.16 – Registers window
В случаи с командой MUL DWORD PTR DS: [405000] происходит умножение значения ячейки памяти по адресу 405000 на значение регистра EAX, а результат помещается в EDX:EAX без учета знаков операндов.
8 Imul (Integer muLtiply)
Команда IMUL – выполняет целочисленное умножение операндов с учетом их знаковых разрядов. Команда IMUL позволяет использовать больше одного операнда.
Для разбора команды требуется в программе OllyDbg открыть файл Crackme.exe. В открывшейся программе в окне Disassembler window в самом начале находится команда PUSH 0. При помощи окна Assemble необходимо заменить эту команду на IMUL EBP, DWORD PTR [ESI+74], FF800002. При нажатие кнопки Assemble в нижней части окна Assemble, как показано на рисунке 1.17, появится сообщение об ошибке - Unknown identifier.
Рисунок 1.17 – Окно Assemble
Это происходит из-за того, что в программе OllyDbg к числам, которые начинаются с букв, нужно слева приписывать ноль. Поэтому перед числом FF800002 необходимо поставить ноль, как показано на рисунке 1.18.
Рисунок 1.18 – Окно Assemble
В этом примере в команде используются три операнда: содержимое регистра ESI+74 умножается на число FF800002 с учетом знаков, а результат сохраняется в регистре EBP. До выполнения команды в регистре ESI содержится адрес 401000, а в регистре EBP – 0012FFF0, как показано на рисунке 1.19.
Рисунок 1.19 – Registers window
Примечание: регистры могут содержать другие значения.
Теперь необходимо выделить в окне Disassembler window строку с командой IMUL EBP, DWORD PTR [ESI+74], 0FF800002 щелчком левой кнопки мыши, и нажать F7. В окне Dump при помощи операции Go to можно увидеть, что по адресу ESI+74, то есть 401074 содержится значение C7000000, это же значение показано на рисунке 1.20.
Рисунок 1.20 – Dump
При умножении C7000000 на FF800002 получится С69С8001 8E000000. Поскольку EBP не может вместить его полностью то при выполнении команды в нём остаётся только то, что поместилось, и как показано на рисунке 1.21 – это 8E000000, а остальное отбрасывается.
Рисунок 1.21 – Registers window
Команда IMUL EDX, DWORD PTR [EBP-18] перемножит содержимое по адресу регистра EDX на содержимое по адресу регистра EBP минус 18, результат будет сохранен в регистре EDX и при необходимости урезан до размера 4 байта.
Команда IMUL EBX перемножит содержимое по адресу регистра EBX на содержимое по адресу регистра EAX, результат будет сохранен в EDX:EAX.
Основной способ для умножения больших чисел - использовать IMUL только с одним операндом, так как в этом случае результат сохраняется в EDX:EAX, то есть он может быть двойного размера, чего нельзя добиться при использовании двух или трёх операндах, соответственно, данную возможность следует применять для маленьких чисел.