Привет!. Хочу перехватывать удаления файла.Из юзер мода. Перехват ставлю на Nt функции. Вообщем схема такова Перехватываю NtSetInformation с флагом FileDispositionInformation. Если FILE_DISPOSITION_INFORMATION FileInformation==1,я ставлю ему 0 (что б потом закрыть хендл и спокойно переимновать файл),заношу в массив хендл. Все это делается для того, что все выше перечисленные процедуры НЕ удаляют файл,а лишь дают разрешение.Файл удалятся при закрытие последнего хендла. Для этого я перехватываю NtCloseHandle там проверяю в массиве -это ли хендл-и если он переименовываю файл ,который должны удалить... Внутри NtCloseHandle использую критические секции для того, что б избежать одновременного доступа к массиву. Одно при вызове LeaveCriticalSection-происходит самоблокировка-т.к. вызывается снова перехват NtCloseHandle и попадаю на EnterCriticalSection внутри NtCloseHandle... Сделал проверку ZwQueryObject,что б хендл относился к дисковому файлу,во избежании самоблокировки.. Все хорошо,однако тут появиласб вторая трабла-некоторые приложения падают или неккоректно отрабатывают.Код вроде правильный Код (Text): void GetTypeHandle(HANDLE hKey,WCHAR* ch) { DWORD rLen=0, sLen=0; POBJECT_TYPE_INFORMATION pot=NULL; NTSTATUS status; pNtQueryObject=NULL; reinterpret_cast<FARPROC&>(pNtQueryObject) = GetProcAddress(GetModuleHandle(TEXT("ntdll.dll")), "ZwQueryObject"); if (pNtQueryObject==NULL) { wcscpy(ch,L""); return; } pot = (POBJECT_TYPE_INFORMATION) new BYTE[512]; if ( pot==NULL) { wcscpy(ch,L""); return; } status = pNtQueryObject(hKey, ObjectTypeInformation, pot, 512, &rLen); if ((status!=STATUS_SUCCESS) || (rLen==0)) { wcscpy(ch,L""); return; } wcsncpy(ch, pot->TypeName.Buffer, pot->TypeName.Length / 2); if(pot) { delete []pot; } } Вообщем вопрос-в чем могут быть траблы (мож сталкивался кто..) И если это все неправильно-как можно отследить удаление файлов другими способами с возможностью не дать их удалить или переименовать?
Зачем столько гемора? Проверяешь 4 и 5 параметры, если они не те что тебе нуны, выполняешь, в противном случии не выполняешь а просто возвращаешь успешное возвращение и все давольны вот так: Код (Text): .if Param4 != 1 && Param5 != 0Dh push Param5 push Param4 push Param3 push Param2 push Param1 call _ZwSetInformationFile .else xor eax,eax .endif
Вместо массива использовать список... Ибо как удалять хендлы и кто знает сколько их будет? Где падают? Отладчик? Надо кода больше выложить, одна GetTypeHandle не поможет Да.. Но ТС хочет отследить именно сам момент удаления по закрытию хендла... Я например тоже делал так Код (Text): NTSTATUS NTAPI zNtSetInformationFile( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, IN PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass ) { NTSTATUS Status; CHAR ObjectName[MAX_PATH+1]; if ((FileInformationClass == FileDispositionInformation) && (QueryObjectName(FileHandle,ObjectName,MAX_PATH)) && (IsProtected(ObjectName))) // is protected file? { Status = STATUS_SUCCESS; } else { Status = oldNtSetInformationFile( FileHandle, IoStatusBlock, FileInformation, Length, FileInformationClass ); } return Status; }
1.А вы попробуйте удалить через Эксплорер Через shift+del. Знаете что произойдет (не верите-посмотрите FileSpy) ?-Прийдет FILE_DISPOSITION_INFORMATION FileInformation=1,затем FILE_DISPOSITION_INFORMATION FileInformation=0,затем снова FILE_DISPOSITION_INFORMATION FileInformation=1. Вот и получится баг!Первый раз я файл переименую,затем експлорер,при втором заходе пройдется-и вы получите error-даного файла нет!!! 2. Хотите прикол? Откройте файл ,а затем вызовите DeleteFile() для этого файла. Функция отрабтает УСПЕШНО.Но файл не удалится... Когда он удалится? Да сразу,после того,как вы сделаете CloseHandle,либо закроете приложение.Но после DeleteFile()-вы не сможете даже переименовать файл..Т.е FILE_DISPOSITION_INFORMATION FileInformation=1 НИ О ЧЕМ НЕ ГОВОРИТ! Просто файлу разрешено удалится.А удаление происходит после закрытие последнего хендла... А если пользоваться Nt функциями,то уволить такую прогу я могу в 2 счета. Вызвать более одного раза NtSetInformation. Так что не все так просто
Использую set из STL..Просто пишу здесь по простому.. Не могу сказать.Во -первых у меня все отлично.У других тоже.А вот у третих-фигня.Експлорер может перезагрузится.. Виртуалка -ВООБЩЕ запускается,но GUI не отображается. Падет Excel.... А вот весь код,при котором СТАБИЛЬНО падает. Вот одна единственная функция перехватчик.. Все остальное -закоментировал..Падает стабильно-описано выше.. Код (Text): NTSTATUS WINAPI pUnrealCloseHandle(HANDLE fHandle) { if(fHandle!=INVALID_HANDLE_VALUE) { WCHAR typ[512]=L""; GetTypeHandle(fHandle,typ); if(wcscmp(typ,L"File")==0) { pRtlEnterCriticalSection(&crsc); NTSTATUS st; st=pNtCloseHandle(fHandle); pRtlLeaveCriticalSection(&crsc); return st; } } return pNtCloseHandle(fHandle); }
А вот вообще читсый эксперимент! Код (Text): NTSTATUS WINAPI pUnrealCloseHandle(HANDLE fHandle) { WCHAR typ[512]=L""; GetTypeHandle(fHandle,typ); return pNtCloseHandle(fHandle); } Вот так тоже траблы... Ну мож подскажет кто-как все это можно обойти или хотя б предположение-почему такое может возникать... Приложения не то,что бы падают.. Просто кто падает,а кто выдает ошибки какие-то.По поводу использования файлов или еще какие мессаги..Такое ощущение,что хендлы как-то... невалиднами становятся..Что ли..