Глава 2. Фундаментальные знания для обратной инженерии.

Отчёт по СНИР

ТЕМА: «Reverse Engineering»

Выполнили:

Студенты 442 гр.

Ремизов М.С.,

Ананьев Д.С.

Проверил:

Доц. Каф ЭВМ

Засорин С.В.

Рязань 2016

Оглавление.

  1. Введение.

· Понятие. ........................................................................................4

· Виды "обратной разработки". .....................................................4

· Что можно получить? ...................................................................4

  1. Фундаментальные знания для обратной инженерии.
    • Архитектура. .......................................................................................5
    • Организация памяти. ..........................................................................6
    • Представление данных. ......................................................................7
    • Регистры микропроцессора. ...............................................................8
    • Способы адресации. .........................................................................10
    • Логика и организация программы. ....................................................11
    • Структура COM- и EXE-программ.
      Размещение программ в памяти. .....................................................17
    • Команды пересылки и строковые операции. ...................................17
    • Прерывания. .......................................................................................18
    • Операции.............................................................................................19
    • Представление знака в числах..........................................................20
    • Порядок байта. ...................................................................................21
    • Виды памяти. ......................................................................................22
    • Предсказатели переходов. ................................................................22
    • Хэш-функции. ......................................................................................23
  2. Основная часть.

· Поиск в коде того, что нужно. .....................................................24

· Примеры [Сапёр (Windows XP)]. ................................................29

· Основные способы взлома программ. ......................................34

· Основные способы защиты программ. .....................................36

· Методы противодействия. .........................................................38

  1. Основные программы для обратной инженерии.

· Отладчик DEBUG. .....................................................................50

· Отладчик TurboDebugger. ........................................................52

· Отладчик SoftICE. .....................................................................55

· Интерактивный дизассемблер IDA. ........................................57

· Отладчик OllyDbg. ....................................................................59

  1. Вывод. .................................................................................................61
  2. Литература. ........................................................................................61

Глава 1. Введение.

Понятие

Обра́тная разрабо́тка (обратный инжиниринг, реверс-инжиниринг; англ. reverse engineering) — исследование некоторого готового устройства или программы, а также документации на него с целью понять принцип его работы; например, чтобы обнаружить недокументированные возможности (в том числе программные закладки), сделать изменение или воспроизвести устройство, программу или иной объект с аналогичными функциями, но без прямого копирования.

Применяется обычно в том случае, если создатель оригинального объекта не предоставил информации о структуре и способе создания (производства) объекта. Правообладатели таких объектов могут заявить, что проведение обратной разработки или использование её результатов нарушает их исключительное право по закону об авторском праве и патентному законодательству.

Виды «Обратной разработки»

Реверс-инжиниринг (или, ради краткости, реверсинг) программного обеспечения — это когда постигают суть неведомой программы с закрытым исходным кодом. Процесс нередко происходит с применением специализированного софта: декомпиляторов, отладчиков, дизассемблеров, распаковщиков и прочих хитрых инструментов.

Реверсинг «железа» — определение структуры и спецификаций устройства. Создание альтернативных драйверов уже упомянуто, а ещё «прошивки» всякие бывают («firmware»), которые иногда хочется менять и переделывать под свои цели. К примеру, освобождать сотовые модемы от коварной привязки к конкретному оператору.

Что можно получить?

Выпустила какая-нибудь надменная контора новую компьютерную «железку», но драйверы изготовила только для коммерческих операционных систем. Сочла пользователей свободных GNU/Linux и *BSD недостаточно многочисленными и платежеспособными, чтобы тратить ради них свои силы. Поэтому сколько ни втыкай такое устройство в ноутбук с Linux, оно не заработает.

Тогда за дело берутся опытные программисты. Идейные. Из тех, кто желает, чтобы люди не зависели от прихотей разных контор и могли пользоваться «железкой» в свободных ОС.

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

То есть, идёт разработка в обратном направлении, от готового результата к истоку, от бинарной сборки к исходному коду. Нужно уразуметь, какая функция что делает, какой алгоритм должен получиться etc.

В случае успеха изготавливается новый софт, необязательно клон имеющегося, но выполняющий те же самые задачи. Если программа оказывается работоспособной, то пользователей свободных ОС можно будет порадовать драйвером для «железки».

