Привет всем!Хотел бы выложить совой класс для работы с драйврами.В классе реализованны следующие методы:
Регистрация драйвера в системе
Динамическая загрузка драйвера
Динамическая выгрузка драйвера
Удаление драйвера из системы
Расчёт IOCTO кода
и три метода общения с драйвером.
Вот код модуля dDriver:
function ZwUnloadDriver(DriverServiceName: PUnicodeString): cardinal;
stdcall;external 'ntdll.dll';
type
TDriver = class
private
DrName: TString;
DrPath: TString;
hDriver: Cardinal;
RegisteredStatus,
LoadedStatus,
UnRegisteredStatus,
UnLoadStatus: boolean;
public
constructor Create(Name,Path: PCHAR); //создаём объукт-драйвер.Название девайса,путь к драйверу
function Registered: boolean; //Регистрация драйвера в системе. True - успех
function Load: boolean; //Динамическая подгрузка драйвера,True - успех
function Start(Popitka:byte = 0):boolean; //Если лень вызывать сначала Registered,а потом
//Load,то можно вызвать сразу Start.Передаём колличество попыток загрузки драйвера
function UnLoad: boolean; //Динамическая выгрузкаиз драйвера.True - успех
function UnRegistered: boolean; //Снимаем регистрацию драйвера из системы
function Stop:boolean; //Выгружаем драйвер и UnRegistered.
function IOCTL_CODE(DeviceType, FunctionNo, Method, Access: Integer): Integer; //Получить IOCTL запрос
function WriteToDriver(Var WriteBuf; SizeW: DWORD): integer; //Читаем байты из драйвера,исполтуя WriteFile
function ReadFromDriver(Var ReadBuf; SizeR: DWORD): integer; //Пишем байты в драйвер,используя ReadFile
function ReadWrite(Var ToDroverBuf; SizeOfToDroverBuf: DWORD; CTL_CODE: DWORD; //Можно сразу и прочитать и записать данные.
Var FromDriverBuf; SizeOfFromDriverBuf: DWORD): Integer; //Используется DeviceIOcontrol
property MyDriverName: TString read DrName; //Свойство название девайса
property MyDriverPath: TString read DrPath; //Путь к драйверу
//property MyDriverHandle: Cardinal read hDriver; //Получить hDriver
function TDriver.Load: boolean;
var
Image: TUnicodeString;
Buff: array [0..MAX_PATH] of WideChar;
begin
StringToWideChar(DrvReg + DrName, Buff, MAX_PATH);
RtlInitUnicodeString(@Image, Buff);
Result := ZwLoadDriver(@Image) = 0;
LoadedStatus:= Result;
end;
function TDriver.Registered: boolean;
var
Key, Key2: HKEY;
dType: dword;
Err: dword;
NtPath: array[0..MAX_PATH] of Char;
begin
Result := false;
dType := 1;
Err := RegOpenKeyA(HKEY_LOCAL_MACHINE, 'system\CurrentControlSet\Services', Key);
if Err = ERROR_SUCCESS then
begin
Err := RegCreateKeyA(Key, drName, Key2);
if Err <> ERROR_SUCCESS then Err := RegOpenKeyA(Key, drName, Key2);
if Err = ERROR_SUCCESS then
begin
lstrcpy(NtPath, PChar('\??\' + drPath));
RegSetValueExA(Key2, 'ImagePath', 0, REG_SZ, @NtPath, lstrlen(NtPath));
RegSetValueExA(Key2, 'Type', 0, REG_DWORD, @dType, SizeOf(dword));
RegCloseKey(Key2);
Result := true;
end;
RegCloseKey(Key);
end;
RegisteredStatus:= Result;
end;
function TDriver.Start(Popitka:byte = 0):boolean;
Var F:Boolean;
i:byte;
Begin
F:=false;
i:=0;
repeat
F:=(Registered and Load);
if not F then
begin
UnLoad;
UnRegistered;
end;
inc(i);
if i = Popitka then
Break;
until F;
Result:=F;
End;
function TDriver.UnLoad: boolean;
var
Image: TUnicodeString;
Buff: array [0..MAX_PATH] of WideChar;
begin
StringToWideChar(DrvReg + DrName, Buff, MAX_PATH);
RtlInitUnicodeString(@Image, Buff);
Result := ZwUnloadDriver(@Image) = 0;
UnLoadStatus:= Result;
end;
function TDriver.UnRegistered: boolean;
var
Key: HKEY;
begin
Result := false;
if RegOpenKeyA(HKEY_LOCAL_MACHINE, 'system\CurrentControlSet\Services', Key) = ERROR_SUCCESS then
begin
RegDeleteKey(Key, PChar(drName+'\Enum'));
RegDeleteKey(Key, PChar(drName+'\Security'));
Result := RegDeleteKey(Key, drName) = ERROR_SUCCESS;
RegCloseKey(Key);
end;
UnRegisteredStatus:= Result;
end;
function TDriver.Stop:boolean;
Begin
Result:= UnLoad and UnRegistered;
End;
function TDriver.ReadFromDriver(var ReadBuf; SizeR: DWORD): integer;
Var H,N:Dword;
begin
ZeroMemory(@ReadBuf,SizeR);
Result:=Integer(LoadedStatus and RegisteredStatus);
if Result = 0 then
exit;
h:= CreateFile(PCHAR('\\.\'+DrName),GENERIC_ALL,0,nil,OPEN_EXISTING,0,0);
if h = INVALID_HANDLE_VALUE then
begin
Result:= -1;
exit;
end;
ReadFile(h,ReadBuf,SizeR,N,0);
Result:=N;
CloseHandle(h);
end;
function TDriver.WriteToDriver(var WriteBuf; SizeW: DWORD): integer;
Var H,N:Dword;
begin
Result:=Integer(LoadedStatus and RegisteredStatus);
if Result = 0 then exit;
h:= CreateFile(PCHAR('\\.\'+DrName),GENERIC_ALL,0,nil,OPEN_EXISTING,0,0);
if h = INVALID_HANDLE_VALUE then
begin
Result:= -1;
exit;
end;
WriteFile(h,WriteBuf,SizeW,N,0);
Result:=N;
CloseHandle(h);
end;
function TDriver.ReadWrite(Var ToDroverBuf; SizeOfToDroverBuf:
DWORD; CTL_CODE: DWORD;
Var FromDriverBuf; SizeOfFromDriverBuf: DWORD): Integer;
var
Bytes: dword;
begin
Result:= -1;
hDriver := CreateFile(pChar('\\.\'+DrName),GENERIC_ALL,0,nil,OPEN_EXISTING,0,0);
if hDriver = INVALID_HANDLE_VALUE then exit;
if @FromDriverBuf <> nil then ZeroMemory(@FromDriverBuf,SizeOfFromDriverBuf);
if DeviceIoControl(hDriver,
CTL_CODE,
@ToDroverBuf,SizeOfToDroverBuf, //Данные,посылаемые в драйвер
@FromDriverBuf, SizeOfFromDriverBuf, //Данные,которые оставит драйвер
Bytes, nil) then
Result:=Bytes;
CloseHandle(hDriver);
end;
function TDriver.IOCTL_CODE(DeviceType, FunctionNo, Method, Access: Integer): Integer;
begin
Result :=( (DeviceType shl 16) or (Access shl 14) or (FunctionNo shl 2) or Method);
end;
end.
Вот пример вызова:
Код
program DriverLoader;
{$Apptype Console}
uses
windows,dDriver,SysUtils;
Var
Name,Path:String;
Driver: TDriver;
DataToDriver,DataFromDriver:Array[0..19] of char;
CTL:DWORD;
begin
Name:= 'Share';
Path:='D:\Sniffer\Share\i386\Share.sys';
WriteLn('Name: ',Name);
WriteLn('Path: ',Path);
Driver:= TDriver.Create(pChar(Name),pChar(Path));
{if Driver.Registered then
WriteLn('Registered!') else
WriteLn('Not Registered!');
if Driver.Load then
WriteLn('Loaded!') else
WriteLn('Not Loaded!');}
Driver.Start(3);
CTL:=Driver.IOCTL_CODE(FILE_DEVICE_UNKNOWN,$803,METHOD_BUFFERED,FILE_ANY_ACCESS);
//Поробуем передать драйверу Hellow...
DataToDriver:='Project1.exe';
Driver.WriteToDriver(DataToDriver,Length(DataToDriver));
//Попробуем получить от драйвера Hellow.
Driver.ReadFromDriver(DataFromDriver,SizeOf(DataFromDriver));
WriteLn(DataFromDriver);
//Попробуем и то и то
FillChar(DataToDriver,0,SizeOf(DataToDriver)); FillChar(DataFromDriver,0,SizeOf(DataFromDriver));
DataToDriver:='Hellow against!';
Driver.ReadWrite(DataToDriver,SizeOf(DataToDriver),CTL,DataFromDriver,SizeOf(DataToDriver));
WriteLn(DataFromDriver);
{if Driver.UnLoad then
WriteLn('UnLoad!') else
WriteLn('Not UnLoad!');
if Driver.UnRegistered then
WriteLn('UnRegistered!') else
WriteLn('Not UnRegistered!');}
Driver.Stop;
ReadLn;
end.
NTSTATUS CtlDriverDispatchRead(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
//Если записать в Irp->UserBuffer то,запишется в буфер,которий лежит в ReadFile от приложения
PIO_STACK_LOCATION pIrpStack;
pIrpStack=IoGetCurrentIrpStackLocation(Irp);
NTSTATUS CtlDriverDispatch(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
//В данном случае рабочий буфер будет Irp->AssociatedIrp.SystemBuffer тут.
PIO_STACK_LOCATION pIrpStack;
PVOID pBuff = Irp->UserBuffer; //писать в прогу
PVOID pBuff_In = Irp->AssociatedIrp.SystemBuffer; //буфер от проги
DWORD *Pid = NULL;
DWORD PID = 0;
pIrpStack=IoGetCurrentIrpStackLocation(Irp);
DbgPrint("CtlDriverDispatch...\n");
DbgPrint("CTL: %d",IOCTL_SHARE);
if (pIrpStack->Parameters.DeviceIoControl.IoControlCode == IOCTL_SHARE)// если такой IOCTL пришёл,то
{//делаем это.
__try
{
DbgPrint("We are in SEH mdoe!\n");
Pid = pBuff_In;
DbgPrint("RECV %s \n",pBuff_In);
Уважаемый Neo данный код будет работать в системе windows7x64 bit ?
У меня динамическая загрузка драйвера с использованием SСManagera в системе windows7x64 bit не происходит,
хотя не меняя код ни приложения ни драйвера все отлично происходит в системе windows7x32 bit. Что можете
предложить к решению данной проблемы ?
Немного погуглив отвечу на свой вопрос сам. Данный код не сможет произвести загрузку драйвера в windows7x64 bit
всему виной то что это самопальный драйвер и не имеет цифровой подписи. Но код можно использовать в случае 32 разрядной
системы. Чтобы всё же воспользоваться им в 64 разрядной windows7 придется отключить проверку цифровой подписи (методов в
сети полно, даже есть рекомендации в msdn), скомпилировать приведенный драйвер для _amd64_ и пользоваться как того задумывал
автор. Автору большое спасибо за труды и их доступность. нет повести печальнее на свете чем повесть о Ромео и Джульетте
Сообщение отредактировал maskaads - Среда, 31.08.2016, 18:02