Заклинание кода: Бет

Дата публикации 3 дек 2002

Заклинание кода: Бет — Архив WASM.RU

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

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

Как вам должно быть известно, ассемблеры переводят инструкции из понятной и запоминающейся (мнемонической) человеку формы в форму, понятную ЭВМ - в машинный код. Инструкции в машинном коде имеют определенный формат и состоят из нескольких полей, главным из которых является опкод - код операции. А некоторые, простые инструкции, состоят только из опкода и других полей у них нет.

Одной из таких инструкций является NOP. Её опкод - 90h. У этой инструкции нет параметров, поэтому знания её опкода достаточно для заклинания. Вот пример программы:

Код (Text):
  1.  
  2. format PE console
  3. entry start
  4.  
  5. include '..\..\include\kernel.inc'
  6. include '..\..\include\user.inc'
  7. include '..\..\include\macro\stdcall.inc'
  8. include '..\..\include\macro\import.inc'
  9.  
  10. section '.code' code executable readable
  11.  
  12. start:
  13.  
  14.         db      90h     ; nop
  15.  
  16.         invoke  ExitProcess,0
  17.  
  18. section '.idata' import data readable writeable
  19.  
  20.                 library kernel32,'kernel32.dll'
  21. kernel32:       import  ExitProcess,'ExitProcess'

Надеюсь, у читателей этой главы, новоявленных заклинателей, не возникнет вопроса, почему эта программа ничего не делает. А для тех, у кого возникнет, поясняю: инструкция NOP ничего не делает (отсюда и её мнемноника - No OPerations). Если быть более точным, то NOP имеет тот же опкод, что и инструкция XCHG EAX,EAX, однако результат (отсутствие изменений) от этого не меняется.

Но NOP - это не очень интересно. Безусловно, поначалу заклинание внушает, однако на практике оно не очень полезно. Было бы неплохо, если бы мы могли заклинать что-нибудь более полезное - например, увеличивать или уменьшать значение в eax на 1.

Это возможно. Для этого есть мнемоники INC (INCrement) и DEC (DECrement). Опкод INC EAX - 40h, опкод DEC EAX - 48h. Далее я приведу текст программы, в которой в eax кладётся число 10, затем содержимое eax увеличивается на 1 пять раз, потом - трижды уменьшается на 1. Используя абак несложно посчитать, что в результате должно получиться 12. Это число мы отобразим с помощью MessageBox.

Код (Text):
  1.  
  2. format PE console
  3. entry start
  4.  
  5. include '..\..\include\kernel.inc'
  6. include '..\..\include\user.inc'
  7. include '..\..\include\macro\stdcall.inc'
  8. include '..\..\include\macro\import.inc'
  9.  
  10. section '.data' data writeable readable
  11.  
  12. _d      db '%d',0
  13.  
  14. section '.code' code executable readable
  15.  
  16. start:
  17.  
  18.         mov     eax,10
  19.         db      40h     ; inc eax
  20.         db      40h     ; inc eax
  21.         db      40h     ; inc eax
  22.         db      40h     ; inc eax
  23.         db      40h     ; inc eax
  24.         db      48h     ; dec eax
  25.         db      48h     ; dec eax
  26.         db      48h     ; dec eax
  27.  
  28.         push    eax
  29.         push    _d
  30.         call    [printf]
  31.         add     esp,8
  32.  
  33.         invoke  ExitProcess,0
  34.  
  35. section '.idata' import data readable writeable
  36.  
  37.                 library kernel32,'kernel32.dll',\
  38.                         msvcrt,'msvcrt.dll'
  39. kernel32:       import  ExitProcess,'ExitProcess'
  40. msvcrt:         import  printf,'printf'

Скомпилировав и запустив программу можно убедиться, что в результате получается 12. Наше заклинание верно и ошибок нет. На досуге можете поэкспериментировать с PUSH EAX (опкод 50h) и POP EAX (опкод 58h).

Однако этого вам может показаться мало. Возможно, вы захотите сделать заклинание PUSH EBX или даже INC EDX - и это вполне вам по силам! Я дам вам общую формулу для этих инструкций, когда операндом является регистр (именно регистр, а не ячейка памяти, причём 32-х битный!). Общая формула такова:

Базовый опкод + номер регистра

Базовые опкоды:

  • INC - 40h
  • DEC - 48h
  • PUSH - 50h
  • POP - 58

Номера регистров:

  • EAX - 0
  • ECX - 1
  • EDX - 2
  • EBX - 3
  • ESP - 4
  • EBP - 5
  • ESI - 6
  • EDI - 7

Используя эту формулу легко вычислить, например, опкод PUSH EDX: 48h+2=4Ah. Я рекомендую потренироваться в составление простых заклинаний на основе приведённых выше.

Довольно практики, перейдём к теоретическим вопросам. Какой длины может быть опкод? Для процессоров семейств x86 он может быть длиной до 3 байт. Также, под опкод может использоваться часть байта ModR/M, о котором будет рассказано в следующих главах.

Да, инструкции могут различаться по размеру. А в некоторых процессорах с другой архитектурой инструкции имеют фиксированную длину. Почему же в x86 это не так? Согласно легенде, когда интеловские гномы добывали руду для первых процессоров, они ещё не умели дробить руду на одинаковые по размеру инструкции. Знание же и умение делать это пришло позже. Но и после этого интеловские гномы продолжали дробить руду на разноразмерные инструкции, поскольку они умели это делать хорошо, а их изделия знали и использовали уже многие.

Также я хотел рассмотреть, зачем понадобилось делать отдельный мнемоник для XCHG EAX,EAX - NOP. Причина, несомненно, в метафизическом смысле числа 90h. В каком-то смысле девятка (как утроенная триада) символизирует Инь и Янь, а ноль среди своих прочих значений символизирует Абсолют. Внесение такого мощного магического слова в ассемблер укрепило положение x86 на астральном плане.

В следущей главе мы попытаемся поместить в EAX единицу. Более того, наша попытка окажется успешной! :smile3: © Aquila / WASM.RU


0 1.038
archive

archive
New Member

Регистрация:
27 фев 2017
Публикаций:
532