Глава 2. Фундаментальные знания для обратной инженерии.

Архитектура

Архитектура микропроцессора

Главное, что должен делать центральный процессор,-упрощать работу со следующими объектами вычислительной системы:

присваивания и арифметические выражения;

безусловные/условные переходы;

логические выражения;

циклы;

массивы/структуры данных;

подпрограммы;

устройства ввода/вывода.

Стандартная архитектура центрального процессора , обладающего такими возможностями, должна включать:

набор регистров для адресации данных и выполнения арифметических операций;

устройство управления для исполнения команд;

арифметико-логическое устройство (АЛУ) для выполнения арифметических и логических операций;

секцию правления вводом/выводом.

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

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

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

Операционное устройство предназначено для выполнения команд. Оно содержит АЛУ, устройство управления и 10 регистров.

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

Например, процессор 8086 имеет 14 16-разрядных регистров, доступных для программиста. Начиная с микропроцессора ш80386 пользовательских регистров стало 16- добавились два сегментных регистра FS и GS. Остальные регистры расширились до 32 бит. Основные регистры микропроцессоров семейства 80х86 показаны ниже. Регистры позволяют свести операции к командам, имеющим не более одного операнда, находящегося в памяти.


Рисунок 1. Регистры.

Организация памяти

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

1) Память, доступная только для чтения и называемая постоянной памятью( Read Only Memory, ROM).

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

2) Память произвольного доступа (Random Access Memory, RAM), или оперативная память. Эта память доступна для чтения и записи и является памятью, с которой работает программист. Она также является энергозависимой памятью

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

Минимальная компьютерная единица информации называется битом. Бит может принимать только одно значение из двух- 0 или 1. Память разбивается на блоки различных размеров- байт, слово, сегмент, страница и др.

Микропроцессор работает в одном из следующих режимов:

реальный режим- режим , в котором работал процессор 8086;

защищённый режим, позволяющий максимально реализовать возможности процессоров 80х86;

режим виртуального 8086- режим, возможный при работе процессора в защищённом режиме;

режим системного управления- режим, появившийся в микропроцессоре Pentium;

Для простоты рассмотрим адресацию памяти в реальном режиме.

1. По содержимому регистров CS и IP , хранящих адрес команды в виде базового адреса, то есть адреса начала сегмента (CS), и смещения( номера байта в сегменте) (IP), определяется место нахождение (EA) команды, выполняемой на следующем шаге.

2. Вычисленный адрес запоминается в стеке.

3. Из оперативной памяти считывается команда с этим адресом и пересылается в процессор.
4. Команды помещаются в очередь команд и выполняются в порядке очерёдности.

5. Местоположение данных, участвующих в командах, определяется в шинном интерфейсе по информации, содержащейся в адресной части команды, в регистрах сегментов DS, SS и ES, а также в регистрах SP, BP, SI, DI.

6. Данные, прочитанные из памяти, пересылаются в АЛУ или регистр данных (DS) и обрабатываются текущей командой, адрес которой был найден на шаге 2. Результат обработки данных помещается в оперативную память или в какой-либо из регистров.

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

Преставление данных

Данне в памяти ЭВМ меют двоичное представление. В самом общем случае мы можеи отвести под целое число любое количество соседних байтов. Рассмотрим некоторые наиболее часто используемые типы данных:

целые числа;

двоично-десятичные числа;

неупакованный BDC-формат;

упакованный BDC-формат;

числа с плавающей точкой;

символьный тип.

Определения данных
Директивы ассемблера, позволяющие выделить память для числовых переменных и констант. Как и в случае других директив распределения памяти, ассемблер связывает тип с любой переменной, определённой с помощью этих директив.
Директивы распределения памяти могут иметь соответствующие типу переменных преобразователи -word ptr, qword ptr, tbyte ptr.

Директива Интерпретация Тип данных
db Определить байт Целое
dw Определить слово Целое
dd Определить двойное слово Короткое целое, короткое вещественное
dq Определить слово длинной 8 байт Длинное целое, длинное вещественное
dt Определить слово длинной 10 байт Упакованное десятичное, временное вещественное

Таблица 1. Директивы данных и их интерплитация.

Общий формат директивы определения данных
[имя] dn выражение

где
задавать имя элемента данных необязательно;

