Привет всем!Хотел бы выложить совой класс для работы с драйврами.В классе реализованны следующие методы: Регистрация драйвера в системе Динамическая загрузка драйвера Динамическая выгрузка драйвера Удаление драйвера из системы Расчёт 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