Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
СПро - методичка.pdf
Скачиваний:
32
Добавлен:
16.03.2016
Размер:
847.14 Кб
Скачать

8.5. Контрольные вопросы и задания

1.Каково назначение и область применения языка Ассемблер?

2.Какие группы регистров процессора Вы знаете?

3.Каково назначение и область применения регистров общего назначения?

4.Каково назначение и область применения управляющих регистров?

5.Каково назначение и область применения сегментных регистров?

6.Для чего используется регистр флагов?

7.Приведите особенности применения арифметических команд Ассемблера.

8.Приведите особенности применения логических команд Ассемблера.

9.Приведите особенности применения команд управления.

9 ИСПОЛЬЗОВАНИЕ ЯЗЫКА АССЕМБЛЕР

9.1. Цель работы

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

9.2. Указания по подготовке к выполнению лабораторной работы

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

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

9.3. Обзор темы работы

Яык ассемблера — это символическое представление машинного языка. Все процессы в машине на самом низком, аппаратном уровне приводятся в действие только командами (инструкциями) машинного языка. Отсюда понятно, что, несмотря на общее название, язык ассемблера для каждого типа компьютера свой. Это касается и внешнего вида программ, написанных на ассемблере, и идей, отражением которых этот язык является.

По-настоящему решить проблемы, связанные с аппаратурой (или даже, более того, зависящие от аппаратуры как, к примеру, повышение быстродействия программы), невозможно без знания ассемблера.

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

— машинного. А теперь представим, что у такого пользователя возникла не-

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

9.4. Задание на лабораторную работу

Вариант 1.

На языке Ассемблер написать функции работы со строками символов: определение размера строки, копирование строк, добавление строк, сравнение строк. Сравнить работу функций co стандартными функциями С++.

Вариант 2.

На языке Ассемблер написать функции работы с матрицами: транспонирование матриц, суммирование двух матриц, умножение двух матриц. Использовать функции из основной программы на С++.

Вариант 3.

На языке Ассемблер написать функции вычисления: суммы чисел от 1до N, чисел Фибоначчи, факториала. Использовать функции из основной программы на С++.

Вариант 4.

На языке Ассемблер написать функции обработка массивов целых чисел: поиск минимума/максимума, сортировка по возрастанию/убыванию, определение среднего арифметического. Использовать функции из основной программы на С++.

Вариант 5.

На языке Ассемблер написать функции статистической обработки массива строк: определение количества символов в каждой строке, определение числа слов в каждой строке, определение количества гласных и согласных букв в тексте. Использовать функции из основной программы на С++.

Вариант 6.

На языке Ассемблер написать функции кодирования текстовой строки методами подстановки и смещения таблицы кодов символов. Использовать функции из основной программы на С++.

Вариант 7.

На языке Ассемблер написать следующие функции работы с матрицами: определение максимального/минимального элемента матрицы (с выводом на экран номера столбца и строки, где этот элемент находиться), среднего арифметического значения элементов строк и столбцов. Использовать функции из основной программы на С++.

Вариант 8.

На языке Ассемблер написать следующие функции: перевод числа из десятичной системы счисления в двоичную (на входе – целое десятичное число, на выходе – массив целых чисел, содержащий отображение в двоичный формат), определение четности или нечетности целого числа, определение принадлежности числа к простым числам. Использовать функции из основной программы на С++.

Вариант 9.

На языке Ассемблер написать следующие функции обработки массива целых чисел: определения количества положительных и отрицательных чисел, суммы чисел массива, среднего арифметического значения, количества чисел, больших чем среднее арифметическое. Использовать функции из основной программы на С++.

Вариант 10.

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

9.5.Контрольные вопросы и задания

1.На какие основные группы делится система команд языка Ассемблер?

2.Какие методы адресации используются в современных процессорах?

3.В чем заключается косвенных метод адресации? Какие регистры процессора могут использоваться при этом?

4.В чем заключается прямой метод адресации?

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

6.Какие команды пересылки данных Вы знаете?

7.Какие арифметические и логические команды Вы знаете?

8.В чем заключаются особенности выполнения команд умножения и деления?

10ИЗМЕНЕНИЕ ФУНКЦИОНАЛЬНОСТИ WINDOWS-ПРИЛЖЕНИИЙ

10.1.Цель работы

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

10.2. Указания по подготовке к выполнению лабораторной работы

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

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

10.3. Обзор темы работы

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

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

ВWindows 98 процессы фактически совместно используют 2 Гб адресного пространства (от 0x80000000 до 0xFFFFFFFF). На этот регион отображаются только системные компоненты и файлы, проецируемые в память.

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

Вот ситуации, в которых требуется прорыв за границы процессов и доступ к адресному пространству другого процесса:

создание подкласса окна, порожденного другим процессом;

получение информации для отладки (например, чтобы определить, какие DLL используются другим процессом);

установка ловушек (hooks) в других процессах.

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

ив 16-разрядной Windows, Microsoft пришлось создать механизм, позволяю-

щий внедрять DLL в адресное пространство другого процесса Рассмотрим его на примере

Процесс А (вроде утилиты Spy++) устанавливает ловушку WH_GETMESSAGE и наблюдает за сообщениями, которые обрабатываются окнами в системе. Ловушка устанавливается вызовом SetWindowsHookEx

HHOOK hHook = SetWindowsHookEx(WH_GETMESSAGE, GetMbgProc, hiribtDll, 0);