dn применяет одно из следующих символьных значений : db, dw, dd, dq, dt;

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

Представление данных сопроцессора

Математический сопроцессор серии 80х87 может обрабатывать 7 типов данных:

целое число со знаком;

короткое целое со знаком;

длинное целое со знаком;

целое число в упакованном BCD-формате;

короткое вещественное число;

длинное вещественное число;

расширенное вещественное число.

Регистры микропроцессора

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

Регистра общего назначения (РОНы)

EAX(AX), EBX(BX), ECX(CX), EDX(DX)- регистры, которые расположены в самом микропроцессора. Заметим, что EAX, EBX, ECX и EDX это 32-битные регистры, которые появились поздней, для упрощения работы программиста, следовательно АХ,ВХ,СХ и DX - 16-битные регистры.

Таблица 1. РОНы микропроцессора.

Рассмотрим каждый из регистров белее подробно.

Регистр АХ (ЕАХ). Является основным сумматором и применяются для арифметических операций, строковых операций, операций ввода/вывода. Команды умножения, деления, преобразования, коррекции используют регистр AL- младший байт регистра АХ. Старший байт регистра АХ- регистр АН используется для задания функций обслуживающих программ.

Регистр ВХ (ЕВХ). Применяется для вычислительных операций и в различных методах адресации. Это единственный рон, который можно использовать в качестве индекса элементов массива. Применяется в команде преобразования для указания начала таблицы.

Регистр СХ (ЕСХ). Необходим для управления числом повторений в командах цикла. Применяется в командах сдвига для указания числа бит, на которое сдвигается содержимое операнда.

Регистр DX (EDX). Применяется в комадах ввода/вывода, умножения, деления, использующих регистровую пару DX:AX.

Регистровые указатели и индексные регистры

Регистровые указатели SP и BP обеспечивают доступ к данным в сегменте стека. РЕгистр BP используется также в различных методах адресации.

Индексные регистры SI и DI применяются в строковых операциях и в различных методах адресации.

Таблица 2. Индексные регистры и регистровые указатели.

Регистр SP (ESP). Указатель стека обеспечивает использование стека в памяти.

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

Адрес начала стека равен 16 х SS+ SP, где SS - сожержимое регистра сегмента стека.

Регистр BP (EBP). Облегчает доступ к параметрам, значения которых передаются с помощью сохранения данных в стеке.

Регистр SI (ESI). Является указателем источника. Применяется в строковых операциях. В строковых операциях связан с регистром сегмента данных DS.

Адрес источника равен 16 *DS+SI.

Регистр DI (EDI). Является указателем приёмника. В строковых операциях связан с дополнительным регистром сегмента данных ES.

Адрес приёмника равен 16* ES + DI.

Сегментные регистры

Каждый сегментный регистр используется для адресации определённого типа. Имеется четыре сегментных регистра: CS, DS, ES, SS. Микропроцессоры фирмы Intel, начиная с 80486, имеют два новых дополнительных сегментных регистра -FS и GS.

Регистр CS. Определяет сегмент кода- сегмент программы, содержащий выполняемые команды. Устанавливается при загрузке программы автоматически.

Регистр DS. Определяет сегмент данных или некоторую область памяти. Втроковых операциях связан с регистром источника SI. Команды обработки данных по умолчанию используют для адресации регистр DS. ПРи загрузке программы значение регистра DS устанавливается программистом.

Регистр ES. Определяет дополнительный сегмент данных и применяется в тех случаях, когда требуется обратиться к произвольному сегменту памяти. В строковых операциях связан с регистром приёмника DI. Инициализируется программистом.

Регистр SS. Регистр сегмента стека, связан с регистром SP. Содержит начальный адрес сегмента стека ( в то время как SP устанавливается на конец стека). Регистры SS и SP при загрузке программы устанавливаются автоматически.

Регистры состояния управления

В микропроцессоре присутствуют несколько регистров \, содержащих инфорацию о состоянии микропроцессора и программы, команды которой находятся в очереди команд. К Этим регистрам относятся счетчик команд IP (EIP), регистр флагов FL (EFL) и системные регистры.

Счетчик команд IP (EIP). Называется также командным указателем. Он связан с регистром сегмента кодов CS и содержит смещение команды, которая должна быть выполнена. При выполнении команды значение счётчика увеличивается за исключением тех случаев, когда команда относится к командам управления- перехода, цикла, вызова подпрограммы и возвращение из подпрограммы.

