Лазаем внутри ядра

Тема в разделе "WASM.NT.KERNEL", создана пользователем galenkane, 28 май 2026 в 23:22.

  1. galenkane

    galenkane Active Member

    Публикаций:
    1
    Регистрация:
    13 янв 2017
    Сообщения:
    469
    ════════════════════════════════════════════════════════════
    Исследование загрузки DLL/драйверов в ядре Windows
    ════════════════════════════════════════════════════════════

    ───────────────────────────────────
    Цель исследования
    ───────────────────────────────────

    Проследить полный путь загрузки драйверов ядра Windows — от перечисления PnP-устройств до валидации PE-заголовков. Определить, какие проверки выполняет ядро при загрузке образа в память.

    ───────────────────────────────────
    Стенд
    ───────────────────────────────────

    • Host: macOS (Apple Silicon)
    • Target VM: Windows 11 ARM64 (ядро 26100) — Parallels
    • Debugger VM: Windows 11 ARM64 — Parallels
    • Транспорт: serial через Unix-сокеты ([ICODE]/tmp/kd.sock[/ICODE] ↔ [ICODE]/tmp/debugger.sock[/ICODE]), socat relay
    • Удалённое управление: windbg-agent MCP сервер на Debugger VM ([ICODE]0.0.0.0:44444[/ICODE])

    ───────────────────────────────────
    Цепочка вызовов загрузки драйвера
    ───────────────────────────────────

    Полный путь от перечисления PnP-устройств до чтения PE-файла:

    Код (Text):
    1.  
    2. PnpDeviceActionWorker
    3.   └─ PiProcessStartSystemDevices
    4.        └─ PipProcessDevNodeTree
    5.             └─ PipCallDriverAddDevice
    6.                  └─ IopLoadDriver
    7.                       └─ MmLoadSystemImageEx
    8.                            └─ MiObtainSectionForDriver
    9.                                 └─ MiCreateSectionForDriver
    10.                                      └─ MiCreateSystemSection
    11.                                           └─ MiCreateSection
    12.                                                └─ MiCreateImageOrDataSection
    13.                                                     └─ MiCreateNewSection
    14.                                                          └─ MiCreateImageFileMap
    15.                                                               └─ MiVerifyImageHeader
    16.  
    ───────────────────────────────────
    Валидация PE-образа
    ───────────────────────────────────

    ► Проверка MZ-сигнатуры (MiCreateImageFileMap+0x148)

    Первая проверка — чтение первых 2 байт файла и сравнение с сигнатурой [ICODE]MZ[/ICODE] (0x5A4D):

    Код (Text):
    1.  
    2. ldrh   w8,[x2]          ; читаем первые 2 байта буфера файла
    3. mov    w9,#0x5A4D        ; 'MZ' = 0x5A4D
    4. cmp    w8,w9             ; проверяем MZ-сигнатуру
    5. bne    error             ; отклоняем, если не MZ
    6.  
    Если первые два байта не [ICODE]MZ[/ICODE] — файл отклоняется немедленно.

    ► Чтение PE-смещения (e_lfanew)

    После проверки MZ ядро читает поле [ICODE]e_lfanew[/ICODE] по смещению [ICODE]+0x3C[/ICODE] от начала файла — это указатель на PE-заголовок:

    Код (Text):
    1.  
    2. ldr    w8,[x0,#0x3C]    ; e_lfanew — смещение до PE-заголовка
    3.  
    ► Проверка границ

    Ядро проверяет, что:

    • Смещение [ICODE]e_lfanew[/ICODE] не выходит за пределы файла
    • Размер PE-заголовка не превышает размер файла
    • Есть достаточно места для чтения Optional Header

    ► Проверка PE\0\0-сигнатуры (MiVerifyImageHeader+0x20)

    Вторая ключевая проверка — чтение 4 байт по смещению [ICODE]e_lfanew[/ICODE] и сравнение с сигнатурой [ICODE]PE\0\0[/ICODE] (0x00004550):

    Код (Text):
    1.  
    2. ldr    w8,[x0]          ; читаем 4 байта по смещению e_lfanew
    3. mov    w9,#0x4550        ; 'PE\0\0' = 0x00004550
    4. cmp    w8,w9             ; проверяем PE-сигнатуру
    5. bne    error             ; отклоняем, если не PE
    6.  
    ► Извлечение полей PE-заголовка

    После подтверждения PE-сигнатуры [ICODE]MiVerifyImageHeader[/ICODE] извлекает и проверяет поля:

    Код (Text):
    1.  
    2. Смещение от PE  Поле                   Проверка
    3. ──────────────  ─────────────────────  ──────────────────────────────────────
    4. +0x04           Machine                Должно быть ненулевым (0xAA64 = ARM64)
    5. +0x16           Characteristics        Проверяется бит 1 (IMAGE_FILE_EXECUTABLE_IMAGE)
    6. +0x18           Optional Header Magic  0x20B = PE32+ (64-bit)
    7. +0x14           SizeOfOptionalHeader   Проверяется корректность размера
    8. +0x38           SectionAlignment       Проверка выравнивания секций
    9. +0x50           SizeOfImage            Проверка размера образа
    10. +0x28           EntryPoint             Проверка точки входа
    11.  
    ► Сводка констант

    Код (Text):
    1.  
    2. Константа   Значение    Назначение
    3. ──────────  ──────────  ──────────────────────────────
    4. 0x5A4D      'MZ'        Сигнатура DOS-заголовка
    5. 0x4550      'PE\0\0'    Сигнатура PE-заголовка
    6. 0x20B       PE32+       Magic для 64-битных образов
    7. 0xAA64      ARM64       Machine type для Windows on ARM
    8. 0x3C        e_lfanew    Смещение указателя на PE-заголовок в MZ
    9.  
    ───────────────────────────────────
    Наблюдаемые драйверы
    ───────────────────────────────────

    При установке точки останова на [ICODE]MiCreateImageFileMap[/ICODE] во время PnP-перечисления наблюдались загрузки:

    vmbusr.sys — VMBus Resource Device Driver (Hyper-V)
    vmbkmclr.sys — VMBus Kernel CLR Driver (Hyper-V)

    Оба драйвера являются компонентами интеграции Hyper-V и ожидаемо загружаются в среде Parallels VM.

    Пример определения загружаемого драйвера через структуру [ICODE]KLDR_DATA_TABLE_ENTRY[/ICODE] в регистре x22:

    Код (Text):
    1.  
    2. dt nt!_KLDR_DATA_TABLE_ENTRY @x22
    3.  
    Поле [ICODE]BaseDllName[/ICODE] содержит имя загружаемого модуля.

    ───────────────────────────────────
    Структуры данных
    ───────────────────────────────────

    ► KLDR_DATA_TABLE_ENTRY

    Структура, используемая ядром для учёта загруженных модулей:

    Код (Text):
    1.  
    2. dt nt!_KLDR_DATA_TABLE_ENTRY
    3.    +0x000 InLoadOrderLinks : _LIST_ENTRY
    4.    +0x010 ExceptionTable   : Ptr64 Void
    5.    +0x018 EntryPoint       : Ptr64 Void
    6.    +0x028 DllBase           : Ptr64 Void
    7.    +0x030 SizeOfImage       : Uint4B
    8.    +0x038 FullDllName       : _UNICODE_STRING
    9.    +0x048 BaseDllName       : _UNICODE_STRING
    10.    ...
    11.  
    ► PsLoadedModuleList

    Глобальный связный список всех загруженных модулей ядра. Каждый элемент — [ICODE]KLDR_DATA_TABLE_ENTRY[/ICODE], связанный через [ICODE]InLoadOrderLinks[/ICODE].

    ───────────────────────────────────
    MDL (Memory Descriptor List)
    ───────────────────────────────────

    При маппинге PE-файла в адресное пространство ядра используется MDL:

    Код (Text):
    1.  
    2. MiCreateImageFileMap
    3.   → MiCreateMdl
    4.   → MiCopyHeaderIfResident
    5.   → проверка MZ
    6.  
    MDL описывает физические страницы файла, которые будут отображены в виртуальную память ядрового пространства.

    ───────────────────────────────────
    Выводы
    ───────────────────────────────────


    1. Двухступенчатая валидация: ядро проверяет MZ-сигнатуру (первые 2 байта) и PE-сигнатуру (4 байта по смещению e_lfanew) как первые два обязательных шага при загрузке любого драйвера.

    2. Строгий порядок: сначала [ICODE]MiCreateImageFileMap[/ICODE] проверяет MZ, затем [ICODE]MiVerifyImageHeader[/ICODE] проверяет PE\0\0 и поля заголовка. Нарушение любого условия приводит к отклонению образа.

    3. PE32+ только для 64-бит: на ARM64-системах ядро ожидает magic [ICODE]0x20B[/ICODE] (PE32+). 32-битные PE ([ICODE]0x10B[/ICODE]) не принимаются.

    4. PnP-перечисление: загрузка драйверов запускается через [ICODE]PnpDeviceActionWorker[/ICODE] → [ICODE]PiProcessStartSystemDevices[/ICODE], что является стандартным механизмом Plug and Play для инициализации устройств.

    5. Отладочный стенд: двух-VM конфигурация с socat relay и windbg-agent MCP позволяет эффективно исследовать внутренние механизмы ядра в реальном времени, устанавливая точки останова на конкретных функциях цепочки загрузки.
    --- Сообщение объединено, 28 май 2026 в 23:33 ---
    Кому какая тема интересна могу ресерч провести если годное будет)