На каком языке пишутся драйвера?
Драйвера пишутся на компилируемых языках, поддерживающих бинарные интерфейсы соостветствующих ОС. Это C, C++, assembler, кое-где psacal.
Python этим требованиям не соответствует.
Встречный вопрос: драйвером какого устройства хотите нас порадовать?
Ответ написан более трёх лет назад
Комментировать
Нравится 6 Комментировать
Влад Животнев @inkvizitor68sl
Linux-сисадмин с 8 летним стажем.
Драйвера чего к чему) ?
Если драйвера устройств к винде — то да, C/C++
Если драйвера стораджа к openstack — то они бывают и на python.
Ответ написан более трёх лет назад
Комментировать
Нравится 1 Комментировать
Frontend developer
Нельзя, нужен низкоуровневый язык.
Ответ написан более трёх лет назад
> Если нет, то почему ?
Прям вот только низкоуровневый? То есть на C++ писать уже нельзя, только на ассемблере?
Ваш ответ на вопрос
Войдите, чтобы написать ответ

- Python
Как сгенерировать случайное имя файла?
- 1 подписчик
- час назад
- 42 просмотра

- Python
Когда запускаю клиента вылетает из всех устройств?
- 1 подписчик
- 6 часов назад
- 43 просмотра
Для каких задач подходит Python: разбираемся вместе с NASA и опытными разработчиками
Python называют универсальным языком программирования. Он действительно подходит почти для любых задач или это просто миф?



Мария Даровская
Журналист, коммерческий автор и редактор. Пишет про IT, цифровой маркетинг и бизнес.
Сайт: darovska.com.
Python заслужил славу самого простого языка для входа в разработку — код на нём лаконичный и его легко читать. Мы решили разобраться, для каких задач он подходит и в какие проекты вписывается идеально, а на каких используется с ограничениями. Попутно расспросили бывалых питонистов, что они любят писать на Python, а что — не особо.
Невероятная популярность Python
«Я точно не собирался создавать язык, предназначенный для массового применения», — сказал как-то Гвидо ван Россум, создатель Python. В общем, он не специально 🙂 Сегодня Python — один из самых популярных языков программирования. Например, он несколько раз становился языком года по версии TIOBE.

По количеству проектов на GitHub он тоже держит отличные позиции — в 2020 году разменял свой миллион: больше проектов только у JS. То есть и на GitHub это самый популярный язык программирования, если вы понимаете, о чём мы 😉

Pinterest и Instagram* были написаны на Python. В ЦРУ использовали Python для создания своего хакерского инструментария, в Google — для поиска по веб-страницам, в Pixar — для производства фильмов, в Spotify — в рекомендательной системе. А ещё на Python кодят NASA и их подрядчики.
И это вполне оправданный выбор — помимо лаконичности, качества кода и низкого порога входа, в Python есть ещё одна киллер-фича: библиотеки практически для всего на свете — от разработки игр до астрономии и расчёта генетических алгоритмов (тот же DEAP). Шутка ли — участники комьюнити уже загрузили в сеть более 145 тысяч библиотек. Такими темпами скоро можно будет не писать программы на Python и он станет no-code-инструментом 🙂 Плюс Python может давать выигрыш в скорости создания программ по сравнению с другими языками в два или три раза.
Разберёмся, в каких направлениях и насколько успешно сегодня используют Python. Но мы же за визуальное сопровождение повествования, поэтому резюме по каждому направлению сделаем с помощью эмодзи. Вот наша объективнейшая система оценок:
— идеально подходит.
— вполне хорош.
— есть ограничения.
— к чёрту ваш Python (спойлер: этот смайлик больше не появится в статье).
Автоматизация и скрипты
Один из мифов о Python гласит, что это язык сценариев, а его конкуренты — Perl, Ruby, Bash, Zsh и Lua. Python и правда позволяет легко автоматизировать задачи и писать скрипты, да и файлы с Python-кодом часто называют сценариями, а не программами.

Михаил Корнеев
Тимлид в компании BestDoctor и автор YouTube-канала «Хитрый питон»
«Python — язык-клей, на котором можно быстро всё выстроить и объединить. Например, моему знакомому нужно было автоматизировать работу в Trello: ставить задачи, передавать статистику, строить графики, присылать напоминания при задержке сроков и так далее. Мы очень быстро нашли готовую Python-библиотеку для работы с Trello — и он выполнил эту задачу буквально за несколько дней».
Ещё программы на Python используют для управления компонентами других приложений — их подключают в контрольных точках, чтобы настроить продукт под конечного пользователя или выполнить какие-то рутинные операции, передать информацию с одного этапа на другой, то есть как своеобразный клей между большими блоками-кубиками.

