Текущий архив: 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_SUCCESSResult := 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
Страницы: 1 2 вся ветка
Текущий архив: 2007.03.25;
Скачать: CL | DM;
Память: 0.58 MB
Время: 0.033 c