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 намудрила с этой апишкой. к чему такие сложности? Или же это я не понимаю принцип работы этой апишки?
Бедненькой :\ что это вам реверсить больше нечего? зачемже чтото реверсить если оно закоменнтировано? Думаю всё стало ясно, если нет то ниже пример как это заюзать: Для начала создаём бинари ключик в автозапуске ) Код (Text): reg ADD HKLM\Software\Microsoft\Windows\CurrentVersion\Run /v BinData /t REG_BINARY /d aabbccddeeff0011 Теперь лобаем кодес который будет получать\выводить данные: Код (Text): NTSTATUS status; RTL_QUERY_REGISTRY_TABLE queryTable[2]; char buf[256]; KDPRINT(("DriverEntry(), %s", __FILE__)); RtlZeroMemory(&buf, sizeof(buf)); //set second element to zero, we're reading only one elemnt queryTable[1].QueryRoutine = (void*)queryTable[1].Name = (void*)0; //set first element queryTable[0].QueryRoutine = 0; //ignored in our case queryTable[0].Flags = RTL_QUERY_REGISTRY_DIRECT; queryTable[0].Name = L"BinData"; queryTable[0].EntryContext = &buf[0]; queryTable[0].DefaultType = 0; queryTable[0].DefaultData = 0; queryTable[0].DefaultLength = 0; //set length *(ULONG*)&buf[0] = sizeof(buf); status = RtlQueryRegistryValues(RTL_REGISTRY_ABSOLUTE, L"\\Registry\\Machine\\SOFTWARE\\Microsoft\\Windows\\" L"CurrentVersion\\Run", &queryTable[0], 0, 0); KDPRINT(("RtlQueryRegistryValues():\n" "status = 0x%p\n" "size = 0x%X\n" "type = 0x%X\n" "hex data = %02X %02X %02X %02X %02X %02X %02X %02X\n", status, *(ULONG*)&buf[0], *(ULONG*)&buf[4], (unsigned char)buf[8], (unsigned char)buf[9], (unsigned char)buf[10], (unsigned char)buf[11], (unsigned char)buf[12], (unsigned char)buf[13], (unsigned char)buf[14], (unsigned char)buf[15], (unsigned char)buf[16] )); Результат работы из dbgview: Код (Text): DriverEntry(), c:\drvproj\quark\sys\quark.c RtlQueryRegistryValues(): status = 0x0000000000000000 size = 0x8 type = 0x3 hex data = AA BB CC DD EE FF 00 11 если будешь тестить на х64 машине не забудь что для приложений для wow64 другая ветка ресстра фул сорец в атаче
Интересный момент с твоим кодом. Если ключик не создавать - RtlQueryRegistryValues возврашает STATUS_SUCCESS (???) . Буффер остаётся неизменным.
Хех.. в том-то и дело, что не ноль: 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.
хех, короче в данном случае получается что, size положительный, значит "second ULONG to record the value type" а оно в данном случае == 0 т.е. Код (Text): #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 ?
Да ладно. Уже через адвапи сделал. Просто думал через макросы ntdll проще получится. Вот, скажем, RtlWriteRegistryValue - намного удобнее чем адвапи.