Алексей Фирсов
Руководитель Python-практики в компании S7 TechLab
«Я играю в Factorio, там надо возить ресурсы с помощью поездов, управляя сигналами путей. Нужно было постоянно делать это вручную. Как-то я заскучал и написал на Python код, который загрузил в «Яндекс.Станцию». Теперь, когда я говорю: «Алиса, включи станцию угля», — у меня автоматически включается эта станция. Я сделал это за два дня.
А недавно знакомая попросила написать ей бота для онлайн-магазина. Он должен вести клиента по определённому маршруту и предлагать товары. Это заняло всего 10 часов».
Оценка: автоматизация и скрипты —
Машинное обучение
В ML, Big Data, AI и других модных словах Python — настоящий король. Он легко обходит главных конкурентов — R и Julia (см. нашу статью о языках программирования для ML). На Python собрано больше всего ML-проектов на GitHub. Лидирует он и в авторитетном рейтинге Towards Data Science.


А ещё у Python куча специализированных библиотек.
- Scikit-learn, на которой Spotify делает свою рекомендательную систему.
- Ramp на основе Pandas для быстрого прототипирования в ML.
- Культовая библиотека для машинного обучения TensorFlow, разработанная исследователями из группы Google Brain в рамках Google AI. Её используют для создания алгоритмов машинного обучения и моделирования сложных процессов.
- PyTorch для создания нейронных сетей.

Алексей Некрасов
Лидер направления Python в МТС, программный директор направления Python в Skillbox
«Я давно занимаюсь инвестициями — в «Тинькофф.Пульсе» можете найти меня под ником znbiz, а с недавних пор я ещё и разрабатываю свою платформу для управления инвестиционными портфелями. Вот как мне помог Python:
- Нужны были исторические данные — написал парсеры на Python.
- Нужно было сделать модель и обучить её на данных — и тут тоже мне помог Python.
- Нужно получать уведомления (удобнее всего через Telegram) — написал Telegram-бота на Python.
- Понадобился бэк для выгрузки портфелей — да Python именно для этого и создан».
Оценка: машинное обучение —
Анализ данных
В Python-библиотеках есть всё необходимое для работы с данными и их визуализации. Например, чтобы быстро создавать структуры и управлять ими, используют библиотеку Pandas. А визуализируют их с помощью Matplotlib, Seaborn или Plotly. Они позволяют рисовать много разных диаграмм и матриц.
Одна из фундаментальных библиотек — NumPy, она подходит для сложных вычислений и поддерживает многомерные массивы. Для работы с многомерными данными также используют набор инструментов PyOD, для индексации документов на естественном языке — Gensim, а со статистическими расчётами отлично справляется SciPy.
Поэтому Python по праву возглавляет рейтинги языков программирования для Data Analysis.

Также в Python предусмотрены интерфейсы для всех популярных реляционных баз данных — Sybase, Oracle, Informix, ODBC, MySQL, PostgreSQL, SQLite и так далее.

Сергей Гилев
Директор по аналитике компании Playkot
«Python — идеальный инструмент для анализа данных в любой сфере. Это было понятно, ещё когда я учился в университете на мехмате и изучал язык С. Я хотел освоить Python, но тогда у меня не было реальных задач, поэтому я придумал себе задачу сам. Как раз набирал обороты Instagram*, и я увидел, что мои фото получают разное количество лайков. Мне стало интересно проанализировать, от чего зависит их количество.
В то время я ещё почти ничего не знал про Python и анализ данных. Но благодаря этой задаче разобрался с API Instagram*, освоил пакет request, научился работать с БД из Python. В итоге регулярно собирал данные, сколько лайков и комментариев набирали фотографии, — потом это пригодилось в работе».
Оценка: анализ данных —
Драйверы и программирование железа
Python используют, чтобы запрограммировать различные устройства, но это не самый популярный язык для драйверов. Программы на Python часто разворачивают в среде более крупных приложений. Например, для тестирования аппаратных устройств программы на Python могут обращаться к разным компонентам, которые умеют работать на аппаратном уровне. А на GitHub можно найти множество примеров самописных драйверов для джойстиков и контроллеров.

Драйверы на Python пишут для различных ОС — например, вот интересный пост о драйверах PlayStation, написанных на Python под Linux. У некоторых брендов есть даже свои Python-библиотеки с набором модулей — как, например, у компании NI, которая делает оборудование и ПО для автопрома, космоса, оборонки и энергетики.
Правда, у Python есть большая проблема — низкая скорость исполнения. Поэтому драйвера на нём подходят лишь для тех устройств, которые не особо требовательны к ресурсам. Под видеокарты драйвера обычно пишут на более скоростных и низкоуровневых языках — C, C++, Assembler.

