Обновлено: 04.02.2023
В базе содержится один файл с именем wmio.sys. Этот файл принадлежит продукту Windows (R) Win 7 DDK driver и разработан компанией Windows (R) Win 7 DDK provider. Описание этого файла — Generic Port I/O. Этот файл содержит драйвер. Вы можете найти его в разделе драйверов в System Explorer.
Продукт: Windows (R) Win 7 DDK driver Компания: Windows (R) Win 7 DDK provider Описание: Generic Port I/O Версия: 6.1.7600.16385 MD5: 86083399ccf04f294325de7b390c3efd SHA1: b1de51bc3415c99f783f24cd8f7374a7e6c62a3c SHA256: 5854719ed3d70e105d97240207cc2b0258b6e2d61e933be8314bd4552650290d Размер: 6144 Папка: C:WindowsSystem32DRIVERS ОС: Windows XP Частота: Низкая
PCI Express Config Space
Немного отвлечёмся на один нюанс про PCIE Config Space. С этим адресным пространством не всё так просто — со времён шины PCI для доступа к её конфигурационному пространству используется метод с использованием I/O портов 0xCF8 / 0xCFC. Он применён и в нашем драйвере AsrDrv101:
Чтение и запись PCI Config Space
Но через этот метод доступны только 0x100 байт конфигурационного пространства, в то время как в стандарте PCI Express размер Config Space у устройств может быть достигать 0x1000 байт! И полноценно вычитать их можно только обращением к PCI Extended Config Space, которая замаплена где-то в адресном пространстве, обычно чуть пониже BIOS:
Адресное пространство современного x86 компа, 0-4 ГБ
На чипсетах Intel (ну, в их большинстве) указатель на эту область адресного пространства можно взять из конфига PCI устройства 0:0:0 по смещению 0x60, подробнее описано в даташитах:
У AMD я такого не нашёл (наверняка есть, плохо искал), но сам факт неуниверсальности пнул меня в сторону поиска другого решения. Погуглив стандарты, я обнаружил, что указатель на эту область передаётся системе через ACPI таблицу MCFG
А сами ACPI таблицы можно найти через запись RSDP, поискав её сигнатуру по адресам 0xE0000-0xFFFFF, а затем распарсив табличку RSDT. Отлично, здесь нам и пригодится функционал поиска по памяти. Получаем нечто такое:
На всякий случай оставляем вариант для чипсетов Intel
Всё, теперь осталось при необходимости заменить чтение PCI Express Config Space через драйвер на чтение через память. Теперь-то разгуляемся!
Простейший WDM-драйвер
В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.
Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
- Windows DDK (Driver Development Kit);
- VMware Workstation или Virtual Box;
- Windows XP;
- Visual Studio 2005;
- DDKWizard;
- KmdManager
- DebugView;
Настройка рабочего места
Установка DDK
Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.
Установка и настройка Microsoft® Visual Studio 2005
Установка Microsoft® Visual Studio 2005 ничем не сложнее установки DDK. Если Вы будете использовать её только для написания драйверов, то когда инсталлятор спросит какие компоненты необходимо установить, выберите только Visual C++.
Далее можно установить Visual Assist X. С помощью этой программы (аддона) можно будет легко настроить подсказки для удобного написания драйверов.
После установки Visual Assist X в Visual Studio 2005 появится новое меню VAssistX. Далее в этом меню: Visual Assist X Options -> Projects -> C/C++ Directories -> Platform: Custom, Show Directories for: Stable include files . Нажимаем Ins или на иконку добавить новую директорию и в появившейся строке, если у вас Windows XP вписываем %WXPBASE%incddkwxp .
Установка и настройка DDKWizard
- Создать системные (рекомендуется) или пользовательские переменные со следующими именами и значением, которое соответствует пути к DDK
Версия DDK Имя переменной Путь по умолчанию Windows XP DDK WXPBASE C:WINDDK2600 Windows 2003 Server DDK WNETBASE C:WINDDK3790.1830 Windows Vista/Windows 2008 Server WDK WLHBASE Windows 7/Windows 2008 Server R2 WDK W7BASE Например, если я использую Windows XP DDK, то я должен создать переменную WXPBASE со значением, которое соответствует пути к DDK. Так как я не изменял путь установки, то значение у меня будет C:WINDDK2600.
- Скопируйте скачанный скрипт ddkbuild.cmd, например, в папку с DDK. У меня это C:WINDDK.
- Добавьте в конец системной переменной Path путь к скрипту ddkbuild.cmd.
Установка необходимого ПО для запуска драйверов
- DebugView (link) — это утилитка, которая позволяет просматривать отладочный вывод как режима пользователя так и режима ядра.
- KmdManager (link) — утилита динамической загрузки/выгрузки драйверов
Постановка задачи
Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.
Немного теории
- драйверы классов;
- минидрайверы;
- функциональные драйверы;
- фильтрующие драйверы.
Необязательно определять все возожные функции в своем драйвере, но он обязательно должен содержать DriverEntry и AddDevice .
IRP — это структура, которая используется драйверами для обмена данными.
- верхние фильтрующие драйверы;
- нижние фильтрующие драйверы.
Отличия между верхними и нижними фильтрующими драйверами
Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.
Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.
Проблемы синхронизации
В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:
Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.
Экшен
Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»
Также необходимо описать структуру DEVICE_EXTENSION
Объект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.
Начнем с функции, которая является главной точкой входа нашего драйвера.
theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:
Далее, как я и писал выше, нужно инициализировать указатели на функции
Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:
Эту функцию я опишу чуть ниже.
Возвращаем status , в котором, если функция InstallFilter завершилась удачей, хранится значение STATUS_SUCCESS .
Переходим к функции InstallFilter . Вот её прототип:
Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \Device\KeyboardClass0
pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства
- Первый аргумент это объект драйвера, который мы получили как параметр функции InstallFilter. Он передается в IoCreateDevice для того чтобы установить связь между нашим драйвером и новым устройством.
- Третий параметр это имя устройства
- Четвертый параметр это тип устройства
- Пятый параметр это флаги, которые обычно устанавливаются для запоминающих устройств.
- Шестой параметр описывает можно ли открывать манипуляторы устройства в количестве больше одного. Если FALSE можно открыть только один манипулятор. Иначе можно открыть любое количество манипуляторов.
- Седьмой параметр это память, в которой будем сохранен созданный объект устройства.
Флаги, которые мы устанавливаем для нашего устройства, должны быть эквивалентными флагам устройства, поверх которого мы включаемся в стек.
Далее мы должны выполнить преобразования имени устройства, которое мы включаем в стек.
Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.
Далее разберем функцию DispatchRead с прототипом:
Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросов
Перед тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.
где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:
Теперь разберем функцию, которая будет вызываться каждый раз при завершении IRP . Прототип:
Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.
Проверяем, удачно завершен запрос или нет
Чтобы достать структуру KEYBOARD_INPUT_DATA нужно обратиться к системному буферу IRP -пакета.
Узнаем количество клавиш
И выводим каждую клавишу:
И не забываем уменьшать количество не обработанных запросов
Возвращаем статус запроса
Разберем функцию завершения работы. Прототип:
Извлекаем устройство из стека:
Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.
Как запустить драйвер и просмотреть отладочную информацию
Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.
P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот
Выводы?
Как видите, имея права администратора, можно делать с компьютером практически что угодно. Будьте внимательны — установка утилит от производителя вашего железа может обернуться дырой в системе. Ну а желающие поэкспериментировать со своим ПК — добро пожаловать на низкий уровень! Наработки выложил на GitHub. Осторожно, бездумное использование чревато BSODами.
В Windows есть фича «Изоляция ядра», которая включает I/O MMU, защищает от DMA атак и так далее (кстати об этом — в следующих сериях)
Так вот, при включении этой опции, некоторые драйвера (в том числе RW Everything и китайско-подписанный chipsec_hlpr) перестают запускаться:
Простейший WDM-драйвер
В данной статье описан процесс написания простейшего драйвера, который выводит скан-коды нажатых клавиш.
Также в данной статье описан процесс настройки рабочего места для написания драйверов.
Если Вам интересно, прошу под кат.
Подготовка стенда
Установка необходимого ПО для написания простейшего драйвера
- Windows DDK (Driver Development Kit);
- VMware Workstation или Virtual Box;
- Windows XP;
- Visual Studio 2005;
- DDKWizard;
- KmdManager
- DebugView;
Настройка рабочего места
Установка DDK
Установка предельно проста. Единственное на что необходимо обратить внимание — это диалог, в котором Вам предлагается выбрать компоненты, которые будут установлены. Настоятельно рекомендую отметить всю документацию и примеры.
Установка и настройка Microsoft® Visual Studio 2005
Установка Microsoft® Visual Studio 2005 ничем не сложнее установки DDK. Если Вы будете использовать её только для написания драйверов, то когда инсталлятор спросит какие компоненты необходимо установить, выберите только Visual C++.
Далее можно установить Visual Assist X. С помощью этой программы (аддона) можно будет легко настроить подсказки для удобного написания драйверов.
После установки Visual Assist X в Visual Studio 2005 появится новое меню VAssistX. Далее в этом меню: Visual Assist X Options -> Projects -> C/C++ Directories -> Platform: Custom, Show Directories for: Stable include files . Нажимаем Ins или на иконку добавить новую директорию и в появившейся строке, если у вас Windows XP вписываем %WXPBASE%incddkwxp .
Установка и настройка DDKWizard
- Создать системные (рекомендуется) или пользовательские переменные со следующими именами и значением, которое соответствует пути к DDK
Версия DDK Имя переменной Путь по умолчанию Windows XP DDK WXPBASE C:WINDDK2600 Windows 2003 Server DDK WNETBASE C:WINDDK3790.1830 Windows Vista/Windows 2008 Server WDK WLHBASE Windows 7/Windows 2008 Server R2 WDK W7BASE Например, если я использую Windows XP DDK, то я должен создать переменную WXPBASE со значением, которое соответствует пути к DDK. Так как я не изменял путь установки, то значение у меня будет C:WINDDK2600.
- Скопируйте скачанный скрипт ddkbuild.cmd, например, в папку с DDK. У меня это C:WINDDK.
- Добавьте в конец системной переменной Path путь к скрипту ddkbuild.cmd.
Установка необходимого ПО для запуска драйверов
- DebugView (link) — это утилитка, которая позволяет просматривать отладочный вывод как режима пользователя так и режима ядра.
- KmdManager (link) — утилита динамической загрузки/выгрузки драйверов
Постановка задачи
Задача: написать драйвер, который будет выводить в дебаг скан-коды нажатых клавиш и их комбинаций.
Немного теории
- драйверы классов;
- минидрайверы;
- функциональные драйверы;
- фильтрующие драйверы.
Необязательно определять все возожные функции в своем драйвере, но он обязательно должен содержать DriverEntry и AddDevice .
IRP — это структура, которая используется драйверами для обмена данными.
- верхние фильтрующие драйверы;
- нижние фильтрующие драйверы.
Отличия между верхними и нижними фильтрующими драйверами
Через верхние фильтрующие драйверы проходят все запросы, а это значит, что они могут изменять и/или фильтровать информацию, идущую к функциональному драйверу, ну и далее, возможно, к устройству.
Пример использования верхних фильтрующих драйверов:
Фильтр-хук драйвер, который устанавливает свою хук-функцию для системного драйвера IpFilterDirver, для отслеживания и фильтрации траффика. Такие драйверы используются в брандмауэрах.
Через нижние фильтрующие драйверы проходит меньше запросов потому что большинство запросов выполняет и завершает функциональный драйвер.
Проблемы синхронизации
В драйвере, который мы будем писать, есть несколько «проблемных» секций. Для нашего драйвера вполне достаточно использования ассемблерных вставок:
Префикс lock позволяет безопасно выполнить идущую за ним команду. Она блокирует остальные процессоры, пока выполняется команда.
Экшен
Для начала необходимо включить заголовочные файлы «ntddk.h», «ntddkbd.h»
Также необходимо описать структуру DEVICE_EXTENSION
Объект pLowerDO это объект устройства, который находится ниже нас в стеке. Он нужен нам для того чтобы знать кому дальше отправлять IRP-пакеты.
Еще для работы нашего драйвера нам нужна переменная, в которой будет храниться количество не завершенных запросов.
Начнем с функции, которая является главной точкой входа нашего драйвера.
theDriverObject – объект драйвера, содержит указатели на все необходимые операционной системе функции, которые мы должны будем инициализировать.
ustrRegistryPath – имя раздела в реестре, где хранится информация о данном драйвере.
Для начала необходимо объявить и обнулить переменные:
Далее, как я и писал выше, нужно инициализировать указатели на функции
Функция DispatchRead будет обрабатывать запросы на чтение. Она будет вызываться, когда нажата или отпущена клавиша клавиатуры.
Функция DriverUnload вызывается, когда драйвер уже не нужен и его можно выгрузить из памяти, или когда пользователь сам выгружает драйвер. В данной функции должна производиться «зачистка», т.е. освобождаться ресурсы, которые использовались драйвером, завершаться все незавершенные запросы и т.д.
Функция DispatchThru это функция-заглушка. Все что она делает это передача IRP-пакета следующему драйверу (драйверу который находится под нашим в стеке, т.е. pLowerDO из DEVICE_EXTENSION ).
Далее мы вызываем нашу функцию, для создания и установки нашего устройства в стек устройств:
Эту функцию я опишу чуть ниже.
Возвращаем status , в котором, если функция InstallFilter завершилась удачей, хранится значение STATUS_SUCCESS .
Переходим к функции InstallFilter . Вот её прототип:
Эта функция создает объект устройства, настраивает его и включает в стек устройств поверх \Device\KeyboardClass0
pKeyboardDevice – это объект устройсва, которое мы должны создать.
Вызываем IoCreateDevice для создания нового устройства
- Первый аргумент это объект драйвера, который мы получили как параметр функции InstallFilter. Он передается в IoCreateDevice для того чтобы установить связь между нашим драйвером и новым устройством.
- Третий параметр это имя устройства
- Четвертый параметр это тип устройства
- Пятый параметр это флаги, которые обычно устанавливаются для запоминающих устройств.
- Шестой параметр описывает можно ли открывать манипуляторы устройства в количестве больше одного. Если FALSE можно открыть только один манипулятор. Иначе можно открыть любое количество манипуляторов.
- Седьмой параметр это память, в которой будем сохранен созданный объект устройства.
Флаги, которые мы устанавливаем для нашего устройства, должны быть эквивалентными флагам устройства, поверх которого мы включаемся в стек.
Далее мы должны выполнить преобразования имени устройства, которое мы включаем в стек.
Функция IoAttachDevice внедряет наше устройство в стек. В pdx->pLowerDO будет храниться объект следующего (нижнего) устройства.
Далее разберем функцию DispatchRead с прототипом:
Данная функция будет вызываться операционной системой при нажатии или отпускании клавиши клавиатуры
Увеличиваем счетчик незавершенных запросов
Перед тем как передать запрос следующему драйверу мы должны настроить указатель стека для драйвера. IoCopyCurrentIrpStackLocationToNext копирует участок памяти, который принадлежит текущему драйверу, в область памяти следующего драйвера.
Когда запрос идет вниз по стеку в нем еще нет нужных нам данных, поэтому мы должны задать функцию, которая вызовется, когда запрос будет идти вверх по стеку с нужными нам данными.
где ReadCompletionRoutine наша функция.
Передаем IRP следующему драйверу:
Теперь разберем функцию, которая будет вызываться каждый раз при завершении IRP . Прототип:
Структура PKEYBOARD_INPUT_DATA используется для описания нажатой клавиши.
Проверяем, удачно завершен запрос или нет
Чтобы достать структуру KEYBOARD_INPUT_DATA нужно обратиться к системному буферу IRP -пакета.
Узнаем количество клавиш
И выводим каждую клавишу:
И не забываем уменьшать количество не обработанных запросов
Возвращаем статус запроса
Разберем функцию завершения работы. Прототип:
Извлекаем устройство из стека:
Проверяем есть незавершенные запросы или нет. Если мы выгрузим драйвер без этой проверки, при первом нажатии на клавишу после выгрузки будет БСоД.
Как запустить драйвер и просмотреть отладочную информацию
Для запуска драйвера я использовал утилиту KmdManager. Для просмотра отладочной информации использовалась утилита DbgView.
P. S. Статью писал давно, ещё на третьем курсе, сейчас уже почти ничего не помню. Но если есть вопросы, постараюсь ответить.
P. P. S. Прошу обратить внимание на комментарии, в частности на этот
Читаем BIOS
В качестве примера применения нашего «тулкита», попробуем набросать скрипт чтения BIOS. Он должен быть «замаплен» где-то в конце 32-битного адресного пространства, потому что компьютер начинает его исполнение с адреса 0xFFFFFFF0. Обычно в ПК стоит флеш-память объёмом 4-16 МБ, поэтому будем «сканировать» адресное пространство с адреса 0xFF000000, как только найдём что-нибудь непустое, будем считать, что тут начался BIOS:
В результате получаем:
Вот так в 10 строчек мы считали BIOS
Но подождите-ка, получилось всего 6 мегабайт, а должно быть 4 или 8 что-то не сходится. А вот так, у чипсетов Intel в адресное пространство мапится не вся флешка BIOS, а только один её регион. И чтобы считать всё остальное, нужно уже использовать SPI интерфейс.
Не беда, лезем в даташит, выясняем, что SPI интерфейс висит на PCI Express:
И для его использования, нужно взаимодействовать с регистрами в BAR0 MMIO по алгоритму:
Задать адрес для чтения в BIOS_FADDR
Задать параметры команды в BIOS_HSFTS_CTL
Прочитать данные из BIOS_FDATA
Пилим новый скрипт для чтения через чипсет:
Исполняем и вуаля — в 20 строчек кода считаны все 8 МБ флешки BIOS! (нюанс — в зависимости от настроек, регион ME может быть недоступен для чтения).
Точно так же можно делать всё, что заблагорассудится — делать снифер USB пакетов, посылать произвольные ATA команды диску, повышать частоту процессора и переключать видеокарты. И это всё — с обычными правами администратора:
Немного помучившись, получаем ответ от SSD на команду идентификации
А если написать свой драйвер?
Некоторые из вас наверняка уже подумали — зачем так изворачиваться, реверсить чужие драйвера, если можно написать свой? И я о таком думал. Более того, есть Open-Source проект chipsec, в котором подобный драйвер уже разработан.
Зайдя на страницу с кодом драйвера, вы сразу наткнетесь на предупреждение:
В этом предупреждении как раз и описываются все опасности, о которых я рассказывал в начале статьи — инструмент мощный и опасный, следует использовать только в Windows режиме Test Mode, и ни в коем случае не подписывать. Да, без специальной подписи на обычной системе просто так запустить драйвер не получится. Поэтому в примере выше мы и использовали заранее подписанный драйвер от ASRock.
Если кто сильно захочет подписать собственный драйвер — понадобится регистрировать собственную компанию и платить Microsoft. Насколько я нагуглил, физическим лицам такое развлечение недоступно.
Точнее я так думал, до вот этой статьи, глаз зацепился за крайне интересный абзац:
У меня под рукой нет Windows DDK, так что я взял 64-битный vfd.sys , скомпилированный неким critical0, и попросил dartraiden подписать его «древне-китайским способом». Такой драйвер успешно загружается и работает, если vfdwin запущена с правами администратора
Драйвер из статьи действительно подписан, и действительно неким китайским ключом:
Как оказалось, сведения о подписи можно просто посмотреть в свойствах.. А я в HEX изучал
Немного поиска этого имени в гугле, и я натыкаюсь на вот эту ссылку, откуда узнаю, что:
есть давно утёкшие и отозванные ключи для подписи драйверов
если ими подписать драйвер — он прекрасно принимается системой
малварщики по всему миру используют это для создания вирусни
Основная загвоздка — заставить майкрософтский SignTool подписать драйвер истёкшим ключом, но для этого даже нашёлся проект на GitHub. Более того, я нашёл даже проект на GitHub для другой утилиты подписи драйверов от TrustAsia, с помощью которого можно подставить для подписи вообще любую дату.
Несколько минут мучений с гугл-переводчиком на телефоне, и мне удалось разобраться в этой утилите и подписать драйвер одним из утекших ключей (который довольно легко отыскался в китайском поисковике):
И в самом деле, китайская азбука
И точно так же, как и AsrDrv101, драйвер удалось без проблем запустить!
А вот и наш драйвер запустился
Из чего делаю вывод, что старая идея с написанием своего драйвера вполне себе годная. Как раз не хватает функции маппинга памяти. Но да ладно, оставлю как TODO.
Windows: достучаться до железа
Меня всегда интересовало низкоуровневое программирование – общаться напрямую с оборудованием, жонглировать регистрами, детально разбираться как что устроено. Увы, современные операционные системы максимально изолируют железо от пользователя, и просто так в физическую память или регистры устройств что-то записать нельзя. Точнее я так думал, а на самом деле оказалось, что чуть ли не каждый производитель железа так делает!
Через Python в дебри
Конечно же я захотел сделать свой небольшой «тулкит» для различных исследований и экспериментов на базе такого драйвера. Причём на Python, мне уж очень нравится, как просто выглядит реализация сложных вещей на этом языке.
Первым делом нужно установить драйвер в систему и запустить его. Делаем «как положено» и сначала кладём драйвер (нужной разрядности!) в System32:
Раньше в похожих ситуациях я извращался с папкой %WINDIR%Sysnative, но почему-то на моей текущей системе такого алиаса не оказалось, хотя Python 32-битный. (по идее, на 64-битных системах обращения 32-битных программ к папке System32 перенаправляются в папку SysWOW64, и чтобы положить файлик именно в System32, нужно обращаться по имени Sysnative).
Затем регистрируем драйвер в системе и запускаем его:
А дальше запущенный драйвер создаёт виртуальный файл (кстати, та самая колонка «имя» в таблице с анализом дров), через запросы к которому и осуществляются дальнейшие действия:
И ещё одна полезная программа для ползания по системе, WinObj
Тоже ничего особенного, открываем файл и делаем ему IoCtl:
Вот здесь чутка подробнее. Я долго думал, как же обеспечить адекватную обработку ситуации, когда таких «скриптов» запущено несколько. Не останавливать драйвер при выходе нехорошо, в идеале нужно смотреть, не использует ли драйвер кто-то ещё и останавливать его только если наш скрипт «последний». Долгие упорные попытки получить количество открытых ссылок на виртуальный файл драйвера ни к чему не привели (я получал только количество ссылок в рамках своего процесса). Причём сама система точно умеет это делать — при остановке драйвера с открытым файлом, он остаётся висеть в «Pending Stop». Если у кого есть идеи — буду благодарен.
В конечном итоге я «подсмотрел», как это делают другие программы. Выяснилось, что большинство либо не заморачиваются, либо просто ищут запущенные процессы с тем же именем. Но одна из исследованных программ имела кардинально другой подход, который я себе и перенял. Вместо того, чтобы переживать по количеству ссылок на файл, просто на каждый запрос открываем и закрываем файл! А если файла нет, значит кто-то остановил драйвер и пытаемся его перезапустить:
А дальше просто реверсим драйвер и реализуем все нужные нам вызовы:
Легко и непринуждённо в пару команд читаем физическую память
Прокси-драйвера
В итоге получается обходной манёвр – всё, что программе запрещено делать, разработчик вынес в драйвер, программа устанавливает драйвер в систему и уже через него программа делает, что хочет! Более того – выяснилось, что RW Everything далеко не единственная программа, которая так делает. Таких программ не просто много, они буквально повсюду. У меня возникло ощущение, что каждый уважающий себя производитель железа имеет подобный драйвер:
Софт для обновления BIOS (Asrock, Gigabyte, HP, Dell, AMI, Intel, Insyde…)
Софт для разгона и конфигурации железа (AMD, Intel, ASUS, ASRock, Gigabyte)
Софт для просмотра сведений о железе (CPU-Z, GPU-Z, AIDA64)
Софт для обновления PCI устройств (Nvidia, Asmedia)
Во многих из них практически та же самая модель поведения – драйвер получает команды по типу «считай-ка вот этот физический адрес», а основная логика – в пользовательском софте. Ниже в табличке я собрал некоторые прокси-драйвера и их возможности:
Результаты краткого анализа пары десятков драйверов. Могут быть ошибки!
Mem – чтение / запись физической памяти
PCI – чтение / запись PCI Configuration Space
I/O – чтение / запись портов I/O
Alloc – аллокация и освобождение физической памяти
Map – прямая трансляция физического адреса в вирутальный
MSR – чтение / запись x86 MSR (Model Specific Register)
Жёлтым обозначены возможности, которых явно нет, но их можно использовать через другие (чтение или маппинг памяти). Мой фаворит из этого списка – AsrDrv101 от ASRock. Он устроен наиболее просто и обладает просто огромным списком возможностей, включая даже функцию поиска шаблона по физической памяти (!!)
Неполный перечень возможностей AsrDrv101
Чтение / запись RAM
Чтение / запись IO
Чтение / запись PCI Configuration Space
Чтение / запись MSR (Model-Specific Register)
Чтение / запись CR (Control Register)
Чтение TSC (Time Stamp Counter)
Чтение PMC (Performance Monitoring Counter)
Alloc / Free физической памяти
Поиск по физической памяти
Самое нехорошее в такой ситуации — если подобный драйвер остаётся запущенным на ПК пользователя, для обращения к нему не нужно даже прав администратора! То есть любая программа с правами пользователя сможет читать и писать физическую память — хоть пароли красть, хоть ядро пропатчить. Именно на это уже ругались другие исследователи. Представьте, что висящая в фоне софтина, красиво моргающая светодиодиками на матплате, открывает доступ ко всей вашей системе. Или вирусы намеренно ставят подобный драйвер, чтобы закрепиться в системе. Впрочем, любой мощный инструмент можно в нехороших целях использовать.
В чём суть, капитан?
В архитектуре x86 есть понятие «колец защиты» («Ring») – режимов работы процессора. Чем ниже номер текущего режима, тем больше возможностей доступно исполняемому коду. Самым ограниченным «кольцом» является «Ring 3», самым привилегированным – «Ring -2» (режим SMM). Исторически сложилось, что все пользовательские программы работают в режиме «Ring 3», а ядро ОС – в «Ring 0»:
Режимы работы x86 процессора
В «Ring 3» программам запрещены потенциально опасные действия, такие как доступ к I/O портам и физической памяти. По логике разработчиков, настолько низкоуровневый доступ обычным программам не нужен. Доступ к этим возможностям имеют только операционная система и её компоненты (службы и драйверы). И всё бы ничего, но однажды я наткнулся на программу RW Everything:
RW Everything действительно читает и пишет практически всё
Эта программа была буквально напичкана именно теми функциями, которые обычно запрещаются программам «Ring 3» — полный доступ к физической памяти, I/O портам, конфигурационному пространству PCI (и многое другое). Естественно, мне стало интересно, как это работает. И выяснилось, что RW Everything устанавливает в систему прокси-драйвер:
Смотрим последний установленный драйвер через OSR Driver Loader
Читайте также:
- Кристальная оплетка horizon где достать
- Kingdom miyagi о чем
- Сколько стоит uni
- Почему нет настройки модов в скайрим
- Сколько всего сундуков в мондштате genshin impact
У нас Windows 10-64.
Задача разработать например драйвер устройства под Windows.
Устанавливаем Windows Device Driver Kit 7 :
Скачиваем с офф.сайта microsoft ISO, разархивируем , запустим KitSetup.exe
так выглядят в Панель управленияПрограммыПрограммы и компоненты
установлен у меня в C:WinDDK7600.16385.1
В C:WinDDK7600.16385.1src много примеров исходных кодов.
Примечание : если у вас уже установлен Win Driver Kit 10 , то придется удалить.
Фишка в том , что сборку надо запускать через запуск сначала командного файла (который устанавливает переменные среды) :
см. Пуск->Windows Driver
открывается консоль, где и надо ввести build (в каталоге вашего проекта). Процесс сборки выглядит примерно так:
для x64 входим через C:WindowsSystem32cmd.exe /k C:WinDDK7600.16385.1binsetenv.bat C:WinDDK7600.16385.1 fre x32-64
Windows 10 — надо сначала отключить проверку цифровой подписи (у меня срабатывает при нажатой SHIFT + клик Перезагрузка)
Отключаем.
Далее просто пробуем написать простейший kernel драйвер
На самом деле в дальнейшем в этой ветке сайта мы будем заниматься UMDF драйверами, но для проверки первого драйвера подвернулся пример driver.sys (kernel драйвер, драйвер уровня ядра)
Компилируем простейший драйвер (sys — кернел драйвер)
#include <wdm.h>
static
VOID Unload(DRIVER_OBJECT * pDriverObj)
{
DbgPrint("...........Unloadn");
}
NTSTATUS DriverEntry(DRIVER_OBJECT * pDriverObj, UNICODE_STRING * pRegPath)
{
DbgPrint("DriverEntry................n");
return STATUS_SUCCESS;
}
Для варианта сборки x86 пробуем зарегистрировать драйвер
Для варианта сборки amd64 получаем
Теперь по другому пробуем проверить запущен ли все-таки драйвер через программу OSR Driver Loader:
Получается драйвер все-таки запускается несмотря на ругань по поводу сертификата.
смотрим например еще так :
C:WINDOWSsystem32>sc query mydriver
Имя_службы: mydriver
Тип : 1 KERNEL_DRIVER
Состояние : 4 RUNNING
(STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN)
Код_выхода_Win32 : 0 (0x0)
Код_выхода_службы : 0 (0x0)
Контрольная_точка : 0x0
Ожидание : 0x0
osr driver loader — прекрасно и сама регистрирует / запускает / останавливает / удаляет драйвер. Только не забывайте перезагружаться.
Отладка
У нас на сайте см. отдельный раздел по отладке драйверов.
svthlsns.sys is part of Windows (R) Win 7 DDK driver and developed by Windows (R) Win 7 DDK provider according to the svthlsns.sys version information.
svthlsns.sys’s description is «LoadSense«
svthlsns.sys is digitally signed by Savitech Corp..
svthlsns.sys is usually located in the ‘c:program files (x86)savitechsvloadsensex64’ folder.
None of the anti-virus scanners at VirusTotal reports anything malicious about svthlsns.sys.
If you have additional information about the file, please share it with the FreeFixer users by posting a comment at the bottom of this page.
Vendor and version information [?]
The following is the available information on svthlsns.sys:
Property | Value |
---|---|
Product name | Windows (R) Win 7 DDK driver |
Company name | Windows (R) Win 7 DDK provider |
File description | LoadSense |
Internal name | SvThLSNS.sys |
Original filename | SvThLSNS.sys |
Legal copyright | © Microsoft Corporation. All rights reserved. |
Product version | 6.1.7600.16385 |
File version | 6.1.7600.16385 built by: WinDDK |
Here’s a screenshot of the file properties when displayed by Windows Explorer:
Product name | Windows (R) Win 7 DDK driver |
Company name | Windows (R) Win 7 DDK provider |
File description | LoadSense |
Internal name | SvThLSNS.sys |
Original filename | SvThLSNS.sys |
Legal copyright | © Microsoft Corporation. All rights.. |
Product version | 6.1.7600.16385 |
File version | 6.1.7600.16385 built by: WinDDK |
Digital signatures [?]
svthlsns.sys has a valid digital signature.
Property | Value |
---|---|
Signer name | Savitech Corp. |
Certificate issuer name | VeriSign Class 3 Code Signing 2010 CA |
Certificate serial number | 37bfbdc6cfddd02cdd8143446ae82a11 |
VirusTotal report
None of the 56 anti-virus programs at VirusTotal detected the svthlsns.sys file.
Hashes [?]
Property | Value |
---|---|
MD5 | f7bbfe134e2fb4f49bb836aa872fd505 |
SHA256 | cd8a5883c8a244bb35eae4d112b45c27f047feaa39ce539b4ebe462c6a5aed93 |
What will you do with svthlsns.sys?
To help other users, please let us know what you will do with svthlsns.sys:
What did other users do?
The poll result listed below shows what users chose to do with svthlsns.sys. 100% have voted for removal. Based on votes from 9 users.
Votes | |||
---|---|---|---|
Keep | 0 % | 0 | |
Remove | 100 % | 9 |
NOTE: Please do not use this poll as the only source of input to determine what you will do with svthlsns.sys. Only 9 users has voted so far so it does not offer a high degree of confidence.
Malware or legitimate?
If you feel that you need more information to determine if your should keep this file or remove it, please read this guide.
And now some shameless self promotion
Hi, my name is Roger Karlsson. I’ve been running this website since 2006. I want to let you know about the FreeFixer program. FreeFixer is a freeware tool that analyzes your system and let you manually identify unwanted programs. Once you’ve identified some malware files, FreeFixer is pretty good at removing them. You can download FreeFixer here. It runs on Windows 2000/XP/2003/2008/2016/2019/Vista/7/8/8.1/10. Supports both 32- and 64-bit Windows.
If you have questions, feedback on FreeFixer or the freefixer.com website, need help analyzing FreeFixer’s scan result or just want to say hello, please contact me. You can find my email address at the contact page.
File Info | Description |
---|---|
File Size: | 8.0 kB |
File Modification Date/Time: | 2017:03:18 18:18:17+00:00 |
File Inode Change Date/Time: | 2017:11:05 07:07:54+00:00 |
File Type: | Win32 EXE |
MIME Type: | application/octet-stream |
Machine Type: | Intel 386 or later, and compatibles |
Time Stamp: | 2016:11:01 02:09:09+00:00 |
PE Type: | PE32 |
Linker Version: | 11.0 |
Code Size: | 4608 |
Initialized Data Size: | 4608 |
Uninitialized Data Size: | 0 |
Entry Point: | 0x178a |
OS Version: | 6.3 |
Image Version: | 6.3 |
Subsystem Version: | 6.3 |
Subsystem: | Native |
File Version Number: | 6.3.9600.17336 |
Product Version Number: | 6.3.9600.17336 |
File Flags Mask: | 0x003f |
File Flags: | Private build |
File OS: | Windows NT 32-bit |
Object File Type: | Driver |
File Subtype: | 7 |
Language Code: | English (U.S.) |
Character Set: | Unicode |
Company Name: | Windows (R) Win 7 DDK provider |
File Description: | BCM Function 2 Device Driver |
File Version: | 6.3.9600.17336 |
Internal Name: | bcmfn2.sys |
Legal Copyright: | © Broadcom Corporation. All rights reserved. |
Original Filename: | bcmfn2.sys |
Product Name: | Windows (R) Win 7 DDK driver |
Product Version: | 6.3.9600.17336 |
✻ Portions of file data provided by Exiftool (Phil Harvey) distributed under the Perl Artistic License.
В нашей базе содержится 3 разных файлов с именем fwkbdrtm.sys . You can also check most distributed file variants with name fwkbdrtm.sys. Чаще всего эти файлы принадлежат продукту Windows (R) Win 7 DDK driver. Наиболее частый разработчик — компания Windows (R) Win 7 DDK provider. Самое частое описание этих файлов — Siemens Keyboard Filter Driver. Этот файл содержит драйвер. Вы можете найти его в разделе драйверов в System Explorer.
Подробности о наиболее часто используемом файле с именем «fwkbdrtm.sys»
- Продукт:
- Windows (R) Win 7 DDK driver
- Компания:
- Windows (R) Win 7 DDK provider
- Описание:
- Siemens Keyboard Filter Driver
- Версия:
- 6.1.7600.16385
- MD5:
- f51ae57cf9177010d4ae565f67ef7354
- SHA1:
- 3944657927d8db2da0562e2fc02dc4d936e0622c
- SHA256:
- 7e0770975e37c36910f34c4eb0c8b0b435439a6b229e20c2567ff8e37a317045
- Размер:
- 21464
- Папка:
- C:WindowsSystem32DRIVERS
- ОС:
- Windows XP
- Частота:
- Средняя
- Цифровая подпись:
- SIEMENS AG
Драйвер «fwkbdrtm.sys» безопасный или опасный?
Последний новый вариант файла «fwkbdrtm.sys» был обнаружен 3970 дн. назад. В нашей базе содержится 2 шт. вариантов файла «fwkbdrtm.sys» с окончательной оценкой Безопасный и ноль вариантов с окончательной оценкой Опасный . Окончательные оценки основаны на комментариях, дате обнаружения, частоте инцидентов и результатах антивирусных проверок.
Драйвер с именем «fwkbdrtm.sys» может быть безопасным или опасным. Чтобы дать правильную оценку, вы должны определить больше атрибутов файла. Самый простой способ это сделать — воспользоваться нашей бесплатной утилитой для проверки файлов посредством нашей базы данных. Эта утилита содержит множество функций для контролирования вашего ПК и потребляет минимум системных ресурсов.
Щёлкните здесь, чтобы загрузить System Explorer.
Комментарии пользователей для «fwkbdrtm.sys»
У нас пока нет комментариев пользователей к файлам с именем «fwkbdrtm.sys».
Добавить комментарий для «fwkbdrtm.sys»
Для добавления комментария требуется дополнительная информация об этом файле. Если вам известны размер, контрольные суммы md5/sha1/sha256 или другие атрибуты файла, который вы хотите прокомментировать, то вы можете воспользоваться расширенным поиском на главной странице .
Если подробности о файле вам неизвестны, вы можете быстро проверить этот файл с помощью нашей бесплатной утилиты. Загрузить System Explorer.
Проверьте свой ПК с помощью нашей бесплатной программы
System Explorer это наша бесплатная, удостоенная наград программа для быстрой проверки всех работающих процессов с помощью нашей базы данных. Эта программа поможет вам держать систему под контролем. Программа действительно бесплатная, без рекламы и дополнительных включений, она доступна в виде установщика и как переносное приложение. Её рекомендуют много пользователей.