Регистр флагов FL (EFL). Содержит 16 (32) бит. Отдельные биты имеют определённое функциональное назначение и называются флагами. Их может быть три вида:

системные флаги- отражают текущее состояние компьютера в целом и чаще используются операционной системой, а не программами пользователя;

флаги состояния- изменяются после выполнения каждой команды;

флаги управления.

Способы адресации

Операнды могут адресоваться следующими способами:

Непосредственная адресация. Операнд находится в поле команды. Например, в командах

mov AX, 512

mov DX, offset mes

dnjhst jgthfylf ( 512 и offset mes) задаются непосредственно.

Регистровая адресация. Операнд находится в одном из оегистров. Например, оба операнда в команде

mov DS, AX

задаются с помощью регистрового способа адресации.

Косвенно-регистровая адресация. Адрес операнда находится в одном из регистров - SI, DI, BX. Например, команда

mov AX,[SI]

переписывает содержимое слова, смещение которого указано в регистре SI, в регистре AX. Второй операнд задан с помощью косвенно-регистрового метода адресации.

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

mov AL, db ; db- смещение байта

mov AX, dw; dw- смещение слова

mov EAX, dd ; dd-смещение двойного слова

Базовая адресация. Относительный адрес операнда равен сумме содержимого базового регистра (BP или BX) и смещения (8- или 16- разрядного).Например:

mov AX, ddd [BX]

mov AX, ddd [BP]

Индексная адресация. Относительный адрес операнда формируется путём сложения содержимого индексного регистр (SI или DI) и смещения( 8- или 16- разрядного). В частности, если второй операнд команды mov является индексным, то команда, как и в случае базовой адресации, транслируется как mov AX, xxxx [r]. Например:

mov AX, ddd [SI]

mov AX, ddd [DI]

Базово-индексная адресация. Относительный адрес операнда равен сумме значений базового регистра ( BX или BP) и индексного регистра (SI или DI). Этот способ реализуется при значении поля адреса 0,1 ,2 или 3. Например:

mov AX, [BX+SI]

mov AX, [BX+DI]

mov AX, [BP+SI]

mov AX, [Bp+DI]

Базово-индексная относительная адресация. К сумме значений базового и индексного регистра прибавляется смещение (8- или 16- разрядное). Например:

mov AX, add[BX+SI]

mov AX, add[BX+DI]

mov AX, add[BP+DI]

Дадим пару замечаний:

Если х - смещение, то операнды [x] и х транслируются одинаково. Например:

mov AX, [ddd]

mov AX, ddd

Недопустима команда

mov AX, [BX+x]

Вместо её можно применить комаду

mov AX, x[BX]

или

mov AX, [BX+offset x]

При непосредственном методе адресации не всегда ясно, чколько байт содержит операнд. В этом случае применяется модификатор ptr. Например:

mov byte ptr x, 255

mov byte ptr [DI+515],4

mov word ptr [DI+515],4

Логика и организация программы

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

Безусловный переход

jmp адрес

Эта команда передаёт управление команде , которая находится по указанному адресу. Адрес может быть указан с помощью смещения, состоящего :

из одного байта(short ptr);

из слова(near ptr);

из двойного слова( far ptr).

Команда прибавляет к счётчику команд IP указанное смещение или устанавливает IP равным указанному двойному слову.
При внутрисегментном переходе предполагается, что содержимое регистра CS не изменяется, а изменяется регистр IP.
Для межсегментного перехода адрес ( значение, на которое осуществляется переход) состоит из четырёх байт, два из которых составляют смещение, и два - значение сегментной составляющей адреса. Переход между сегментами или переход более чем на 127 байт называется дальним переходом.
Покажем на примере межсегментный переход:

code segment

assume CS:code

start:

jmp far ptr lab2

lab1 label far

mov AX, 4C00h

int 21h

code ends

code2 segment

assume CS: code2

lab2 label far

mov AH, 10h

int 16h

jmp far ptr lab1

code2 ends

end star

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

Команды условного перехода

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

jne lab1

управление передаётся на метку lab1 в том и только в том случае, когда флаг ZF равен 0. Если же ZF=1, то выполняется команда, следующая за командой перехода.

