ObReferenceObjectByName

Тема в разделе "WASM.WIN32", создана пользователем zss, 2 окт 2005.

  1. zss

    zss New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2004
    Сообщения:
    40
    Адрес:
    Чехов-2
    Пытаюсь определить DriveEntry драйвера и слетаю в синяк.

    ObReferenceObjectByName () вызываю для L"\\Driver\\drvname"



    В чем можетбыть баг ?
     
  2. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Покажи как вызываешь? Вот это должно работать:


    Код (Text):
    1. status = ObReferenceObjectByName (
    2.                         pusObjectPath,
    3.                         OBJ_CASE_INSENSITIVE,
    4.                         NULL,
    5.                         GENERIC_READ,
    6.                         *IoDriverObjectType,
    7.                         KernelMode,
    8.                         NULL,
    9.                         &pObject );
     
  3. zss

    zss New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2004
    Сообщения:
    40
    Адрес:
    Чехов-2
    мой код (обрати внимание на IoDriverObjectType DDK разрешает NULL,а с IoDriverObjectType я не смог собрать - компилятор говорит, что не знает его)
    Код (Text):
    1.  
    2. ULONG GetDriverAddress (PCHAR driverName, PARAM_ADDRESS param){
    3.  
    4.     UNICODE_STRING  stringW = {0};
    5.     ANSI_STRING     stringA = {0};
    6.     PDRIVER_OBJECT  driverObject = NULL;
    7.     ULONG           result = 0;
    8.     BYTE            name [MAX_PATH] = {0};
    9.  
    10.     strcpy (name, "\\Driver\\");
    11.     strcpy (name, driverName);
    12.  
    13.     RtlInitAnsiString (&stringA, name);
    14.     RtlAnsiStringToUnicodeString (&stringW, &stringA, TRUE);
    15.     __try {
    16.  
    17.         if (!NT_SUCCESS (ObReferenceObjectByName (&stringW, OBJ_CASE_INSENSITIVE,
    18.                          NULL, FILE_READ_ACCESS, [b]NULL[/b], KernelMode,
    19.                          NULL, (PVOID *) &driverObject))){
    20.             #ifdef DBG
    21.             DbgPrint (("DRVMON: Failed get reference object by name (GetDriverEntry)\n"));
    22.             #endif
    23.             return 0;
    24.         }
    25.  
    26.         switch (param){
    27.         case DRIVER_ENTRY :
    28.             result = (ULONG) driverObject->DriverStartIo;
    29.             break;
    30.         case ADD_DEVICE :
    31.             result = (ULONG) driverObject->DriverExtension->AddDevice;
    32.             break;
    33.         }
    34.  
    35.         ObDereferenceObject ( (PVOID)driverObject );
    36.     }
    37.     __finally {
    38.         RtlFreeUnicodeString (&stringW);
    39.     }
    40.  
    41.     return result;
    42. }
    43.  
     
  4. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    NULL в качестве ObjectType никак не можно. Должен быть указатель на тип объекта. Линкер ругается потому что ддк определяет указатели на всего три объекта тип:

    extern POBJECT_TYPE *IoFileObjectType;

    extern POBJECT_TYPE *ExEventObjectType;

    extern POBJECT_TYPE *ExSemaphoreObjectType;

    экспортируется же намного больше. Достаточно просто знать имена переменных, в который лежат соотв. указатели и определить их. Этот код должен собраться без проблем и работать.


    Код (Text):
    1. #include <ntddk.h>
    2.  
    3. NTSTATUS DriverEntry(PDRIVER_OBJECT, PUNICODE_STRING);
    4.  
    5. #pragma alloc_text( INIT, DriverEntry )
    6.  
    7. #undef ObReferenceObjectByName
    8. __declspec(dllimport)
    9. NTSTATUS
    10.   ObReferenceObjectByName(
    11.     IN PUNICODE_STRING  ObjectName,
    12.     IN ULONG            Attributes,
    13.     IN PACCESS_STATE    PassedAccessState OPTIONAL,
    14.     IN ACCESS_MASK      DesiredAccess OPTIONAL,
    15.     IN POBJECT_TYPE     ObjectType,
    16.     IN KPROCESSOR_MODE  AccessMode,
    17.     IN OUT PVOID        ParseContext OPTIONAL,
    18.     OUT PVOID           *Object
    19.     );
    20.  
    21. extern POBJECT_TYPE *IoDriverObjectType;
    22.  
    23. #ifndef DECLARE_CONST_UNICODE_STRING
    24. #define DECLARE_CONST_UNICODE_STRING(_variablename, _string) \
    25. const WCHAR _variablename ## _buffer[] = _string; \
    26. const UNICODE_STRING _variablename = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWSTR) _variablename ## _buffer };
    27. #endif
    28.  
    29. DECLARE_CONST_UNICODE_STRING( g_usDriverPath, L"\\Driver\\Beep" );
    30.  
    31. NTSTATUS
    32. DriverEntry(
    33.     IN PDRIVER_OBJECT DriverObject,
    34.     IN PUNICODE_STRING RegistryPath
    35.     )
    36. {
    37.  
    38.     NTSTATUS        status;
    39.     PDRIVER_OBJECT  pDriverObject;
    40.  
    41.     status = ObReferenceObjectByName (
    42.                             (PUNICODE_STRING) &g_usDriverPath,
    43.                             OBJ_CASE_INSENSITIVE,
    44.                             NULL,
    45.                             GENERIC_READ,
    46.                             *IoDriverObjectType,
    47.                             KernelMode,
    48.                             NULL,
    49.                             &pDriverObject);
    50.  
    51.     if ( NT_SUCCESS( status ) ) {
    52.  
    53.         DbgPrint( "%wZ at %p\n", &g_usDriverPath, pDriverObject->DriverStart );
    54.  
    55.         ObDereferenceObject( pDriverObject );
    56.     }
    57.  
    58.     return STATUS_DEVICE_CONFIGURATION_ERROR;
    59. }
     
  5. zss

    zss New Member

    Публикаций:
    0
    Регистрация:
    11 июл 2004
    Сообщения:
    40
    Адрес:
    Чехов-2
    Four-F

    обяъясни пожалуйста, что это означает
    Код (Text):
    1.  
    2. [b]#undef[/b] ObReferenceObjectByName
    3. __declspec(dllimport)
    4.  




    и почему __declspec(dllimport)



    а также что это есть такое
    Код (Text):
    1. #ifndef DECLARE_CONST_UNICODE_STRING
    2. #define DECLARE_CONST_UNICODE_STRING(_variablename, _string) \
    3. const WCHAR _variablename ## _buffer[] = _string; \
    4. const UNICODE_STRING _variablename = { sizeof(_string) - sizeof(WCHAR), sizeof(_string), (PWSTR) _variablename ## _buffer };
    5. #endif
    6.  
     
  6. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"




    Почему же? можно. Это означает что тип объекта нам не важен. ObjectType нужен только, если объект нам передан из юзермодного кода для проверки типа объекта.
     
  7. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Строго говоря #undef ObReferenceObjectByName не нужен. Я выдрал определение из одного проекта и зацепил эту строку. У меня в проекте я просто хочу быть уверен, что компилятор будет использовать именно это определение.

    Что такое __declspec(dllimport) см. в MSDN. Закоментарь его, скомпили и посмотри в дизасме разницу. Без __declspec(dllimport) функция будет вызываться через доп. трамплин. Можно и без __declspec(dllimport).

    Это макрос :) Определен в ntdef.h начиная с ХР. Позволяет вместо такого убогого кода определить сразу всё что нужно.
    Код (Text):
    1. UNICODE_STRING us;
    2. RtlInitUnicodeString( &us, L"bla-bla" );
    Единственно - если юникод сторок будет очень много, то может быть выгоднее использовать RtlInitUnicodeString.

    Ты, возможно, путаешь с ObReferenceObjectByHandle. Там ObjectType опционален. Функции, работающие с именами другая история. Хотя, чёрт его знает. Доберусь до отладчика - посмотрю.