Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Перехват системного сервиса с помощью драйвера.  (Прочитано 18635 раз)
0 Пользователей и 1 Гость смотрят эту тему.
Rulik
Помогающий

ru
Offline Offline

« : 10-09-2006 12:25 » 

Добрый день АЛЛ.
Фишка такая:

Написал драйвер, который перехватывает через таблицу SST функции экспортируемые из ntoskernl.exe в ring3.
И тут первый заморочка!
Для функции NtCreateFile все отлавливаеться, а вот функция NtDeleteFile не реагирует, сколько не удаляй файлы.

Пасматрел их индексы в SST? вроде все правильно:

25   0B   NtCreateFile
003E   1   NtDeleteFile

И вот не могу понять в чем фича. Пишу все для WinXP.

Может ктонить знает в чем загвоздка?
Записан
SlavaI
Главный специалист

ru
Offline Offline

« Ответ #1 : 13-09-2006 09:45 » 

" вот функция NtDeleteFile не реагирует, сколько не удаляй файлы."

Гыыы. Они похоже твоим приложением удаляются через открытие с флагом DeleteOnClose.
Записан
Rulik
Помогающий

ru
Offline Offline

« Ответ #2 : 13-09-2006 10:39 » 

Я написал тестовую прогу, которая вызывает DeleteFile(...), эффект тот же.
Вроде эта ф-ция должна работать через SST. Поправьте если не прав.

Да и хотелось бы вообще отлавливать удаление файлов из User-mode.
Т.к. имею грешок удалять все "лишние", а патом кусать локти и востанавливать это "лишнее".
А так я смогу просто блокировать очень важные файлы.
« Последнее редактирование: 13-09-2006 10:42 от Rulik » Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #3 : 14-09-2006 04:19 » 

Написал драйвер, который перехватывает через таблицу SST функции экспортируемые из ntoskernl.exe в ring3.
Интересная штука, а ты не можешь выложить исходники, что бы посмотреть как такие вещи делаются.
Не разу на уровне драйверов ни чего делать не преходилось, жутко как интересно.
Записан
Rulik
Помогающий

ru
Offline 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
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #5 : 18-09-2006 11:12 » 

Rulik ну ты даешь, ты бы свой проект в архивчик (*.zip) упаковал и прикрепил его к сообщению.
Записан
Serg79
Команда клуба

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 18-09-2006 11:12 » 

Улыбаюсь
Записан
Rulik
Помогающий

ru
Offline Offline

« Ответ #7 : 20-09-2006 09:21 » 

 Ангел
Прикрепил проект.
Чет вапще не могу понять почему не работат.

* sys.rar (3.3 Кб - загружено 863 раз.)
Записан
Rulik
Помогающий

ru
Offline 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 Кб - загружено 881 раз.)
Записан
Rulik
Помогающий

ru
Offline 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.com
3. Книга Гари Неббета "Native Reference API" (есть на русском)
Записан
Rulik
Помогающий

ru
Offline 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
Помогающий

ru
Offline 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 Кб - загружено 876 раз.)
« Последнее редактирование: 10-12-2007 17:47 от Алексей1153++ » Записан
Rulik
Помогающий

ru
Offline 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++ » Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines