ZwUnloadDriver: как правильно выгрузить драйвер?

Тема в разделе "WASM.NT.KERNEL", создана пользователем Rel, 16 ноя 2009.

  1. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Доброго времени суток. Сейчас передо мной стоит задача переделать инсталятор драйвера, чтобы тот мог выгружать предыдущую версию и загружать новую без перезагрузки. В драйвере предусмотрена "динамическая выгрузка". Драйвер регистрируется в системе соответствующим ключем реестра (создаются поля ImagePath, Type, Group, Start и тд), загружается функцией ZwLoadDriver. Загрузка проходит нормально, но с выгрузкой предыдущей версии - проблемы. Я пытаюсь выгрузить драйвер с помощью функции ZwUnloadDriver, отправляя в качестве параметра путь к тому же ключу реестра, по которому производилась регистрация. На это действо выскакивает ошибка с кодом 0xC0000034 (STATUS_OBJECT_NAME_NOT_FOUND), я попытался для эксперимента явно добавить поле ObjectName, в качестве значения которого указал ту же строку, что и в имени драйвера (имени ключа реестра). Но стала выскакивать другая ошибка - 0xC000003B (STATUS_OBJECT_PATH_SYNTAX_BAD), смысл которой я не могу понять. Помогите пожалуйста разобраться... Заранее спасибо! Если будет нужно, завтра выложу код загрузки и выгрузки драйвера...

    ЗЫ Извините канеш за глупый вопрос, наверняка решение лежит совсем рядом, но я его в упор не вижу.
    ЗЗЫ И ещё извините за терминологию, которой изложил проблему, просто раньше не доводилось иметь дело с драйверами)))
     
  2. wasm_test

    wasm_test wasm test user

    Публикаций:
    0
    Регистрация:
    24 ноя 2006
    Сообщения:
    5.582
    Покажи код.
    Обычно для выгрузки драйвера нужен примерно такой код
    Код (Text):
    1. UNICODE_STRING RegistryPath;
    2. NTSTATUS Status;
    3.  
    4. RtlInitUnicodeString (&RegistryPath, L"\\Registry\\Machine\\CurrentControlSet\\Services\\ServiceName");
    5. Status = ZwUnloadDriver (&RegistryPath);
    6. DbgPrint ("ZwUnloadDriver returned status %lx\n", Status);
     
  3. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Я бы всё же воспользовался API менеджера служб, с ними проблем уж точно никогда не было.
     
  4. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    Драйвер запускается по ключу:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\drvntk32

    Код (Text):
    1. DisplayName (REG_SZ) = drvntk32
    2.  
    3. ErrorControl (REG_DWORD) = 0x00000000
    4.  
    5. Group (REG_SZ) = Streams Drivers
    6.  
    7. ImagePath (REG_SZ) = \SystemRoot\drvntk32.sys
    8.  
    9. Start (REG_DWORD) = 0x00000001
    10.  
    11. Type (REG_DWORD) = 0x00000001
    Код выгружающий драйвер:

    Код (Text):
    1. bool StopDriver(const WCHAR* name)
    2.  
    3. {
    4.  
    5.     LONG status = FALSE;
    6.  
    7.  
    8.  
    9.     HMODULE hNtdll = LoadLibrary(L"ntdll.dll");
    10.  
    11.     PZWUD pZwUnloadDriver = (PZWUD)GetProcAddress(hNtdll, "ZwUnloadDriver");
    12.  
    13.     if(pZwUnloadDriver == NULL) { printf("pZwUnloadDriver == NULL\n"); return false; }
    14.  
    15.     PRIUS pRtlInitUnicodeString = (PRIUS)GetProcAddress(hNtdll, "RtlInitUnicodeString");
    16.  
    17.     if(pRtlInitUnicodeString == NULL) { printf("pRtlInitUnicodeString == NULL\n"); return false; }
    18.  
    19.  
    20.  
    21.     UNICODE_STRING uRegName;
    22.  
    23.     pRtlInitUnicodeString(&uRegName, name);
    24.  
    25.     status = pZwUnloadDriver(&uRegName);
    26.  
    27.     printf("ZwUnloadDriver = 0x%x\n", status);
    28.  
    29.  
    30.  
    31.     return status == STATUS_SUCCESS;
    32.  
    33. }
    Запускается с параметром: name = L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\Services\\drvntk32";

    Возникает ошибка: 0xC0000034;

    Если я явно добавляю в указанный ключ поле ObjectName (REG_SZ) = drvntk32, то при попытке выгрузки возникает ошибка: 0xC000003B.

    Вот как то так))
     
  5. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Мыслей особых у меня нет, но попробуй написать так:

    Код (Text):
    1. L"\\Registry\\Machine\\SYSTEM\\ControlSet00X\\Services\\drvntk32"
    где X это номер текущей конфигурации. Этот номер можно взять отсюда:

    Код (Text):
    1. HKEY_LOCAL_MACHINE\SYSTEM\Select, Current
    Не факт, что поможет, но мало ли.
     
  6. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Забыл ключ System.
     
  7. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    спасибо, но это было первое что я попробовал))
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    конвенции вызова NtApi корректны?
    \SystemRoot\ - это папка винды, нужна именно она, или всё же \SystemRoot\system32 ?
     
  9. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    да, адреса функций проверял, если ты об этом))))

    да, драйвер лежит в папке винды, он бы не запустился при старте системы, если путь был бы неправильным...

    кажется, что просто не хватает некоторых полей в ключе реестра, но чего именно не хватает - мне не понятно...
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    нет, я про то что API должны быть stdcall.
     
  11. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    a)) да, конечно stdcall...
     
  12. AntiFreeze

    AntiFreeze Дмитрий

    Публикаций:
    0
    Регистрация:
    26 июн 2008
    Сообщения:
    65
    Rel, а ключ реестра ты случайно не удаляёшь?
     
  13. Rel

    Rel Well-Known Member

    Публикаций:
    2
    Регистрация:
    11 дек 2008
    Сообщения:
    5.323
    нет... странно это все... мне кажется, что дело все таки в неправильном ключе реестра... жалко, придется видимо делать с перезагрузкой...
     
  14. AgentMC

    AgentMC New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2010
    Сообщения:
    2
    Случайно натолкнулся на такую же проблему. Решение - читать МСДН.
    Rel
    ваш код:
    МСДН (http://msdn.microsoft.com/en-us/library/ff567117(VS.85).aspx)
     
  15. x64

    x64 New Member

    Публикаций:
    0
    Регистрация:
    29 июл 2008
    Сообщения:
    1.370
    Адрес:
    Россия
    Это не может быть причиной, т.к. сервисы NtLoadDriver() и NtUnloadDriver() используют флаг OBJ_CASE_INSENSITIVE.
     
  16. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    Rel, а стандартные консольные утилиты (net или sc) нормально этот драйвер выгружают? Попробуй:
    Код (Text):
    1. net stop drvntk32
     
  17. 0x6b65

    0x6b65 Забанен

    Публикаций:
    0
    Регистрация:
    8 окт 2009
    Сообщения:
    92
    Да, еще не увидел в коде разрешения привелегии загрузки/выгрузки драйверов SE_LOAD_DRIVER_NAME, хотя это дает совершенно другой статус ошибки.
     
  18. AgentMC

    AgentMC New Member

    Публикаций:
    0
    Регистрация:
    13 июн 2010
    Сообщения:
    2
    x64
    да, странно, но если SYSTEM - 0xC0000034, System - 0x0