Аргумент WH_GETMESSAGE определяет тип ловушки, а параметр GetMsgProc — адрес функции (в адресном пространстве Вашего процесса), которую система должна вызывать всякий раз, когда окно собирается обработать сообщение Параметр hinstDll идентифицирует DLL, содержащую функцию GetMsgProc В Windows значение htnstDll для DLL фактически задаст адрес в виртуальной памяти, по которому DLL спроецирована на адресное пространство процесса. И, наконец, последний аргумент, 0, указывает поток, для которого предназначена ловушка. Поток может вызвать SеtWindowsHookEx и передать ей идентификатор другого потока в системе Передавая 0, мы сообщаем системе, что ставим ловушку для всех существующих в ней GUI-потоков

Теперь посмотрим, как все это действует:

1.Поток процесса В собирается направить сообщение какому-либо окну.

2.Система проверяет, не установлена ли для данного потока ловушка

WH_GETMESSAGE.

3.Затем выясняет, спроецирована ли DLL, содержащая функцию GctMsgProc, на адресное пространство процесса В

4.Если указанная DLL еще не спроецирована, система отображает ее на адресное пространство процесса В и увеличивает счетчик блокировок (lock count) проекции DLL в процессе В на 1

5.Система проверяет, не совпадают ли значения hinstDll этой DLL, относящиеся к процессам А и В Если hinstD!l в обоих процессах одинаковы, то и адрес GetMsgProc в этих процессах тоже одинаков Тогда система может просто вызвать GetMsgProc в адресном пространстве процесса А. Если же hinstDll различны, система определяет адрес функции GetMsgProc в адресном пространстве процесса В по формуле:

GetMsgProc В = histDll В + (GetMsgProc А – hinstDll А)

Вычитая hinstDll из GetMsgProcA, Вы получаете смещение (в байтах) адреса функции GetMsgProc. Добавляя это смещение к hinstDll В, Вы получаете адрес GetMsgProc, соответствующий проекции DLL в адресном пространстве процесса В

6.Счетчик блокировок проекции DLL в процессе В увеличивается на 1.

7.Вызывается GetMsgProc в адресном пространстве процесса В.

8.После возврата из GetMsgProc счетчик блокировок проекции DLL в адресном пространстве процесса В уменьшается на 1.

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

Итак, чтобы создать подкласс окна, сформированного потоком другого процесса, можно сначала установить ловушку WH_GETMESSAGE для этого потока, а затем — когда будет вызвана функция GetMsgProc – обратиться к SetWindowLongPtr и создать подкласс Разумеется, процедура подкласса должна быть в той же DLL, что и GetMsgProc.

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

BOOL UnhookWindowsHookEx(HHOOK hHook);

Когда поток обращается к этой функции, система просматривает внутренний список процессов, в которые ей пришлось внедрить данную DLL, и уменьшает счетчик ее блокировок на 1 Как только этот счетчик обнуляется, DLL автоматически выгружается. Вспомните: система увеличивает его непосредственно перед вызовом GetMsgProc. Это позволяет избежать нарушения доступа к памяти Если бы счетчик не увеличивался, то другой поток мог бы вызвать UnhookWindowsHookEx в тот момент, когда поток процесса В пытается выполнить код GetMsgProc,

Все это означает, что нельзя создать подкласс окна и тут же убрать ловушку — она должна действовать в течение всей жизни подкласса.

10.4. Задание на лабораторную работу

Вариант 1.

Установить ловушку на сообщения, поступающие от клавиатуры для программы «Блокнот». Ловушка должна преобразовывать символьные сообщения, подменяя кода нажимаемых клавиш таким образом: «a->b», «b->c», «d->f», … , «z->a». Предусмотреть возможность снятия ловушки.

Вариант 2.

Установить ловушку на сообщения, поступающие от мыши для программы «Paint». Ловушка должна преобразовывать сообщения, подменяя кода сообщений таким образом: «WM_LBUTTONDOWN<->

WM_RBUTTONDOWN», «WM_LBUTTONUP<-> WM_RBUTTONUP». Во время прихода сообщения WM_MOUSEMOVE выводить координаты мыши на экран. Предусмотреть возможность снятия ловушки.

Вариант 3.

Установить ловушку на сообщения, поступающие во все программы. В отдельном окне выводить информацию о поступающих сообщениях: имя окна, в которое поступает сообщение, тип сообщения (в виде цифрового идентификатора и в виде символьного для нескольких наиболее распространенных сообщений, например, WM_PAINT, WM_LBUTTONDOWN, … ). Предусмотреть возможность снятия ловушки.

Вариант 4.

Установить ловушку на сообщения, поступающие от клавиатуры для программы «Блокнот». Ловушка должна преобразовывать аппаратные сообщения, подменяя виртуальные кода нажимаемых клавиш таким образом: «left<- >right», «up<->down», «backspace<->del». Предусмотреть возможность снятия ловушки.

Вариант 5.

Написать программу, рисующую прямоугольник в клиентской области окна. Написать другую программу, устанавливающую ловушку на сообщения, поступающие первой программе. Организовать перехват сообщения WM_PAINT, подменяя рисование прямоугольника эллипсом. Предусмотреть возможность снятия ловушки.

Вариант 6.

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

Вариант 7.

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

Вариант 8.

Установить ловушку на сообщения, поступающие от клавиатуры для программы «Блокнот». Ловушка должна по нажатию определенной комбинации клавиш выводить в окно «блокнота» строку символов, содержащую фамилии студентов, выполнивших задание. Нажимая другие комбинации клавиш,