Как написать драйвер для программы

Создание драйверов. Часть 1. В данной статье мне хотелось бы показать, как создавать драйвера, если Вам необходима теоретическая информация то советую прочесть книгу Дэвида Соломона и Марка Руссиновича «Внутреннее устройство Microsoft Windows 2000». Для начала мы сделаем простой драйвер для Windows 2000, который послужит нам каркасом для дальнейших экспериментов. Для работы понадобится «Windows 2000 Driver Development Kit», именно с помощью данного пакета создаются драйвера, в его состав входят компилятор, линкер, заголовочные файлы, lib-файлы, документация, полезные инструменты и конечно множество примеров.

Для написания и редактирования исходных текстов драйверов можно воспользоваться редактором, входящим в состав MS Visual Studio или Блокнотом, незаменимым инструментом программиста. Для просмотра объектов операционной системы понадобиться программа WinObj, автором которой является Марк Руссинович, программу можно найти на сайте http://www.sysinternals.com/, так же с этого адреса можно скачать программу DebugView, которая позволяет просматривать диагностические сообщения, посылаемые функциями OutputDebugString и DbgPrint.

Что такое Драйвера — Объяснение | Как это работает

Начнем, создайте на диске С: папку и назовите её «MyFirstDriver», затем в ней папку «sys» и «loader», это нужно для того чтобы легче было работать с путями к бинарным файлам. В папке «sys» создайте три файла, с именами «makefile», «sources» и «MyFirstDriver.c». В файле «makefile» напишите следующее:

Этот файл нужен для работы программы Build. В файле «sources» напишите следующее:

TARGETNAME=MyFirstDriver
TARGETTYPE=DRIVER
TARGETPATH=obj
SOURCES=MyFirstDriver.c

Этот файл нужен для настройки процесса компиляции:
TARGETNAME – имя драйвера;
TARGETTYPE – тип бинарного файла, который мы хотим создать, может иметь следующие значения: DRIVER, GDI_DRIVER, MINIPORT, LIBRARY, DYNLINK (for DLLs).
TARGETPATH – путь для папки с временными файлами;
SOURCES – путь к файлу с исходным текстом драйвера.

Теперь переходим к исходному файлу «MyFirstDriver.c», в нем напишите следующее:

#include «ntddk.h» /*—————————————————————*/ NTSTATUS MyFirstDriverCreate (IN PDEVICE_OBJECT fdo, IN PIRP irp); NTSTATUS MyFirstDriverClose (IN PDEVICE_OBJECT fdo, IN PIRP irp); NTSTATUS MyFirstDriverControl (IN PDEVICE_OBJECT fdo, IN PIRP irp); VOID MyFirstDriverUnload (IN PDRIVER_OBJECT fdo); /*—————————————————————*/ NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,IN PUNICODE_STRING RegistryPath) < NTSTATUS status; PDEVICE_OBJECT fdo; UNICODE_STRING devName; UNICODE_STRING devLink; #if DBG DbgPrint(«in DriverEntry»); #endif DriverObject->DriverUnload = MyFirstDriverUnload; DriverObject->MajorFunction[IRP_MJ_CREATE] = MyFirstDriverCreate; DriverObject->MajorFunction[IRP_MJ_CLOSE] = MyFirstDriverClose; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = MyFirstDriverControl; RtlInitUnicodeString(\Device\MyFirstDriver»); status = IoCreateDevice(DriverObject,sizeof(PDEVICE_OBJECT),fdo); if(!NT_SUCCESS(status))return status; #if DBG DbgPrint(«IoCreateDevice status ok»); #endif RtlInitUnicodeString(\??\MyFirstDriver»); status = IoCreateSymbolicLink(devName); if(!NT_SUCCESS(status)) < IoDeleteDevice( fdo ); return status; >#if DBG DbgPrint(«DriverEntry STATUS_SUCCESS»); #endif return STATUS_SUCCESS; > /*—————————————————————*/ NTSTATUS MyFirstDriverCreate(IN PDEVICE_OBJECT fdo, IN PIRP irp) < #if DBG DbgPrint(«Run MyFirstDriverCreate»); #endif irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; > NTSTATUS MyFirstDriverClose(IN PDEVICE_OBJECT fdo, IN PIRP irp) < #if DBG DbgPrint(«Run MyFirstDriverClose»); #endif irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; > NTSTATUS MyFirstDriverControl (IN PDEVICE_OBJECT fdo, IN PIRP irp) < #if DBG DbgPrint(«Run MyFirstDriverControl»); #endif irp->IoStatus.Status = STATUS_SUCCESS; irp->IoStatus.Information = 0; IoCompleteRequest(irp, IO_NO_INCREMENT); return STATUS_SUCCESS; > VOID MyFirstDriverUnload(IN PDRIVER_OBJECT fdo) < UNICODE_STRING deviceLink; RtlInitUnicodeString(\??\MyFirstDriver»); IoDeleteSymbolicLink( IoDeleteDevice(fdo->DeviceObject); #if DBG DbgPrint(«Run MyFirstDriverUnload — delete link»); #endif >

