Здравствуйте. Вот прочитал на www.wasm.ru интересный способ получения информации от драйвера используя объект. Вот код драйвера: Код (Text): #include <ntddk.h> //#include <winnt.h> #include "Driver.h" VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject); NTSTATUS Create_File_IRProcessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp); NTSTATUS Close_HandleIRProcessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp); NTSTATUS ReadWrite_IRPhandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp); NTSTATUS DeviceControlRutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp); KSPIN_LOCK MySpinLock; 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 ; //макрос для простого доступа к SST ядра #define NTCALL(_function) KeServiceDescriptorTable->ntoskrnl.ServiceTable[_function] //импортируем указатель на SDT extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable; //импортируем версию ядра NT extern PUSHORT NtBuildNumber; //обьявляем прототип True функции для перехватываемой функции typedef NTSTATUS (*NtOpenPrcPointer) ( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL); //обьявляем True функцию NtOpenPrcPointer TrueNtOpenProcess; //номер системного вызова NtOpenProcess /////////////////////////////////////////////////// ULONG OpenProcId; ULONG PID=1556; HANDLE EVEN; PVOID EVEN2; ULONG PID2=0; ULONG POINT; NTSTATUS TREST; ////////////////////////////////////////////////////// //функция - обработчик перехвата NTSTATUS NewNtOpenProcess ( OUT PHANDLE ProcessHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, IN PCLIENT_ID ClientId OPTIONAL) { HANDLE ProcessId; //безопасным образом извлекаем ProcessId __try { ProcessId = ClientId->UniqueProcess; } __except(EXCEPTION_EXECUTE_HANDLER) { return STATUS_INVALID_PARAMETER; } if (ProcessId == (HANDLE)PID) { if(PID2!=0){ KeSetEvent(EVEN2,0,FALSE); return STATUS_ACCESS_DENIED; }return TrueNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); } else return TrueNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId); } NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { ULONG CR0Reg; NTSTATUS status; UNICODE_STRING fullFileName; HANDLE fileHandle; IO_STATUS_BLOCK iostatus; OBJECT_ATTRIBUTES oa; UNICODE_STRING devName; PDEVICE_OBJECT fdo; PEXAMPLE_DEVICE_EXTENSION dx; UNICODE_STRING symLinkName; DriverObject->DriverUnload=UnloadRoutine; DriverObject->MajorFunction[IRP_MJ_CREATE]=Create_File_IRProcessing; DriverObject->MajorFunction[IRP_MJ_CLOSE]=Close_HandleIRProcessing; DriverObject->MajorFunction[IRP_MJ_READ]=ReadWrite_IRPhandler; DriverObject->MajorFunction[IRP_MJ_WRITE]=ReadWrite_IRPhandler; DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DeviceControlRutine; RtlInitUnicodeString(&devName,L"\\Device\\MYSEC"); status=IoCreateDevice(DriverObject,sizeof(EXAMPLE_DEVICE_EXTENSION), &devName,FILE_DEVICE_UNKNOWN, 0, FALSE, &fdo); dx=(PEXAMPLE_DEVICE_EXTENSION) fdo->DeviceExtension; dx->fdo=fdo; #define SYM_LINK_NAME L"\\DosDevices\\MYSEC" RtlInitUnicodeString(&symLinkName,SYM_LINK_NAME); dx->ustrSymLinkName=symLinkName; status=IoCreateSymbolicLink(&symLinkName,&devName); KeInitializeSpinLock(&MySpinLock); //определяем версию ядра системы switch (*NtBuildNumber) { case 2195 : //win 2k OpenProcId = 0x06A; break; case 2600 : //win xp OpenProcId = 0x07A; 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 // разрешаем прерывания } RtlInitUnicodeString(&fullFileName,L"\\??\\C:\\make my driver.txt"); InitializeObjectAttributes(&oa, &fullFileName, OBJ_CASE_INSENSITIVE | OBJ_KERNEL_HANDLE, NULL, NULL); status=ZwCreateFile(&fileHandle, GENERIC_WRITE | SYNCHRONIZE, &oa, &iostatus, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_WRITE, FILE_OPEN_IF, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0); ZwClose(fileHandle); return status; } NTSTATUS CompleteIrp(PIRP Irp,NTSTATUS status,ULONG info) { Irp->IoStatus.Status=status; Irp->IoStatus.Information=info; IoCompleteRequest(Irp,IO_NO_INCREMENT); return status; } NTSTATUS ReadWrite_IRPhandler(IN PDEVICE_OBJECT fdo,IN PIRP Irp) { ULONG BytesTdx=0; NTSTATUS status=STATUS_SUCCESS; return CompleteIrp(Irp,status,BytesTdx); } NTSTATUS Create_File_IRProcessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp) { PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp); return CompleteIrp(Irp,STATUS_SUCCESS,0); } NTSTATUS Close_HandleIRProcessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp){ return CompleteIrp(Irp,STATUS_SUCCESS,0); } NTSTATUS DeviceControlRutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp) { NTSTATUS status=STATUS_SUCCESS; PEXAMPLE_DEVICE_EXTENSION dx; PIO_STACK_LOCATION IrpStack; KIRQL irql; KIRQL currentIrql; ULONG BytesTdx=0; ULONG ControlCode; ULONG method; IrpStack=IoGetCurrentIrpStackLocation(Irp); IrpStack=IoGetCurrentIrpStackLocation(Irp); dx=(PEXAMPLE_DEVICE_EXTENSION) fdo->DeviceExtension; ControlCode=(ULONG)(IrpStack->Parameters.DeviceIoControl.IoControlCode); method=ControlCode & 0x03; irql=KeGetCurrentIrql(); currentIrql=KeGetCurrentIrql(); KeAcquireSpinLock(&MySpinLock,&irql); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(ControlCode!=0){ PID2=ControlCode; EVEN=(HANDLE *)PID2; __asm{ mov ecx, ExEventObjectType mov ecx, [ecx] mov ecx, [ecx] } TREST=ObReferenceObjectByHandle(EVEN,EVENT_MODIFY_STATE,*ExEventObjectType,UserMode,EVEN2,NULL); if(TREST!=STATUS_SUCCESS){PID2=0;}; } else { PID2=0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// KeReleaseSpinLock(&MySpinLock,irql); return CompleteIrp(Irp,status,BytesTdx); } VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject) { ULONG CR0Reg; //снимаем перехват __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 // разрешаем прерывания } return; } Драйвер должен не дать завершить процесс с PID =1556. Вот код программы которая должна получить данные о попытке завершить процесс с PID=1556. Код (Text): #include <windows.h> #include <shellapi.h> #include <iostream.h> #include <conio.h> HANDLE g_hEvent; DWORD WINAPI P(PVOID pvParam) { DWORD dwResult = 0; DWORD FILE_O; int KP=0; while(KP!=1) { FILE_O=WaitForSingleObject(g_hEvent,INFINITE); if(FILE_O!=WAIT_FAILED){break;} } MessageBox(0,0,0,0); getch(); return(dwResult); } void main() { g_hEvent=CreateEvent(NULL,FALSE,FALSE,NULL); int x=0; DWORD dwThreadId; CreateThread(NULL,0,P,(PVOID) &x, 0, &dwThreadId); HANDLE hHandle=CreateFile("\\\\.\\MYSEC",GENERIC_READ|GENERIC_WRITE,FILE_SHARE_READ|FILE_SHARE_WRITE,NULL, OPEN_EXISTING,NULL,NULL); if(hHandle==INVALID_HANDLE_VALUE){cout<<"???????????";getch();} unsigned long ioctlCode=(unsigned long)&g_hEvent; DWORD BBB=0; unsigned char xdata=0x0; unsigned char xdata2=0x0; DeviceIoControl(hHandle,ioctlCode,&xdata2,sizeof(xdata2),&xdata,sizeof(xdata),&BBB,NULL); cout<<"RT "; HANDLE h; h=CreateEvent(NULL,TRUE,FALSE,"1");//??????? ????? WaitForSingleObject(h,50000);//?????? ????? exit(1); } Как видно при попытке завершения процесса с PID=1556 программа выдаст MessageBox. Только при запуске программы после соответствующей загрузке драйвера я наблюдаю синий экран. Подскажите пожалуйста, в чем причина. Вроде все как в статье сделал. Заранее благодарен. С уважением HAWK.
да сам синий экран я разгледеть не успеваю-компьютер перезагружается. Если убрать KeSetEvent,то всё работает без проблем.Выходит,что проблема с обработкой хэндэла передоваемому драйверу.Но где ошибка я не вижу.
hawk настройка сброса крешдампа в ХР2 выбираеш тип - дамп памяти ядра. после бсода - открываеш этот дамп в отладчике WinDbg и отдаёш комманду Код (Text): !analyze -v и шлёш вывод сюда
сейчас попробую.Подскажите,а данная ситуация может быть обусловленна тем,что драйвер я запускаю из drivermonitor,а не из программы?Ведь в таком случае мой одноуровневый драйвер,не находиться в контексте программы в которой я создаю объект.
Clerk Вы имели ввиду под - IRQL_NOT_LESS_OR_EQUAL. В KeSetEvent нужен указатель на обьект. ,следующие изменения: TREST=ObReferenceObjectByHandle(EVEN,EVENT_MODIFY_STATE,*ExEventObjectType,UserMode,&EVEN2,NULL); ?
Даже при таком изменение толку нет: /////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(ControlCode!=0){ PID2=ControlCode; EVEN=(HANDLE )PID2; //__asm{ /// mov ecx, ExEventObjectType // mov ecx, [ecx] // mov ecx, [ecx] // } TREST=ObReferenceObjectByHandle(EVEN,EVENT_MODIFY_STATE,*ExEventObjectType,UserMode,&EVEN2,NULL); if(TREST!=STATUS_SUCCESS){PID2=6;} else {KeSetEvent(EVEN2,0,FALSE);} } else { PID2=0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// Выходит TREST!=STATUS_SUCCESS; Кто нибудь помогите пожалуйста. Из-за чего это может быть.
hawk Ёпт, да запипихни ты вызов сразу до вызова установки эвента, у тебя в DeviceControlRutine() сам то хоть понимаешь что слепил и как оно работать должно. Дебаггер бери и смори что и как.)
Уважаемый Clerk, простите меня за стиль и безграматность написания. Вот исправил, но все равно не пашет. Пишет Код (Text): NTSTATUS DeviceControlRutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp) { NTSTATUS status=STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack; KIRQL irql; KIRQL currentIrql; ULONG BytesTdx=0; ULONG ControlCode; IrpStack=IoGetCurrentIrpStackLocation(Irp); ControlCode=(ULONG)(IrpStack->Parameters.DeviceIoControl.IoControlCode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(ControlCode!=0){ PID2=ControlCode; EVEN=(HANDLE *)PID2; TREST=ObReferenceObjectByHandle(EVEN,EVENT_MODIFY_STATE,*ExEventObjectType,UserMode,&EVEN2,NULL); KeSetEvent(EVEN2,0,FALSE); if(TREST!=STATUS_SUCCESS){PID2=6;}; } else { PID2=0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// return CompleteIrp(Irp,status,BytesTdx); } Выдает IRQL_NOT_LESS_OR_EQUAL.:-(
Вот сделал как в примере: Код (Text): NTSTATUS DeviceControlRutine(IN PDEVICE_OBJECT fdo,IN PIRP Irp) { HANDLE buff; NTSTATUS status=STATUS_SUCCESS; PEXAMPLE_DEVICE_EXTENSION dx; PIO_STACK_LOCATION IrpStack; KIRQL irql; PKEVENT EVEN2; KIRQL currentIrql; ULONG BytesTdx=0; ULONG ControlCode; IrpStack=IoGetCurrentIrpStackLocation(Irp); ControlCode=(ULONG)(IrpStack->Parameters.DeviceIoControl.IoControlCode); /////////////////////////////////////////////////////////////////////////////////////////////////////////////// if(ControlCode!=0){ IrpStack->Parameters.DeviceIoControl.InputBufferLength=sizeof(HANDLE); buff=(PHANDLE)Irp->AssociatedIrp.SystemBuffer; PID2=ControlCode; TREST=ObReferenceObjectByHandle(buff,EVENT_MODIFY_STATE,*ExEventObjectType,UserMode,&EVEN2,NULL); //if(TREST!=STATUS_OBJECT_TYPE_MISMATCH){PID2=0;PID=212;}; //if(TREST!=STATUS_ACCESS_DENIED){PID2=0;PID=232;}; //if(TREST!=STATUS_INVALID_HANDLE){PID2=0;PID=380;}; if(TREST!=STATUS_SUCCESS){PID2=0;PID=1704;}; // else {KeSetEvent(EVEN2,0,FALSE);} } else { PID2=0; } /////////////////////////////////////////////////////////////////////////////////////////////////////////////// return CompleteIrp(Irp,status,BytesTdx); } И получаю STATUS_SUCCESS: Подскажите пожалуйста в чем может быть причина.