Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2007.03.25;
Скачать: CL | DM;

Вниз

Перечисление системных объектных типов   Найти похожие ветки 

 
BiN ©   (2006-10-18 16:20) [0]

Как по вашему, возможна ли ситуация, когда NtQueryObject(0, ObjectAllTypesInformation... возвращает не полный список типов

Собственно, кусок действующего кода

procedure TSystemTypeList.Refresh;
var
 Data: POBJECT_ALL_TYPES_INFO;
 TypeInfo: POBJECT_TYPE_INFO;
 dwToRead: DWORD;
 dwRead: DWORD;
 ntRes: NTSTATUS;
 i: Integer;
begin
 Clear;
 Data:=nil;
 try
   dwToRead:=0;
   ntRes:=NtQueryObject(0, ObjectAllTypesInformation, Data, dwToRead, @dwRead);

   while ntRes=STATUS_INFO_LENGTH_MISMATCH do
   begin
     dwToRead:=dwRead;
     ReallocMem(Data, dwToRead);
     ntRes:=NtQueryObject(0, ObjectAllTypesInformation, Data, dwToRead, @dwRead);
   end;
   if not NT_SUCCESS(ntRes) then
     RaiseNtStatusError(ntRes);
   ReallocMem(Data, dwRead);
   TypeInfo:=@(Data^.ObjectsTypeInfo);
   for i:=0 to Data^.NumberOfObjectTypes-1 do
   begin
     Add(TypeInfo);
     TypeInfo:=POBJECT_TYPE_INFO((DWORD(TypeInfo.Name.Buffer)+TypeInfo.Name.Length) and not 3+4);
   end;
 finally
   ReallocMem(Data, 0);
 end;
end;


В результате, в список по пока невыясненным причинам не попадает, например, тип "File". Но при этом вызов NtQueryObject(hTempHandle, ObjectTypeInformation... с хэндлом файла в качестве параметра отрабатывает вполне корректно.


 
Ketmar ©   (2006-10-18 16:47) [1]

файл чужой просто? (это так, бредовое предположение)


 
BiN ©   (2006-10-18 16:53) [2]


> Ketmar ©   (18.10.06 16:47) [1]
>
> файл чужой просто? (это так, бредовое предположение)


Свой.


 
Ketmar ©   (2006-10-18 16:54) [3]

тады не знаю. ИШ спроси. %-)


 
Игорь Шевченко ©   (2006-10-18 16:59) [4]

"This information class is only available if FLG_MAINTAIN_OBJECT_TYPELIST was set in
NtGlobalFlags at boot time.
The format of the data returned to the SystemInformation buffer is a sequence of
SYSTEM_OBJECT_TYPE_INFORMATION structures, chained together via the NextEntryOffset
member. Immediately following the name of the object type is a sequence of
SYSTEM_OBJECT_INFORMATION structures, which are chained together via the
NextEntryOffset member.The ends of both the object type chain and the object chain
are marked by a NextEntryOffset value of zero."

(с) Gary Nebbett


 
BiN ©   (2006-10-18 17:11) [5]


> Игорь Шевченко ©   (18.10.06 16:59) [4]

Игорь, я не использую QSI.
Вот список, который возвращается (число элементов совпадает с NumberOfObjectTypes = 23)

Type
Directory
SymbolicLink
Token
Process
Thread
Job
Event
EventPair
Mutant
Callback
Semaphore
Timer
Profile
WindowStation
Desktop
Section
Key
Port
WaitablePort
Adapter
Controller
Device

Тип "File" по идее должен идти 26-м


 
Игорь Шевченко ©   (2006-10-18 17:49) [6]

BiN ©   (18.10.06 17:11) [5]


> Игорь, я не использую QSI.


А без разницы. NtQueryObject (AllTypes) лезет в ту же дырку, что и QSI

Ты ради интереса этот флаг через gflags установи и сравни результат.


 
Игорь Шевченко ©   (2006-10-18 17:56) [7]


> А без разницы. NtQueryObject (AllTypes) лезет в ту же дырку,
>  что и QSI


Обманул я тебя. В разные места. NtQueryObject (...AllTypes...) не должна видеть типов, объявленных динамически по ObCreateObjectType


 
han_malign ©   (2006-10-18 18:07) [8]

offtop:
(TypeInfo.Name.Length == TypeInfo.Name.MaximumLength)?
(... and not 3 + 4) - смело(например для смещения 8) ==> ((... +3) and not 3)


 
BiN ©   (2006-10-18 21:31) [9]


> Игорь Шевченко ©   (18.10.06 17:56) [7]
>
> Обманул я тебя. В разные места. NtQueryObject (...AllTypes.
> ..) не должна видеть типов, объявленных динамически по ObCreateObjectType

Ну что ж, видно придется через другое место реализовывать... -)
Спасибо.


