Управління електроживленням в Windows. Управління електроживленням в Windows мають доступ до осередків пам'яті; драйвер не може маніпулювати фізичної пам'яттю безпосередньо, проте може отримати віртуальний адреса для будь-якого фізичного і маніпулювати ним

Компанія Microsoft в операційній системі Windows 10 приділяє велику увагу безпеці. Одним з важливих елементів системи є "Захисник Windows", але здатний він впоратися не з усіма загрозами. Зокрема, останнім часом набирають особливу поширеність віруси Ransomware, найвідомішими реінкарнації яких є шкідливі програми Petya і. Компанія Microsoft впровадила в Windows 10 функції ізоляції ядра і цілісність пам'яті, які спрямовані на боротьбу з вірусами Ransomware. За замовчуванням вони відключені.

Зміст:

Що таке ізоляція ядра і цілісність пам'яті

ізоляція ядра - це процес додатковий захисту, який забезпечується шляхом огородження процесів комп'ютера від операційної системи і пристрої. За рахунок цих процесів вдається уникнути підриву роботи операційної системи при попаданні на комп'ютер вірусів.

цілісність пам'яті - це супутня ізоляції ядра захисна функція, яка спрямована на обмеження доступу з боку невідомих потенційно небезпечних програм до процесів з високим рівнем безпеки.

Важливо: Функція ізоляції ядра може працювати тільки в тому випадку, якщо є достатні для цього умови з боку апаратних даних комп'ютера. В налаштуваннях BIOS повинна бути активна технологія віртуалізації, за рахунок якої комп'ютер під управлінням Windows 10 може запускати різні додатки в віртуальному контейнері, обмежуючи для них доступ від ключових компонентів системи.

Як включити ізоляцію ядра і цілісність пам'яті

Параметри операційної системи Windows 10 дозволяють управляти функціями безпеки на комп'ютері в повній мірі. Через настройки Windows 10 можна включити ізоляцію ядра і цілісність пам'яті наступним чином:


Як зазначалося вище, якщо апаратна складова комп'ютера не підтримує можливість віртуалізації, ця функція не буде працювати. При включенні користувач побачить в нижньому правому куті повідомлення "Неможливо забезпечити цілісність пам'яті. Можлива несумісність ". Якщо це повідомлення з'явилося, рекомендується перейти в BIOS і подивитися чи включена функція Secure Boot (Boot Mode).

Як відключити ізоляцію ядра і цілісність пам'яті

Нові функції в операційній системі, які серйозно впливають на її роботу, завжди ризикують стати причиною виникнення проблем при роботі комп'ютера. Не виняток і функція ізоляції ядра. Користувачі, які вже її випробували, відзначають на форумах Microsoft, що стикаються з проблемами при запуску ряду ігор і програм. Єдиний спосіб, як вирішити дану проблему, це відключити функцію ізоляції ядра і цілісність пам'яті. Можливо, в майбутніх оновленнях розробники програми або Microsoft поправить дану несумісність.

Є 3 способи, як відключити ізоляцію ядра і цілісність пам'яті:


Диспетчер електроживлення (power manager) очей не зводить з показників використання електроенергії по всій системі. Історично управління споживанням енергії складалося з відключення монітора і зупинки обертання дисководів. Але ця проблема швидко стає все більш складною - через вимоги до збільшення тривалості роботи ноутбуків від батарей, а також міркувань економії енергії на настільних комп'ютерах (які залишають постійно включеними) і високу вартість споживаної серверними фермами електроенергії.

Нові засоби управління електроживленням включають зменшення споживання енергії компонентами, коли система не використовується, для цього окремі пристрої переключаються в стан резервування або навіть повністю відключаються (за допомогою вимикача живлення). Мультипроцесорні системи відключають окремі процесори, коли вони не потрібні, і навіть можуть зменшувати тактову частоту процесорів (для зменшення енергоспоживання). Коли процесор не діє, споживання ним енергії також зменшується, оскільки йому не потрібно робити нічого, крім очікування виникнення переривання.