Как Вы видите драйвер очень прост и имеет основные функции:
DriverEntry – данная функция есть в каждом драйвере и является точкой входа.
Параметры:
IN PDRIVER_OBJECT DriverObject – адрес объекта драйвера;
IN PUNICODE_STRING RegistryPath – путь в реестре, где содержится информация о драйвере.
Тип возвращаемого значения NTSTATUS, на самом деле это просто тип LONG, может принимать следующие значения:
STATUS_SUCCESS – успешно;
STATUS_N – где, N – номер ошибки.
В функции DriverEntry происходит заполнение полей структуры DriverObject:
DriverUnload – здесь регистрируется функция выгрузки драйвера;
MajorFunction[IRP_MJ_CREATE] – здесь регистрируется функция обработки запросов открытия драйвера;
MajorFunction[IRP_MJ_CLOSE] — здесь регистрируется функция обработки запросов закрытия драйвера;
MajorFunction[IRP_MJ_DEVICE_CONTROL] — здесь регистрируется функция обработки IOCTLзапросов. Так же в DriverEntry создается символьная ссылка и устройство. Для вывода отладочной информации с помощью функции DbgPrint мы используем возможности условной компиляции, то есть конструкция:

#if DBG
DbgPrint(«»);
#endif

будет присутствовать только в версиях Checked.
Для компиляции запустите «Checked Build Environment»,
Создание драйверов
Появится консольное окно, далее с помощью команды «cd» перейдите в папку с файлами драйвера и наберите команду build –cZ
Создание драйверов
Теперь драйвер готов, следующим шагом будет создание программы, которая будет динамически загружать наш драйвер с помощью SCM (Service Control Manager), подробно о нем написано в MSDN`е. Для этого создайте обыкновенную консольную версию программы и поместите все файлы проекта в папку «loader», в исходнике загрузчика напишите следующее:

#include #include #include using namespace std; void ErrorView(); int main() < cout/**/if(CloseHandle(hHandl)) else/**/ SERVICE_STATUS ServiceStatus; /**/if(ControlService(schService,SERVICE_CONTROL_STOP,else >else >else >else cout void ErrorView()/*Функция вывода сообщений об ошибках. */

Создание драйверов

Перед тем как запускать программу, запустите DebugView, только после этого запускайте загрузчик драйвера.

Читайте также:
Не запускается программа установки касперского

Как Вы видите наш драйвер заработал, на этом пока все.

Источник: blagin.ru

Как написать драйвер для программы

Ну вот мы и добрались до самого интересного — сейчас будем писать драйвер. Итак, приступим. Для удобства выполнения, всю последовательность действий по написанию драйвера я распишу по пунктам.

1. Создание директории проекта

Установив DDK, на Вашем компьютере в директории C:WINDDK2600.1106 должны появиться файлы DDK. В этой директории создадим папку, в которой будут храниться наши проекты. Назовем ее, например, MyDrivers.

В папке MyDrivers создадим папку FirstDriver — тут будет находится наш первый проект драйвера.

2. Подготовка файлов проекта

В папке FirstDriver создайте пустой текстовый файл и переименуйте его под именем FirstDriver.c

При попытке переименовки со сменой расширения файла, появляется следующее предупреждение:

Не обращаем внимания на это предупреждение, и нажимаем Да. При этом наш файл примет вид:

Если же никакого предупреждения не было и переименованный файл так и остался текстовым с именем FirstDriver.c и расширением .txt, то в настройках своийств папки, которые можно найти в Пуск-> Настройка-> Панель управления-> Свойства паки уберите галочку напротив пункта «Скрывать расширения для зарегестрированных типов файлов». Попробуйте еще раз и все должно быть в порядке.

Теперь нам надо добавить еще два очень важных файла в наш проект, без которых драйвер нам не сделать. Они называются makefile и sources (обратите внимание, у них нет расширения). Их можно создать самим, но мы сделаем проще: скопируем готовые из какого либо примера проекта драйвера из DDK. Например, возьмем их из C:WINDDK2600.1106srcgeneralcancelsys.

Итак, копируем из указанной директории эти два файла и вставляем их в нашу папку проекта FirstDriver. Эти файлы управляют процессрм компиляции драйвера. Файл makefile оставляем без изменений, а вот sources надо подредактировать.

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

TARGETNAME=Port TARGETPATH=c:WINDDK2600.1106MyDriversFirstDriver TARGETTYPE=DRIVER SOURCES=FirstDriver.c

Первым параметром идет TARGETNAME, которому мы присвоили Port. Это значит, что когда DDK откомпилирует наш код и создаст драйвер, имя этого файла будет Port.sys Следующем параметром идет TARGETPATH, которому мы указали путь к папке нашего проекта.

Если Вы устанавливали DDK в другое место, или создали пупку проекта в другой директории, здесь Вам надо это поправить на тот путь, который у Вас. Параметр TARGETTYPE пока оставлю без комментариев. В параметре SOURCES указываем, из каких файлов будет компилироваться драйвер. У нас это файл FirstDriver.c, вот мы его и указали.

3. Код драйвера

Всю подготовительную работу мы сделали. Можно приступать к самой содержательной части — коду драйвера. Писать мы будем его на Си.

Еще раз напомню решаемую нами задачу: надо написать драйвер под Windows 2000, XP с помощью которого можно будет работать с портами компьютера (читать и писать данные) .

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

#include «ntddk.h»
#define NT_DEVICE_NAME L»\Device\NTName» #define WIN32_DEVICE_NAME L»\DosDevices\MYDRIVER» #define IOCTL_READ CTL_CODE (FILE_DEVICE_UNKNOWN, 0x800, METHOD_BUFFERED, FILE_ANY_ACCESS) #define IOCTL_WRITE CTL_CODE (FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)

NTSTATUS CtlCreate(IN PDEVICE_OBJECT, IN PIRP); NTSTATUS CtlClose(IN PDEVICE_OBJECT, IN PIRP); NTSTATUS CtlDispatch(IN PDEVICE_OBJECT,IN PIRP); VOID UnloadOperation(IN PDRIVER_OBJECT pDriverObject); NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath) < PDEVICE_OBJECT pDeviceObject; UNICODE_STRING uniNtName; UNICODE_STRING uniWin32Name; RtlInitUnicodeString( RtlInitUnicodeString( IoCreateSymbolicLink(uniNtName); IoCreateDevice(pDriverObject,0,pDeviceObject); pDriverObject->MajorFunction[IRP_MJ_CREATE]=CtlCreate; pDriverObject->MajorFunction[IRP_MJ_CLOSE]=CtlClose; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=CtlDispatch; pDriverObject->DriverUnload = UnloadOperation; return STATUS_SUCCESS; > NTSTATUS CtlCreate(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp) < Irp->IoStatus.Status=STATUS_SUCCESS; Irp->IoStatus.Information=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; > NTSTATUS CtlClose(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp) < Irp->IoStatus.Status=STATUS_SUCCESS; Irp->IoStatus.Information=0; IoCompleteRequest(Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; > VOID UnloadOperation(IN PDRIVER_OBJECT pDriverObject) < PDEVICE_OBJECT deviceObject = pDriverObject->DeviceObject; UNICODE_STRING uniWin32NameString; RtlInitUnicodeString( IoDeleteSymbolicLink( IoDeleteDevice( deviceObject ); return; > NTSTATUS CtlDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp) < PIO_STACK_LOCATION pIrpStack; PUSHORT pIOBuffer;
USHORT Port; USHORT ValueToPort;

pIrpStack=IoGetCurrentIrpStackLocation(Irp); pIOBuffer=Irp->AssociatedIrp.SystemBuffer; switch (pIrpStack->Parameters.DeviceIoControl.IoControlCode)
case IOCTL_READ: Port=pIOBuffer[0]; pIOBuffer[0]=READ_PORT_UCHAR((PUCHAR)Port); Irp->IoStatus.Information=2; break; case IOCTL_WRITE: Port=pIOBuffer[0]; ValueToPort=pIOBuffer[1]; WRITE_PORT_USHORT((PUSHORT)Port,(USHORT)ValueToPort); Irp->IoStatus.Information=0; break;
> Irp->IoStatus.Status=STATUS_SUCCESS; IoCompleteRequest (Irp,IO_NO_INCREMENT); return STATUS_SUCCESS; >

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

Источник: kernelchip.ru

Статья Создание драйвера под Windows. Часть 1: Введение

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

После 20 минут поисков по сети я наткнулся на Github Павла Иосифовича (zodiacon — Overview). Личность легендарная в своих кругах, достаточно посмотреть на его репозиторий, публикации и выступления на именитых конференциях. Помимо этого, Павел является автором/соавтором нескольких книг: «Windows Internals» (книга, имеющаяся у меня на полке, которая принесла немало пользы), и «Windows Kernel Programming» 2019 года выпуска (бегло пролистав 11 Глав или 390 страниц, я понял – это то, что нужно!).
Кстати, книгу вы можете купить прямо на сайте Павла

Читайте также:
Программа чтобы изменить голос

Ссылка скрыта от гостей

Книгу я приобрёл в бумажной версии, чтобы хоть и немного, но поддержать автора. Безупречное качество, несмотря на то, что она издается в мягком переплете. Хорошие плотные листы формата А4 и качественная краска. (книга без проблем пережила вылитую на нее кружку горячего кофе).
Пока я сидел на балконе и читал четвёртую главу книги, в голову пришла мысль: а почему бы не сделать ряд статей на тему «Программирования драйвера под Windows», так сказать, совместить полезное, с еще более полезным.

И вот я здесь, пишу предысторию.

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

Базовые понятия о внутреннем устройстве Windows (Windows Internals) ​

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

Следовательно, нам стоит ознакомиться с такими базовыми понятиями как:

Ссылка скрыта от гостей
Процесс – это объект, который управляет запущенной инстанцией программы.​
Ссылка скрыта от гостей

Технология, позволяющая создавать закрытые пространства памяти для процессов. В своем роде — это песочница.​

Ссылка скрыта от гостей

Это сущность, которая содержится внутри процесса и использует для работы ресурсы, выделенные процессом — такие, как виртуальная память. По сути, как раз таки потоки и запускают код.​

Ссылка скрыта от гостей

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

Ссылка скрыта от гостей
Это сложно описать словами коротко, проще один раз увидеть картинку.​
В упрощённом виде это выглядит так:​

image1.png

Ссылка скрыта от гостей
Дескрипторы и объекты необходимы для регулирования доступа к системным ресурсам.​

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

Дескриптор – это некая абстракция, которая позволяет скрыть реальный адрес памяти от Программы в пользовательском режиме.​

  • Таненбаум, Бос: Современные операционные системы
  • Windows Internals 7th edition (Part 1)


Настройка рабочего пространства ​

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

Что нам понадобится:

1. Visual Studio 2017 и старше.​

(Community Version хватает с головой) Также во вкладке „Individual components” необходимо установить

MSVC v142 — VS 2019 C++ ARM build tools (Latest) MSVC v142 — VS 2019 C++ ARM Spectre-mitigated libs (Latest) MSVC v142 — VS 2019 C++ ARM64 build tools (Latest) MSVC v142 — VS 2019 C++ ARM64 Spectre-mitigated libs (Latest) MSVC v142 — VS 2019 C++ ARM64EC build tools (Latest — experimental) MSVC v142 — VS 2019 C++ ARM64EC Spectre-mitigated libs (Latest — experimental) MSVC v142 — VS 2019 C++ x64/x86 build tools (Latest) MSVC v142 — VS 2019 C++ x64/x86 Spectre-mitigated libs (Latest)

image10.png

и далее по списку.

2. Windows 10/11 SDK (последней версии)​

Ссылка скрыта от гостей

image3.png

Тут все просто. Качаем iso файл, монтируем и запускаем установщик.

3. Windows 10/11 Driver Kit (WDK)​

Ссылка скрыта от гостей

image4.png

В конце установки вам будет предложено установить расширение для Visual Studio. Обязательно установите его!

image11.png

После закрытия окна установки WDK появится установщик Расширения VisualStudio

image2.png

4. Sysinternals Suite

Ссылка скрыта от гостей

Скачайте и распакуйте в удобное для вас место. Это набор полезных утилит, которые пригодятся для исследования Windows, дебага драйвера и прочего.

image8.png

5. Виртуальная Машина с Windows для тестов.​

Выбор ПО для виртуализации на ваше усмотрение. Я буду использовать «VMware Workstation 16 pro».
Написанные драйверы лучше тестировать именно в виртуальной машине, так как Ядро — ошибок не прощает, и вы будете часто улетать в синий экран смерти.

После того, как все было установлено, пора запускать Visual Studio и начинать писать драйвер.

Создание проекта ​

Запускаем Visual Studio и создаем новый проект. Создадим пустой проект „Empty WDM Driver“

image21.png

Называем его как душе угодно.

image24.png

И вот он, наш свеженький чистенький проект для нашего первого драйвера.

image27.png

Теперь необходимо создать cpp файл, в котором мы будем писать сам драйвер.

image7.png

image14.png

Вот и все. Настройку системы и среды мы закончили.

image22.png

Первый драйвер ​

Сначала импортируем ntddk.h эта одна из базовых библиотек для работы с ядром. Больше информации
Ссылка скрыта от гостей

Читайте также:
Как открыть доступ к программе по сети

. Как и у любой программы, у драйвера должна быть точка входа DriverEntry , как функция Main в обычной программе. Готовый прототип этой функции выглядит так

#include NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) < /* In_ это часть SAL(Source Code Ananotation Language) Аннотации не видимы для компилятора, но содержат метаданные которые, улучшают анализ и чтение кода. */ return STATUS_SUCCESS; >

Если мы попробуем собрать наш проект, то получим следующие ошибки и предупреждения.

image15.png

  1. Отключить эту фичу в Visual Studio, что делать не рекомендуется. Так как сообщения об ошибках могут быть полезны и сэкономят вам время и нервы в дальнейшем.
  2. Более правильный и классический метод это использовать макросы в c++. Как видно из сообщения с кодом C4100 объекты RegistryPath и DriverObject не упомянуты в теле функции. Подробнее

Ссылка скрыта от гостей

include NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath)

Теперь, если пересобрать проект, то мы увидим, что ошибка С220 и предупреждение C4100 пропали, но к ним на смену пришли LNK2019 и LNK1120. Однако это уже не ошибки компиляции — это ошибки линкера. А кто говорил что будет легко?
О том, что такое линкер можно почитать

Ссылка скрыта от гостей

Дело в том, что наша функция не представлена в стандартном линкере С++ и вообще она девушка капризная и хочет Си-линкер. Удовлетворим желание дамы и дадим ей то, чего она хочет.

Делается это просто. Перед функцией надо добавить extern «C» так наш линкер будет понимать, что эта функция должна линковаться С-линкером.

Собираем проект заново и вуаля — Драйвер собрался.

image17.png

Что на данный момент умеет наш драйвер? Сейчас это по сути пустышка, которая после загрузки, в случае успеха, вернет нам сообщения об удачном запуске. Давайте заставим его нас поприветствовать и проверим его работоспособность. Выводить сообщения мы будем при помощи функции KdPrint(()); да именно в двойных кавычках.

Итоговый код драйвера будет выглядеть так:

#include //Указываем линкеру, что DriverEntry должна линковаться С-линкером extern «C» NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) < //Убираем варнинг C4100 и связанную с ним ошибку C220 UNREFERENCED_PARAMETER(DriverObject); UNREFERENCED_PARAMETER(RegistryPath); //Выводим сообщение KdPrint((«Hi Codeby, this is our first driver! Yuhu!n»)); return STATUS_SUCCESS; >

Собираем или пересобираем драйвер.

image6.png

Важно! Сборка драйвера должна происходить в режиме Debug.

image12.png

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

image5.png

Но что делать дальше? Как проверить его работоспособность?
Для этого нам и понадобится наша виртуальная машина с Windows, но перед запуском на ней драйвера, нам придется проделать пару манипуляций. Дело в том, что в Windows есть встроенная защита, и если драйвер не подписан «нужной» подписью ака сертификатом, то драйвер просто не загрузится.

Дальнейшие действия нужно проделать в Windows на виртуальной машине.
Чтобы отключить эту проверку подписи, а точенее перевести Windows в тестовый режим, запустите cmd.exe от имени администратора и введите следующую команду bcdedit /set testsigning on .

image13.png

Перезагрузите виртуальную машину.
Если все прошло удачно, в правом нижнем углу вы увидите следующую надпись (2 нижнее строчки могут отличиться в зависимости от версии Windows)

image9.png

Возвращаемся в папку с драйвером и копируем его в виртуальную машину. Теперь нам надо создать службу для запуска драйвер. Открываем консоль от имени администратора и вводим следующую команду:
sc create Name type= kernel binPaht= PATH_TO_DRIVER

в моем случае это выглядит так:

image19.png

Также проверить успешность создания можно через реестр.

image16.png

В той же консоли мы можем попробовать запустить нашу службу.
sc start CodebyDriver

image18.png

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

Создадим новый ключ в реестре и назовем его Debug Print Filter .

image23.png

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

image25.png

Перезагружаем виртуальную машину.

После перезапуска запускаем DebugView данный инструмент находится в архиве Sysinternals, который мы ранее скачали. Ее можно смело скопировать в виртуальную машину.

Запускаем DebugView от имени Администратора и ставим галочку “Capture Kerner”

image20.png

Capture Win32 и Capture Global Win32 можно снять, если летит много сообщений.

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

image26.png

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

Спасибо за чтение!

P.S: Я сам только начал изучать тему работы с драйверами. Так что если у вас есть предложения или правки по технической части статьи, прошу отписать в комментарии, чтобы я мог внести изменения в статью.
P.P.S: Как вы могли заметить, писать мы будем преимущественно на С++, посему могу посоветовать отличный канал с уроками по С++ — The Cherno.

Источник: codeby.net

Рейтинг
( Пока оценок нет )
Загрузка ...
EFT-Soft.ru