Смекни!
smekni.com

Семантический анализ структуры EXE файла и дисассемблер (с примерами и исходниками), вирусология (стр. 4 из 12)

  • метка ближняя — в стек заносится содержимое указателя команд eip/ip и в этот же регистр загружается новое значение адреса, соответствующее метке;
  • метка дальняя — в стек заносится содержимое указателя команд eip/ip и cs. Затем в эти же регистры загружаются новые значения адресов, соответствующие дальней метке;
  • r16, 32 или m16, 32 — определяют регистр или ячейку памяти, содержащие смещения в текущем сегменте команд, куда передается управление. При передаче управления в стек заносится содержимое указателя команд eip/ip;
  • указатель на память — определяет ячейку памяти, содержащую 4 или 6-байтный указатель на вызываемую процедуру. Структура такого указателя 2+2 или 2+4 байта. Интерпретация такого указателя зависит от режима работы микропроцессора:

Состояние флагов после выполнения команды (кроме переключения задачи):

выполнение команды не влияет на флаги

При переключении задачи значения флажков изменяются в соответствии с информацией о регистре eflags в сегменте состояния TSS задачи, на которую производится переключение.
Применение:
Команда call позволяет организовать гибкую и многовариантную передачу управления на подпрограмму с сохранением адреса точки возврата.

О б ъ е к т н ы й к о д (четыре формата):

Прямая адресация в сегменте:

|11101000|disp-low|diep-high|

Косвенная адресация в сегменте:

|11111111|mod010r/m|

Косвенная адресация между сегментами:

|11111111|mod011r/m|

Прямая адресация между сегментами:

|10011010|offset-low|offset-high|seg-low|seg-high|

CMP

(CoMPare operands)

Сравнение операндов

Схема команды: cmp операнд1,операнд2

Назначение: сравнение двух операндов.

Алгоритм работы:

  • выполнить вычитание (операнд1-операнд2);
  • в зависимости от результата установить флаги, операнд1 и операнд2 не изменять (то есть результат не запоминать).

Состояние флагов после выполнения команды:

11 07 06 04 02 00
OF SF ZF AF PF CF
r r r r r r

Применение:
Данная команда используется для сравнения двух операндов методом вычитания, при этом операнды не изменяются. По результатам выполнения команды устанавливаются флаги. Команда cmp применяется с командами условного перехода и командой установки байта по значению setcc.

О б ъ е к т н ы й к о д (три формата):

Регистр или память с регистром:

|001110dw|modregr/m|

Непосредственное значение с регистром AX (AL):

|0011110w|--data--|data, если w=1|

Непосредственное значение с регистром или памятью:

|100000sw|mod111r/m|--data--|data, если sw=0|

DEC

(DECrement operand by 1)

Уменьшение операнда на единицу

Схема команды: dec операнд

Назначение: уменьшение значения операнда в памяти или регистре на 1.

Алгоритм работы:
команда вычитает 1 из операнда. Состояние флагов после выполнения команды:

11 07 06 04 02
OF SF ZF AF PF
r r r r r

Применение:
Команда dec используется для уменьшения значения байта, слова, двойного слова в памяти или регистре на единицу. При этом заметьте то, что команда не воздействует на флаг cf.

О б ъ е к т н ы й к о д (два формата):

Регистр: |01001reg|

Регистр или память: |1111111w|mod001r/m|

DIV

(DIVide unsigned)

Деление беззнаковое

Схема команды: div делитель

Назначение: выполнение операции деления двух двоичных беззнаковых значений.

Алгоритм работы:
Для команды необходимо задание двух операндов — делимого и делителя. Делимое задается неявно и размер его зависит от размера делителя, который указывается в команде:

  • если делитель размером в байт, то делимое должно быть расположено в регистре ax. После операции частное помещается в al, а остаток — в ah;
  • если делитель размером в слово, то делимое должно быть расположено в паре регистров dx:ax, причем младшая часть делимого находится в ax. После операции частное помещается в ax, а остаток — в dx;
  • если делитель размером в двойное слово, то делимое должно быть расположено в паре регистров edx:eax, причем младшая часть делимого находится в eax. После операции частное помещается в eax, а остаток — в edx.

Состояние флагов после выполнения команды:

11 07 06 04 02 00
OF SF ZF AF PF CF
? ? ? ? ? ?

Применение:
Команда выполняет целочисленное деление операндов с выдачей результата деления в виде частного и остатка от деления. При выполнении операции деления возможно возникновение исключительной ситуации: 0 — ошибка деления. Эта ситуация возникает в одном из двух случаев: делитель равен 0 или частное слишком велико для его размещения в регистре eax/ax/al.

О б ъ е к т н ы й к о д:

|1111011w|mod110r/m|

INT

(INTerrupt)

Вызов подпрограммы обслуживания прерывания

Схема команды: int номер_прерывания

Назначение: вызов подпрограммы обслуживания прерывания с номером прерывания, заданным операндом команды.

Алгоритм работы:

  • записать в стек регистр флагов eflags/flags и адрес возврата. При записи адреса возврата вначале записывается содержимое сегментного регистра cs, затем содержимое указателя команд eip/ip;
  • сбросить в ноль флаги if и tf;
  • передать управление на программу обработки прерывания с указанным номером. Механизм передачи управления зависит от режима работы микропроцессора.