> han_malign ©   (18.10.06 18:07) [8]
>
> offtop:
> (TypeInfo.Name.Length == TypeInfo.Name.MaximumLength)?
> (... and not 3 + 4) - смело(например для смещения 8) ==>
> ((... +3) and not 3)


Увы, замечание непонятно. Разъясни, пожалуйста.


 
Rouse_ ©   (2006-10-19 10:55) [10]

Об этом баге уже давно изветсно :) Тянется еще с четверки: http://www.anticracking.sk/EliCZ/bugs/WinBugs.htm


 
n0name   (2006-10-20 10:21) [11]

Надежнее по \ObjectTypes пройтись.


 
BiN ©   (2006-10-20 10:35) [12]


> n0name   (20.10.06 10:21) [11]
>
> Надежнее по \ObjectTypes пройтись.

Тоже вариант.


 
Игорь Шевченко ©   (2006-10-20 11:07) [13]

n0name   (20.10.06 10:21) [11]

Что и делает NtQuerySystemInformation


 
n0name   (2006-10-20 11:07) [14]


var
ns: Integer;
hDir: DWORD;
oaDirName: OBJECT_ATTRIBUTES;
usDirName: UNICODE_STRING;
pvBuffer: Pointer;
pObj: POBJDIR_INFORMATION;
rl, cont: DWORD;
begin
RtlInitUnicodeString(@usDirName, "\ObjectTypes");
ZeroMemory(@oaDirName, sizeof(oaDirName));
oaDirName.Len := sizeof(oaDirName);
oaDirName.ObjectName := @usDirName;
ns := ZwOpenDirectoryObject(@hDir, DIRECTORY_QUERY, @oaDirName);
if (ns = 0) then
 begin
  rl := 0;
  cont := 0;
  pvBuffer := GetMemory($1000);
  ns := ZwQueryDirectoryObject(hDir, pvBuffer, $1000, 0, 1, @cont, @rl);
  pObj := pvBuffer;
  if (ns = 0) then
   while (pObj.ObjectName.Length <> 0) do
    begin
     ListBoxAddString(GetDlgItem(hDlg, 1000), pObj.ObjectName.Buffer);
     pObj := Pointer(DWORD(pObj) + 16);
    end;
  FreeMemory(pvBuffer);
 end;
RtlFreeUnicodeString(@usDirName);
end;


 
n0name   (2006-10-20 11:12) [15]


> Что и делает NtQuerySystemInformation

FLG_MAINTAIN_OBJECT_TYPELIST по умолчанию не установлен AFAIR


 
BiN ©   (2006-10-20 11:20) [16]


> n0name   (20.10.06 11:12) [15]

Данный метод в контексте моей задачи все же не подходит.
Только QSI или NtQueryObject(0, ObjectAllTypesInformation.
Т.к. только они дают соответствие индекса типа и его имени.


 
Riply ©   (2006-10-21 11:48) [17]

>Игорь Шевченко
А как узнать установлен ли флаг FLG_MAINTAIN_OBJECT_TYPELIST ?
>BiN
Нашлось ли решение ?
У меня перечислялись все типы и считала, что так и должно быть :)


 
n0name   (2006-10-21 12:49) [18]


