Rulik
Помогающий
Offline
|
|
« : 10-09-2006 12:25 » |
|
Добрый день АЛЛ. Фишка такая:
Написал драйвер, который перехватывает через таблицу SST функции экспортируемые из ntoskernl.exe в ring3. И тут первый заморочка! Для функции NtCreateFile все отлавливаеться, а вот функция NtDeleteFile не реагирует, сколько не удаляй файлы.
Пасматрел их индексы в SST? вроде все правильно:
25 0B NtCreateFile 003E 1 NtDeleteFile
И вот не могу понять в чем фича. Пишу все для WinXP.
Может ктонить знает в чем загвоздка?
|
|
|
Записан
|
|
|
|
SlavaI
Главный специалист
Offline
|
|
« Ответ #1 : 13-09-2006 09:45 » |
|
" вот функция NtDeleteFile не реагирует, сколько не удаляй файлы."
Гыыы. Они похоже твоим приложением удаляются через открытие с флагом DeleteOnClose.
|
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #2 : 13-09-2006 10:39 » |
|
Я написал тестовую прогу, которая вызывает DeleteFile(...), эффект тот же. Вроде эта ф-ция должна работать через SST. Поправьте если не прав.
Да и хотелось бы вообще отлавливать удаление файлов из User-mode. Т.к. имею грешок удалять все "лишние", а патом кусать локти и востанавливать это "лишнее". А так я смогу просто блокировать очень важные файлы.
|
|
« Последнее редактирование: 13-09-2006 10:42 от Rulik »
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #3 : 14-09-2006 04:19 » |
|
Написал драйвер, который перехватывает через таблицу SST функции экспортируемые из ntoskernl.exe в ring3.
Интересная штука, а ты не можешь выложить исходники, что бы посмотреть как такие вещи делаются. Не разу на уровне драйверов ни чего делать не преходилось, жутко как интересно.
|
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #4 : 18-09-2006 10:59 » |
|
Вот исходник: NTSTATUS Driver_IoCtl(IN PDEVICE_OBJECT fdo, IN PIRP Irp); NTSTATUS CreateDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp); NTSTATUS CloseDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp); VOID Driver_UnLoad(IN PDRIVER_OBJECT pDriverObject);
//**************************************************************** // Собственно обработчик NtDeleteFile // // // // //*************************************************************** NTSTATUS MyNtDeleteFileProc(IN PUNICODE_STRING FileName) { DbgPrint("MyNtDeleteFileProc %ws",FileName); return STATUS_ACCESS_DENIED; } //**************************************************************** // Точка входа в драйвер // // // Инициализация обработчиков дравера. // //*************************************************************** NTSTATUS DriverEntry ( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath ) { ULONG CR0Reg; //Счетчик для зануления указателей ULONG i; //Строки для создания Символьных Линков для подключения к драйверу UNICODE_STRING devName,symLink; //Указатель на объект драйвера PDEVICE_OBJECT fdo; //Ствтус завершения NTSTATUS status=STATUS_SUCCESS; //Указатель на структуру расширения объекта драйвера PDRV_EXTENSION dx;
DbgPrint("Driver_Entry\n");
//Обнуляем указатели на обработчики (для уверенности) for (i = 0; i <= IRP_MJ_MAXIMUM_FUNCTION; i++) { DriverObject->MajorFunction[i] = NULL; }
//Обработчики //Открытие устройства DriverObject->MajorFunction [IRP_MJ_CREATE] = CreateDevice; //Закрытие устройства DriverObject->MajorFunction [IRP_MJ_CLOSE] = CloseDevice; //Коды управления устройством DriverObject->MajorFunction [IRP_MJ_DEVICE_CONTROL] = Driver_IoCtl; //Выгрузка драйвера DriverObject->DriverUnload = Driver_UnLoad;
//Инициализируем строку с именем устройства RtlInitUnicodeString(&devName,L"\\Device\\SysMan");
//Создаем объект "устройство" status=IoCreateDevice(DriverObject,sizeof(struct _DRV_EXTENSION),&devName,FILE_DEVICE_UNKNOWN,0,TRUE,&fdo); if(!NT_SUCCESS(status)) { DbgPrint("IoCreateDevice ERROR\n"); return status; }
//Сохраняем указатель на расширение объекта драйвера dx=(PDRV_EXTENSION)fdo->DeviceExtension; dx->fdo=fdo;
DbgPrint("SysMan FDO %X, DevExt=%X.\n",fdo,dx);
//Строка с именем, для регистрации в USER мод RtlInitUnicodeString(&symLink,L"\\DosDevices\\SysMan");
dx->SymLinkName=symLink; dx->OrigFunc=NTCALL(SERVICE_ID);
//Создаем псевдоним устройства status=IoCreateSymbolicLink(&symLink,&devName); if(!NT_SUCCESS(status)) { IoDeleteDevice(fdo); DbgPrint("IoCreateSymbolicLink ERROR\n"); return status; }
__asm { cli // запрещаем прерывания mov eax, cr0 mov CR0Reg,eax and eax,0xFFFEFFFF // сбросить WP bit mov cr0, eax }
DbgPrint("SetUp MyNtDeleteFileProc"); NTCALL(SERVICE_ID)=MyNtDeleteFileProc; __asm { mov eax, CR0Reg mov cr0, eax // востановить содержимое CR0 sti // разрешаем прерывания }
return status; }
//**************************************************************** // Завершение запросов // // // // //*************************************************************** NTSTATUS CompliteIrp(PIRP Irp,NTSTATUS status,ULONG info) { //Заносим статус завершения Irp->IoStatus.Status = status; //Доп инфу Irp->IoStatus.Information=info; //Помечаем пакет как завершенный IoCompleteRequest(Irp,IO_NO_INCREMENT); //Возвращаем статус return status; } //**************************************************************** // Окрытие и закрытие Дэвайса // // // // //**************************************************************** NTSTATUS CreateDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { DbgPrint("Device opned"); //Подтверждаем открытие устройства return CompliteIrp(Irp,STATUS_SUCCESS,0); } NTSTATUS CloseDevice(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { DbgPrint("Device closed"); //Одтверждаем закрытие устройства return CompliteIrp(Irp,STATUS_SUCCESS,0); } //**************************************************************** // Обработка запросов // // // // //*************************************************************** NTSTATUS Driver_IoCtl(IN PDEVICE_OBJECT fdo, IN PIRP Irp) { NTSTATUS status =STATUS_SUCCESS; PIO_STACK_LOCATION IrpStack =IoGetCurrentIrpStackLocation(Irp); PDRV_EXTENSION dx =(PDRV_EXTENSION)fdo->DeviceExtension; ULONG ControlCode =IrpStack->Parameters.DeviceIoControl.IoControlCode; ULONG method =ControlCode&0x03;
DbgPrint("Driver_IoCTL\n");
switch(ControlCode) { case IOCTL_INIT_DRV: { break; } } CompliteIrp(Irp,status,0);
return status;
// IoDeleteDevice() }
//**************************************************************** // Выгрузка драйвера из памяти // // // // //*************************************************************** VOID Driver_UnLoad(IN PDRIVER_OBJECT DriverObject) { PDRV_EXTENSION dx=(PDRV_EXTENSION)DriverObject->DeviceObject->DeviceExtension; ULONG CR0Reg;
__asm { cli; mov eax, cr0 mov CR0Reg,eax and eax,0xFFFEFFFF // сбросить WP bit mov cr0, eax } NTCALL(SERVICE_ID)=dx->OrigFunc; __asm { mov eax, CR0Reg mov cr0, eax // востановить содержимое CR0 sti; } //Удаляем псевдоним IoDeleteSymbolicLink(&dx->SymLinkName); //Удаляем устройство IoDeleteDevice(dx->fdo); DbgPrint("Driver_UnLoad\n"); }
Может че я и не правильно делаю, прошу пнуть. Тока не запинать до смерти.
|
|
« Последнее редактирование: 17-11-2007 12:47 от Алексей1153++ »
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #5 : 18-09-2006 11:12 » |
|
Rulik ну ты даешь, ты бы свой проект в архивчик (*.zip) упаковал и прикрепил его к сообщению.
|
|
|
Записан
|
|
|
|
Serg79
|
|
« Ответ #6 : 18-09-2006 11:12 » |
|
|
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #7 : 20-09-2006 09:21 » |
|
Прикрепил проект. Чет вапще не могу понять почему не работат.
|
sys.rar (3.3 Кб - загружено 937 раз.)
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #8 : 21-09-2006 03:49 » |
|
" вот функция NtDeleteFile не реагирует, сколько не удаляй файлы."
Гыыы. Они похоже твоим приложением удаляются через открытие с флагом DeleteOnClose.
Удаляет не мое приложение, я просто хочу защитить от удаления важные файлы. Т.к. ту писал процедуру удаления файлов и допустил ошибку. И есь винт был чист как младенец. Вот и хочу написать для себя прогу, которая при папытке удаления указанных файлов, будет их либо переносить в безопасное место, либо не давать удалять. Почему хачу написать? Потому что это просто интересно. Да и со своей прогой мона патом и доработать, что то добавить, чтото убрать.
|
|
|
Записан
|
|
|
|
kvak
Гость
|
|
« Ответ #9 : 21-09-2006 08:08 » |
|
Привет, Rulik Меня заинтересовала твоя проблема. Вот что удалось надыбать дизассемблированием DeleteFile: На самом деле NtDeleteFile не вызывается при вызове DeleteFile из юзер мод, а вызывается NtSetInformationFile на открытый файл хэндл удаляемого файла (открытый функцие NtOpenFile с флагом DELETE). Так что в худшем случае стоит перехватывать NtSetInformationFile и по хэндлу найти имя файла (правда, я ни в курсе как это делать) и далее определить принадлежность его к важным и ни удалять. А еще лучше хукать NtOpenFile, и смотреть открылся ли твой файл на доступ dwDesiredAccess == DELETE, в этом случае просто возвращать STATUS_ACCESS_DENIED. p.s. Я переписал немного твой проект (в прицепе) и захукал NtOpenFile, так, чтобы программу calc.exe нильзя было удалить - всё работает
|
sys.zip (4 Кб - загружено 951 раз.)
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #10 : 22-09-2006 02:22 » |
|
Привет, Rulik Меня заинтересовала твоя проблема. Вот что удалось надыбать дизассемблированием DeleteFile: На самом деле NtDeleteFile не вызывается при вызове DeleteFile из юзер мод, а вызывается NtSetInformationFile на открытый файл хэндл удаляемого файла (открытый функцие NtOpenFile с флагом DELETE). Так что в худшем случае стоит перехватывать NtSetInformationFile и по хэндлу найти имя файла (правда, я ни в курсе как это делать) и далее определить принадлежность его к важным и ни удалять. А еще лучше хукать NtOpenFile, и смотреть открылся ли твой файл на доступ dwDesiredAccess == DELETE, в этом случае просто возвращать STATUS_ACCESS_DENIED. p.s. Я переписал немного твой проект (в прицепе) и захукал NtOpenFile, так, чтобы программу calc.exe нильзя было удалить - всё работает Спасибо. Очень памог. Только, скажи пожайлуста, где ты выдернул прототип для функции NtOpenFile? Просто сам пытался найти, но безуспешно для NtDeleteFile. Удалось выяснить тока что передаеться в нее 4 байта.
|
|
|
Записан
|
|
|
|
kvak
Гость
|
|
« Ответ #11 : 22-09-2006 04:24 » |
|
Привет, Rulik Взять описание многих Native API функций можно например в этих местах: 1. http://undocumented.ntinternals.net (лежит полезный .chm файл) 2. www.osronline.com3. Книга Гари Неббета "Native Reference API" (есть на русском)
|
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #12 : 23-09-2006 09:32 » |
|
2 kvak
Скомпилил твою версия. И получил синий экран при удалении. Как выяснилось из описани: Parameters FileHandle [out] Pointer to a handle for the opened file. The driver must close the handle with zwClose once the handle is no longer in use. DesiredAccess [in] Specifies the ACCESS_MASK value that expresses the types of file access desired by the caller. For information about the types of access that can be specified, see ZwCreateFile in the DDK. ObjectAttributes [in] Pointer to a structure that a caller initializes with InitializeObjectAttributes. If the caller is not running in the system process context, it must set the OBJ_KERNEL_HANDLE attribute for ObjectAttributes. For more information about specifying object attributes, see ZwCreateFile in the DDK. IoStatusBlock [out] Pointer to a structure that contains information about the requested operation and the final completion status. ShareAccess [in] Specifies the type of share access for the file. For more information, see ZwCreateFile in the DDK. OpenOptions [in] Specifies the options to be applied when opening the file. For more information, see ZwCreateFile in the DDK.
Т.е. Надо брать имя файла не из IoStatusBlock а из ObjectAttributes->ObjectName Так написано в MSDN, но при попытке это реализовать, я получаю в этой переменной муссор.
За источники примного благодарен. Буду разбираться дальше.
|
|
|
Записан
|
|
|
|
kvak
Гость
|
|
« Ответ #13 : 25-09-2006 04:43 » |
|
2 kvak
Скомпилил твою версия. И получил синий экран при удалении. Как выяснилось из описани: ... ObjectAttributes [in] Pointer to a structure that a caller initializes with InitializeObjectAttributes. If the caller is not running in the system process context, it must set the OBJ_KERNEL_HANDLE attribute for ObjectAttributes. For more information about specifying object attributes, see ZwCreateFile in the DDK. IoStatusBlock [out] Pointer to a structure that contains information about the requested operation and the final completion status.
Т.е. Надо брать имя файла не из IoStatusBlock а из ObjectAttributes->ObjectName Так написано в MSDN, но при попытке это реализовать, я получаю в этой переменной муссор.
За источники примного благодарен. Буду разбираться дальше.
Да, действительно тут я был ни прав юзая IoStatusBlock, т.к. он [out]. С ObjectAttributes все работает нормально! И выгружается без проблем, никаких БСОД-ов. Работаю на такой системе: Microsoft Windows XP Professional 5.1.2600 Service Pack 2 Build 2600 156 Hotfix(s) Installed. Как разберешься, почему у тебя БСОД - поделись инфой
|
|
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #14 : 25-09-2006 05:01 » |
|
2 kvak
У меня тоже BSOD исчесли как тока стал узать ObjectAttributes. А до этого вылетал с Page Fault иногда (использовал когда IoStatusBlock).
Ща тоже все работает, но в переменно ObjectAttributes->ObjectName лежит мусор. (смотрел и SoftIce'ом и через DbgPring)
Можешь прицепить свой проект? Взгляну, что я делаю не так.
|
|
« Последнее редактирование: 10-12-2007 17:49 от Алексей1153++ »
|
Записан
|
|
|
|
kvak
Гость
|
|
« Ответ #15 : 25-09-2006 05:32 » |
|
2 kvak
У меня тоже BSOD исчесли как тока стал узать ObjectAttributes. А до этого вылетал с Page Fault иногда (использовал когда IoStatusBlock).
Ща тоже все работает, но в переменно ObjectAttributes->ObjectName лежит мусор. (смотрел и SoftIce'ом и через DbgPring)
Можешь прицепить свой проект? Взгляну, что я делаю не так.
Я кажется понял в чем твоя ошибка, ObjectAttributes->ObjectName - это PUNICODE_STRING, следовательно надо применить оператор "->Buffer" к нему, т.е. ObjectAttributes->ObjectName->Buffer. И тогда будет все хорошо. зы На всякий случай прицепил свой проект. Дай знать если у тебя будут проблемы и с ним
|
sys.zip (4.02 Кб - загружено 927 раз.)
|
« Последнее редактирование: 10-12-2007 17:47 от Алексей1153++ »
|
Записан
|
|
|
|
Rulik
Помогающий
Offline
|
|
« Ответ #16 : 26-09-2006 02:30 » |
|
2 kvak
У меня тоже BSOD исчесли как тока стал узать ObjectAttributes. А до этого вылетал с Page Fault иногда (использовал когда IoStatusBlock).
Ща тоже все работает, но в переменно ObjectAttributes->ObjectName лежит мусор. (смотрел и SoftIce'ом и через DbgPring)
Можешь прицепить свой проект? Взгляну, что я делаю не так.
Я кажется понял в чем твоя ошибка, ObjectAttributes->ObjectName - это PUNICODE_STRING, следовательно надо применить оператор "->Buffer" к нему, т.е. ObjectAttributes->ObjectName->Buffer. И тогда будет все хорошо. зы На всякий случай прицепил свой проект. Дай знать если у тебя будут проблемы и с ним Ты прав. Проблема была именно в отсутствии "->Buffer". Как дописал все поперло. Спасибо kvak.
|
|
« Последнее редактирование: 17-12-2007 16:40 от Алексей1153++ »
|
Записан
|
|
|
|
|