Таким образом, обычно флаги устанавливаются с помощью команды сравнения cmp, действия которой аналогично действию команды вычитания sub, за исключением того, что команда сmp не записывает результат вычитания в первый операнд.

Команды сравнения

Для того чтобы делать переходы на основании выполнения отношений равно, меньше, не меньше, больше, не больше и др., применяется команда cmp. (табл. 3)

Команда Отношения между операндами команды cmp или свойства результата операции Значение флагов
ja/jnbe Выше CF=0 и ZF=0
jae/jnb Выше или равно/не ниже/не перенос CF=0
jb/jnae/jc Ниже/перенос CF=1
jbe/jna Ниже или рано/не выше CF=1 или ZF=1
jcxz/jecxz CX=0/ECX=0 Не влияет на флаги
je/jz Равно/ноль ZF=1
jg/jnle Больше ZF=0 и SF= OF
jge/jnl Больше или равно/не меньше SF=OF
jl/jnge Меньше SF не равно OF
jle/jng Меньше или равно/не больше ZF=1 или SF не равно OF
jne/jnz Не равно/не ноль ZF=0
jno Не переполнение OF=0
jnp/jpo Не паритет/паритет нечётный PF=0
jns Не знак SF=0
jp/jpe Паритет/паритет чётный PF=1
jo Переполнение OF=1
js знак SF=1

Таблица 3. Отношения между операндами команды cmp.

Команды цикла

Для организации циклов применяется команда цикла loop метка и её разновидности.
Команда loop работает следующим образом:

1. Значеие регистра CX уменьшается на 1.

2. Если CX не равно 0, то управление передаётся на метку, иначе выполняется следующий за командой loop оператор.

Логические операции и команды сдвига

Логические операции используются для сброса и установки битов и для арифметических операций с кодами ASCII.

Команды логических операций and, or, xor, not, test обрабатывают байт или слово , в регистре или в памяти, и воздействуют на флаги CF, OF , а остальные флаги зависят от результата операции.
В командах:

and операнд1, операнд2; Поразрядное логические сложение (И)

or операнд1, операнд2; Поразрядное логическое сложение (ИЛИ)

xor операнд1, операнд2; Поразрядное сложение по модулю 2

not операнд1, операнд2; Поразрядное логическое НЕ

результат выполнения операции записывается в первый операнд.

Команда test действует подобно команде and кроме того, что результат выполнения поразрядного логического умножения не записывается на место первого операнда.

Действие команд сдвига показано ниже. Операндом команды сдвига является байт или слово.


Рисунок 2. Действия команд сдвига

Организация циклов

Команда loop позволяет организовать цикл, состоящие из небольшого количества команд. В общем случае в начале или внутри цикла проверяется некоторое условие, и если оно не выполнено, производится выход из цикла. В конце цикла ставится оператор перехода jmp на начало цикла.

Вызов подпрограмм

Перед тем как вызывается подпрограмма, её объявляют.

Например, call <имя подпрограммы>.

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

Алгоритм работы команды call:

1. Если вызов межсегментный, то значение CS запоминается в стеке и регистр CS устанавливается в значение, равное адресу сегмента подпрограммы.

2.Значение счётчика команд IP запоминается в стеке и регистр IP устанавливается в значение, равное смещению команд.

Команда возврата ret просто извлекает из стека значение регистра IP. Если возврат длинный, то применяется команда retf. В этом случае после извлечения IP производится извлечение CS. Команда может иметь операнд:
ret cnt; cnt- произвольная константа
После возврата из процедуры значение SP увеличивается на cnt.

Внешние подпрограммы

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

extrn имя:far

extrn имя:near

Структура COM- и EXE- программ. Размещение программы в памяти

Готовый для выполнения файл называется загрузочным модулем. Он может быть построе несколькими способами и в зависимости от способа построения имеет расширение exe или com.
Для выполнения подпрограммы пользователя операционная система размещает коды программ в свободной оперативной памяти в добавляет перед программой состоящий из 256 байт блок, который называется префиксом программного сегмента (PSP). После его размещения операционная система передаёт управление в точку входа этой программы.
Операционная система при этом выполняет следующие действия:

1. Определяет сегментный адрес префикса программного сегмента (PSP).