> А как узнать установлен ли флаг FLG_MAINTAIN_OBJECT_TYPELIST
> ?

PEB.NtGlobalFlag and FLG_MAINTAIN_OBJECT_TYPELIST > 0


 
BiN ©   (2006-10-21 14:14) [19]


> Riply ©   (21.10.06 11:48) [17]
>
> >Игорь Шевченко
> А как узнать установлен ли флаг FLG_MAINTAIN_OBJECT_TYPELIST
> ?

function RtlGetNtGlobalFlags: DWORD; stdcall; external "ntdll.dll" name "RtlGetNtGlobalFlags";


> >BiN
> Нашлось ли решение ?
> У меня перечислялись все типы и считала, что так и должно
> быть :)

Да, там перечисляются все типы, но их порядок в директории \ObjectTypes не соответсвует индексам ObjectTypeIndex из структуры _SYSTEM_HANDLE_INFORMATION. Для решения, как я уже говорил, использую комбинацию NtQueryObject(0, ObjectAllTypesInformation и NtQueryObject(Handle, ObjectTypeInformation.


 
n0name   (2006-10-21 16:40) [20]


> function RtlGetNtGlobalFlags: DWORD; stdcall; external "ntdll.
> dll" name "RtlGetNtGlobalFlags";

Зачем? Если загрузчик сам копирует это значение в PEB.


 
BiN ©   (2006-11-04 18:12) [21]


> BiN ©   (20.10.06 11:20) [16]
> QSI или NtQueryObject(0, ObjectAllTypesInformation.
>
> .... только они дают соответствие индекса типа и его имени.
>


Ошибка. NtQueryObject(0, ObjectAllTypesInformation не не годится для определения соответствия между индексом типа и его именем.
Т.е при сброшенном флаге  FLG_MAINTAIN_OBJECT_TYPELIST остается использовать только   NtQueryObject(Handle, ObjectTypeInformation.

Всем спасибо.


 
Riply ©   (2006-11-05 10:00) [22]

Т.е. при сброшеном флаге, для определения таблицы соответствия,
надо создать объекты всех типов и посмотреть их индексы ?
Как-то некузяво :))


 
BiN ©   (2006-11-05 14:25) [23]


> Riply ©   (05.11.06 10:00) [22]
>
> Т.е. при сброшеном флаге, для определения таблицы соответствия,
>
> надо создать объекты всех типов и посмотреть их индексы
> ?
> Как-то некузяво :))

Подобная таблица соответсвия сама по себе мало где применима без объектов, точнее без их описателей.
Если нужно получить список типов, используем NtQueryDirectoryObject.
Если хотим определить имя типа объекта, хэндл которого получили с помощью QSI, то NtQueryObject(Handle, ObjectTypeInformation


 
Riply ©   (2006-11-05 22:45) [24]

>[23] BiN ©   (05.11.06 14:25)
>таблица соответсвия сама по себе мало где применима
>Если хотим определить имя типа объекта,
>то NtQueryObject(Handle, ObjectTypeInformation
Перед вызовом NtQueryObject, все таки хотелось бы
по таблице посмотреть, что за тип у хендла. А то и зависнуть можно :)
Да и при поиске чего то конкретного удобно сразу отбасывать хэндлы не тех типов.
У меня дела обстоят таким образом:
NtQueryObject(0, ObjectAllTypesInformation..  выдает следующий список:
Type
Directory
SymbolicLink
Token
Process
Thread
Job
DebugObject
Event
EventPair
Mutant
Callback
Semaphore
Timer
Profile
KeyedEvent
WindowStation
Desktop
Section
Key
Port
WaitablePort
Adapter
Controller
Device
Driver
IoCompletion
File
WmiGuid
FilterConnectionPort
FilterCommunicationPort

Порядковый номер соответствует типу.
Проверяла на NtQueryObject.
Флаг FLG_MAINTAIN_OBJECT_TYPELIST не установлен.
(если я все правильно делаю) RtlGetNtGlobalFlags возвращает 112,
как и PPEB^.NtGlobalFlag.
Можно ли временно менять состояние флага и как ? И безопасно ли это ( смена флага ) ?


 
Ketmar ©   (2006-11-05 23:07) [25]

фигасе люди лазят по системе...


 
BiN ©   (2006-11-06 01:21) [26]


> Riply ©   (05.11.06 22:45) [24]
>
> Порядковый номер соответствует типу.

О, ангидрид в мою перекись! У меня в программе был баг... Кто ж думал, что типы индексируются с единицы, а не с нуля!!!!


> Перед вызовом NtQueryObject, все таки хотелось бы
> по таблице посмотреть, что за тип у хендла.  А то и зависнуть можно :)

С зависанием можно бороться следующим образом:
1) Просто, как Розыч: вызывать DuplicateHandle и NtQueryObject в отдельном потоке - при таймауте, убивать поток.
2) Сложно (ну не люблю я убивать потоки -)): определять заранее индекс "рискованного" типа File, создав объект данного типа (предпочитаю CreateNamedPipe, т.к. на создание дискового файла может и прав не хватить). У описателей с таким индексом (в W2k он равен 26) исследую FILE_OBJECT, а именно .DeviceObject.DeviceType на предмет равенства FILE_DEVICE_NAMED_PIPE, и FileName соответсвенно. Завис, как известно, случается с запросом имени именованных каналов, находящихся в ожидании завершения IO.

