RtlQueryRegistryValues

Discussion in 'WASM.BEGINNERS' started by Quark, Jan 31, 2008.

  1. Quark

    Quark New Member

    Blog Posts:
    0
    Joined:
    Aug 7, 2007
    Messages:
    211
    NTSTATUS
    RtlQueryRegistryValues(
    IN ULONG RelativeTo,
    IN PCWSTR Path,
    IN PRTL_QUERY_REGISTRY_TABLE QueryTable,
    IN PVOID Context,
    IN PVOID Environment OPTIONAL
    );

    не совсем понимаю её работу.

    параметр PRTL_QUERY_REGISTRY_TABLE[0].EntryContext:

    If the RTL_QUERY_REGISTRY_DIRECT flag is set, this is a pointer to the buffer to store the result of the query operation for this key

    Ну допустим мне нужно посмотреть ключик RegBinary. Если размер ключа <= 4б - значение она возвращает в это самое EntryContext. Если ключ большой, то, как я выяснил дизассемблируя ntdll, буффер EntryContext должен содержать длину буффера, а значение возвращается уже по смещению 8б..

    Вобщем что-то Microsoft намудрила с этой апишкой. к чему такие сложности? Или же это я не понимаю принцип работы этой апишки?
     
  2. rain

    rain New Member

    Blog Posts:
    0
    Joined:
    Apr 22, 2006
    Messages:
    976
    Бедненькой :\ что это вам реверсить больше нечего? зачемже чтото реверсить если оно закоменнтировано?

    Думаю всё стало ясно, если нет то ниже пример как это заюзать:
    Для начала создаём бинари ключик в автозапуске )
    Code (Text):
    1. reg ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v BinData /t REG_BINARY /d aabbccddeeff0011
    Теперь лобаем кодес который будет получать\выводить данные:
    Code (Text):
    1.     NTSTATUS status;
    2.     RTL_QUERY_REGISTRY_TABLE queryTable[2];
    3.     char buf[256];
    4.  
    5.     KDPRINT(("DriverEntry(), %s", __FILE__));
    6.  
    7.     RtlZeroMemory(&buf, sizeof(buf));
    8.    
    9.  
    10.     //set second element to zero, we're reading only one elemnt
    11.     queryTable[1].QueryRoutine = (void*)queryTable[1].Name = (void*)0;
    12.  
    13.     //set first element
    14.     queryTable[0].QueryRoutine  = 0; //ignored in our case
    15.     queryTable[0].Flags         = RTL_QUERY_REGISTRY_DIRECT;
    16.     queryTable[0].Name          = L"BinData";
    17.     queryTable[0].EntryContext  = &buf[0];
    18.     queryTable[0].DefaultType   = 0;
    19.     queryTable[0].DefaultData   = 0;
    20.     queryTable[0].DefaultLength = 0;
    21.  
    22.     //set length
    23.     *(ULONG*)&buf[0] = sizeof(buf);
    24.  
    25.     status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE,
    26.                                     L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\"
    27.                                     L"CurrentVersion\\Run",
    28.                                     &queryTable[0],
    29.                                     0,
    30.                                     0);
    31.  
    32.  
    33.     KDPRINT(("RtlQueryRegistryValues():\n"
    34.             "status = 0x%p\n"
    35.             "size    = 0x%X\n"
    36.             "type    = 0x%X\n"
    37.             "hex data = %02X %02X %02X %02X %02X %02X %02X %02X\n",
    38.             status,
    39.             *(ULONG*)&buf[0],
    40.             *(ULONG*)&buf[4],
    41.             (unsigned char)buf[8],
    42.             (unsigned char)buf[9],
    43.             (unsigned char)buf[10],
    44.             (unsigned char)buf[11],
    45.             (unsigned char)buf[12],
    46.             (unsigned char)buf[13],
    47.             (unsigned char)buf[14],
    48.             (unsigned char)buf[15],
    49.             (unsigned char)buf[16]
    50.              ));
    Результат работы из dbgview:
    Code (Text):
    1. DriverEntry(), c:\drvproj\quark\sys\quark.c
    2. RtlQueryRegistryValues():
    3. status = 0x0000000000000000
    4. size  = 0x8
    5. type  = 0x3
    6. hex data = AA BB CC DD EE FF 00 11
    если будешь тестить на х64 машине не забудь что для приложений для wow64 другая ветка ресстра
    фул сорец в атаче
     
  3. Quark

    Quark New Member

    Blog Posts:
    0
    Joined:
    Aug 7, 2007
    Messages:
    211
    Интересный момент с твоим кодом. Если ключик не создавать - RtlQueryRegistryValues возврашает STATUS_SUCCESS (???) . Буффер остаётся неизменным.
     
  4. rain

    rain New Member

    Blog Posts:
    0
    Joined:
    Apr 22, 2006
    Messages:
    976
    да, размер получается == 0
     
  5. Quark

    Quark New Member

    Blog Posts:
    0
    Joined:
    Aug 7, 2007
    Messages:
    211
    Хех.. в том-то и дело, что не ноль:

    00000000 2:10:39.843 [1080] E:\VC6\progs\temps\temp2\main.cpp
    00000001 2:10:39.843 [1080] RtlQueryRegistryValues():
    00000002 2:10:39.843 [1080] status = 0x00000000 (!!!)
    00000003 2:10:39.843 [1080] size = 0x100 (!!!)
    00000004 2:10:39.843 [1080] type = 0x0
    00000005 2:10:39.843 [1080] hex data = 00 00 00 00 00 00 00 00

    Поля BinData не существует вообще, а функция выдаёт success. Функция не выдаёт ошибку, хотя, она ссылается на ZwQueryValueKey. та в свою очередь выдаёт 0xC0000034. RtlQueryRegistryValues проверяет результат её выполнения, но всёравно выдаёт success.
     
  6. rain

    rain New Member

    Blog Posts:
    0
    Joined:
    Apr 22, 2006
    Messages:
    976
    хех, короче в данном случае получается что, size положительный, значит "second ULONG to record the value type" а оно в данном случае == 0 т.е.
    Code (Text):
    1. #define REG_NONE                    ( 0 )   // No value type
    upd:
    хотя стоп!
    "Nonstring data with size, in bytes, <= sizeof -- The value is stored in the memory location specified by EntryContext."
    а как это отличить? короче я хз вообщем =\ действительно странно. А зачем такие извраты мож просто чекнуть ZwQueryValueKey ?
     
  7. Quark

    Quark New Member

    Blog Posts:
    0
    Joined:
    Aug 7, 2007
    Messages:
    211
    Да ладно. Уже через адвапи сделал. Просто думал через макросы ntdll проще получится. Вот, скажем, RtlWriteRegistryValue - намного удобнее чем адвапи.