Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
metod_lab_ps_2_SPO_ch2_lab_rab (1).doc
Скачиваний:
1
Добавлен:
01.04.2025
Размер:
342 Кб
Скачать
☆

1.3 Самостійна підготовка

Підготуйте бланк звіту. Проробіть рекомендовану літературу [1].

При підготовці зверніть увагу на такі питання:

  • загальна структура РЕ-файла;

  • структура основного заголовку РЕ- файла;

  • структура додаткового заголовка РЕ – файла;

  • основні секції РЕ – файла.

Уважно проаналізуйте текст консольної Windows програми read_pe.asm (додаток), за допомогою якої в отладчику td32.exe можна проаналізувати значення усіх полів заголовків виконуваного файла, ім’я якого задається в сегменті даних.

1.4 Порядок виконання роботи

  • В будь якому текстовому редакторі наберіть текст модуля read_pe.asm, який наведено у лістінгу 1.1 і збережіть його на диску.

  • Сформуйте модуль, що виконується (файл read_pe.exe).

  • Перевірте роботу програми read_pe.exe.

  • У відладчику настройте дамп пам’яті на буфер з началом досліджуваного виконуваного модуля. Користуючись засобами відладчика (зокрема, вікном Variables) дослідить зміст основних полів заголовку РЕ – файла.

  • Занесить в звіт отриману інформацію згідно свого варіанту.

2 Планування та створення потоків

в середовищі Win32

2.1 Мета роботи

  • Вивчення основ створення багатопоточних програм.

  • Засвоєння особливостей створення, закриття та керування роботою дочірніх потоків.

  • Засвоєння засобів створення та керування потоками, що надаються операційною системою Windows.

2.2 Основні відомості

Потік (Thread) визначає послідовність виконання коду в процесі. При ініціалізації процесу система завжди створює первинний потік. Більшість процесів обходиться одним первинним потоком. Але ж процеси можуть створювати додаткові потоки, що дозволяє їм ефективніше виконувати свою роботу.

Кожен потік починає свою роботу з деякої вхідної функції. На мові асемблера це оформлюється у такий спосіб:

TreadProc proc

arg pvParam:DWORD

…

ret

ThreadProc endp

Функція потоку може виконувати будь які завдання. Раніше або пізніше вона закінчує свою роботу та повертає керування. У цей момент потік зупиняється, пам’ять, що була відведена під його стек, звільняється, а лічильник користувачів його об’єкта ядра “потік” зменшується на 1. Коли лічильник обнулюється, цей об’єкт ядра руйнується системою. Але цей об’єкт ядра може жити значно довше, ніж потік, що зіставлений з ним.

При розробці функції потоку необхідно звертати увагу на такі основні питання:

  • Функція потоку може мати будь яке ім’я. Але, якщо у програмі є декілька функцій потоків, їм треба присвоювати різні імена, інакше компілятор або компанувальник вирішать, що створюються декілька реалізацій однієї і тієї ж функції.

  • Функції потоку передається один єдиний параметр, сенс якого визначається програмістом, а не операційною системою.

  • Функція потоку може повертати значення (у регістрі еах), яке використовується як код завершення потоку.

  • Функції потоків за мірою можливості повинні обходитися своїми параметрами та локальними змінними. Так як до статичної або глобальної змінної можуть одночасно звернутися декілька потоків, є ризик зіпсувати її вміст. Але ж параметри та локальні змінні створюються у стеку потоку, тому вони у значно меншому ступені піддані впливу інших потоків.

Для створення потоків у середовищі Win32 призначена функція API CreateThread.

При кожному виклику цієї функції система створює об’єкт ядра “потік”. Це не сам потік, а компактна структура даних, що використовується операційною системою для керування потоком та зберігає статистичну інформацію про потік.

Система виділяє пам’ять під стек потоку з адресного простору процесу. Новий потік виконується у контексті того ж процесу, що й батьківський потік. Тому він отримує доступ до всіх описувачів об’єктів ядра, всієї пам’яті і стеків усіх потоків процесу. За рахунок цього потоки у рамках одного процесу можуть легко взаємодіяти один з одним.

Функції CreateThread передаються 6 параметрів:

  • Параметр psa є покажчиком на структуру типу SECURITY_ATTRIBUTES. Якщо достатньо, щоб об’єкту ядра “потік” були присвоєні атрибути захисту за умовчанням (що буває частіше за всього), то в цьому параметрі передають значення NULL. А для того, щоб дочірні процеси змогли успадкувати описувач цього об’єкту, треба визначити структуру типу SECURITY_ATTRIBUTES та ініціалізувати її елемент hinheritHandle значенням TRUE.

  • Параметр cbStack визначає, яку частину адресного простору потік зможе використувати під свій стек. Якщо в цьому параметрі передається нульове значення, стек для нового потоку створюється на основі інформації, вбудованої компанувальником у ехе-файл.

  • Параметр pfnStartAddr визначає адресу функції потоку, з якої буде починати роботу потік, що створюється.

  • Параметр pvParam ідентичний однойменному параметру функції потоку. Таким чином, цей параметр дозволяє передавати функції потоку яке-небудь ініціализуюче значення. Воно може бути або просто числовим значенням, або покажчиком на структуру даних з додатковою інформацією.

  • Параметр fdwCreate визначає додаткові прапори, що керують створенням потоку. Він приймає одне з двох значень: 0 (виконання потоку починається миттєве) або CREATE_SUSPENDED. В останньому випадку система створює потік, ініціализує його та призупиняє до наступних вказівок.

  • Параметр pdwThreadID — це адреса змінної типу DWORD, у якій функція звертає ідентифікатор, зіставлений системою новому потоку.

  • Функцію потоку слід проектувати так, щоб потік завершувався тільки після того, як вона вертає керування. Це єдиний спосіб, який гарантує коректне очищення усіх ресурсів, що належать потоку.

Більш докладну інформацію про планування, створення та закриття потоків можна отримати, наприклад в [1].