Алексей Фирсов
Руководитель Python-практики в компании S7 TechLab
«Python позволяет быстро написать драйвера для любого железа. Когда я работал в компании, которая занималась киберпрограммированием и офлайн-квестами, у нас появилась задача — запрограммировать контроллеры, чтобы двери во время квеста открывались в нужное время. Мы написали их на Python — всё работало хорошо и стабильно.
Ещё один пример программирования контроллеров — программа лояльности. Я написал драйвер для сканера штрихкодов за три часа. В тест система ушла уже на следующий день, а в продакшн — через месяц. В итоге сеть два года проработала на этом драйвере. На Node.js это заняло бы гораздо больше времени».
Оценка: драйверы и программирование железа —
Прототипирование
Python быстрее и проще в работе, чем большинство других языков программирования. Это гибкий язык, который очень легко читать и понимать. Python позволяет совместить в одной программе функциональную, объектно-ориентированную, структурную, аспектно-ориентированную парадигмы программирования — так можно быстро опробовать несколько парадигм и выбрать подходящую, не меняя язык.
Кроме того, с точки зрения Python-программ компоненты, написанные на Python и С, выглядят одинаково. Поэтому нередко систему вначале быстро собирают и тестируют на Python, а потом уже переносят самые требовательные к ресурсам компоненты на компилируемые языки типа С или C++.
Высокая скорость разработки прототипов возможна благодаря большому количеству библиотек и динамической типизации Python. Поэтому его активно используют для экстремального программирования и проверки гипотез.

Алексей Фирсов
Руководитель Python-практики в компании S7 TechLab
«Для любого прототипа подойдёт Python, но только до достижения определённого количества пользователей, которые одновременно будут работать с сервисом. Для меня это планка в 10 тысяч человек. Когда она будет пройдена, стоит подумать про Go. Хотя возможностей Python может хватить и для этого числа пользователей — всё зависит от проекта.
Но эта особенность не должна останавливать проекты на Python, потому что при масштабировании проект всё равно переписывают, на каком бы языке он ни был написан. Ведь за время роста меняются технологии, появляются новые фреймворки — переделок не избежать».
Оценка: прототипирование —
GameDev
Хотя стандартом отрасли считаются языки С и C++, Python также можно встретить в игровой индустрии. Да, на Python не пишется ядро игр, но его применяют для описания логики и сценариев. Например, на Python пишет игры компания CCP Games — та же MMORPG EVE Online почти полностью написана на «удаве». При этом в игре одновременно находится от 15 до 50 тысяч игроков — и она неплохо выдерживает такую нагрузку.

Python используют и в культовом World of Tanks — для некоторых компонентов интерфейса и внутриигровых скриптов. Например, код на Python отвечает за состояние маркеров и прицелов (для каждого типа есть свой Python-класс). А вот за расположение маркеров и прицелов на экране отвечает уже клиентский C++-код.

Чаще всего Python используется в разработке игр как дополнительный, встраиваемый в движок скриптовый язык. Программирование игр и создание мультимедийного контента возможно с помощью библиотек pygame, cgkit, pyglet, РуSoy, PandaBD. Но всё-таки Python — далеко не самый популярный инструмент для геймдева. Делать на нём сложную красивую графику и движки требовательных к ресурсам игр — не лучшее решение.
Оценка: GameDev —
Минусы Python
Одним из недостатков Python называют его интерпретируемость. Это замедляет работу масштабных проектов. Считается, что, если ваш проект рассчитан на плотную нагрузку, вам больше подойдут Go или C++ — у скомпилированных языков процесс обработки происходит быстрее. По этой же причине опытные разработчики не советуют обрабатывать видео на Python.

Алексей Фирсов
Руководитель Python-практики в компании S7 TechLab
«Я бы не советовал делать на Python сложный рендеринг видео — например, как на YouTube. Python всё равно проиграет в скорости».
Но у интерпретируемости есть и преимущество — писать программы на Python гораздо быстрее, а объём кода обычно в 3−5 раз меньше аналогичных листингов Java и в 5−10 раз меньше эквивалентного кода на C++.
Зачастую Python-код в 1000 раз медленнее аналогичного кода на C/C++. Он не подходит для ПО, которое работает в режиме реального времени и требует минимальных задержек. Тем не менее Python уже неоднократно оптимизировали, и в большинстве сфер он работает достаточно шустро.
Так что всякий раз, когда вы пишете на Python задачу вроде обработки файла или конструирования графического пользовательского интерфейса, программа будет выполняться со скоростью языка С, потому что тут же привязывается к скомпилированному коду на С внутри интерпретатора Python. В итоге выигрыш в скорости разработки на Python чаще всего оказывается выгоднее, чем любые потери в скорости исполнения, особенно учитывая производительность современных компьютеров.
Ещё один минус и плюс одновременно — динамическая типизация. Она также существенно упрощает и ускоряет процесс кодинга, но увеличивает количество возможных ошибок, особенно у неопытного разработчика. Для масштабных проектов всё-таки больше подойдёт статическая типизация.
Python имеет низкий порог вхождения, простой и понятный синтаксис, лаконичный код. Но простоту для входа новичков эксперты называют и минусом — по их словам, на Python легко написать плохой код.