> Можно ли временно менять состояние флага и как ? И безопасно
> ли это ( смена флага ) ?

Менять вроде можно с помощью NtSetSystemInformation(SystemGlobalFlag,.. при установленной debug-привилегии.
Безопасно ли, см. http://www.osronline.com/ddkx/ddtools/gflags_7u5v.htm


 
Riply ©   (2006-11-06 13:26) [27]

>[26] BiN ©   (06.11.06 01:21)
:)
>исследую FILE_OBJECT, а именно .DeviceObject.DeviceType
>на предмет равенства FILE_DEVICE_NAMED_PIPE, и FileName соответсвенно
А с помощью чего исследуешь ?
NtQueryObject(...ObjectTypeInformation... ?
Я не нашла ничего похожего на ".DeviceObject.DeviceType".
Во всяком случае в OBJECT_TYPE_INFORMATION у меня этого нет.
Правда в OBJECT_BASIC_INFORMATION три параметра - "Unknown".


 
Riply ©   (2006-11-06 13:32) [28]

>[25] Ketmar ©   (05.11.06 23:07)
>фигасе люди лазят по системе...
Что делать, если больше негде :)) Да и интересного там много :)


 
BiN ©   (2006-11-06 14:28) [29]


> Riply ©   (06.11.06 13:26) [27]
>
> А с помощью чего исследуешь ?

С помощью \Device\PhysicalMemory.


 
Ketmar ©   (2006-11-06 17:21) [30]

>[28] Riply(c) 6-Nov-2006, 13:32
>Что делать, если больше негде :)) Да и интересного там
>много :)
мне б твой молодой энтузиазм...


 
Rouse_ ©   (2006-11-06 17:42) [31]


> Просто, как Розыч: вызывать DuplicateHandle и NtQueryObject
> в отдельном потоке - при таймауте, убивать поток.

Дим ну сколько раз я тебе повторял - что деструктор потока у меня не срабатывает, т.к. синхронный пайп я таки отлавливаю на NtQueryFile а не NtQueryObject - где и будет зависон :)


 
Rouse_ ©   (2006-11-06 17:46) [32]

