Last active
September 3, 2016 18:28
-
-
Save HoShiMin/cb0936c6521414275128 to your computer and use it in GitHub Desktop.
API для работы с драйверами
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
unit DriversAPI; | |
{ | |
Автор: HoShiMin, 2016 | |
Основные понятия: | |
IRP - I/O Request Packet, передаваемые драйверу данные | |
Имя драйвера - имя службы драйвера | |
Имя устройства - указано в ДРАЙВЕРЕ, ему посылать IOCTL! | |
IOCTL - пользовательский контрольный код: | |
0x000 : 0x7FF - зарезервировано Microsoft | |
0x800 : 0xFFF - определяется пользователем | |
RawIOCTL - пользовательский код (IOCTL), переведённый в системный вид | |
с помощью функции GenerateIOCTL (см. ниже): | |
Параметры GenerateIOCTL: | |
DeviceType - определяет устройство: | |
0х0000 : 0х7FFF - зарезервировано Microsoft | |
0х8000 : 0хFFFF - определяется пользователем | |
IOCTL - контрольный код: | |
0x000 : 0x7FF - зарезервировано Microsoft | |
0x800 : 0xFFF - определяется пользователем | |
AccessMethod - тип доступа к буферу: | |
METHOD_BUFFERED: | |
Драйвер: | |
Входной буфер в pIrp->AssociatedIrp.SystemBuffer | |
Выходной буфер - выходные данные копировать во входной буфер, | |
размер выходных данных определяется размером | |
наибольшего буфера | |
Клиент: | |
Передавать и получать данные во входном буфере | |
METHOD_IN_DIRECT или METHOD_OUT_DIRECT: | |
Драйвер: | |
Входной буфер в pIrp->AssociatedIrp.SystemBuffer | |
Выходной буфер в pIrp->MdlAddress | |
Клиент: | |
Зависит от драйвера, в общем случае отправлять данные во входном буфере, | |
получать - в выходном, в частном случае выходной буфер получать во входном | |
METHOD_NEITHER: | |
Драйвер: | |
Входной буфер в Parameters.DeviceIoControl.Type3InputBuffer (IO_STACK_LOCATION) | |
Выходной буфер в pIrp->UserBuffer | |
Клиент: | |
Отправка данных во входном буфере | |
Получение данных в выходном буфере | |
### ВНИМАНИЕ! Неверный тип доступа к буферу может вызвать BSOD! | |
Подробнее о типах доступа к буферу: | |
http://msdn.microsoft.com/en-us/library/windows/hardware/ff540663(v=vs.85).aspx | |
http://blagin.ru/sozdanie-drajverov-chast-4-obmen-dannymi/ | |
http://drp.su/ru/driver_dev/08_06.htm | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
*** Отключение проверки подписи драйверов на 64х-битных ОС: | |
В консоли набрать: | |
* Отключение проверки цифровой подписи (разрешить устанавливать неподписанные драйвера): | |
bcdedit.exe /set loadoptions DISABLE_INTEGRITY_CHECKS | |
bcdedit.exe /set TESTSIGNING ON | |
* Включение проверки цифровой подписи (запретить устанавливать неподписанные драйвера): | |
bcdedit.exe /set loadoptions ENABLE_INTEGRITY_CHECKS | |
bcdedit.exe /set TESTSIGNING OFF | |
* Включение поддержки ядерной отладки (kernel-debugging) для WinDbg и Kernel Debugger из WDK: | |
bcdedit.exe /debug on - включить | |
bcdedit.exe /debug off - выключить | |
После выполнения необходимо перезагрузить Windows | |
} | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
interface | |
uses | |
Windows, WinSvc, SysUtils; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
const | |
METHOD_BUFFERED = 0; | |
METHOD_IN_DIRECT = 1; | |
METHOD_OUT_DIRECT = 2; | |
METHOD_NEITHER = 3; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
// Определение разрядности Windows: | |
function Is64BitWindows: BOOL; | |
// Текст последней ошибки: | |
function LastError: string; | |
// Приводит IOCTL к системному виду: | |
function GenerateIOCTL(DeviceType, FunctionNumber, AccessMethod, Access: LongWord): LongWord; inline; | |
// Получить дескриптор устройства, которому будем посылать IOCTL (DeviceName указан в ДРАЙВЕРЕ! Это НЕ имя службы драйвера): | |
function GetDeviceHandle(const DeviceName: string): THandle; inline; | |
// Отправка IOCTL драйверу (устройству): | |
function SendIOCTL(hDevice: THandle; IOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil; Method: LongWord = METHOD_NEITHER): Boolean; inline; overload; | |
function SendIOCTL(const DeviceName: string; IOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil; Method: LongWord = METHOD_NEITHER): Boolean; inline; overload; | |
function SendRawIOCTL(hDevice: THandle; RawIOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil): Boolean; inline; overload; | |
function SendRawIOCTL(const DeviceName: string; RawIOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil): Boolean; inline; overload; | |
// "Ручные" установка, запуск, остановка и удаление драйвера: | |
function CreateDriverService(const DriverPath, DriverName: string): THandle; | |
function OpenDriverService (const DriverName: string): THandle; | |
function StartDriverService (hService: THandle): Boolean; | |
function StopDriverService (hService: THandle): Boolean; | |
function DeleteDriverService(hService: THandle): Boolean; | |
function CloseService (hService: THandle): LongBool; | |
// "Автоматические" установка, запуск, остановка и удаление драйвера: | |
function InstallDriver(const DriverPath, DriverName: string): Boolean; | |
function DeleteDriver(const DriverName: string): Boolean; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
implementation | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function Is64BitWindows: BOOL; | |
{$IFNDEF CPUX64} | |
var | |
IsWow64Process: function(hProcess: THandle; Wow64Process: PBOOL): BOOL; stdcall; | |
Wow64Process: BOOL; | |
{$ENDIF} | |
begin | |
{$IFDEF CPUX64} | |
Result := True; | |
{$ELSE} | |
IsWow64Process := GetProcAddress(GetModuleHandle(kernel32), 'IsWow64Process'); | |
Wow64Process := False; | |
if Assigned(IsWow64Process) then Wow64Process := IsWow64Process(GetCurrentProcess, @Wow64Process) and Wow64Process; | |
Result := Wow64Process; | |
{$ENDIF} | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function LastError: string; | |
var | |
Buffer: PChar; | |
ErrorCode: LongWord; | |
const | |
BufferSize = 1024; | |
begin | |
ErrorCode := GetLastError; | |
GetMem(Buffer, BufferSize); | |
FillChar(Buffer^, BufferSize, #0); | |
FormatMessage( | |
FORMAT_MESSAGE_FROM_SYSTEM, | |
nil, | |
ErrorCode, | |
LANG_NEUTRAL, | |
Buffer, | |
BufferSize, | |
nil | |
); | |
Result := '(0x' + IntToHex(ErrorCode, 8) + ') ' + Copy(Buffer, 1, Length(Buffer) - 2); | |
FreeMem(Buffer); | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function GenerateIOCTL(DeviceType, FunctionNumber, AccessMethod, Access: LongWord): LongWord; inline; | |
begin | |
Result := (DeviceType shl 16) or (Access shl 14) or (FunctionNumber shl 2) or AccessMethod; | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function GetDeviceHandle(const DeviceName: string): THandle; inline; | |
begin | |
Result := CreateFile( | |
PChar('\\.\' + DeviceName), | |
GENERIC_READ or GENERIC_WRITE, | |
FILE_SHARE_READ or FILE_SHARE_WRITE, | |
nil, | |
OPEN_EXISTING, | |
FILE_ATTRIBUTE_NORMAL or FILE_ATTRIBUTE_SYSTEM, | |
0 | |
); | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function SendIOCTL(hDevice: THandle; IOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil; Method: LongWord = METHOD_NEITHER): Boolean; inline; overload; | |
var | |
RawIOCTL: LongWord; | |
RawBytesReturned: LongWord; | |
begin | |
RawIOCTL := GenerateIOCTL($8000, IOCTL, Method, FILE_ANY_ACCESS); | |
Result := DeviceIoControl(hDevice, RawIOCTL, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, RawBytesReturned, nil); | |
if BytesReturned <> nil then BytesReturned^ := RawBytesReturned; | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function SendIOCTL(const DeviceName: string; IOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil; Method: LongWord = METHOD_NEITHER): Boolean; inline; overload; | |
var | |
hDevice: THandle; | |
RawIOCTL: LongWord; | |
RawBytesReturned: LongWord; | |
begin | |
Result := False; | |
hDevice := GetDeviceHandle(DeviceName); | |
if hDevice = INVALID_HANDLE_VALUE then Exit; | |
RawIOCTL := GenerateIOCTL($8000, IOCTL, Method, FILE_ANY_ACCESS); | |
Result := DeviceIoControl(hDevice, RawIOCTL, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, RawBytesReturned, nil); | |
if BytesReturned <> nil then BytesReturned^ := RawBytesReturned; | |
CloseHandle(hDevice); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function SendRawIOCTL(hDevice: THandle; RawIOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil): Boolean; inline; overload; | |
var | |
RawBytesReturned: LongWord; | |
begin | |
Result := DeviceIoControl(hDevice, RawIOCTL, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, RawBytesReturned, nil); | |
if BytesReturned <> nil then BytesReturned^ := RawBytesReturned; | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function SendRawIOCTL(const DeviceName: string; RawIOCTL: LongWord; InputBuffer: Pointer; InputBufferSize: LongWord; OutputBuffer: Pointer; OutputBufferSize: LongWord; BytesReturned: PLongWord = nil): Boolean; inline; overload; | |
var | |
hDevice: THandle; | |
RawBytesReturned: LongWord; | |
begin | |
Result := False; | |
hDevice := GetDeviceHandle(DeviceName); | |
if hDevice = INVALID_HANDLE_VALUE then Exit; | |
Result := DeviceIoControl(hDevice, RawIOCTL, InputBuffer, InputBufferSize, OutputBuffer, OutputBufferSize, RawBytesReturned, nil); | |
if BytesReturned <> nil then BytesReturned^ := RawBytesReturned; | |
CloseHandle(hDevice); | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function CreateDriverService(const DriverPath, DriverName: string): THandle; | |
var | |
hSCManager: THandle; | |
begin | |
Result := 0; | |
// Открываем менеджер сервисов: | |
hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); | |
if hSCManager = 0 then Exit; | |
// Создаём сервис: | |
Result := CreateService( | |
hSCManager, | |
PChar(DriverName), | |
PChar(DriverName), | |
SERVICE_ALL_ACCESS, | |
SERVICE_KERNEL_DRIVER, | |
SERVICE_DEMAND_START, | |
SERVICE_ERROR_NORMAL, | |
PChar(DriverPath), | |
nil, | |
nil, | |
nil, | |
nil, | |
nil | |
); | |
CloseServiceHandle(hSCManager); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function OpenDriverService(const DriverName: string): THandle; | |
var | |
hSCManager: THandle; | |
begin | |
Result := 0; | |
hSCManager := OpenSCManager(nil, nil, SC_MANAGER_ALL_ACCESS); | |
if hSCManager = 0 then Exit; | |
Result := OpenService(hSCManager, PChar(DriverName), SERVICE_ALL_ACCESS); | |
CloseServiceHandle(hSCManager); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function StartDriverService(hService: THandle): Boolean; | |
type | |
PPWideChar = ^PWideChar; | |
begin | |
Result := StartService(hService, 0, PPWideChar(nil)^); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function StopDriverService(hService: THandle): Boolean; | |
var | |
ServiceStatus: _SERVICE_STATUS; | |
begin | |
Result := ControlService(hService, SERVICE_CONTROL_STOP, ServiceStatus); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function DeleteDriverService(hService: THandle): Boolean; | |
begin | |
Result := DeleteService(hService); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function CloseService(hService: THandle): LongBool; | |
begin | |
Result := CloseServiceHandle(hService); | |
end; | |
//HHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHHH | |
function InstallDriver(const DriverPath, DriverName: string): Boolean; | |
var | |
hService: THandle; | |
begin | |
Result := False; | |
hService := CreateDriverService(DriverPath, DriverName); | |
if hService = 0 then Exit; | |
Result := StartDriverService(hService); | |
CloseServiceHandle(hService); | |
end; | |
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - | |
function DeleteDriver(const DriverName: string): Boolean; | |
var | |
hService: THandle; | |
begin | |
Result := False; | |
hService := OpenDriverService(DriverName); | |
if hService = 0 then Exit; | |
Result := StopDriverService(hService) and DeleteDriverService(hService); | |
CloseServiceHandle(hService); | |
end; | |
end. |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
memes