Windows підтримує спеціальний режим вимкнення під назвою гібернація (hybernation), при якому виконується копіювання всієї фізичної пам'яті на диск, а потім споживання енергії знижується до мінімального (в стані глибокого сну ноутбуки можуть працювати тижнями), при цьому батарея розряджається мінімально. Оскільки все стан пам'яті записано на диск, то ви можете навіть замінити батарею ноутбука (поки він знаходиться в сплячому). Коли система відновлює свою роботу, виходячи з глибокого сну, вона відновлює збережений стан пам'яті (і повторно ініціалізує пристрої). Це призводить комп'ютер в той же самий стан, в якому він був перед глибокого сну (без необхідності виконувати повторно реєстрацію і запускати всі програми і служби, які виконувалися. Windows намагається оптимізувати цей процес, ігноруючи немодифіковані сторінки (мають резервування на диску), і стискає інші сторінки пам'яті для зниження необхідного обсягу введення-виведення. Алгоритм глибокого сну передбачає автоматичну балансування пропускної здатності системи вводу-виводу і процесора. Щоб при більш високої пропускної здатності процесора знизити потребу в пропускної здатності системи вводу-виводу, використовується більш ресурсномістке, але при цьому більш ефективне стиснення даних. Достатня пропускна здатність системи введення-виведення дозволяє уникнути стиснення при переході в режим гібернації. при використанні мультипроцессоров останнього покоління вхід в стан глибокого сну і вихід з нього можуть становити всього кілька секунд, навіть якщо оперативна пам & ть системи має великий обсяг.

Альтернатива глибокого сну - стан очікування (standby mode), при якому диспетчер електроживлення переводить всю систему на нижчу стан споживання енергії (використовується рівно стільки енергії, скільки потрібно для регенерації стану динамічної пам'яті). Оскільки пам'ять не потрібно копіювати на диск, то перехід в цей стан на деяких системах здійснюється швидше, ніж гібернація.

Незважаючи на доступність глибокого сну і стану очікування, багато користувачів не позбулися звички вимикати свій персональний комп'ютер після закінчення роботи.

Гибернация використовується в Windows для здійснення псевдовиключенія запуску, званого HiberBoot, яке здійснюється набагато швидше звичайного вимикання і запуску. Коли користувач дає системі команду на вимикання, HiberBoot виводить користувача з системи, а потім переводить її в стан глибокого сну в тій точці, з якої можна буде знову нормально увійти в систему. Пізніше, коли користувач знову включить систему, HiberBoot відновить роботу системи з точки входу в неї користувача. Для користувача все це схоже на дуже швидке вимкнення, оскільки більшість кроків ініціалізації системи пропускається. Зрозуміло, іноді систему потрібно вимикати по-справжньому, щоб усунути проблеми або встановити оновлення ядра. Якщо система отримує команду на перезапуск, а не на виключення, вона переносить даний вимикання і виконує звичайну завантаження.

Очікується, що обчислювальні пристрої на телефонах і планшетних комп'ютерах, а також на нових поколіннях ноутбуків завжди будуть споживати невелику кількість електроенергії. Щоб забезпечити такий режим, в сучасній Windows реалізована спеціальна версія управління електроживленням, яка називається CS (connected standby - очікування в режимі підключення). CS можлива на системах зі спеціальним обладнанням підключення до мережі, здатним відстежувати трафік в невеликому наборі підключень, використовуючи набагато менше енергії, ніж при роботі центрального процесора. Виходить, що CS-система завжди включена, вихід з CS здійснюється відразу ж, як тільки користувач включив екран. Очікування в режимі підключення відрізняється від звичайного режиму очікування, тому що CS-система буде також виходити з очікування, коли отримає пакет з відслідковується підключення. Після того як батарея починає сідати, CS-система переходить в стан глибокого сну, щоб уникнути повного розрядження акумулятора та можливої \u200b\u200bвтрати призначених для користувача даних.

Досягнення продожітельность роботи батареї вимагає не тільки як можна більш частого вимикання процесора. Важливо також якомога довше утримувати процесор в вимкненому стані. Мережеве обладнання CS-системи дозволяє Процесори залишатися вимкненими до надходження даних, але повторне включення процесора може бути викликане й іншими подіями. Засновані на NT драйвери пристроїв Windows, системні служби і самі додатки часто запускаються без особливої \u200b\u200bпричини, тільки для того, щоб перевірити стан справ. Подібна активність опитування зазвичай заснована на установках таймерів на періодичний запуск коду в системі або додатку. Опитування, заснований на сигналах таймера, може внести сум'яття в події, що включають процесор. Щоб уникнути цього в сучасній Windows від таких таймерів потрібно вказати параметр похибки, що дозволяє операційній системі об'єднувати події таймера і скорочувати кількість окремих підстав для включення процесора. У Windows також оформляються умови, при яких додаток, що не знаходиться в стадії активного виконання, може виконувати код у фоновому режимі. Операції, подібні перевірки оновлень або освіження вмісту, не можуть виконуватися тільки за запитом запуску після закінчення часу таймера. Додаток має підкорятися операційній системі в питаннях подібної фонової активності. Наприклад, перевірка на наявність оновлень повинна відбуватися тільки один раз в день або наступного разу, коли на пристрої буде відбуватися заряд батареї. Набір системних посередників надає різні умови, які можуть використовуватися для обмежень на виконання фонової активності. Якщо фонової задачі потрібні доступ до дешевої мережі або призначені для користувача повноваження, посередники не стануть виконувати завдання, поки не виникнуть необхідні умови.

Сьогодні багато додатків реалізуються як з локальним кодом, так і зі службами, що знаходяться в хмарі. Windows надає службу повідомлень Windows (Windows Notification Service (WNS)), що дозволяє стороннім службам проштовхувати повідомлення в пристрій Windows в CS, не вимагаючи від мережевого обладнання CS спеціально прислухатися до пакетів від сторонніх серверів. WNS-повідомлення можуть сповіщати про критичних за часом події, таких як надходження текстового повідомлення або виклику по VoIP. При надходженні WNS-пакета процесор повинен буде включитися для його обробки, але мережеве обладнання CS має можливість розрізняти трафік різних підключень, що означає, що процесор не повинен включатися у відповідь на кожен довільний пакет, що надходить з мережевого інтерфейсу.

У моєму основному ноутбуці різні проблеми з електроживленням виникають часто, що можна пояснити роботою в інсайдерських збірках. Однак і в стабільній версії 1 803 я помітив, що моя система перестала йти в сон. При цьому монітор вимикався через вказаний проміжок часу, що натякало на правильне визначення системою стану бездіяльності.

Я виставив маленький період переходу в сон, 1-2 хвилини і приступив до діагностики.

Перевірка запитів до підсистеми живлення від додатків і драйверів

Насамперед треба дивитися в powercfg, Що утримує ОС від переходу в сон. Процеси і драйвери, які звертаються до підсистеми електроживлення, можна побачити в командному рядку від імені адміністратора:

Powercfg -requests

Відразу видно, що запит до SYSTEM йде від DRIVER - в даному випадку, Realtek використовує аудиопоток.

У списку також може бути присутнім WebRTC від Chrome, а відразу після перезапуску системи там можна побачити запити оптимізації завантаження, індекс пошуку, але вони швидко зникають. Можна внести процес або драйвер в список виключень, і він не буде перешкоджати відходу в сон.

Powercfg -requestsoverride DRIVER "Realtek High Definition Audio (HDAUDIO \\ FUNC_01 & VEN_10EC & DEV_0269 & SUBSYS_17AA2204 & REV_1002 \\ 4 & d00657 & 0 & 0001)" SYSTEM

Команда читається як «ігнорувати запит від DRIVER [повне ім'я драйвера] до SYSTEM».

Список винятків зберігається в розділі реєстру

HKEY_LOCAL_MACHINE \\ SYSTEM \\ CurrentControlSet \\ Control \\ Power \\ PowerRequestOverride

і виводиться командою

Powercfg -requestsoverride

Я перезавантажився для вірності, але система відмовлялася засипати. Перевіривши виключення і список запитів, я виявив, що драйвер Realtek продовжував використовувати аудиопоток, хоча був внесений в виключення.

Я потанцювати трошки з бубном навколо винятків, але успіху не добився. Швидке гугленіе підтвердило, що в деяких випадках вони не спрацьовують. Це типово для legacy запитів, але тут був інший випадок, і я не перший, хто з цим зіткнувся.

У підсумку я видалив Realtek зі списку. Можна видаляти записи в редакторі реєстру або консолі. Команда майже така ж, як при додаванні, просто не вказується куди йде запит, тобто в даному випадку в кінці команди немає SYSTEM:

Powercfg -requestsoverride DRIVER "Realtek High Definition Audio (HDAUDIO \\ FUNC_01 & VEN_10EC & DEV_0269 & SUBSYS_17AA2204 & REV_1002 \\ 4 & d00657 & 0 & 0001)"

Ми підемо іншим шляхом

Обчислення процесу, що використовує підсистему звуку

Відомо, що чорними справами займається драйвер Realtek. Очевидно, він завантажується при старті системи, тому ім'я файлу нескладно з'ясувати за допомогою Autoruns.

Три записи відносяться до двох файлів, один з яких - панель управління, судячи з імені. Тому об'єктом інтересу став ravbg64.exe.

Драйвери режиму ядра: Частина 1: Основні поняття - Архів WASM.RU

огляд архітектури

Внутрішній світ Windows 2000 розділений на дві частини з чітко визначеними кордонами, як в плані адресного простору, так і в плані прав і обов'язків коду в цьому адресному просторі виконується.

З поділом адресного простору все напрочуд просто. Всі чотири, доступного в 32-х розрядної архітектури, гігабайти розділені на дві рівні частини (4GT RAM Tuning і Physical Address Extension я опускаю як зкзотіческіе). Нижня половина віддана процесам користувацького режиму, верхня належить ядру.

З поділом прав і обов'язків трохи складніше.

До призначеним для користувача належать такі процеси:

  • Процеси підтримки системи (System Support Processes) - наприклад, процес входу в систему Winlogon (реалізований в \\% SystemRoot% \\ System32 \\ Winlogon.exe);
  • Процеси сервісів (Service Processes) - наприклад, спулер;
  • Призначені для користувача програми (User Applications) - бувають п'яти типів: Win32, Windows 3.1, MS-DOS, POSIX і OS / 2;
  • Підсистеми оточення (Environment Subsystems) - підтримується три підсистеми оточення: Win32 (реалізована в \\% SystemRoot% \\ System32 \\ Csrss.exe), POSIX (реалізована в \\% SystemRoot% \\ System32 \\ Psxss.exe), OS / 2 (реалізована в \\% SystemRoot% \\ System32 \\ os2ss.exe).

Ядро складається з наступних компонентів:

    Виконавча система (Executive) - управління пам'яттю, процесами і потоками та ін .;
  • Ядро (Kernel) - планування потоків, диспетчеризація переривань і виключень і ін. (Реалізовано в \\% SystemRoot% \\ System32 \\ Ntoskrnl.exe);
  • Драйвери пристроїв (Device Drivers) - драйвери апаратних пристроїв, мережеві драйвери, драйвери файлових систем;
  • Рівень абстрагування від устаткування (Hardware Abstraction Layer, HAL) - ізолює три перерахованих вище компонента від відмінностей між апаратними архітектурами (реалізований в \\% SystemRoot% \\ System32 \\ Hal.dll);
  • Підсистема підтримки вікон і графіки (Windowing And Graphics System) - функції графічного інтерфейсу користувача (Graphic User Interface, GUI) (реалізована в \\% SystemRoot% \\ System32 \\ Win32k.sys).

Мал. 1-1. Спрощена схема архітектури Windows 2000

Режим користувача і режим ядра

Хоча процесори сімейства Intel x86 підтримують чотири рівні привілеїв (званих кільцями захисту), в Windows використовуються тільки два: 0-ой для режиму ядра і 3-ий для режиму користувача. Це пов'язано з підтримкою інших процесорів (alpha, mips), в яких реалізовано тільки два рівня привілеїв. Попередні випуски Windows NT підтримували ці архітектури, але в Windows 2000 залишилася підтримка тільки x86.

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

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

Компоненти ядра поділяють єдиний адресний простір, виконуються в привілейованому режимі процесора (званому режимом ядра), можуть виконувати всі, в тому числі і привілейовані, команди процесора, мають необмежений і прямий доступ до системних даних і коду, мають прямий, або через HAL, доступ до обладнання.

Код ядра (власне це і є сама система) розглядається як повністю довірчий. Тому, будучи завантаженим в системне адресний простір, драйвер стає частиною системи і на нього не накладаються які-небудь обмеження.

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

Драйвери Windows 2000

Windows 2000 підтримує безліч типів драйверів пристроїв.

Існує два базових, які мають своїх представників:

  • Драйвери для користувача режиму (User-Mode Drivers):
    • Драйвери віртуальних пристроїв (Virtual Device Drivers, VDD) - використовуються для підтримки програм MS-DOS (не плутати з VxD драйверами в Windows 95/98 - це зовсім різні речі, хоча і мають одну назву);
    • Драйвери принтерів (Printer Drivers).
  • Драйвери режиму ядра (Kernel-Mode Drivers):
    • Драйвери файлової системи (File System Drivers) - реалізують введення-виведення на локальні і мережеві диски;
    • Успадковані драйвери (Legacy Drivers) - написані для попередніх версій Windows NT;
    • Драйвери відеоадаптерів (Video Drivers) - реалізують графічні операції;
    • Драйвери потокових пристроїв (Streaming Drivers) - реалізують введення-виведення відео та звуку;
    • WDM-драйвери (Windows Driver Model, WDM) - підтримують технологію Plag and Play і управління електроживленням. Їх відмітною особливістю є сумісність на рівні програмного коду між Windows 98, Windows ME і Windows 2000.

У різних джерелах ви можете зустріти класифікацію трохи відмінну від наведеної вище, це не суть важливо. Важливим є те, що драйвери, які ми будемо писати, не підпадають ні під один із пунктів цієї класифікації. Це ні драйвери файлової системи, ні успадковані драйвери, ні драйвери відеоадаптерів або звукових карт, ні WDM-драйвери, тому що не підтримують Plag "n" Play і управління електроживленням. Це не драйвери користувальницького режиму (це взагалі не цікаво). Насправді це просто чортзна-що таке, тому що система сама дозволяє легко і просто додати в саму себе код незрозуміло для якого пристрою, і робити з нею все що завгодно! Це як якщо б до вас вночі в двері постукав абсолютно незнайома людина, і ви ні слова не кажучи впустили б його на нічліг, та ще поклали б у своє ліжко! Однак, це не є якимось багом або дірою в системі безпеки. Просто система працює так, як вона працює. Інакше і бути не може, тому що взаємодіючи з оточенням, система змушена надавати до себе доступ. І якби це було не так, то це була б повністю закрита, а значить, нікому не потрібна система.

Як випливає із самої назви, драйвер пристрою це програма призначена для управління якимось пристроєм, причому пристрій це не обов'язково має бути фізичним. Воно може бути логічним або, як в нашому випадку, віртуальним.

За своєю структурою драйвер пристрою є ні чим іншим як файлом PE-формату (Portable Executable, PE). Таким же як звичайні exe і dll. Тільки завантажується і працює за іншими правилами. Драйвери можна розглядати як DLL режиму ядра, призначені для виконання завдань нерозв'язних з призначеного для користувача режиму. Принципова різниця тут (не рахуючи рівня привілеїв) в тому, що ми не зможемо безпосередньо звертатися до драйверу, ні до його коду, ні до його даними, а будемо користуватися спеціальним механізмом надаються диспетчером вводу-виводу (Input / Output Manager). Диспетчер введення-виведення забезпечує середовище для функціонування драйверів, а також надає механізми для їх завантаження, вивантаження і управління ними.

Приступаючи до розробки драйверів режиму ядра, ви відчуєте себе досконалим новачком, тому що весь попередній досвід використання API тут не допоможе - ядро \u200b\u200bнадає зовсім інший набір функцій. Також доведеться користуватися погано документовані (певними тільки в заголовних файлах) або зовсім недокументованими функціями і структурами даних.

Одно- і багаторівневі драйвери

Більшість драйверів керуючих фізичними пристроями є багаторівневими (layered drivers). Обробка запиту вводу-виводу поділяється між кількома драйверами. Кожен виконує свою частину роботи. Наприклад, запит на читання файлу передається драйверу файлової системи, котрий, виконавши деякі операції (наприклад, розбиття запиту на кілька частин), передає його "нижче" - драйверу диска, а той, у свою чергу, відправляє запит драйверу шини. Крім того між цими драйверами можна додати будь-яку кількість драйверів-фільтрів (наприклад, шифруючих дані). Виконавши запит нижчий драйвер (lower-level driver) передає його результати "наверх" - вищестоящому (higher-level driver). Але, на щастя, у нас все буде значно простіше. Наші драйвери завжди будуть однорівневими (monolithic drivers), що сильно спростить весь процес їх написання і налагодження.

контекст потоку

Оскільки, в більшості випадків, ми маємо всього один процесор, а додатків, які потрібно виконувати багато, то природно, що для створення ілюзії одночасного їх виконання треба послідовно підключати ці додатки до процесора, причому дуже швидко. Ця процедура називається перемиканням контексту потоку (thread context switching). Якщо система перемикає контекст потоків належать одному процесу, то необхідно зберегти значення регістрів процесора, що відключається потоку, і завантажити, попередньо збережені значення регістрів процесора підключається потоку. І оновити деякі структури даних. Якщо ж підключається потік належить іншому процесу, то необхідно ще в регістр CR3 процесора завантажити покажчик на каталог сторінок (page directory) процесу. Оскільки кожному призначеному для користувача процесу надано закрите адресний простір, то у різних процесів різні проекції адресних просторів, а значить, і різні каталоги сторінок і набори таблиць сторінок за якими процесор транслює віртуальні адреси у фізичні. Все це не має прямого відношення до програмування драйверів. Але я нагадую про це в зв'язку ось із чим. Так як перемикання контексту операція не найшвидша, то драйвери, з міркувань кращої продуктивності, як правило, не створюють своїх потоків. Але код драйвера все ж потрібно виконувати. Тому, для економії часу на перемикання контекстів, драйвери виконуються в режимі ядра в одному з трьох контекстів:

  • в контексті користувацького потоку ініціював запит вводу-виводу;
  • в контексті системного потоку режиму ядра (ці потоки належать процесу System);
  • як результат переривання (а значить, не в контексті будь-якого процесу або потоку, який був поточним на момент переривання).

Не зовсім розумію як можна виконати щось "не в контексті будь-якого процесу або потоку", але з огляду на авторитет людей це написали (Д. Соломон і М. Руссинович), а також те, що нам це не знадобиться, т.к . ми не будемо обробляти ні програмні, ні тим більше, апаратні переривання, про третій випадок можна відразу забути. Залишаються перші два варіанти. Якщо ініціюється запит вводу-виводу, то ми в контексті потоку цей запит ініціював, і значить, можемо безпосередньо звертатися до адресного простору процесу якому цей потік належить. Якщо ми в контексті системного потоку, то ні до якого користувача процесу звертатися безпосередньо не можемо, а до системного ми і так завжди можемо звернутися. Якщо потрібно з драйвера подивитися, що там у якогось процесу лежить за таким-то адресою, то доведеться або самим перемикати контекст, або за таблицями сторінок транслювати адреси.

Рівні запитів переривань

Переривання - невід'ємна частина будь-якої операційної системи. Переривання вимагає обробки, тому виконання поточного коду припиняється і керування передається обробнику переривання. Існують як апаратні, так і програмні переривання. Переривання обслуговуються відповідно до їх пріоритету. Windows 2000 використовує схему пріоритетів переривань, відому під назвою рівні запитів переривань (interrupt request levels, IRQL). Всього існує 32 рівня, з 0 (passive), що має найнижчий пріоритет, по 31 (high), що має відповідно найвищий. Причому, переривання з IRQL \u003d 0 (passive) по IRQL \u003d 2 (DPC \\ dispatch) є програмними, а переривання з IRQL \u003d 3 (device 1) по IRQL \u003d 31 (high) є апаратними. Не плутайте рівні пріоритету переривань з рівнями пріоритетів потоків - це зовсім різні речі. Переривання з рівнем IRQL \u003d 0, строго кажучи, перериванням не є, тому що воно не може перервати роботу ніякого коду (адже для цього цей код повинен виконуватися на ще більш низькому рівні переривання, а такого рівня немає). На цьому IRQL виконуються потоки користувальницького режиму. І код наших драйверів теж буде виконуватися на цьому IRQL. Це аж ніяк не означає, що код будь-якого драйвера завжди виконується на рівні "passive". Просто ми не будемо обробляти ні програмні, ні тим більше апаратні переривання. А звідси випливають, по крайней мере, два дуже важливих висновки.

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

Другий важливий момент: на рівні переривання passive можна викликати будь-які функції ядра (в DDK в описі кожної функції обов'язково вказано, на якому рівні переривання її можна викликати), а також звертатися до сторінок пам'яті скинутим в файл підкачки. На більш високих рівнях переривання (DPC / dispath і вище), спроба звернення до сторінці відсутньої у фізичній пам'яті призводить до краху системи, тому що диспетчер пам'яті (Memory Manager) не може обробити помилку сторінки.

"Блакитний екран смерті"

Думаю кожен, хоча б один раз, бачив хвилюючу картину під назвою "блакитний екран смерті" (Blue Screen Of Death, BSOD). Напевно, немає потреби пояснювати, що це таке і чому виникає. Важливо тут те, що взявшись за розробку драйверів режиму ядра, приготуйтеся до того, що BSOD дастаточно часто з'являтиметься на екрані вашого монітора.

У третьому кільці все було просто: накидав приблизний код, розставив int3 де треба, запустив і ... в отладчике вже розбираєшся що до чого. Якщо щось не так - прибив, виправив помилки, перекомпіліровать ... і так далі, до тих пір поки код не запрацює як треба. При програмуванні драйверів про цю техніку можна забути. Тут "сапер" помиляється один раз. Один невірний рух ... і можна відкинутися на спинку крісла і хвилинку розслабитися.

Для того щоб бачити BSOD якомога рідше слід дотримуватися одного дуже простого правила: "Сім разів відміряй - один відріж" ... в сенсі "Сім разів перевір - один запусти". Це звичайно просто сказати, але значно важче зробити. Але як правило, з огляду на те, що структура драйверів, які ви будете писати (після прочитання цих статей), відносно проста, можна розібратися з помилками і до появи BSOD. Якщо ж він наполегливо з'являється перед вашими очима, і ви ніяк не можете зрозуміти причину, можливим способом прояснити ситуацію є аналіз аварійного дампа (crash dump). Про те, що це таке, як його зробити і аналізувати можна почитати в статті Марка Руссиновича "Аналіз аварійних дампів пам'яті" http://www.osp.ru/win2000/2001/03/025.htm. Справа ця (аналіз) дуже непроста, але думаю, що до цього не дійде.

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

Тепер висвітлимо деякі більш практичні речі (зовсім практичними вони стануть в наступних статтях), а саме, що нам знадобиться, щоб всю цю теорію перетворити в практику.

Driver Development Kit

Перше це звичайно Комплект розробки драйверів пристроїв (Windows 2000 Driver Development Kit, 2KDDK), який можна вільно скачати з сайту Microsoft (у всякому случе я зливав його абсолютно безоплатно звідси: http://www.microsoft.com/ddk/). В цей пакет входить документація, яка є багатим джерелом інформації про внутрішні структури даних і внутрішньосистемних функціях використовуваних драйверами пристроїв.

Крім документації в DDK входить набір бібліотечних файлів (* .lib), які будуть вкрай необхідні при компонуванні. У DDK входить два комплекти цих файлів: для остаточної версії Windows (званої вільним випуском (free build)); і для налагоджування (званої перевірочним випуском (checked build)). Знаходяться ці файли в каталогах% ddk% \\ libfre \\ i386 і% ddk% \\ libchk \\ i386 відповідно. Отладочная версія відрізняється більш суворою перевіркою помилок. Використовувати потрібно файли відповідні вашої версії системи помістивши їх в каталог \\ masm32 \\ lib \\ w2k.

файли, що включаються

Також нам знадобляться включаються (* .inc) файли з визначеннями прототипів функцій. Їх нам (точніше мені) теж доведеться робити самим. Я перепробував багато різних утиліт, конвертують * .lib -\u003e * .inc, як входять в пакет masm32 by hutch, так і злитих мною в різний час з безкрайніх просторів Internet. З усіх що є у мене в наявності, тільки protoize.exe by f0dder впоралася зі своїм завданням, і мені практично нічого не довелося правити руками. Ця чудова тулза буде лежати в каталозі \\ tools \\ protoize. Сайт автора: http://f0dder.didjitalyphrozen.com/. Тільки ви її там не знайдете. f0dder кілька разів постил цю утиліту в конференції http://board.win32asmcommunity.net/. Інклуд будуть лежати в каталозі \\ include \\ w2k. Їх слід помістити в каталог \\ masm32 \\ include \\ w2k. Для конвертації використовувалися * .lib для вільного випуску Windows 2000, т. К. У мене стоїть саме цей варіант (і у вас, напевно, теж).

Наступна проблема серйозніша. Це практично повна відсутність включення файл з визначеннями необхідних структур, символьних констант і макросів. Знайти що-небудь путнє в мережі ви навряд чи зможете - аж надто екзотичне це заняття - писати драйвери режиму ядра на асемблері. Дещо можна знайти у EliCZ http://www.anticracking.sk/EliCZ/. Дещо у Y0da http://mitglied.lycos.de/yoda2k/index.htm (частково зроблене їм самим, частково узяте у того ж EliCZ). Але зроблено це з рук геть погано, (при всій моїй глибокій повазі до наших Словацька і німецькому колегам): імена членів багатьох структур відрізняються від визначених у оригінальних заголовних файлах з DDK; вкладені структури і об'єднання не мають імен; хоча в оригіналі вони іменовані. І взагалі, все знаходиться в деякому безладі, і при перегляді викликає гнітюче враження. Непогано зроблений тільки ntstatus.inc. Частково це пояснюється тим, що EliCZ почав створювати свої інклуд ще під час відсутності у нього DDK (як він сам каже). У будь-якому випадку, я не раджу вам їх використовувати, принаймні без ретельної перевірки. Дещо, свого часу, миготіло в конференції http://board.win32asmcommunity.net/, але якість теж не особливо вражає. Коротше, єдино правильне рішення в даній ситуації - робити все самим, причому вручну, т. К. Будь-які тулзи, що дозволяють автоматизувати цей процес, мені не відомі. Якщо ви, раптом, натрапите на щось варте уваги, не вважайте за працю - дайте мені знати.

налагодження драйверів

Також нам потрібно відладчик, причому, оскільки налагоджувати доведеться код режиму ядра, то і відладчик потрібен відповідний. Найкращим вибором буде SoftICE. Або можна скористатися Kernel Debugger входять до складу DDK. Цей відладчик вимагає двох комп'ютерів - провідного і веденого, що не кожен може собі дозволити. Марк Руссинович (Mark Russinovich, http://www.sysinternals.com/) написав утиліту LiveKd, яка дозволяє використовувати Kernel Debugger без підключення другого комп'ютера. Не знаю чи є вона на сайті (не перевіряв), але на диску до книжки "Внутрішній устрій Microsoft Windows 2000" є. Також цей відладчик надзвичайно корисний для дослідження внутрішньої будови системи, за умови що у вас встановлені налагоджувальні символи, які можна (або було можна) вільно скачати з сайту Microsoft.

  • Девід Соломон, Марк Руссинович, "Внутрішнє пристрій Microsoft Windows 2000", вид. "Пітер", 2001.

    Хоча в цій книзі немає жодного рядка вихідного коду, вона перш за все для програмістів.

  • Свен Шрайбер, "Недокументовані можливості Windows 2000", вид. "Пітер", 2002.

    Суто практична книга, в якій розкрито безліч таємниць Windows 2000.

  • Walter Oney, "Programming the Microsoft Driver Model", Microsoft Press, 1999.

    У цій книзі упор зроблений на Plag "n" Play драйвери, але це анітрохи не благає її достоїнств, тому що базові принципи розробки драйверів універсальні.

  • Джеффрі Ріхтер, "Windows для професіоналів: створення ефективних Win32-додатків з урахуванням специфіки 64-розрядної версії Windows", изд. "Пітер", 2000.

    Ця книжка не має ніякого безпосереднього відношення до програмування драйверів, але теж дуже цікава ;-)

    Цей список ні в якому разі не претендує на повноту. Багато що, особливо по англійськи, можна знайти в Internet (крім Шрайбера, все книги є в електронному варіанті). Відносно книг хочу сказати ще, що всі вони з розряду "must have". Побачите - купуйте не дивлячись. Все, крім Walter "а Oney, переведені на наш" великий и могучий ".

    І останнє. Я не є великим фахівцем в області розробки драйверів, так що помилки або неточності, як в цій, так і в усіх наступних статтях, дуже ймовірні. Знайдете - сміливо тикайте носом. Скажу спасибі.