Точнее, парнондю - не отлавливаю а отсекаю :)
У меня задача была заточена именно на Файл


 
BiN ©   (2006-11-06 19:32) [33]


> Rouse_ ©   (06.11.06 17:42) [31]
>
>
> > Просто, как Розыч: вызывать DuplicateHandle и NtQueryObject
>
> > в отдельном потоке - при таймауте, убивать поток.
>
> Дим ну сколько раз я тебе повторял - что деструктор потока
> у меня не срабатывает, т.к. синхронный пайп я таки отлавливаю
> на NtQueryFile а не NtQueryObject - где и будет зависон
> :)


Пардон, а NtQueryFile это что?
Сань, я по своей дырявой памяти вкратце воспроизводил твой метод, так как приснопямятная ветка утекла в Лету.


 
Rouse_ ©   (2006-11-06 19:37) [34]

:))

NtQueryInformationFile конечно :)
Вот смотри:

function GetFileNameThread(lpParameters: Pointer): DWORD; stdcall;
 var
   FileNameInfo: FILE_NAME_INFORMATION;
   ObjectNameInfo: TOBJECT_NAME_INFORMATION;
   IoStatusBlock: IO_STATUS_BLOCK;
   pThreadParam: TGetFileNameThreadParam;
   dwReturn: DWORD;
 begin
   ZeroMemory(@FileNameInfo, SizeOf(FILE_NAME_INFORMATION));
   pThreadParam := PGetFileNameThreadParam(lpParameters)^;
   Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock,
     @FileNameInfo, MAX_PATH * 2, FileNameInformation);
   if Result = STATUS_SUCCESS then
   begin
     Result := NtQueryObject(pThreadParam.hFile, ObjectNameInformation,
       @ObjectNameInfo, MAX_PATH * 2, @dwReturn);
     if Result = STATUS_SUCCESS then
     begin
       pThreadParam.Status := Result;
       WideCharToMultiByte(CP_ACP, 0,
         @ObjectNameInfo.Name.Buffer[ObjectNameInfo.Name.MaximumLength -
         ObjectNameInfo.Name.Length],
         ObjectNameInfo.Name.Length, @pThreadParam.Data[0],
         MAX_PATH, nil, nil);
     end
     else
     begin
       pThreadParam.Status := STATUS_SUCCESS;
       Result := STATUS_SUCCESS;
       WideCharToMultiByte(CP_ACP, 0,
         @FileNameInfo.FileName[0], IoStatusBlock.Information,
         @pThreadParam.Data[0],
         MAX_PATH, nil, nil);
     end;
   end;
   PGetFileNameThreadParam(lpParameters)^ := pThreadParam;
   ExitThread(Result);
 end;


вот тут на пайпе будет не STATUS_SUCCESS

   Result := NtQueryInformationFile(pThreadParam.hFile, @IoStatusBlock,
     @FileNameInfo, MAX_PATH * 2, FileNameInformation);
   if Result = STATUS_SUCCESS then


соответственно дальнейшая проверка не нужна...


 
Rouse_ ©   (2006-11-06 19:38) [35]

а код целиком можешь тут посмотреть: http://forum.sources.ru/index.php?showtopic=152912


 
BiN ©   (2006-11-06 20:22) [36]


> вот тут на пайпе будет не STATUS_SUCCESS
>
>    Result := NtQueryInformationFile(pThreadParam.hFile,
> @IoStatusBlock,
>      @FileNameInfo, MAX_PATH * 2, FileNameInformation);
>    if Result = STATUS_SUCCESS then

Ты уверен? Пример ниже демонстрирует, что NtQueryInformationFile вполне дружит с каналами. Или ты имел ввиду только "проблемные" каналы?


procedure TForm1.Button1Click(Sender: TObject);
var
 hPipe: THandle;
 ObjectNameInfo: PFILE_NAME_INFORMATION;
 IoStatusBlock: IO_STATUS_BLOCK;
 dwSize: DWORD;
 S: WideString;
