نمونه برنامه دلفی برای ارتباط با درایور ها (سورسی که به زبان سی است) شامل متدهای زیر:
Registering the driver in the system
Dynamic loading driver
Dynamic unloading drivers
Removing the driver from the system
Calculation IOCTO code
and three methods of communication with the driver.
unit dDriver;
interface
uses Windows;
const
METHOD_BUFFERED = 0;
METHOD_NEITHER = 3;
FILE_ANY_ACCESS = 0;
FILE_READ_ACCESS = 1;
FILE_WRITE_ACCESS = 2;
FILE_DEVICE_UNKNOWN = $00000022;
Type
NTStatus = cardinal;
TString = array[0..MAX_PATH] of char;
PUnicodeString = ^TUnicodeString;
TUnicodeString = record
Length: WORD;
MaximumLength: WORD;
Buffer: PWideChar;
end;
const
STATUS_OBJECT_NAME_EXISTS = $40000000;
OBJ_CASE_INSENSITIVE = $00000040;
OBJ_OPENIF = $00000080;
DIRECTORY_TRAVERSE = $0002;
DIRECTORY_CREATE_OBJECT = $0004;
procedure RtlInitUnicodeString(DestinationString: PUnicodeString; SourceString: PWideChar);
stdcall; external 'ntdll.dll';
function ZwLoadDriver(DriverServiceName: PUnicodeString): cardinal;
stdcall;external 'ntdll.dll';
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
property MyRegisteredStatus: boolean read RegisteredStatus; //???????
property MyLoadedStatus: boolean read LoadedStatus;
property MyUnRegisteredStatus: boolean read UnRegisteredStatus;
property MyUnLoadStatus: boolean read UnLoadStatus;
end;
implementation
const
DrvReg = '\registry\machine\system\CurrentControlSet\Servic es\';
function EnablePrivilegeEx(Process: dword; lpPrivilegeName: PChar):Boolean;
var
hToken: dword;
NameValue: Int64;
tkp: TOKEN_PRIVILEGES;
ReturnLength: dword;
begin
Result:=false;
OpenProcessToken(Process, TOKEN_ADJUST_PRIVILEGES or TOKEN_QUERY, hToken);
if not LookupPrivilegeValue(nil, lpPrivilegeName, NameValue) then
begin
CloseHandle(hToken);
exit;
end;
tkp.PrivilegeCount := 1;
tkp.Privileges[0].Luid := NameValue;
tkp.Privileges[0].Attributes := SE_PRIVILEGE_ENABLED;
AdjustTokenPrivileges(hToken, false, tkp, SizeOf(TOKEN_PRIVILEGES), tkp, ReturnLength);
if GetLastError() <> ERROR_SUCCESS then
begin
CloseHandle(hToken);
exit;
end;
Result:=true;
CloseHandle(hToken);
end;
{ TDriver }
constructor TDriver.Create(Name, Path: PCHAR);
begin
inherited Create;
lStrCpy(DrName,Name);
lStrCpy(DrPath,Path);
RegisteredStatus:= False; LoadedStatus:= False;
UnRegisteredStatus:= False; UnLoadStatus:= False;
hDriver:=0;
//EnablePrivilegeEx(GetCurrentProcessId, 'SeLoadDriverPrivilege'); //SetDebugPrivileges
end;
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,ME THOD_BUFFERED,FILE_ANY_ACCESS);
//???????? ???????? ???????? Hellow...
DataToDriver:='Project1.exe';
Driver.WriteToDriver(DataToDriver,Length(DataToDri ver));
//????????? ???????? ?? ???????? Hellow.
Driver.ReadFromDriver(DataFromDriver,SizeOf(DataFr omDriver));
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.
#include "ntddk.h"
#define NT_DEVICE_NAME L"\\Device\\Share"
#define WIN32_DEVICE_NAME L"\\DosDevices\\SHare"
#define DWORD unsigned long
#define SECTION_SIZE 255
#define IOCTL_SHARE CTL_CODE (FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
NTSTATUS CtlCreate(IN PDEVICE_OBJECT, IN PIRP);
NTSTATUS CtlClose(IN PDEVICE_OBJECT, IN PIRP);
NTSTATUS CtlDriverDispatch(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS CtlDriverDispatchWrite(IN PDEVICE_OBJECT,IN PIRP); //???? ?????????? ????? WriteFile
NTSTATUS CtlDriverDispatchRead(IN PDEVICE_OBJECT,IN PIRP); //???? ?????????? ????? ReadFile
NTSTATUS UnloadDriver(IN PDRIVER_OBJECT pDriverObject); //???? ?????????? ????? DeviceIOControl
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject, IN PUNICODE_STRING RegistryPath)
{
PDEVICE_OBJECT pDeviceObject;
UNICODE_STRING uniNtName;
UNICODE_STRING uniWin32Name;
RtlInitUnicodeString(&uniNtName, NT_DEVICE_NAME);
RtlInitUnicodeString(&uniWin32Name, WIN32_DEVICE_NAME);
IoCreateSymbolicLink(&uniWin32Name, &uniNtName);
IoCreateDevice(pDriverObject,0,&uniNtName,FILE_DEV ICE_UNKNOWN,0,FALSE,&pDeviceObject);
pDriverObject->MajorFunction[IRP_MJ_CREATE]=CtlCreate;
pDriverObject->MajorFunction[IRP_MJ_CLOSE]=CtlClose;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=CtlDriverDispatch;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = CtlDriverDispatchWrite;
pDriverObject->MajorFunction[IRP_MJ_READ] = CtlDriverDispatchRead;
pDriverObject->DriverUnload = UnloadDriver;
DbgPrint("Driver has been loaded!");
return STATUS_SUCCESS;
}
NTSTATUS CtlCreate(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS CtlClose(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
Irp->IoStatus.Status=STATUS_SUCCESS;
Irp->IoStatus.Information=0;
IoCompleteRequest(Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS UnloadDriver(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT deviceObject = pDriverObject->DeviceObject;
UNICODE_STRING uniWin32NameString;
RtlInitUnicodeString( &uniWin32NameString, WIN32_DEVICE_NAME );
IoDeleteSymbolicLink( &uniWin32NameString );
IoDeleteDevice( deviceObject );
DbgPrint("Driver has been Unloaded!");
return STATUS_SUCCESS;
}
NTSTATUS CtlDriverDispatchWrite(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
//? Irp->UserBuffer ????? ??,??? ?????? ???????????? WriteFile??
PIO_STACK_LOCATION pIrpStack;
pIrpStack=IoGetCurrentIrpStackLocation(Irp);
Irp->IoStatus.Information = 0;
if (pIrpStack->MajorFunction == IRP_MJ_WRITE)
{
__try
{
ULONG Length = pIrpStack->Parameters.Write.Length;
DbgPrint("Recv:%s \n",Irp->UserBuffer);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error");
}
}
Irp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest (Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
NTSTATUS CtlDriverDispatchRead(IN PDEVICE_OBJECT pDeviceObject,IN PIRP Irp)
{
//???? ???????? ? Irp->UserBuffer ??,????????? ? ?????,??????? ????? ? ReadFile ?? ??????????
PIO_STACK_LOCATION pIrpStack;
pIrpStack=IoGetCurrentIrpStackLocation(Irp);
DbgPrint("CtlDriverDispatchRead");
if (pIrpStack->MajorFunction == IRP_MJ_READ)
{
__try
{
RtlCopyMemory(Irp->UserBuffer,"Hellow!FromDrover",18);
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error");
}
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest (Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
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);
RtlCopyMemory(pBuff,"12345",5);
DbgPrint("Sended: %s","12345");
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DbgPrint("Error");
}
}
Irp->IoStatus.Information = 0;
Irp->IoStatus.Status=STATUS_SUCCESS;
IoCompleteRequest (Irp,IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
من اینو تست نکردم (مال خودم رو دارم)
منبع برادران روس
شب خوش