Алексей Фирсов
Руководитель Python-практики в компании S7 TechLab
«Код, написанный новичком, будет корявым — и хотя он будет работать, потом в этом коде будет тяжело разобраться. Потому что Python даёт карт-бланш: ты можешь делать всё. А раз можно написать код плохо, то большинство напишет плохо, потому что будет лень писать хорошо».
Так для чего же подходит Python
Python — действительно универсальный инструмент. Его с удовольствием используют в проектах по машинному обучению и аналитике данных. Применяют для автоматизации, прототипирования и написания драйверов. Правда, в обработке видео, 3D-графике и GameDev у него есть серьёзные ограничения. Тем не менее Python задействуют и в таких проектах — используют для некоторых компонентов интерфейса и внутриигровых скриптов.
Вы тоже можете научиться решать задачи любого уровня сложности с помощью Python, ведь он просто идеален для новичков или как второй язык. Изучить его можно на нашем курсе «Профессия Python-разработчик».
Windows: достучаться до железа

Меня всегда интересовало низкоуровневое программирование – общаться напрямую с оборудованием, жонглировать регистрами, детально разбираться как что устроено. Увы, современные операционные системы максимально изолируют железо от пользователя, и просто так в физическую память или регистры устройств что-то записать нельзя. Точнее я так думал, а на самом деле оказалось, что чуть ли не каждый производитель железа так делает!
В чём суть, капитан?
В архитектуре x86 есть понятие «колец защиты» («Ring») – режимов работы процессора. Чем ниже номер текущего режима, тем больше возможностей доступно исполняемому коду. Самым ограниченным «кольцом» является «Ring 3», самым привилегированным – «Ring -2» (режим SMM). Исторически сложилось, что все пользовательские программы работают в режиме «Ring 3», а ядро ОС – в «Ring 0»:

В «Ring 3» программам запрещены потенциально опасные действия, такие как доступ к I/O портам и физической памяти. По логике разработчиков, настолько низкоуровневый доступ обычным программам не нужен. Доступ к этим возможностям имеют только операционная система и её компоненты (службы и драйверы). И всё бы ничего, но однажды я наткнулся на программу RW Everything:

Эта программа была буквально напичкана именно теми функциями, которые обычно запрещаются программам «Ring 3» — полный доступ к физической памяти, I/O портам, конфигурационному пространству PCI (и многое другое). Естественно, мне стало интересно, как это работает. И выяснилось, что RW Everything устанавливает в систему прокси-драйвер:

Прокси-драйвера
В итоге получается обходной манёвр – всё, что программе запрещено делать, разработчик вынес в драйвер, программа устанавливает драйвер в систему и уже через него программа делает, что хочет! Более того – выяснилось, что 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)
- Чтение CPUID
- Alloc / Free физической памяти
- Поиск по физической памяти
Самое нехорошее в такой ситуации — если подобный драйвер остаётся запущенным на ПК пользователя, для обращения к нему не нужно даже прав администратора! То есть любая программа с правами пользователя сможет читать и писать физическую память — хоть пароли красть, хоть ядро пропатчить. Именно на это уже ругались другие исследователи. Представьте, что висящая в фоне софтина, красиво моргающая светодиодиками на матплате, открывает доступ ко всей вашей системе. Или вирусы намеренно ставят подобный драйвер, чтобы закрепиться в системе. Впрочем, любой мощный инструмент можно в нехороших целях использовать.
Через Python в дебри
Конечно же я захотел сделать свой небольшой «тулкит» для различных исследований и экспериментов на базе такого драйвера. Причём на Python, мне уж очень нравится, как просто выглядит реализация сложных вещей на этом языке.
Первым делом нужно установить драйвер в систему и запустить его. Делаем «как положено» и сначала кладём драйвер (нужной разрядности!) в System32:
#puts the driver into Windows/System32/drivers folder def SaveDriverFile(self): winPath = os.environ['WINDIR'] sys32Path = os.path.join(winPath, "System32") targetPath = os.path.join(sys32Path, "drivers\\" + self.name + ".sys") file_data = open(self.file_path, "rb").read() open(targetPath, "wb").write(file_data)
Раньше в похожих ситуациях я извращался с папкой %WINDIR%\Sysnative, но почему-то на моей текущей системе такого алиаса не оказалось, хотя Python 32-битный. (по идее, на 64-битных системах обращения 32-битных программ к папке System32 перенаправляются в папку SysWOW64, и чтобы положить файлик именно в System32, нужно обращаться по имени Sysnative).
Затем регистрируем драйвер в системе и запускаем его:
#registers the driver for further startup def RegisterDriver(self): serviceManager = win32service.OpenSCManager(None, None, win32service.SC_MANAGER_ALL_ACCESS) driverPath = os.path.join(os.environ['WINDIR'], 'system32\\drivers\\' + self.name + '.sys') serviceHandle = win32service.CreateService(serviceManager,self.name,self.name, win32service.SERVICE_ALL_ACCESS, win32service.SERVICE_KERNEL_DRIVER, win32service.SERVICE_DEMAND_START, win32service.SERVICE_ERROR_NORMAL, driverPath, None,0,None,None,None) win32service.CloseServiceHandle(serviceManager) win32service.CloseServiceHandle(serviceHandle) #starts the driver def RunDriver(self): win32serviceutil.StartService(self.name)
А дальше запущенный драйвер создаёт виртуальный файл (кстати, та самая колонка «имя» в таблице с анализом дров), через запросы к которому и осуществляются дальнейшие действия:

Тоже ничего особенного, открываем файл и делаем ему IoCtl:
#tries to open the driver by name def OpenDriver(self): handle = win32file.CreateFile("\\\\.\\" + self.name, win32file.FILE_SHARE_READ | win32file.FILE_SHARE_WRITE, 0, None, win32file.OPEN_EXISTING, win32file.FILE_ATTRIBUTE_NORMAL | win32file.FILE_FLAG_OVERLAPPED, None) if handle == win32file.INVALID_HANDLE_VALUE: return None return handle #performs IOCTL! def IoCtl(self, ioctlCode, inData, outLen=0x1100): out_buf = win32file.DeviceIoControl(self.dh,ioctlCode,inData,outLen,None) return out_buf
Вот здесь чутка подробнее. Я долго думал, как же обеспечить адекватную обработку ситуации, когда таких «скриптов» запущено несколько. Не останавливать драйвер при выходе нехорошо, в идеале нужно смотреть, не использует ли драйвер кто-то ещё и останавливать его только если наш скрипт «последний». Долгие упорные попытки получить количество открытых ссылок на виртуальный файл драйвера ни к чему не привели (я получал только количество ссылок в рамках своего процесса). Причём сама система точно умеет это делать — при остановке драйвера с открытым файлом, он остаётся висеть в «Pending Stop». Если у кого есть идеи — буду благодарен.
В конечном итоге я «подсмотрел», как это делают другие программы. Выяснилось, что большинство либо не заморачиваются, либо просто ищут запущенные процессы с тем же именем. Но одна из исследованных программ имела кардинально другой подход, который я себе и перенял. Вместо того, чтобы переживать по количеству ссылок на файл, просто на каждый запрос открываем и закрываем файл! А если файла нет, значит кто-то остановил драйвер и пытаемся его перезапустить:
#perform IOCTL! def IoCtl(self, ioctlCode, inData, outLen=0x1100): #open driver file link driverHandle = self.OpenDriver() if driverHandle is None: self.ReinstallDriver() driverHandle = self.OpenDriver() #second try if driverHandle is None: return None #perform IOCTL out_buf = win32file.DeviceIoControl(driverHandle,ioctlCode,inData,outLen,None) #close driver file link win32file.CloseHandle(driverHandle) return out_buf
А дальше просто реверсим драйвер и реализуем все нужные нам вызовы:
class PmxInterface: def __init__(self): self.d = PmxDriver("AsrDrv101") def MemRead(self, address, size, access=U8): buf = ctypes.c_buffer(size) request = struct.pack("

PCI Express Config Space
Немного отвлечёмся на один нюанс про PCIE Config Space. С этим адресным пространством не всё так просто - со времён шины PCI для доступа к её конфигурационному пространству используется метод с использованием I/O портов 0xCF8 / 0xCFC. Он применён и в нашем драйвере AsrDrv101:

Но через этот метод доступны только 0x100 байт конфигурационного пространства, в то время как в стандарте PCI Express размер Config Space у устройств может быть достигать 0x1000 байт! И полноценно вычитать их можно только обращением к PCI Extended Config Space, которая замаплена где-то в адресном пространстве, обычно чуть пониже BIOS:

На чипсетах Intel (ну, в их большинстве) указатель на эту область адресного пространства можно взять из конфига PCI устройства 0:0:0 по смещению 0x60, подробнее описано в даташитах:

У AMD я такого не нашёл (наверняка есть, плохо искал), но сам факт неуниверсальности пнул меня в сторону поиска другого решения. Погуглив стандарты, я обнаружил, что указатель на эту область передаётся системе через ACPI таблицу MCFG
А сами ACPI таблицы можно найти через запись RSDP, поискав её сигнатуру по адресам 0xE0000-0xFFFFF, а затем распарсив табличку RSDT. Отлично, здесь нам и пригодится функционал поиска по памяти. Получаем нечто такое:
rsdp = self.PhysSearch(0xE0000, 0x20000, b"RSD PTR ", step=0x10) #use rsdt only for simplicity rsdt = self.MemRead32(rsdp + 0x10) (rsdtSign, rsdtLen) = struct.unpack("
На всякий случай оставляем вариант для чипсетов Intel
if self.PciRead16(PciAddress(0,0,0,0)) == 0x8086: #try intel way pciexbar = self.PciRead64(PciAddress(0,0,0,0x60)) if pciexbar & 1: self.pciMmTopBus = (1 > 1) & 3))) - 1 self.pciMmAddress = pciexbar & 0xFFFF0000
Всё, теперь осталось при необходимости заменить чтение PCI Express Config Space через драйвер на чтение через память. Теперь-то разгуляемся!
Читаем BIOS
В качестве примера применения нашего "тулкита", попробуем набросать скрипт чтения BIOS. Он должен быть "замаплен" где-то в конце 32-битного адресного пространства, потому что компьютер начинает его исполнение с адреса 0xFFFFFFF0. Обычно в ПК стоит флеш-память объёмом 4-16 МБ, поэтому будем "сканировать" адресное пространство с адреса 0xFF000000, как только найдём что-нибудь непустое, будем считать, что тут начался BIOS:
from PyPmx import PmxInterface pmx = PmxInterface() for i in range(0xFF000000, 0x100000000, 0x10000): data = pmx.MemRead(i, 0x20) if data != b"\xFF"*0x20 and data != b"\x00"*0x20: biosLen = 0x100000000-i print("BIOS Found at 0x%x" % i) f = open("dump.bin", "wb") for j in range(0, biosLen, 0x1000): data = pmx.MemRead(i + j, 0x1000) f.write(data) break
В результате получаем:

Но подождите-ка, получилось всего 6 мегабайт, а должно быть 4 или 8 что-то не сходится. А вот так, у чипсетов Intel в адресное пространство мапится не вся флешка BIOS, а только один её регион. И чтобы считать всё остальное, нужно уже использовать SPI интерфейс.
Не беда, лезем в даташит, выясняем, что SPI интерфейс висит на PCI Express:

И для его использования, нужно взаимодействовать с регистрами в BAR0 MMIO по алгоритму:
- Задать адрес для чтения в BIOS_FADDR
- Задать параметры команды в BIOS_HSFTS_CTL
- Прочитать данные из BIOS_FDATA
Пилим новый скрипт для чтения через чипсет:
from PyPmx import PmxInterface, PciAddress, U32 spi = PciAddress(0, 31, 5) pmx = PmxInterface() spiMmio = pmx.PciRead32(spi + 0x10) & 0xFFFFF000 f = open("dump.bin", "wb") for i in range(0, 0x800000, 0x40): # write BIOS_FADDR pmx.MemWrite32(spiMmio + 0x08, i) # write BIOS_HSFTS_CTL # read 0x40 bytes start clear fcerr & fgo cmd = (0
Исполняем и вуаля - в 20 строчек кода считаны все 8 МБ флешки BIOS! (нюанс - в зависимости от настроек, регион ME может быть недоступен для чтения).
Точно так же можно делать всё, что заблагорассудится - делать снифер USB пакетов, посылать произвольные ATA команды диску, повышать частоту процессора и переключать видеокарты. И это всё - с обычными правами администратора:

А если написать свой драйвер?
Некоторые из вас наверняка уже подумали - зачем так изворачиваться, реверсить чужие драйвера, если можно написать свой? И я о таком думал. Более того, есть Open-Source проект chipsec, в котором подобный драйвер уже разработан.
Зайдя на страницу с кодом драйвера, вы сразу наткнетесь на предупреждение:
. !! !! Chipsec should only be run on test systems! !! It should not be installed/deployed on end-user systems! !! !! There are multiple reasons for that: !! !! 1. Chipsec kernel drivers provide raw access to HW resources to !! user-mode applications (like access to physical memory). This would !! allow malware to compromise the OS kernel. !! 2. The driver is distributed as a source code. In order to load it !! on OS which requires signed drivers (e.g. x64 Microsoft Windows 7 !! and higher), you'll need to enable TestSigning mode and self-sign !! the driver binary. Enabling TestSigning (or equivalent) mode also !! turns off important protection of OS kernel. !! !! 3. Due to the nature of access to HW resources, if any chipsec module !! issues incorrect access to these HW resources, OS can crash/hang. !! !! If, for any reason, you want to production sign chipsec driver and !! deploy chipsec on end-user systems, !! DON'T! !! .
В этом предупреждении как раз и описываются все опасности, о которых я рассказывал в начале статьи - инструмент мощный и опасный, следует использовать только в Windows режиме Test Mode, и ни в коем случае не подписывать. Да, без специальной подписи на обычной системе просто так запустить драйвер не получится. Поэтому в примере выше мы и использовали заранее подписанный драйвер от ASRock.
Если кто сильно захочет подписать собственный драйвер - понадобится регистрировать собственную компанию и платить Microsoft. Насколько я нагуглил, физическим лицам такое развлечение недоступно.
Точнее я так думал, до вот этой статьи, глаз зацепился за крайне интересный абзац:
У меня под рукой нет Windows DDK, так что я взял 64-битный vfd.sys , скомпилированный неким critical0, и попросил dartraiden подписать его «древне-китайским способом». Такой драйвер успешно загружается и работает, если vfdwin запущена с правами администратора
Драйвер из статьи действительно подписан, и действительно неким китайским ключом:

Немного поиска этого имени в гугле, и я натыкаюсь на вот эту ссылку, откуда узнаю, что:
- есть давно утёкшие и отозванные ключи для подписи драйверов
- если ими подписать драйвер - он прекрасно принимается системой
- малварщики по всему миру используют это для создания вирусни
Основная загвоздка - заставить майкрософтский SignTool подписать драйвер истёкшим ключом, но для этого даже нашёлся проект на GitHub. Более того, я нашёл даже проект на GitHub для другой утилиты подписи драйверов от TrustAsia, с помощью которого можно подставить для подписи вообще любую дату.
Несколько минут мучений с гугл-переводчиком на телефоне, и мне удалось разобраться в этой утилите и подписать драйвер одним из утекших ключей (который довольно легко отыскался в китайском поисковике):

И точно так же, как и AsrDrv101, драйвер удалось без проблем запустить!

Из чего делаю вывод, что старая идея с написанием своего драйвера вполне себе годная. Как раз не хватает функции маппинга памяти. Но да ладно, оставлю как TODO.
Выводы?
Как видите, имея права администратора, можно делать с компьютером практически что угодно. Будьте внимательны - установка утилит от производителя вашего железа может обернуться дырой в системе. Ну а желающие поэкспериментировать со своим ПК - добро пожаловать на низкий уровень! Наработки выложил на GitHub. Осторожно, бездумное использование чревато BSODами.
В Windows есть фича "Изоляция ядра", которая включает I/O MMU, защищает от DMA атак и так далее (кстати об этом - в следующих сериях)

Так вот, при включении этой опции, некоторые драйвера (в том числе RW Everything и китайско-подписанный chipsec_hlpr) перестают запускаться:

Тем не менее, рассмотренный пример утилиты на базе AsrDrv работает:
На каком языке пишут драйвера?
я знаком с языками программирования turbo pascal,c++ (GCC) (если честно то только начал). на каком языке пишутся драйвера? не думаю что на одном из этих. Может на ассамблере? И как они пишутся? ссылки приветствуются.
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
Ответы с готовыми решениями:
На каком языке нужно писать драйвера?
У меня проблема.Старый принтер и сканер не работают с 8 и 10.Хочу сам написать для них.
На каком именно ассемблере пишут драйверы?
Всем доброго времени суток! Изучал с горем пополам ассемблер. В Linux, компилятор был nasm. Узнал.
На каком языке пишут программы под линукс
На каком языке пишут программы под линукс и в какой среде?
На каком языке пишут браузерные онлайн игры?
С помощью каких технологий? То, что один человек не может написать такую игру, это я понимаю.
Просто прогер
1292 / 1079 / 13
Регистрация: 13.03.2009
Сообщений: 2,502
Только это тебе не оконные прожки клепать!
Регистрация: 31.07.2010
Сообщений: 20
Драйвера можно писать на любом языке - был бы соответствующий компилятор, обычные средства не пойдут, например, для драйверов под Windows существует пакет DDK (сейчас переименовали в WDK), там используется Си.
Майкрософт не гарантирует корректную работу драйвера собранного другими инструментами.
К-стати насчет ассемблера - DDK позволяет полностью обойтись без него.
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
Сообщение от tig1818c 
Драйвера можно писать на любом языке - был бы соответствующий компилятор
Интересно будет посмотреть на драйвер, написанный на коболе, алголе или фортране
Регистрация: 31.07.2010
Сообщений: 20
Ищущий да обрящет. Найди соответствующий компилятор, и смотри сколько влезет. Думаю, ничего нового не увидишь
Регистрация: 02.08.2010
Сообщений: 270
или на алмире и на каком-нибудь там "Ралира"
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
tig1818c, мне интересно было посмотреть на драйвер (на его исходники, написанные на одном из обозначенных языков). Сколько влезет смотреть на соответствующий компилятор у меня интереса нет
Регистрация: 31.07.2010
Сообщений: 20
Хоть на русском матерном, повторяю, вся проблема в отсутствии среды компиляции
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
Сообщение от tig1818c 
Хоть на русском матерном, повторяю, вся проблема в отсутствии среды компиляции
Ого, уже и среда появилась. А мне казалось, что в предельном случае для написания драйвера достаточно шестнадцатиричного редактора. Слушай, будь другом, напиши мне драйвер на русском, а то жуть как посмотреть охота
Регистрация: 31.07.2010
Сообщений: 20
Могу и на русском, если Вы что-нибудь слышали про Эль-76, но повторяю, исходный текст никогда не превратится в машинный код
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
Сообщение от tig1818c 
Могу и на русском
Давай, напиши. Драйвер мыши не сложно будет для начала?
Сообщение от tig1818c 
если Вы что-нибудь слышали про Эль-76
Допустим, слышал, только не понимаю, как соотносится эль-76 и драйвер?
Сообщение от tig1818c 
но повторяю, исходный текст никогда не превратится в машинный код
А на русский язык сию великую мысль можешь перевести? А то я так и не могу понять, напишешь ты мне драйвер на фортране или нет
Регистрация: 31.07.2010
Сообщений: 20
Немного странно звучит вопрос - причем, допустим Си и драйвер? Эль-76 (другое название Автокод Эльбрус) местами даст большую фору С++. Жаль что слишком машинноориентирован, очень сложный компилятор получается для арифмометров Intel-платформы
Добавлено через 4 минуты
Что касается перевода на русский: может, я мыслю древними понятиями, но они мне привычнее: исходный текст (неважно на каком языке) называется ТЕКСТОМ ПРОГРАММЫ, а результат работы транслятора - КОДОМ ПРОГРАММЫ
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
> причем, допустим Си и драйвер?
Допустим при том, что на Си, как уже говорилось выше, можно написать драйвер. Потом речь зашла о том, что драйвер вроде бы как можно написать на любом языке. Я высказал желание посмотреть на драйвер, написанный на алголе, коболе или фортране. Мне в ответ было сказано, что можно написать на русском или эль76. На предложение написать драйвер на русском опять конкретного ответа не последовало. Вопрос про "при чём тут эль76" касался впервую очередь того, что были обозначены три вполне конкретных языка и мне непонятно было зачем сюда приплетать ещё один язык, про который кроме дремучих советских академиков никто не знает. Но если ты так хочешь - давай приплетём
Не хотелось бы трогать эльбрусы и эль-76 (для которого, кстати, проще написать конвертор в си, чем компилятор), а хотелось бы услышать внятный ответ на вопрос: будешь ты мне приводить фрагменты драйвера на одном из трёх указанных выше языков (алгол, кобол, фортран), или не будешь? Под внятным ответом подразумевается что-то типа "да", "нет", "пошёл на . " и т.п., но никак не "в то время как космические корабли бороздят просторы вселенной"
Добавлено через 1 минуту
Сообщение от tig1818c 
Что касается перевода на русский: может, я мыслю древними понятиями, но они мне привычнее: исходный текст (неважно на каком языке) называется ТЕКСТОМ ПРОГРАММЫ, а результат работы транслятора - КОДОМ ПРОГРАММЫ
Неприниципально. Ни у кого возражений по этому поводу не возникало.
Регистрация: 31.07.2010
Сообщений: 20
Не хотелось бы трогать эльбрусы и эль-76.
Ну спасибо, к академикам меня еще не подшивали, вроде не такой дремучий.
Теперь "про драйвер мыши на фортране". Писать его, естественно, никто не собирается. Вы это хотели от меня? Тем более что изначально я утверждал что это "в принципе возможно", и не более.
Вряд-ли кто-то станет добывать огонь трением, когда в кармане зажигалка.
![]()
![]()
21275 / 8292 / 637
Регистрация: 30.03.2009
Сообщений: 22,656
Записей в блоге: 30
Сообщение от tig1818c 
Тем более что изначально я утверждал что это "в принципе возможно", и не более. Вряд-ли кто-то станет добывать огонь трением, когда в кармане зажигалка
ВОТ! Наконец-то услышал что-то конкретное. После чего все свои вопросы снимаю. А если честно, то я попросту подумал, что на форуме появился очередной залётный умник, который услыхал умных слов типа "драйвер" или "эль-76" и начал гнуть пальцы. Так что извиняй, обознался
А что касается изначального вопроса polimorf96, то ответить можно следующее. Драйвер - это точка состыковки между аппаратурой и прикладным софтом. Драйвер является частью операционной системы. Работа с аппаратурой как правило состоит в чтении-записи данных из портов ввода-вывода. Это некие специальные адреса памяти, которые ассоциируются с аппаратурой. А потому теоретически драйвер и вправду можно написать на любом языке. Но для нормальной и удобной работы с памятью крайне желательно, чтобы язык обладал такой вещью, как указатель, а потмоу большинство языков просто идут лесом. Язык должен иметь компилятор (а не интерпретатор), потому что драйвер всегда должен работать как native код, а не интерпретироваться, а следовательно другая часть языков так же идёт лесом. На большинстве современных архитектур при работе с аппаратурой требуются специфические операции, которые не выражаются в терминах языка программирования, а потому язык должен уметь работать с ассемблерными вставками. Итого в сухом остатке получается, что для написания драйверов используют либо Си, либо голый ассемблер. Си++ как таковой не подойдёт, потому как многие конструкции языка являются высокоуровневыми (new, exception, конструкторы статических объектов), а потому могут работать только под управлением ОС (а нам нужен код, который бы работал внутри ОС)