2. Создаёт два блока памяти- блок памяти для переменных среды и блок памяти для PSP и программы.

3. Помещает в блок памяти переменных среды путь, откуда была загружена программа.

4.Заполняет поля PSP.

Загрузочный модуль размещается в памяти следующим образом:

1. PSP (256 байт)

2. Код программы.

3. Данные программы.

4. Не инициализируемые данные.

EXE-файл загружается, начиная с адреса PSP:100h. В момент загрузки EXE-файла регистры CS, IP, SS и SP инициализируется значениями , указанными в заголовке.
Регистры DS и ES указывают на SPS. CS устанавливается на начало сегмента кодов.
COM-файл состоит из единственного сегмента. Образ COM-файла размещается начиная с адреса PSP:100h. Регистры СS и SS указывают на SPS, регистр SP- на конец сегмента SPS, значение регистра IP равно 100h.
Основное отличие формата COM от EXE заключается в том, что размер COM-программы не превышает 64-Кбайт и все данные, кода команд и область стека в ней размещаются в одном сегменте.

Команды пересылки и строковые операции

Рассмотрим команды пересылки данных. С их помощью можно выполнять операции пересылки, загрузки, сравнения, сканирования строк.
Для обработки строковых данных имеются пять команд:
movs- переписать один байт или одно слово из одной области памяти в другую;
lods- загрузить из памяти один байт или одно слово в регистр-аккумулятор;
stos-содержимое аккумулятора в память;
cmps-сравнить содержимое двух байт или двух слов , расположенных а памяти;
scas-сравнить содержимое аккумулятора в одним батом или с одним словом, расположенным в памяти.

Прерывания

В архитектуре процессоров 8086 предусмотрены особые случаи, когда процессор прекращает выполнение текущей программы и немедленно передаёт управление программе-обработчику, специально написанной для обработки подобных ситуаций. Такая программа-обработчик называется процедурой обработки прерывания.
Для того, чтобы процессор различал от какого устройства прошла команда прерывания, с каждым прерыванием связывают число из диапазона 00h-0FFh.
Используется команда : int номер, где номер - это номер прерывания в 16-ричной записи.
Прерывания могут быть как внешними, так и внутренними.
Внутренние возникают внутри микропроцессора во время вычислительной работы.
Они разделяются на два класса:
-программные прерывания ( int номер);
- исключительные ситуации, возникшие при выполнении команд.

Внешние прерывания называются маскируемыми. Эти прерывания можно запретить с помощью команды cli, обнуляющей флаг IF регистра флагов.
Обработка прерывания в реальном режиме проводится в три этапа:

1. Прекращается выполнение текущей программы.

2. В стеке запоминаются значения регистров FL, затем CS и IP, очищается флаг IF и управление передаётся по адресу из таблицы прерываний.

3. Выполняется процедура обработки прерывания и управление возвращается прерванной программе с помощью команды iret. Эта команда восстанавливает содержимое регистров IP,CS и FL.

Команда int n производит следующие действия:

1. Записывает в стек значение регистра FL.

2. Записывает в стек значение регистра CS.

3. Записывает в стек значение регистра IP.

4. Очищает бит IF.

5.Передаёт в регистра IP содержимое слова, имеющий адрес 4n.

6. Передаёт в регистр CS содержимое слова, имеющий адрес 4n+2.

Команда into генерирует прерывание 4, если значение флага OF =1, а противном случае никакие действия не выполняются.
Обработчик прерывания, или процедура обработки прерывания пишется как обычная подпрограмма.

Арифметические операции

Сложение и вычитание.

add- сложение операнда источника( правого операнда) с содержимым операнда-источника и записывает результат в операнд-приёмник sub- делает тоже самое, только она вычитает операнд-источник из операнда приёмника.

Увеличение и уменьшение.

inc- прибавляет 1 к регистру или переменной.
dec- вычитает 1 из регистра или переменной.

Умножение и деление.

mul-перемножает беззнаковые сомножители, всегда сохраняя 16-битовое произведение в регистре АХ . Заметим что в этой операции требуется указывать только один операнд,- другой сомножитель всегда хранится в регистре AL.
imul- делает тоже самое, только перемножает числа со знаком.
div-всегда записывает частное в регистр AL,а остаток - в AH. В беззнаковом делении делимое должно быть записано в АХ.

