|
|
| Посл.отвђт | Сообщенiе |
|
|
Дата: Авг 20, 2003 09:59:52 Простенькая программа по мотивам Undocumented NT. программа энумерит хэндлы и выводит имя объекта. На некоторых объектах оно виснет внутри ZwQueryObject (при вызове sysenter ). Виснет пока не закрою процесс где этот хэндл породился. Пример хэндлов (виснет не во всех, у меня как минимум в трех - прога для управления BlueTooth от microstar, в проге от Creative для SB Audigy, в AOL на каком-то named pipe (самое обидное т.к. его хэндлы и нужно проэнумерить)) Кроме того всякие TerminateProcess для моего процесса, энумерящего хэндлы - не работают - он висит пока процесс не закроется, из-за хэндла которого беда. Если кто что может сказать по этому поводу - буду очень рад. Ниже код который используется.
#include "stdafx.h"
#include "windows.h"
#include <iostream>
using namespace std;
typedef struct _SYSTEM_HANDLE_INFORMATION { // Information Class 16
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags; // 0x01 = PROTECT_FROM_CLOSE, 0x02 = INHERIT
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING;
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
#define STATUS_INFO_LENGTH_MISMATCH 0xC0000004L
typedef long (__stdcall *tag_ZwQuerySystemInformation ) ( long SystemInformationClass,PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength = NULL);
typedef long (__stdcall *tag_ZwQueryObject) ( HANDLE ObjectHandle, long ObjectInformationClass, PVOID ObjectInformation, ULONG ObjectInformationLength, PULONG ReturnLength = NULL );
tag_ZwQuerySystemInformation ZwQuerySystemInformation;
tag_ZwQueryObject ZwQueryObject;
int main(int argc, char* argv[])
{
HMODULE hntdll=LoadLibrary("ntdll.dll") ;
ZwQuerySystemInformation=(tag_ZwQuerySystemInformation) GetProcAddress(hntdll,"ZwQuerySystemInformation");
ZwQueryObject=(tag_ZwQueryObject) GetProcAddress(hntdll,"ZwQueryObject");
ULONG n;
PULONG p = new ULONG[n = 0x20000];
ULONG x;
while (STATUS_INFO_LENGTH_MISMATCH==ZwQuerySystemInformation(16, p, n * sizeof *p, &x))
delete [] p, p = new ULONG[n *= 2];
PSYSTEM_HANDLE_INFORMATION h = PSYSTEM_HANDLE_INFORMATION(p + 1);
int i;
x=x/sizeof(SYSTEM_HANDLE_INFORMATION);
for(i=0;i<x;i++)
{
if (h->ProcessId==3032)
{
BYTE* r = new BYTE[1024];
_OBJECT_NAME_INFORMATION& so_name = *(_OBJECT_NAME_INFORMATION*)r;
ULONG size;
HANDLE hProc=OpenProcess (PROCESS_DUP_HANDLE,FALSE,h->ProcessId);
if (hProc)
{
HANDLE hObj;
try
{
cout << "Before DuplicateHandle" << endl;
{
if (DuplicateHandle (hProc,(LPVOID)h->Handle,GetCurrentProcess(),&hObj,0,0,DUPLICATE_SAME_ACCESS))
{
cout << "Before QueryObject" << endl;
cout << "Handle is " << h->Handle << endl;
cout << "Process is " << h->ProcessId << endl;
cout << "Type is " << (long)h->ObjectTypeNumber << endl;
//Виснет тут long rv = ZwQueryObject (hObj, 1, &so_name, 1024,&size);
cout << "After QueryObject" << endl;
if (!rv)
{
if (so_name.Name.Length>0)
wcout <<so_name.Name.Buffer << endl;
}
cout << "Before CloseHandle" << endl;
CloseHandle (hObj);
}
else
{
cout << "Error duplicating handle" << endl;
}
}
}
}
CloseHandle (hProc);
delete [] r;
}
h++;
}
return 0;
}
|
|
|
Дата: Авг 20, 2003 11:33:13 Ну да. Недостаток этого метода как раз и состоит в том, что процесс подвисает, когда пытается получить имя пайпа, открытого для синхронного доступа и которые имеют незавершенные операции чтения или записи. Причем любой сервис имеет такой хендл. Есть еще метод получить список хендлов, но он требует определенной установки NtGlobalFlag. |
|
|
Дата: Авг 20, 2003 12:26:24 А для NtGlobalFlag естественно нужны привилегии админа к примеру. так? |
|
|
Дата: Авг 20, 2003 12:30:47 Да, а тогда - можно ли определить статус пайпа и т.д. перед запросом имени? чтоб "умно" обойти такие объекты? что-нить типа QueryIoCompletionStatus и т.д.? Либо тока в тредах их открывать и оставлять на произвол судьбы процесс? кстати. а если я буду запрашивать имя из контекста того процесса, где он открыт? т.е. допустим если виснет из-за какого-то хэндла в aol.exe то если я в aol.exe сделаю поток, который проэнумерит его хэндлы? и последнее - может кто-нить кинет в меня линком на то, где это описано все, чтоб не мучать вопросами? |
|
|
Дата: Авг 20, 2003 13:06:58 Ладно, я кину линком на то место, откуда я почерпнул данную информацию. В WinNT Native Api Reference в конце есть примеры програм, в том числе и для энумерации хендлов. Может чем помогет. P.S. Ашот будет недоступен до конца месяца, так что придется полагаться на свои силы. :) |
|
|
Дата: Авг 20, 2003 13:38:34 Дело в том, что я сейчас смотрю в Native API как раз в тот пример и вокруг QueryObject(ObjectNameInformation) нет никаких танцев с бубном. А вот второй требует установки NtGlobalFlag - это вообще никак - т.к. должно работать под юзерскими привилегиями... Есть ещё мнения у кого-нибудь? Ато придется склониться к тому, чтоб на каждый хэндл делать тред и если повиснет - ждать ребута системы... :((( Фактически мне нужно найти конкретный файл - \\Device\Serial0, который занят програмой и закрыть хэндл на этот файл внутри программы ( простой DuplicateHandle (CLOSE_SOURCE_HANDLE) ). Может быть можно получить информацию об объектах, без зависания - к примеру спросить файл оно или named pipe? а так же для какого доступа открыты? (думал через тип объекта - но там один хрен все они файлы. ) |
|
|
Дата: Авг 22, 2003 15:32:56 · Поправил: Four-F Полистал я тут Неббета и... Из того, что написано во 2 главе явно следует только то, что ZwQueryObject обломится на пайпе только если звать ее с ObjectNameInformation. С другим классом все будет ОК. Проверить я это не могу, но на 99,99% уверен, что это так. Т.е. мы зовем ее с ObjectTypeInformation, если OBJECT_TYPE_INFORMATION.Name.Buffer == "File" - это наш клиент. Пайпы, к сожалению, тоже имеют хендлы типа File. Теперь наша задача как-то отличить хендл порта от пайпа без зависания ZwQueryObject. Если внимательно полистать Неббета, то там иногда мелькают всякие функции, с помощью которых, возможно, можно будет определить пайп это или нет. Например ZwQueryInformationFile с классами FilePipeInformation, FilePipeLocalInformation, FilePipeRemoteInformation. Может и еще что-то есть. Либо еще какие, с помощью которых можно определить тип объекта. А можно сделать так. Всем объектам с типом "File" слать какой-нить безобидный управляющий код через DeviceIoControl. Например так: DeviceIoControl ,, IOCTL_SERIAL_GET_PROPERTIES...И смотреть результаты. Т.к. мы не знаем заранее, какому девайсу шлем код, то потенциально это опасно, но IOCTL_SERIAL_GET_*** из зарезервированного m$ диапазона и вероятность совпадения с другим кодом минимальна, к тому же мы только читаем. К сожалению мне не удалось обнаружить у ся процесса с висящим пайпом, так что протестить на 100% не могу. В аттаче тестовый пример - у мень под 2000 работает. SerialPort открывает comm и висит на MessageBox, а ListOpenProcessHandles <pid decimal> ищет его хендл и закрывает через ZwDuplicateObject ,,, DUPLICATE_CLOSE_SOURCE. В общем, я думаю шансы на успех у тя стремятся к 100%. Только надо очень внимательно почитать литературу, подобрать нужные фильтры и коды и все заработает. Возможно с правами надо будет еще повозиться. Результаты сообчи. |
|
|
Дата: Авг 22, 2003 15:41:19 Похоже там вообще полная задница с этими пайпами. т.к. любая функция при обращении к нему виснет. к примеру SetNamedPipeInformation или как-то так. короче все функции, кроме CloseHandle при обращении к пайпу виснут напрочь. |
|
|
Дата: Авг 22, 2003 15:42:13 |
|
|
Дата: Авг 22, 2003 15:44:18 [ rst: короче все функции, кроме CloseHandle при обращении к пайпу виснут напрочь. ] Т.е. и DeviceIoControl тоже? |
|
|
Дата: Авг 22, 2003 16:02:01 Эту не пробовал... все остальные виснут. |
|
|
Дата: Авг 23, 2003 15:09:53 попробовал DeviceIOControl - виснет. кроме того у тебя в С-коде бага :) ты в DeviceIOControl даешь HANDLE из таблицы хэндлов, а не сдуплицированный - в результате всегда после DeviceIOControl получаем ERROR_INVALID_HANDLE. А если туда передать нормлаьный хэндл, то получится то же самое подвисание на пайпе. |
|
|
Дата: Авг 23, 2003 17:03:39 · Поправил: Four-F [ rst: попробовал DeviceIOControl - виснет. ] :-( Похоже, шансы на успех начали стремиться к 0%. [ rst: ...у тебя в С-коде бага :) ] Запросто - я в попыхах собирал, но на моем тесте работало. |
|
|
Дата: Авг 28, 2003 15:15:23 Из юзер моды варианта нет с такими хендлами возиться :( Время можно не тратить. Самое прикольное что можно получить, это под NT4 сообщение о нарушении целостности каких-то там лицензий (это когда в процессе system с хендлами шалишь)... Только из драйвера, причем в драйвере тоже нельзя всем подряд бездумно ObQueryNameString делать, а то и драйвер повиснет :) |
|
Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.071 |