[x86] Фильтрация загрузок .dll

Тема в разделе "WASM.NT.KERNEL", создана пользователем MuForum, 3 июн 2011.

  1. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Доброго времени суток.
    Необходимо реализовать драйвер под Windows XP, Vista, 7 x86.
    - Который будет контролировать загрузку .dll модулей в процессы.

    Начал копать в сторону перехват SDT функции ZwMapViewOfSection, вроде как то что нужно, НО, когда встала задача именно фильтации, то есть необходимо получать имена модулей, то столкнулся с проблемой...

    ZwMapViewOfSection -> ObReferenceObjectByHandle(SectionHandle, ...) -> затем ObQueryNameString()
    Всё хорошо, имена получаю, НО, некоторые результаты удивляют, а именно получаю результат "(null)" где длина 8.
    - То есть, имена некоторых модулей не могу получить, хотя точно знаю и вижу что подгружается библиотека .dll в процесс.
    Код (Text):
    1. NTSTATUS ZwMapViewOfSection_New(
    2.     __in HANDLE SectionHandle,
    3.     __in HANDLE ProcessHandle,
    4.     __inout PVOID *BaseAddress,
    5.     __in ULONG_PTR ZeroBits,
    6.     __in SIZE_T CommitSize,
    7.     __inout_opt PLARGE_INTEGER SectionOffset,
    8.     __inout PSIZE_T ViewSize,
    9.     __in SECTION_INHERIT InheritDisposition,
    10.     __in ULONG AllocationType,
    11.     __in ULONG Win32Protect)
    12. {
    13.     ULONG               uProcessId      = 0;
    14.     KPROCESSOR_MODE     mAccess         = KeGetPreviousMode();
    15.     // ----
    16.     PEPROCESS           curProcess      = PsGetCurrentProcess();
    17.     ULONG               curProcesId     = (ULONG)PsGetCurrentProcessId();
    18.     // ----
    19.     PVOID               pHandle;
    20.     NTSTATUS            nRes;
    21.     // ----
    22.     ULONG               uLen    = 0;
    23.     WCHAR               buffer[512];
    24.     UNICODE_STRING      tmpStr  = {0, 512, buffer};
    25.     // ----
    26.     if ( curProcesId == g_Main.PID )
    27.     {
    28.         nRes    = ObReferenceObjectByHandle(SectionHandle, 0, NULL, KernelMode, & pHandle, NULL);
    29.         // ----
    30.         if ( nRes != STATUS_SUCCESS )
    31.         {
    32.             DPRINT("ObReferenceObjectByHandle() Error: 0x%.8X;\n\0", nRes);
    33.             // ----
    34.             return g_ZwMapViewOfSection.funcOriginal(SectionHandle, ProcessHandle, BaseAddress,
    35.                 ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
    36.         }
    37.         // ----
    38.         nRes    = ObQueryNameString(pHandle, (POBJECT_NAME_INFORMATION) & tmpStr, tmpStr.MaximumLength, & uLen);
    39.         // ----
    40.         if ( nRes != STATUS_SUCCESS )
    41.         {
    42.             DPRINT("ObQueryNameString() Error: 0x%.8X;\n\0", nRes);
    43.             // ----
    44.             return g_ZwMapViewOfSection.funcOriginal(SectionHandle, ProcessHandle, BaseAddress,
    45.                 ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
    46.         }
    47.         // ----
    48.         DPRINT("ObQueryNameString: '%wZ'; uLen: %ld;\n\0", & tmpStr, uLen);
    49.     }
    50.     // ----
    51.     return g_ZwMapViewOfSection.funcOriginal(SectionHandle, ProcessHandle, BaseAddress,
    52.         ZeroBits, CommitSize, SectionOffset, ViewSize, InheritDisposition, AllocationType, Win32Protect);
    53. }
    Результат: "ObQueryNameString: '(null)'; uLen: 8;"


    P.S. -> Что за ерунда? Каким образом можно решить данную проблему?
     
  2. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    А PsSetLoadImageNotifyRoutine уже не кошерно?
     
  3. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Мне необходимо обнаружить момент, когда процесс A.exe пытаеться добавить name.dll в процесс B.exe и при необходимости мне необходимо эту операцию заигнорить.
    Мне не просто необходимо получать уведомление, мне ещё необходимо отменять операцию при необходимости!
     
  4. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Как именно нужно отменять?

    - Отменять полностью, возвращая статус ошибки?
    - Отменять, но при этом делать вид, что фактически DLL загрузилась?

    Первое делается тривиально, второе сложнее и не понятно зачем. Ну так что?
     
  5. MuForum

    MuForum Member

    Публикаций:
    0
    Регистрация:
    11 мар 2007
    Сообщения:
    109
    Мне необходимо отменить полностью...
    То есть, вернуть результат STATUS_ACCESS_DENIED
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Тогда колбеки файловых фильтров.
    Здесь у меня чуть подробнее по этой теме.
     
  7. steelfactor

    steelfactor New Member

    Публикаций:
    0
    Регистрация:
    26 апр 2007
    Сообщения:
    501
    Попробуй так, у меня по крайней мере работало нормально:

    Код (Text):
    1. NTSTATUS NewZwMapViewOfSection(
    2.     IN HANDLE SectionHandle,
    3.     IN HANDLE ProcessHandle,
    4.     IN OUT PVOID *BaseAddress,
    5.     IN ULONG ZeroBits,
    6.     IN ULONG CommitSize,
    7.     IN OUT PLARGE_INTEGER SectionOffset OPTIONAL,
    8.     IN OUT PSIZE_T ViewSize,
    9.     IN SECTION_INHERIT InheritDisposition,
    10.     IN ULONG AllocationType,
    11.     IN ULONG Protect )
    12. {
    13.     NTSTATUS status;
    14.  
    15.     // Сначала дадим закончить процесс проекции
    16.     status = OldZwMapViewOfSection( SectionHandle,
    17.                     ProcessHandle,
    18.                     BaseAddress,
    19.                     ZeroBits,
    20.                     CommitSize,
    21.                     SectionOffset OPTIONAL,
    22.                     ViewSize,
    23.                     InheritDisposition,
    24.                     AllocationType,
    25.                     Protect );
    26.     if( NT_SUCCESS( status ) )
    27.     {
    28.         unsigned int    imageOffset = 0;
    29.         VOID*       pSection = NULL;
    30.         unsigned int    imageSection = FALSE;
    31.         HANDLE      hRoot = NULL;
    32.         PUNICODE_STRING objectName = NULL;
    33.  
    34.         if( ObReferenceObjectByHandle(  SectionHandle,
    35.                                         SECTION_MAP_EXECUTE,
    36.                                         *MmSectionObjectType,
    37.                                         KernelMode,
    38.                                         &pSection,
    39.                                         NULL ) == STATUS_SUCCESS )
    40.         {
    41.             // Проверить, является ли это секцией имиджа
    42.             // если да - сохранить хэндл и имя объекта
    43.             _asm
    44.             {
    45.                 mov     edx, pSection
    46.                 mov     eax, [edx+14h]
    47.                 add      eax, imageOffset
    48.                 mov     edx, [eax]
    49.                 test     byte ptr [edx+20h], 20h
    50.                 jz        not_image_section
    51.                 mov     imageSection, TRUE
    52.                 mov     eax, [edx+24h]
    53.                 mov     edx, [eax+4]
    54.                 mov     hRoot, edx
    55.                 add      eax, 30h
    56.                 mov     objectName, eax
    57.                 not_image_section:
    58.  
    59.             }...
    В objectName будет имя подгружаемой библиотеки.
    Дальше, думаю, понятно