Команды lea и xlat

Эти команды довольно часто используются при занесении в переменную текстовой строки(пароля) с целью дальнейшей проверки на правильность.

Загрузка исполнительного адреса ( команда lea)

Синтаксис: lea приёмник, источник

Она присваивает значение смещения( offset) операнда источника( а не его значение) операнду приёмник. Операнд источник должен быть ссылкой на ячейку памяти, а в качестве операнда приёмник может выступать любой 16-битный регистр, кроме сегментных.

Кодирование по таблице ( команда xlat)

Синтаксис: xlat операнд

Она переводит байт согласно таблице преобразований. Указатель 256-байтовой таблицы преобразований находится в регистре BX. Байт, который нужно перевести, находится в регистре AL. После выполнения команды xlat байт в AL заменяется на байт, смещённый на AL байтов от начала таблицы преобразований.
Этак команда довольно часто используется при шифровании методом подстановки.
Операнд операнд является не обязательным, поскольку указатель таблицы должен быть загружён в регистр BX ещё до начала выполнения команды.

Основной способ ввода данных.

В ассемблере символы с клавиатуры принимаются с помощью функции 1прерывания 21h. Можно также вводить символ с клавиатуры с помощью прерывания BIOS. Символ вводится в регистр AL с помощью вызова функции 0 прерывания 16h. Строка символов с клавиатуры вводится с помощью функции 0Аh прерывания 21h. вод строки заканчивается нажатием клавиши <Enter>.

Порядок байт (Endianness)

Endianness (порядок байт) это способ представления чисел в памяти.

Конвертирование.

Инструкция BSWAP может использоваться для конвертирования.

Сетевые пакеты TCP/IP используют соглашение big-endian, вот почему программа, работающая на little-endian архитектуре должна конвертировать значения.

Обычно, используются функции htonl() и htons() .

Порядок байт big-endian в среде TCP/IP также называется, «network byte order», а порядок байт на компьютере «host byte order». На архитектуре Intel x86, и других little-endian архитектурах, «host byte order» это little-endian, а вот на IBM POWER это может быть big-endian, так что на последней, htonl() и htons() не меняют порядок байт.

Виды памяти.

Есть три основных типа памяти:

• Глобальная память AKA «static memory allocation». Нет нужды явно выделять, выделение происходит просто при объявлении переменных/массивов глобально. Это глобальные переменные расположенные в сегменте данных или констант. Доступны глобально (поэтому считаются анти-паттерном). Не удобны для буферов/массивов, потому что должны иметь фиксированный размер. Переполнения буфера, случающиеся здесь, обычно перезаписывают переменные или буферы расположенные рядом в памяти.

• Стек AKA «allocate on stack», «выделить память в/на стеке». Выделение происходит просто при объявлении переменных/массивов локально в функции. Обычно это локальные для функции переменные. Иногда эти локальные переменные также доступны и для нисходящих функций (callee-функциям, если функция-caller передает указа-

тель на переменную в функцию-callee). Выделение и освобождение очень быстрое, достаточно просто сдвига SP. Но также не удобно для буферов/массивов, потому что размер буфера фиксирован, если только не используется alloca() (или массив с переменной длиной). Переполнение буфера обычно перезаписывает важные структуры стека.

• Куча (heap) AKA «dynamic memory allocation», «выделить память в куче». Выделение происходит при помощи вызова malloc()/free() или new/delete в Си++. Самый удобный метод: размер блока может быть задан во время исполнения. Изменение размера возможно (при помощи realloc() ), но может быть медленным. Это самый медленный метод выделения памяти: аллокатор памяти должен поддерживать и обновлять все управляющие структуры во время выделения и освобождения. Переполнение буфера обычно перезаписывает все эти структуры. Выделения в куче также ведут к проблеме утечек памяти: каждый выделенный блок должен быть явно освобожден, но кто-то может забыть об этом, или делать это неправильно. Еще одна проблема — это «использовать после освобождения» — использовать блок памяти после того как free() был вызван на нем, это тоже очень опасно.

Предсказатели переходов.

Механизм предсказания переходов выполняет две основные функции — предсказание программного адреса инструкции, на которую производится переход (для всех инструкций перехода), и предск

Наши рекомендации