begin
 hPipe:=CreateNamedPipe("\\.\pipe\myextrapipe", PIPE_ACCESS_DUPLEX, PIPE_TYPE_BYTE,
   1, 0, 0, INFINITE, nil);
 Win32Check(hPipe<>INVALID_HANDLE_VALUE);
 try
   dwSize:=MAX_PATH*SizeOf(WCHAR)+SizeOf(DWORD);

   ObjectNameInfo:=AllocMem(dwSize);
   try
     NtCheckStatus(NtQueryInformationFile(hPipe, @IOStatusBlock, ObjectNameInfo, dwSize, FileNameInformation));
     SetLength(S, ObjectNameInfo^.FileNameLength div SizeOf(WideChar));
     if ObjectNameInfo^.FileNameLength>0 then
       Move(ObjectNameInfo^.FileName[0], S[1], ObjectNameInfo^.FileNameLength);
     Caption:=S;
   finally
     ReallocMem(ObjectNameInfo, 0);
   end;
 finally
   CloseHandle(hPipe);
 end;

end;


 
BiN ©   (2006-11-06 20:25) [37]

вдогонку к [36]

function NT_SUCCESS(Status: NTSTATUS): BOOL;
begin
 Result := Status >= 0;
end;

procedure RaiseNtStatusError(Status: Integer);
var
 ErrorCode: Integer;
 Error: EOSError;
begin
 ErrorCode := LsaNtStatusToWinError(Status);
 if ErrorCode <> 0 then
   Error := EOSError.CreateResFmt(@SOSError, [ErrorCode,
     SysErrorMessage(ErrorCode)])
 else
   Error := EOSError.CreateRes(@SUnkOSError);
 Error.ErrorCode := ErrorCode;
 raise Error;
end;

procedure NtCheckStatus(Status: NTSTATUS);
begin
 if not NT_SUCCESS(Status) then
   RaiseNtStatusError(Status);
end;


 
Riply ©   (2006-11-07 13:19) [38]

>[34] Rouse_ ©   (06.11.06 19:37)
Мои эксперементы показали, что на NtQueryInformationFile мы виснем также
успешно, как и на NtQueryObject(... ObjectNameInformation, с той только
разницей, что после NtQueryInformationFile убить поток можно, а после
NtQueryObject - не получается. Поэтому перед NtQueryObject я вызываю
GetFileType - тоже виснем, но быстрее, проще и безболезненние :)


 
BiN ©   (2006-11-07 13:39) [39]


> Riply ©   (07.11.06 13:19) [38]
>
> GetFileType - тоже виснем, но быстрее, проще и безболезненние
> :)

Из-за того, что GetFileType вызывает NtQueryVolumeInformation


 
BiN ©   (2006-11-07 13:41) [40]


> BiN ©   (07.11.06 13:39) [39]
>
>
> Из-за того, что GetFileType вызывает NtQueryVolumeInformation

пардон, NtQueryVolumeInformationFile


 
Rouse_ ©   (2006-11-07 14:39) [41]

Вполне возможно - пример писался давно и всех тонкостей уже не помню...



Страницы: 1 2 вся ветка

Текущий архив: 2007.03.25;
Скачать: CL | DM;

Наверх




Память: 0.59 MB
Время: 0.052 c
1-1170086620
RedBanner
2007-01-29 19:03
2007.03.25
Скрыть окно программы с панели задач


15-1172586264
jack128
2007-02-27 17:24
2007.03.25
ImageEditor из D2006


11-1142828301
Kealon
2006-03-20 07:18
2007.03.25
KeyPreview


15-1172743261
Игорь Шевченко
2007-03-01 13:01
2007.03.25
Нужна ли локализация Delphi на русский язык ?


2-1172599961
Василиус
2007-02-27 21:12
2007.03.25
помогите позжалста...