|
Познавший АНТИЧАТ
Регистрация: 05.03.2007
Сообщений: 1,985
Провел на форуме: 3288241
Репутация:
3349
|
|
Суть драйвера такова: Он должен перехватывать запуск процессов и заносить в лог.
также она должен защищать програму от выгрузки,
а именно через перехват функции NtOpenProcess
Сначало я начал делать всё без драйвера.
т.е. через инжект своей DLL'ки которая перехватывала запуск программы.
Но не на всех компах работало стабильно. То фаер матерился, то авир.
Бывало аткое, что пашет отлично, но на некоторых прогах - вылетает.
Вот для теста драйвера програма:
Код:
unit Unit1;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls,WInSVC;
type
TForm1 = class(TForm)
Button1: TButton;
Button2: TButton;
Button3: TButton;
Memo1: TMemo;
Button4: TButton;
procedure Button1Click(Sender: TObject);
procedure Button2Click(Sender: TObject);
procedure Button3Click(Sender: TObject);
procedure Button4Click(Sender: TObject);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
CTL_SETPID,CTL_GETPID:dword;
type
TRUNPROC=record
Parent:dword;
PID:dword;
end;
implementation
{$R *.dfm}
const
METHOD_BUFFERED = 0;
FILE_READ_ACCESS = 1;
FILE_WRITE_ACCESS = 2;
FILE_DEVICE_UNKNOWN =$22;
function CTL_CODE(ADeviceType: Integer; AFunction: Integer; AMethod: Integer; AAccess: Integer): DWORD;
begin
Result := (ADeviceType shl 16) or (AAccess shl 14) or (AFunction shl 2) or AMethod;
end;
procedure TForm1.Button1Click(Sender: TObject); // Установка драйвера
var
h:thandle;
g_hSCManager,g_hService:thandle;
p:pansichar;
begin
h:=CreateFile('\\.\MyDRVS', GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if h<>windows.INVALID_HANDLE_VALUE then
begin
memo1.Lines.add('[+] Driver Already Installed');
closehandle(h);
exit;
end;
g_hSCManager:=OpenSCManager(nil,nil, SC_MANAGER_ALL_ACCESS);
if g_hSCManager=0 then
begin
memo1.Lines.add('OpenSCManager ERROR');
exit;
end;
g_hService:=CreateService(g_hSCManager, 'MyDRVS','MyDRVS',
SERVICE_ALL_ACCESS, SERVICE_KERNEL_DRIVER, SERVICE_DEMAND_START,
SERVICE_ERROR_IGNORE, 'F:\RCI\Driver\MyDRVS.sys', nil, nil, nil, nil, nil);
if g_hService=0 then
begin
memo1.Lines.add('CreateService ERROR');
exit;
end;
if StartService(g_hService, 0, p)=false then
begin
memo1.Lines.add('StartService ERROR');
exit;
end;
h:=CreateFile('\\.\MyDRVS', GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, 0);
if h<>windows.INVALID_HANDLE_VALUE then
begin
MessageBox(0, 'OK', 'OPEN', MB_ICONINFORMATION or MB_OK);
exit;
end;
//DeleteService(g_hService);
CloseServiceHandle(g_hService);
CloseServiceHandle(g_hSCManager);
memo1.Lines.add('[+] Install OK');
closehandle(h);
end;
procedure TForm1.Button2Click(Sender: TObject); // установка своего PID для защиты
var
hDriver:thandle;
TrId:dword;
d:dword;
begin
hDriver:=CreateFile('\\.\MyDRVS', GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
memo1.Lines.Add(inttostr(GetLastError));
if hDriver = INVALID_HANDLE_VALUE then
begin
memo1.Lines.add('Open Driver Error');
exit;
end;
d:=GetCurrentProcessId();
DeviceIoControl(hDriver, CTL_SETPID,@d, 4, nil, 0, TrId, nil);
closehandle(hDriver);
memo1.Lines.add('Set PID');
end;
procedure TForm1.Button3Click(Sender: TObject); // снятие защиты
var
hDriver:thandle;
TrId,d:dword;
begin
hDriver:=CreateFile('\\.\MyDRVS', GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hDriver = INVALID_HANDLE_VALUE then
begin
memo1.Lines.add('Open Driver Error');
exit;
end;
d:=$FFFFFFFF;
DeviceIoControl(hDriver, CTL_SETPID,@d, 4, nil, 0, TrId, nil);
closehandle(hDriver);
memo1.Lines.add('UnSet PID');
end;
procedure TForm1.Button4Click(Sender: TObject); // чтение PID'a
var
hDriver:thandle;
TrId,PID:dword;
begin
hDriver:=CreateFile('\\.\MyDRVS', GENERIC_READ+GENERIC_WRITE, FILE_SHARE_READ+FILE_SHARE_WRITE, nil, OPEN_EXISTING, 0, 0);
if hDriver = INVALID_HANDLE_VALUE then
begin
memo1.Lines.add('Open Driver Error');
exit;
end;
DeviceIoControl(hDriver, CTL_GETPID, nil, 0, @PID, 4, TrId, nil);
memo1.Lines.Add(inttostr(PID));
closehandle(hDriver);
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
CTL_GETPID:=CTL_CODE(FILE_DEVICE_UNKNOWN, 1, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS);
CTL_SETPID:=CTL_CODE(FILE_DEVICE_UNKNOWN, 2, METHOD_BUFFERED, FILE_READ_ACCESS + FILE_WRITE_ACCESS);
end;
end.
Вот код драйвера:
Код:
#include <ntddk.h>
#define DEBUG
#ifdef DEBUG
#define DPRINT DbgPrint
#else
#define DPRINT
#endif
#define IOCTL_GETPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x01, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
#define IOCTL_SETPID CTL_CODE(FILE_DEVICE_UNKNOWN, 0x02, METHOD_BUFFERED, FILE_READ_DATA | FILE_WRITE_DATA)
typedef PVOID* PNTPROC;
typedef DWORD (ULONG);
typedef DWORD* PDWORD;
typedef unsigned char (BYTE);
typedef BYTE* PBYTE;
typedef struct _SYSTEM_SERVICE_TABLE
{
PNTPROC ServiceTable;
PDWORD CounterTable;
ULONG ServiceLimit;
PBYTE ArgumentTable;
}
SYSTEM_SERVICE_TABLE ,
* PSYSTEM_SERVICE_TABLE ,
* * PPSYSTEM_SERVICE_TABLE ;
typedef struct _SERVICE_DESCRIPTOR_TABLE {
SYSTEM_SERVICE_TABLE ntoskrnl; //SST для ntoskrnl.exe
SYSTEM_SERVICE_TABLE win32k; //SST для win32k.sys
SYSTEM_SERVICE_TABLE unused1; //не используется
SYSTEM_SERVICE_TABLE unused2; //не используется
}
SERVICE_DESCRIPTOR_TABLE ,
* PSERVICE_DESCRIPTOR_TABLE,
* * PPSERVICE_DESCRIPTOR_TABLE ;
typedef struct _TRUNPROC // структура описывающая запрос к драйверу
{
HANDLE parent;
HANDLE PID;
} TRUNPROC, *PRUNPROC;
#define NTCALL(_function) KeServiceDescriptorTable->ntoskrnl.ServiceTable[_function]
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
extern PUSHORT NtBuildNumber;
typedef NTSTATUS (*NtOpenPrcPointer) (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL);
NtOpenPrcPointer TrueNtOpenProcess;
ULONG OpenProcId;
UNICODE_STRING DeviceName;
UNICODE_STRING SymbolicLinkName;
PDEVICE_OBJECT deviceObject = NULL;
HANDLE ProtectedPid = 0;
TRUNPROC RUNPROC;
//функция - обработчик перехвата
NTSTATUS NewNtOpenProcess (OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL)
{
HANDLE ProcessId;
//безопасным образом извлекаем ProcessId
if ((ULONG *)ClientId > MmUserProbeAddress) return STATUS_INVALID_PARAMETER;
__try
{
ProcessId = ClientId->UniqueProcess;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
DPRINT("Exception");
return STATUS_INVALID_PARAMETER;
}
if (ProcessId == ProtectedPid) //защищаем процесс
{
DPRINT("Access Denied!");
return STATUS_ACCESS_DENIED;
}
else return TrueNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
}
VOID CreateProcessNotifyRoutine(IN HANDLE ParentId,
IN HANDLE ProcessId,
IN BOOLEAN Create)
{
DPRINT("CREATENOTIFY");
if (Create)
{
DPRINT("RUN CREATENOTIFY %d",ProcessId);
RUNPROC.parent=ProcessId;
RUNPROC.PID=ParentId;
}
}
NTSTATUS DriverDispatcher(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS status;
PIO_STACK_LOCATION irpStack;
DPRINT("DriverDispatcher");
irpStack = IoGetCurrentIrpStackLocation (Irp);
if (irpStack->MajorFunction == IRP_MJ_DEVICE_CONTROL)
{
switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case IOCTL_SETPID: // утановка PID
if (irpStack->Parameters.DeviceIoControl.InputBufferLength == sizeof(HANDLE))
{
ProtectedPid=*(HANDLE *)Irp->AssociatedIrp.SystemBuffer;
DPRINT("PID= %d",ProtectedPid);
status = STATUS_SUCCESS;
}
break;
case IOCTL_GETPID: // Чтение PID
if (irpStack->Parameters.Read.Length < 4)
{
DPRINT("LENGTH < 4");
Irp->IoStatus.Information = 0;
status = STATUS_BUFFER_TOO_SMALL;
}
else
{
DPRINT("LENGTH OK");
Irp->IoStatus.Information = 4;
*(HANDLE *)Irp->AssociatedIrp.SystemBuffer=ProtectedPid;
status = STATUS_SUCCESS;
}
break;
default: status = STATUS_INVALID_DEVICE_REQUEST;
}
}
Irp->IoStatus.Status = status;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
return status;
}
VOID DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
ULONG CR0Reg;
DPRINT("Driver Unload");
PsSetCreateProcessNotifyRoutine(*CreateProcessNotifyRoutine, TRUE);
IoDeleteSymbolicLink(&SymbolicLinkName); // удаляем символическую ссылку
IoDeleteDevice(deviceObject); // удаляем устройство
//снимаем перехват
__asm
{
cli // запрещаем прерывания
mov eax, cr0
mov CR0Reg,eax
and eax,0xFFFEFFFF // сбросить WP bit
mov cr0, eax
}
NTCALL(OpenProcId) = TrueNtOpenProcess;
__asm
{
mov eax, CR0Reg
mov cr0, eax // востановить содержимое CR0
sti // разрешаем прерывания
}
DPRINT("Driver Unloaded");
return;
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
ULONG CR0Reg;
NTSTATUS st;
NTSTATUS rc;
PCWSTR dDeviceName = L"\\Device\\MyDRVS";
PCWSTR dSymbolicLinkName = L"\\DosDevices\\MyDRVS";
(long int)ProtectedPid = 0x0FFFFFFFF;
DPRINT("Driver loaded");
RtlInitUnicodeString(&DeviceName, dDeviceName);
RtlInitUnicodeString(&SymbolicLinkName, dSymbolicLinkName);
st = IoCreateDevice(DriverObject, 0, &DeviceName, FILE_DEVICE_NULL, 0, FALSE, &deviceObject);
if (st == STATUS_SUCCESS)
{
DPRINT("IoCreateDevice OK");
st = IoCreateSymbolicLink(&SymbolicLinkName, &DeviceName);
if (st == STATUS_SUCCESS)
{
DPRINT("IoCreateSymbolicLink OK");
}
else
{
DPRINT("IoCreateSymbolicLink ERROR");
}
}
else
{
DPRINT("IoCreateDevice ERROR");
}
//определяем версию ядра системы
switch (*NtBuildNumber)
{
case 2195 : //win 2k
OpenProcId = 0x06A;
DPRINT("WIn2000");
break;
case 2600 : //win xp
OpenProcId = 0x07A;
DPRINT("WinXP");
break;
default :
return STATUS_NOT_IMPLEMENTED;
break;
}
//устанавливаем перехват
TrueNtOpenProcess = NTCALL(OpenProcId);
__asm
{
cli // запрещаем прерывания
mov eax, cr0
mov CR0Reg,eax
and eax,0xFFFEFFFF // сбросить WP bit
mov cr0, eax
}
NTCALL(OpenProcId) = NewNtOpenProcess;
__asm
{
mov eax, CR0Reg
mov cr0, eax // востановить содержимое CR0
sti // разрешаем прерывания
}
rc = PsSetCreateProcessNotifyRoutine(*CreateProcessNotifyRoutine, FALSE);
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] =
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = DriverDispatcher;
DriverObject->DriverUnload = DriverUnload;
DPRINT("END LOAD");
return STATUS_SUCCESS;
}
|