Состояние флагов после выполнения команды:

09 08
IF TF
0 0

Применение:
Как видно из синтаксиса, существуют две формы этой команды:

  • int 3 — имеет свой индивидуальный код операции 0cch и занимает один байт. Это обстоятельство делает ее очень удобной для использования в различных программных отладчиках для установки точек прерывания путем подмены первого байта любой команды. Микропроцессор, встречая в последовательности команд команду с кодом операции 0cch, вызывает программу обработки прерывания с номером вектора 3, которая служит для связи с программным отладчиком.
  • Вторая форма команды занимает два байта, имеет код операции 0cdh и позволяет инициировать вызов подпрограммы обработки прерывания с номером вектора в диапазоне 0–255. Особенности передачи управления, как было отмечено, зависят от режима работы микропроцессора.

О б ъ е к т н ы й к о д (два формата):

Регистр: |01000reg|

Регистр или память: |1111111w|mod000r/m|

JCC
JCXZ/JECXZ

(Jump if condition)

(Jump if CX=Zero/ Jump if ECX=Zero)

Переход, если выполнено условие

Переход, если CX/ECX равен нулю

Схема команды: jcc метка
jcxz метка
jecxz метка

Назначение: переход внутри текущего сегмента команд в зависимости от некоторого условия.


Алгоритм работы команд (кроме jcxz/jecxz):
Проверка состояния флагов в зависимости от кода операции (оно отражает проверяемое условие):

  • если проверяемое условие истинно, то перейти к ячейке, обозначенной операндом;
  • если проверяемое условие ложно, то передать управление следующей команде.

Алгоритм работы команды jcxz/jecxz:
Проверка условия равенства нулю содержимого регистра ecx/cx:

  • если проверяемое условие истинно, то есть содержимое ecx/cx равно 0, то перейти к ячейке, обозначенной операндом метка;
  • если проверяемое условие ложно, то есть содержимое ecx/cx не равно 0, то передать управление следующей за jcxz/jecxz команде программы.

Состояние флагов после выполнения команды:

11 07 06 05 04 03 02 01 00
OF SF ZF 0 AF 0 PF 1 CF
? ? ? r ? r

Применение (кроме jcxz/jecxz):
Команды условного перехода удобно применять для проверки различных условий, возникающих в ходе выполнения программы. Как известно, многие команды формируют признаки результатов своей работы в регистре eflags/flags. Это обстоятельство и используется командами условного перехода для работы. Ниже приведены перечень команд условного перехода, анализируемые ими флаги и соответствующие им логические условия перехода.

Команда Состояние проверяемых флагов Условие перехода
JA CF = 0 и ZF = 0 если выше
JAE CF = 0 если выше или равно
JB CF = 1 если ниже
JBE CF = 1 или ZF = 1 если ниже или равно
JC CF = 1 если перенос
JE ZF = 1 если равно
JZ ZF = 1 если 0
JG ZF = 0 и SF = OF если больше
JGE SF = OF если больше или равно
JL SF <> OF если меньше
JLE ZF=1 или SF <> OF если меньше или равно
JNA CF = 1 и ZF = 1 если не выше
JNAE CF = 1 если не выше или равно
JNB CF = 0 если не ниже
JNBE CF=0 и ZF=0 если не ниже или равно
JNC CF = 0 если нет переноса
JNE ZF = 0 если не равно
JNG ZF = 1 или SF <> OF если не больше
JNGE SF <> OF если не больше или равно
JNL SF = OF если не меньше
JNLE ZF=0 и SF=OF если не меньше или равно
JNO OF=0 если нет переполнения
JNP PF = 0 если количество единичных битов результата нечетно (нечетный паритет)
JNS SF = 0 если знак плюс (знаковый (старший) бит результата равен 0)
JNZ ZF = 0 если нет нуля
JO OF = 1 если переполнение
JP PF = 1 если количество единичных битов результата четно (четный паритет)
JPE PF = 1 то же, что и JP, то есть четный паритет
JPO PF = 0 то же, что и JNP
JS SF = 1 если знак минус (знаковый (старший) бит результата равен 1)
JZ ZF = 1 если ноль

Логические условия "больше" и "меньше" относятся к сравнениям целочисленных значений со знаком, а "выше и "ниже" — к сравнениям целочисленных значений без знака. Если внимательно посмотреть, то у многих команд можно заметить одинаковые значения флагов для перехода. Это объясняется наличием нескольких ситуаций, которые могут вызвать одинаковое состояние флагов. В этом случае с целью удобства ассемблер допускает несколько различных мнемонических обозначений одной и той же машинной команды условного перехода. Эти команды ассемблера по действию абсолютно равнозначны, так как это одна и та же машинная команда. Изначально в микропроцессоре i8086 команды условного перехода могли осуществлять только короткие переходы в пределах -128...+127 байт, считая от следующей команды. Начиная с микропроцессора i386, эти команды уже могли выполнять любые переходы в пределах текущего сегмента команд. Это стало возможным за счет введения в систему команд микропроцессора дополнительных машинных команд. Для реализации межсегментных переходов необходимо комбинировать команды условного перехода и команду безусловного перехода jmp. При этом можно воспользоваться тем, что практически все команды условного перехода парные, то есть имеют команды, проверяющие обратные условия.
Применение jcxz/jecxz: