драйвер для перехвата NtCreateProcess

Тема в разделе "WASM.NT.KERNEL", создана пользователем Mike, 16 дек 2006.

  1. Mike

    Mike New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    5
    Знающие люди, помогите!
    Хочу перехватить функцию NtCreateProcess Windows XP, но ничего не получилось, причем она даже не вызывается. Потом прочитал, что эта функция в XP не используется, а есть NtCreateProcessEx. Пытаюсь перехватить ее, но при перехвате комп перезагружается. Драйвер рабочий- для других функций все отлично работает. В чем дело, не знаю.
     
  2. Shark_X

    Shark_X New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    8
    А для чего тебе перехват NtCreateProcess?
     
  3. Nilos

    Nilos New Member

    Публикаций:
    0
    Регистрация:
    23 ноя 2006
    Сообщения:
    14
    BSOD при сплайсинге, или чё??... интересно....
     
  4. Guest

    Guest Guest

    Публикаций:
    0
    NtCreateSection попробуй
     
  5. hulk45

    hulk45 New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2006
    Сообщения:
    10
    Товарищи меня тоже очень интересует этот вопрос. может кто то поможет. Предыдущее предлжение тоже не помогло.
     
  6. PsReadRtfm

    PsReadRtfm New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    32
    Mikeпокажи код как ты перехватываешь, а причины БСОДа могут быть разные , выложи свежий дамп сюда.
     
  7. Mike

    Mike New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    5
    я попробовал через NtCreateSection
    впринципе работает, но мне нужно вывести PID процесса-прародителя(он выводится нормально через PsGetCurrentProcessId()) и имя исполняемого файла порождаемого процесса(я хочу через ObjectAttributes->ObjectName).
    Но тут возникает опять проблема: как только я обращаюсь к полю
    ObjectAttributes->ObjectName возникает BSOD
    Не пойму в чем дело
     
  8. Mike

    Mike New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    5
    Вот код , кот я использую для NtCreateProcessEx:

    cpp:
    Код (Text):
    1. // DriverEntry            Главная точка входа в драйвер
    2. // UnloadRoutine          Процедура выгрузки драйвера
    3. // DeviceControlRo ine   Обработчик DeviceIoControl IRP пакетов
    4.  
    5. #include "Driver.h"
    6.  
    7. // Предварительные объявления функций:
    8. NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
    9. VOID     UnloadRoutine(IN PDRIVER_OBJECT DriverObject);
    10. NTSTATUS ReadWrite_IRPhandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp );
    11. NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp);
    12. NTSTATUS Close_HandleIRPprocessing(IN PDEVICE_OBJECT fdo, IN PIRP Irp); int d;
    13.  
    14. KSPIN_LOCK MySpinLock;
    15.             //Индекс OldCreateProcessEx в таблице SST Windows XP
    16.             //Индекс OldCreateProcessEx) в таблице SST Win2k
    17. #define INDEX_IN_SST_IN_XP      0x30
    18.  
    19.  
    20. DEVICE_BUFFER   buf[3];                     //Дай бог чоть кто-нить её вызвал!
    21. int             Counter=0;                      //счетчик вызовов
    22. int             CURRENT_INDEX = INDEX_IN_SST_IN_XP  ; //У мен
    23. int             CountCall = 0;     
    24. UNICODE_STRING  UniFileName;                    //временные строки Unicode
    25. ANSI_STRING     AnsiFileName;                   //и ANSI,
    26. NTSTATUS        stat;                           //временные переменные stat
    27. int             len;                            //и len -- для преобразования имени файла из UNICODE в char*
    28.  
    29.  
    30.  
    31. NtCreateProcessEx OldCreateProcessEx;
    32.  
    33. NTSTATUS NewNtCreateProcessEx(
    34. OUT PHANDLE ProcessHandle,
    35. IN ACCESS_MASK DesiredAccess,
    36. IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    37. IN HANDLE InheritFromProcessHandle,
    38. IN BOOLEAN InheritHandles,
    39. IN HANDLE SectionHandle OPTIONAL,
    40. IN HANDLE DebugPort OPTIONAL,
    41. IN HANDLE ExceptionPort OPTIONAL,
    42. IN HANDLE Unknown
    43.  
    44. )
    45.    
    46.    
    47. {
    48.  
    49.  
    50.    
    51.     int size = 0;  
    52.     int ret;                       
    53.     HANDLE PID;                
    54.    
    55.     size = ObjectAttributes->ObjectName->Length / sizeof(WCHAR);   
    56.    
    57.  
    58.     PID = PsGetCurrentProcessId();
    59.     DbgPrint("-Example=Id of Proceeeeeeeess =%d\n",PID);
    60.  
    61.     if (Counter<3)
    62.     {              
    63.         UniFileName.Buffer = (PWSTR) ExAllocatePool(
    64.                             NonPagedPool,
    65.                             ObjectAttributes->ObjectName->MaximumLength/*Length + sizeof(WCHAR))*/);
    66.  
    67.                         UniFileName.MaximumLength = ObjectAttributes->ObjectName->MaximumLength/*Length + sizeof(WCHAR)*/;
    68.                         RtlCopyUnicodeString( &UniFileName, ObjectAttributes->ObjectName );
    69.  
    70.                         stat = RtlUnicodeStringToAnsiString(
    71.                             &AnsiFileName,
    72.                             &UniFileName,
    73.                             TRUE);
    74.  
    75.                         if (NT_SUCCESS(stat))
    76.                         {
    77.                             len = (AnsiFileName.Length > 255? 255 : AnsiFileName.MaximumLength/*Length*/);
    78.                             strncpy(
    79.                                 buf[Counter].FileName,     
    80.                                 AnsiFileName.Buffer /*+ 4*/,    //+4 -- для удаления из начала строки последовательности "\??\"
    81.                                 len);
    82.                            
    83.                             buf[Counter].FileName[len+1] = 0;
    84.                         DbgPrint("-Example=NAME of Proceeeeeeeess =%s\n",buf[Counter].FileName);
    85.                         }
    86.        
    87.         buf[Counter++].PID = PID;
    88.     DbgPrint("-Example=Id of Proceeeeeeeess =%d\n",buf[Counter-1].PID);
    89.     }
    90.     else
    91.         DbgPrint("Malo Mesta v Buffere\n");
    92.            
    93.  
    94.        
    95.        
    96.        
    97. ret=((NtCreateProcessEx)(OldCreateProcessEx)) (
    98.     ProcessHandle,
    99.     DesiredAccess,
    100.     ObjectAttributes,
    101.     InheritFromProcessHandle,
    102.     InheritHandles,
    103.     SectionHandle,
    104.     DebugPort,
    105.     ExceptionPort,
    106.  Unknown
    107.     );
    108.     return ret;
    109.  
    110. }
    111.  
    112.  
    113.  
    114. #pragma code_seg("INIT") // начало секции INIT
    115. /////////////////////////////////////////////////////////////////////
    116. // (Файл init.cpp)
    117. // DriverEntry - инициализация драйвера и необходимых объектов
    118. // Аргументы:  указатель на объект драйвера
    119. //             раздел реестра (driver service key) в UNICODE
    120. // Возвращает: STATUS_Xxx
    121.  
    122. extern "C"
    123. NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject,
    124.                       IN PUNICODE_STRING RegistryPath  )
    125. {
    126.     NTSTATUS status = STATUS_SUCCESS;
    127.     PDEVICE_OBJECT  fdo;
    128.     UNICODE_STRING  devName;
    129.     //PDEVICE_EXTENSION PDEx;
    130.     ULONG   CR0Reg;
    131.     ULONG   i;             
    132.  
    133.     #if DBG
    134.     DbgPrint("=Example= In DriverEntry.");
    135.     DbgPrint("=Example= RegistryPath = %ws.", RegistryPath->Buffer);
    136.     #endif
    137.  
    138.     // Экспорт точек входа в драйвер (AddDevice объявлять не будем)
    139.     // DriverObject->DriverExtension->AddDevice= OurAddDeviceRoutine;
    140.     DriverObject->DriverUnload = UnloadRoutine;
    141.     DriverObject->MajorFunction[IRP_MJ_CREATE]= Create_File_IRPprocessing;
    142.     DriverObject->MajorFunction[IRP_MJ_CLOSE] = Close_HandleIRPprocessing;
    143.     DriverObject->MajorFunction[IRP_MJ_READ]  = ReadWrite_IRPhandler;
    144.     DriverObject->MajorFunction[IRP_MJ_WRITE] = ReadWrite_IRPhandler;
    145.     DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DeviceControlRoutine;
    146.     //========================================================
    147.     // Действия по созданию символьной ссылки
    148.     // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    149.     // очень простой драйвер и эта процедура отсутствует):
    150.     RtlInitUnicodeString( &devName, L"\\Device\\EXAMPLE" );
    151.  
    152.     // Создаем наш Functional Device Object (FDO) и получаем
    153.     // указатель на созданный FDO в нашей переменной fdo.  
    154.     // (В WDM драйвере эту работу также следовало бы выполнять
    155.     // в процедуре OurAddDeviceRoutine.) При создании FDO
    156.     // будет выделено место и под структуру расширения устройства
    157.     // EXAMPLE_DEVICE_EXTENSION (для этого мы передаем в вызов
    158.     // ее размер, вычисляемый оператором sizeof):
    159.     status = IoCreateDevice(DriverObject,
    160.                             sizeof(_DEVICE_EXTENSION),
    161.                             &devName, // может быть и NULL
    162.                             FILE_DEVICE_UNKNOWN,
    163.                             0,
    164.                             TRUE, // c эксклюзивного доступа
    165.                             &fdo);
    166.     if(!NT_SUCCESS(status)) return status;
    167.  
    168.     // Получаем указатель на область, предназначенную под
    169.     // структуру расширение устройства
    170.     PDEVICE_EXTENSION dx = (PDEVICE_EXTENSION)fdo->DeviceExtension;
    171.     dx->fdo = fdo;  // Сохраняем обратный указатель
    172.  
    173.     // Применяя прием условной компиляции, вводим функцию DbgPrint,
    174.     // сообщения которой мы сможем увидеть в окне DebugView, если
    175.     // выполним сборку нашего драйвера как checked (отладочную)
    176.     // версию:
    177.     #if DBG
    178.     DbgPrint("=Example= FDO %X, DevExt=%X.",fdo,dx);
    179.     #endif
    180.  
    181.     //=======================================
    182.     // Действия по созданию символьной ссылки
    183.     // (их нужно было бы делать в OurAddDeviceRoutine, но у нас
    184.     // очень простой драйвер):
    185.     UNICODE_STRING symLinkName;   // Сформировать символьное имя:
    186.     // #define   SYM_LINK_NAME   L"\\??\\Example"
    187.     // Такого типа символьные ссылки ^^ проходят только в NT.
    188.     // (То есть, если перенести бинарный файл драйвера в
    189.     // Windows 98, то пользовательские приложения заведомо
    190.     // не смогут открыть файл по такой символьной ссылке.)
    191.     // Для того, чтобы ссылка работала в и Windows 98 и в NT,
    192.     // необходимо поступать следующим образом:
    193.     #define SYM_LINK_NAME   L"\\DosDevices\\Example"
    194.     RtlInitUnicodeString( &symLinkName, SYM_LINK_NAME );
    195.     dx->SymLinkName = symLinkName;
    196.    
    197.     // Создаем символьную ссылку
    198.     status = IoCreateSymbolicLink( &symLinkName, &devName );
    199.     if (!NT_SUCCESS(status))
    200.     { // при неудаче v удалить Device Object и вернуть управление
    201.         IoDeleteDevice( fdo );
    202.         return status;
    203.     } // Теперь можно вызывать CreateFile("\\\\.\\Example",...);
    204.       // в пользовательских приложениях
    205.       // Объект спин-блокировки, который будем использовать для
    206.       // разнесения во времени выполнения кода обработчика
    207.       // IOCTL запросов. Инициализируем его:
    208.  
    209.     (NtCreateProcessEx)dx->OriginalFunc=(NtCreateProcessEx)NTCALL(CURRENT_INDEX);
    210.     OldCreateProcessEx=dx->OriginalFunc;
    211.     __asm
    212.     {
    213.     cli                        
    214.     mov eax, cr0
    215.     mov CR0Reg,eax
    216.     and eax,0xFFFEFFFF          //сбросить WP bit
    217.     mov cr0, eax
    218.     }
    219.  
    220.     NTCALL(CURRENT_INDEX)=NewNtCreateProcessEx;
    221.  
    222.     __asm
    223.     {
    224.     mov eax, CR0Reg    
    225.     mov cr0, eax                //востановить содержимое CR0
    226.     sti                         //разрешаем прерывания
    227.     }
    228.    
    229.     KeInitializeSpinLock(&MySpinLock);
    230.     // Снова используем условную компиляцию, чтобы выделить код,
    231.     // компилируемый в отладочной версии и не компилируемый в
    232.     // версии free (релизной):
    233.     #if DBG
    234.     DbgPrint("=Example= DriverEntry successfully completed.");
    235.     #endif
    236.     return status;
    237. }
    238. #pragma code_seg() // end INIT section
    239.  
    240. //
    241. // (Файл init.cpp)
    242. // CompleteIrp: Устанавливает IoStatus и завершает обработку IRP
    243. // Первый аргумент - указатель на объект нашего FDO.
    244. //
    245. NTSTATUS CompleteIrp( PIRP Irp, NTSTATUS status, ULONG info)
    246. {
    247.     Irp->IoStatus.Status = status;
    248.     Irp->IoStatus.Information = info;
    249.     IoCompleteRequest(Irp,IO_NO_INCREMENT);
    250.     return status;
    251. }
    252.  
    253. //
    254. // (Файл init.cpp)
    255. // ReadWrite_IRPhandler: Берет на себя обработку запросов
    256. // чтения/записи и завершает обработку IRP вызовом CompleteIrp
    257. // с числом переданных/полученных байт (BytesTxd) равным нулю.
    258. // Аргументы:
    259. // Указатель на объект нашего FDO
    260. // Указатель на структуру IRP, поступившего от Диспетчера ввода/вывода
    261. NTSTATUS ReadWrite_IRPhandler( IN PDEVICE_OBJECT fdo, IN PIRP Irp )
    262. {
    263.     ULONG BytesTxd = 0;
    264.     NTSTATUS status = STATUS_SUCCESS; //Завершение с кодом status
    265.     // Задаем печать отладочных сообщений v если сборка отладочная
    266.     #if DBG
    267.     DbgPrint("-Example- in ReadWrite_IRPhandler.");
    268.     #endif
    269.     return CompleteIrp(Irp,status,BytesTxd);
    270. }
    271.  
    272. //
    273. // (Файл init.cpp)
    274. // Create_File_IRPprocessing: Берет на себя обработку запросов с
    275. // кодом IRP_MJ_CREATE.
    276. // Аргументы:
    277. // Указатель на объект нашего FDO
    278. // Указатель на структуру IRP, поступившего от Диспетчера ВВ
    279. //
    280. NTSTATUS Create_File_IRPprocessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
    281. {
    282.     PIO_STACK_LOCATION IrpStack = IoGetCurrentIrpStackLocation(Irp);
    283.     // Задаем печать отладочных сообщений - если сборка отладочная
    284.     #if DBG
    285.     DbgPrint("-Example- Create File is %ws",
    286.         &(IrpStack->FileObject->FileName.Buffer));
    287.     #endif
    288. return CompleteIrp(Irp,STATUS_SUCCESS,0); // Успешное завершение
    289. }
    290.  
    291. // (Файл init.cpp)
    292. // Close_File_IRPprocessing: Берет на себя обработку запросов с
    293. // кодом IRP_MJ_CLOSE.
    294. // Аргументы:
    295. // Указатель на объект нашего FDO
    296. // Указатель на структуру IRP, поступившего от Диспетчера ввода/вывода
    297. NTSTATUS Close_HandleIRPprocessing(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
    298. {
    299.     #if DBG
    300.     // Задаем печать отладочных сообщений - если сборка отладочная
    301.     DbgPrint("-Example- In Close handler.");
    302.     #endif
    303. return CompleteIrp(Irp,STATUS_SUCCESS,0);// Успешное завершение
    304. }
    305.  
    306. // (Файл init.cpp)
    307. // DeviceControlRoutine: обработчик IRP_MJ_DEVICE_CONTROL запросов
    308. // Аргументы:
    309. // Указатель на объект нашего FDO
    310. // Указатель на структуру IRP, поступившего от Диспетчера ВВ
    311. //  Возвращает:  STATUS_XXX
    312. // #define SMALL_VERSION
    313. // В том случае, если не закомментировать верхнюю строчку v будет
    314. // выполнена компиляция версии, в которой будет обрабатываться только
    315. // один тип IOCTL запросов -- IOCTL_MAKE_SYSTEM_CRASH
    316.  
    317. NTSTATUS DeviceControlRoutine( IN PDEVICE_OBJECT fdo, IN PIRP Irp )
    318. {
    319.     NTSTATUS status = STATUS_SUCCESS;
    320.     //ULONG BytesMes=0;
    321.     ULONG BytesTxd =0; // Число переданных/полученных байт (пока 0)
    322.     PIO_STACK_LOCATION IrpStack=IoGetCurrentIrpStackLocation(Irp);
    323.  
    324.     // Получаем указатель на расширение устройства
    325.     PDEVICE_EXTENSION dx =(PDEVICE_EXTENSION)fdo->DeviceExtension;
    326.     //-------------------------------
    327.     // Выделяем из IRP собственно значение IOCTL кода, по поводу
    328.     // которого случился вызов:
    329.     ULONG ControlCode =IrpStack->Parameters.DeviceIoControl.IoControlCode;
    330.     ULONG method = ControlCode & 0x03;
    331.  
    332.     // Получаем текущее значение уровня IRQL v приоритета,
    333.     // на котором выполняется поток (вообще говоря, целое число):
    334.     KIRQL irql,
    335.     currentIrql = KeGetCurrentIrql();
    336.  
    337.     #if DBG
    338.     DbgPrint("=Example= 33333333333333333");
    339.     DbgPrint("=Example= 000000000000000000000000");
    340.     DbgPrint("-Example- In DeviceControlRoutine (fdo= %X)\n",fdo);
    341.     DbgPrint("-Example- DeviceIoControl: IOCTL %x.", ControlCode );
    342.     if(currentIrql==PASSIVE_LEVEL)
    343.         DbgPrint("-Example- PASSIVE_LEVEL (val=%d)",currentIrql);
    344.     #endif
    345.     // Запрашиваем владение объектом спин-блокировки. В данном
    346.     // примере не выполняется никаких критичных действий, но,
    347.     // вообще говоря, этот прием может быть полезен и даже
    348.     // незаменим, если в приведенном ниже коде должны будут
    349.     // выполнены манипуляции, которые можно делать только
    350.     // эксклюзивно. Пока потоку выделен объект спин-блокировки v
    351.     // никакой другой поток не сможет войти в оператор switch:
    352.     KeAcquireSpinLock(&MySpinLock,&irql);
    353.  
    354.     // Диспетчеризация по IOCTL кодам:
    355.     switch( ControlCode) {
    356. /*Ненужная жесть!
    357.     #ifndef SMALL_VERSION
    358.     case IOCTL_PRINT_DEBUG_MESS:
    359.     {     // Только вводим сообщение и только в отладочной версии
    360.         #if DBG
    361.         DbgPrint("-Example- IOCTL_PRINT_DEBUG_MESS.");
    362.         #endif
    363.         break;
    364.     }
    365.     case IOCTL_CHANGE_IRQL:
    366.     {
    367.         #if DBG
    368.         // Эксперименты по искусственному повышению
    369.         // IRQL v только в отладочной версии!
    370.         DbgPrint("-Example- IOCTL_CHANGE_IRQL.");
    371.         KIRQL dl = DISPATCH_LEVEL, // только для распечатки (2)
    372.         oldIrql,
    373.         newIrql=25; // Новый уровень IRQL (например, 25)
    374.         // Устанавливаем newIrql, сохраняя текущий в oldIrql:
    375.         KeRaiseIrql(newIrql,&oldIrql);
    376.         newIrql=KeGetCurrentIrql(); // Что реально получили?
    377.  
    378.         DbgPrint("-Example- DISPATCH_LEVEL value =%d",dl);
    379.         DbgPrint("-Example- IRQLs are old=%d new=%d",
    380.                         oldIrql,newIrql);
    381.         KeLowerIrql(oldIrql); // Возвращаем старое значение
    382.         #endif
    383.         break;
    384.     }
    385.     #endif // SMALL_VERSION
    386. */
    387.     case IOCTL_MAKE_SYSTEM_CRASH:
    388.     {
    389.         int errDetected=0;
    390.         char x = (char)0xFF;
    391.  
    392.         #if DBG  // Вообще говоря, под NT мы этого уже не увидим:
    393.         DbgPrint("-Example- IOCTL_MAKE_SYSTEM_CRASH.");
    394.         #endif
    395.         // Вызываем системный сбой обращением по нулевому адресу
    396.         __try {
    397.         x = *(char*)0x0L; // ошибочная ситуация
    398.             //^^^^^^^^^^^^ здесь случится сбой NT, но не Win98
    399.         }
    400.         __except(EXCEPTION_EXECUTE_HANDLER)
    401.         {   // Перехват исключения не работает!
    402.             // Эта занимательная ситуация объяснена в 10.2.6,
    403.             // при рассмотрении объектов спин-блокировок.
    404.             errDetected=1;
    405.         };
    406.         #if DBG
    407.         DbgPrint("-Example- Value of x is %X.",x);
    408.         if(errDetected)
    409.             DbgPrint("-Example- Except detected in Example driver.");
    410.         #endif
    411.         break;
    412.     }
    413.     case IOCTL_CATCH_WVM_XP:
    414.     {
    415.         ULONG InputLength   = IrpStack->Parameters.DeviceIoControl.InputBufferLength;
    416.         ULONG OutputLength  = IrpStack->Parameters.DeviceIoControl.OutputBufferLength;
    417.  
    418.         if( OutputLength < sizeof(buf) )           
    419.         {
    420.             status = STATUS_INVALID_PARAMETER;
    421.             break;
    422.         }
    423.         RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer, buf, sizeof(buf));
    424.         //передали sizeof(buf) байт
    425.         BytesTxd = sizeof(buf);
    426.         RtlZeroMemory(buf, sizeof(buf));
    427.         Counter = 0;                       
    428.         break;
    429.     }
    430.     case IOCTL_CATCH_WVM_2K:
    431.     {
    432.         CURRENT_INDEX = INDEX_IN_SST_IN_2K;
    433.         break;
    434.     }
    435.  
    436.     // Ошибочный запрос (код IOCTL, который не обрабатывается):
    437.     default: status = STATUS_INVALID_DEVICE_REQUEST;
    438.     }
    439.     // Освобождение спин-блокировки
    440.     KeReleaseSpinLock(&MySpinLock,irql);
    441.  
    442.     #if DBG
    443.     DbgPrint("-Example- DeviceIoControl: %d bytes from BytesTxd written.", (int)BytesTxd);
    444.     #endif
    445.  
    446. return CompleteIrp(Irp,status,BytesTxd); // Завершение IRP
    447. //return CompleteIrp(Irp,status,BytesMes);
    448. }
    449.  
    450. //
    451. // (Файл init.cpp)
    452. // UnloadRoutine: Выгружает драйвер, освобождая оставшиеся объекты
    453. // Вызывается системой, когда необходимо выгрузить драйвер.
    454. // Как и процедура AddDevice, регистрируется иначе чем
    455. // все остальные рабочие процедуры и не получает никаких IRP.
    456. // Arguments:  указатель на объект драйвера
    457. //
    458.  
    459. #pragma code_seg("PAGE")
    460. // Допускает размещение в странично организованной памяти
    461. //
    462. VOID UnloadRoutine(IN PDRIVER_OBJECT pDriverObject)
    463. {
    464.     PDEVICE_OBJECT  pNextDevObj;
    465.     int i;
    466.     ULONG CR0Reg;
    467.     pNextDevObj = pDriverObject->DeviceObject;
    468.     PDEVICE_EXTENSION dx =(PDEVICE_EXTENSION)pNextDevObj->DeviceExtension;
    469.     // Задаем печать отладочных сообщений v если сборка отладочная
    470.     #if DBG
    471.     DbgPrint("-Example- In Unload Routine.");
    472.     #endif
    473.     //==========================================================
    474.     // Нижеприведенные  операции в полномасштабном WDM драйвере
    475.     // следовало бы поместить в обработчике IRP_MJ_PNP запросов
    476.     // с субкодом IRP_MN_REMOVE_DEVICE, но в силу простоты
    477.     // драйвера, сделаем это здесь.
    478.     // Проходим по всем объектам устройств, контролируемым
    479.     // драйвероv
    480.  
    481.     __asm
    482.     {
    483.     cli;
    484.     mov eax, cr0
    485.     mov CR0Reg,eax
    486.     and eax,0xFFFEFFFF      // сбросить WP bit
    487.     mov cr0, eax
    488.     }
    489.  
    490.     //восстанавливаем старый обработчик
    491.     NTCALL(CURRENT_INDEX)=dx->OriginalFunc;
    492.  
    493.     __asm
    494.     {
    495.     mov eax, CR0Reg    
    496.     mov cr0, eax            // востановить содержимое CR0
    497.     sti;
    498.     }
    499.  
    500.     for(i=0; pNextDevObj!=NULL; i++)
    501.     {
    502.         // Удаляем символьную ссылку и уничтожаем FDO:
    503.         UNICODE_STRING *pLinkName = & (dx->SymLinkName);
    504.         // !!! сохраняем указатель:
    505.         pNextDevObj = pNextDevObj->NextDevice;
    506.  
    507.         #if DBG
    508.         DbgPrint("-Example- Deleted device (%d) : pointer to FDO = %X.",i,dx->fdo);
    509.         DbgPrint("-Example- Deleted symlink = %ws.", pLinkName->Buffer);
    510.         #endif
    511.  
    512.         IoDeleteSymbolicLink(pLinkName);
    513.         IoDeleteDevice( dx->fdo);
    514.     }
    515. }
    516. #pragma code_seg() // end PAGE section
    h:
    Код (Text):
    1. #ifndef _DRIVER_H_04802_BASHBD_1UIWQ1_8239_1NJKDH832_901_
    2. #define _DRIVER_H_04802_BASHBD_1UIWQ1_8239_1NJKDH832_901_
    3. // Выше приведены две строки (в конце файла имеется еще #endif),
    4. // которые в больших проектах запрещают повторные  проходы по тексту,
    5. // который находится внутри h-файла (что весьма удобно для повышения
    6. // скорости компиляции).
    7. // (Файл Driver.h)
    8.  
    9. #ifdef __cplusplus
    10. extern "C"
    11. {
    12. #endif
    13.  
    14. #include "ntddk.h"
    15. #ifdef __cplusplus
    16. }
    17. #endif
    18. #include "IOCTL.h"
    19. // Определяем структуру расширения устройства. Включим в нее
    20. // указатель на FDO (для удобства последующей работы UnloadRoutine) и
    21. // имя символьной ссылки в формате UNOCODE_STRING.
    22. /*
    23. typedef struct _EXAMPLE_DEVICE_EXTENSION
    24. {
    25.     PDEVICE_OBJECT  fdo;
    26.     UNICODE_STRING  ustrSymLinkName; // L"\\DosDevices\\Example"
    27. } EXAMPLE_DEVICE_EXTENSION, *PEXAMPLE_DEVICE_EXTENSION;
    28. */
    29. typedef NTSTATUS (*NtCreateProcessEx) //ето zwWriteVirtualMemory
    30. (
    31.     OUT PHANDLE ProcessHandle,
    32. IN ACCESS_MASK DesiredAccess,
    33. IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    34. IN HANDLE InheritFromProcessHandle,
    35. IN BOOLEAN InheritHandles,
    36. IN HANDLE SectionHandle OPTIONAL,
    37. IN HANDLE DebugPort OPTIONAL,
    38. IN HANDLE ExceptionPort OPTIONAL,
    39.  IN HANDLE Unknown
    40. );
    41. #define MAX_PATH 260
    42. //структура для хранения буфера перехваченнолдрых вызовов NtWriteVirtualMemory()
    43. //Нам сказали через структуру, значит будем через структуру
    44. //Да, даже если там 1 параметр! Потом пригодиться!
    45. typedef struct _DEVICE_BUFFER
    46. {
    47.    
    48.     HANDLE PID;
    49.     char FileName[MAX_PATH];
    50.     //Pid процесса что пишет в память
    51. } DEVICE_BUFFER, *PDEVICE_BUFFER;
    52.  
    53.  
    54. //структура расширения для объекта драйвера
    55. typedef struct _DEVICE_EXTENSION
    56. {
    57.   PDEVICE_OBJECT fdo;
    58.   UNICODE_STRING SymLinkName;       // L"\\DosDevices\\Example"
    59.   NtCreateProcessEx OriginalFunc;
    60.   HANDLE PID;
    61. } DEVICE_EXTENSION, *PDEVICE_EXTENSION;
    62. //typedef unsigned long DWORD;
    63.  
    64. //описания SST
    65. typedef PVOID* PNTPROC;                     //Корче далее идёт замут!!!!
    66. typedef DWORD (ULONG);                      //Все кто хочет понять это
    67. typedef DWORD*  PDWORD;                     //то читайте Свена Шрайбера
    68. typedef unsigned char (BYTE);               //"Недокументированные возможности WINNT"
    69. typedef BYTE* PBYTE;                        //стр 284(листинг 5.1)!!!
    70.                                             //P.S: Это не прикол!!!!
    71.  
    72. typedef struct _SYSTEM_SERVICE_TABLE
    73. {
    74.     PNTPROC ServiceTable;          
    75.     PDWORD  CounterTable;          
    76.     ULONG   ServiceLimit;          
    77.     PBYTE   ArgumentTable;         
    78. }
    79. SYSTEM_SERVICE_TABLE ,
    80. * PSYSTEM_SERVICE_TABLE ,
    81. * * PPSYSTEM_SERVICE_TABLE ;
    82.  
    83.  
    84. typedef struct _SERVICE_DESCRIPTOR_TABLE {
    85.    SYSTEM_SERVICE_TABLE ntoskrnl;  
    86.    SYSTEM_SERVICE_TABLE win32k;    
    87.    SYSTEM_SERVICE_TABLE unused1;   
    88.    SYSTEM_SERVICE_TABLE unused2;   
    89. }
    90. SERVICE_DESCRIPTOR_TABLE ,
    91. //* KeServiceDescriptorTable,
    92. * PSERVICE_DESCRIPTOR_TABLE,
    93. * * PPSERVICE_DESCRIPTOR_TABLE ;                //Всё замут кончился!!!!!!
    94. extern "C"
    95. extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
    96. //Так этот поклонника Руссиновича(Шрайбер) извлекает данные из SDT
    97. #define NTCALL(_function) KeServiceDescriptorTable->ntoskrnl.ServiceTable[_function]
    98.  
    99. extern PUSHORT NtBuildNumber; //Версия ядра - он очень любил писать про номер сборки своего ядра(достал он с ним)
    100.  
    101. #endif
    h:
    Код (Text):
    1. // Внимание! Текст приведенный ниже должен войти в файл Ioctl.h,
    2. // который будет необходим для компиляции тестового приложения.
    3. // (Разумеется, за исключением последней строки с "#endif".)
    4. #ifndef __IOCTL__
    5. #define __IOCTL__
    6.  
    7. #define IOCTL_PRINT_DEBUG_MESS CTL_CODE( \
    8.     FILE_DEVICE_UNKNOWN, 0x801, METHOD_BUFFERED, FILE_ANY_ACCESS)
    9.  
    10. #define IOCTL_CHANGE_IRQL CTL_CODE(\
    11.     FILE_DEVICE_UNKNOWN, 0x802, METHOD_BUFFERED, FILE_ANY_ACCESS)
    12.  
    13. #define IOCTL_MAKE_SYSTEM_CRASH CTL_CODE( \
    14.     FILE_DEVICE_UNKNOWN, 0x803, METHOD_BUFFERED, FILE_ANY_ACCESS)
    15.  
    16. #define IOCTL_TOUCH_PORT_378H CTL_CODE( \
    17.     FILE_DEVICE_UNKNOWN, 0x804, METHOD_BUFFERED, FILE_ANY_ACCESS)
    18.  
    19. #define IOCTL_SEND_BYTE_TO_USER CTL_CODE( \
    20.     FILE_DEVICE_UNKNOWN, 0x805, METHOD_BUFFERED, FILE_ANY_ACCESS)
    21. #define IOCTL_CATCH_WVM_XP  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x806, METHOD_BUFFERED, FILE_ANY_ACCESS)
    22. #define IOCTL_CATCH_WVM_2K  CTL_CODE(FILE_DEVICE_UNKNOWN, 0x807, METHOD_BUFFERED, FILE_ANY_ACCESS)
    23. #endif
    24. // Вариант :
    25. //#define IOCTL_SEND_BYTE_TO_USER CTL_CODE( \
    26. //    FILE_DEVICE_UNKNOWN, 0x805, METHOD_NEITHER, FILE_ANY_ACCESS)
     
  9. gilg

    gilg New Member

    Публикаций:
    0
    Регистрация:
    19 май 2005
    Сообщения:
    527
    Ну а проблема-то в чем?
    Что за бсод? Где? Что говорит "!analyze -v" из WinDbg?
     
  10. hulk45

    hulk45 New Member

    Публикаций:
    0
    Регистрация:
    18 дек 2006
    Сообщения:
    10
    Товарищи меня тоже очень интересует этот вопрос. может кто то поможет. Предыдущее предлжение тоже не помогло.
     
  11. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    проверяй указатель на валидность
     
  12. Mike

    Mike New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    5
    Cra4sh, не мог бы ты поподробней объяснить, как проверить указатель на валидность
     
  13. Cr4sh

    Cr4sh New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2006
    Сообщения:
    668
    NTKERNELAPI
    VOID
    NTAPI
    ProbeForRead(
    IN CONST VOID *Address,
    IN SIZE_T Length,
    IN ULONG Alignment
    );
     
  14. Guest

    Guest Guest

    Публикаций:
    0
    Примечание: ProbeForRead рабоает не всегда стабильно, и вызывать ее надо под __try{}__except{}
     
  15. Mike

    Mike New Member

    Публикаций:
    0
    Регистрация:
    16 дек 2006
    Сообщения:
    5
    Т.е мне нужно в начале нового обработчика NtCreateSEction вставить
    __try{
    ProbeForRead(
    ObjectAttributes->ObjectName ,
    ObjectAttributes->ObjectName->Length,
    1
    );

    }__except{}
     
  16. Guest

    Guest Guest

    Публикаций:
    0
    Mike
    Да.