Всех приветствую! Прошу помочь разобраться в одном вопросе, который я долгое время не могу решить. Мне нужно сделать затирание файла нулями перед удалением. Для этого я перехватываю NtSetInformationFile. Вот тут самое интересное. Сначала попробовал открыть заново файл через NtCreateFile. Не получилось (STATUS_ACCESS_DENIED), доступа нету, т.к. файл уже открыт. Нашёл статью Ms-Rem про изменение прав хендла. Попробовал перевести её с "C" на ассемблер, я не уверен, что правильно, вот что получилось у меня Код (Text): XpLookupHandleTableEntry proc HandleTable: PXP_HANDLE_TABLE, Handle:EXHANDLE LOCAL i,j,k:ULONG LOCAL Entry:PHANDLE_TABLE_ENTRY LOCAL TableCode:ULONG LOCAL sw: ULONG assume ecx:PXP_HANDLE_TABLE mov ecx, HandleTable mov eax, [ecx].TableCode xor eax, TABLE_LEVEL_MASK mov TableCode, eax xor eax,eax assume ecx:NOTHING assume ecx:PEXHANDLE lea ecx, Handle push [ecx].Index push [ecx].Index push [ecx].Index assume ecx:NOTHING pop eax shl eax, 17d and eax, 1FFh mov i, eax pop eax shl eax, 9d and eax, 1FFh mov j, eax pop eax and eax, 1FFh mov k, eax xor eax, eax mov eax, TableCode add eax, TABLE_LEVEL_MASK mov sw, eax mov Entry, 0 .IF sw == 0 ;int 3 mov eax, k imul eax, 4 add eax, TableCode mov Entry, eax .ELSEIF sw == 1 ;int 3 ;int 3 mov eax, k imul eax, 4 add eax, TableCode .if eax != 0 xor eax, eax mov eax, j imul eax, 4 mov ecx, k imul ecx, 4 mov eax, [eax] add eax, ecx mov Entry, eax .endif .ELSEIF sw == 2 ;int 3 ;int 3 ;int 3 mov eax, i imul eax, 4 add eax, TableCode .if eax != 0 mov eax, [eax] mov ecx, j imul ecx, 4 add eax, ecx .if eax != 0 mov eax, [eax] mov ecx, k imul ecx, 4 add eax, ecx mov Entry, eax .endif .endif .ENDIF mov eax, Entry ret XpLookupHandleTableEntry endp SetHandleAccess proc Handle:HANDLE, GrantedAccess:ACCESS_MASK LOCAL currProc:PEPROCESS LOCAL Entry:PHANDLE_TABLE_ENTRY LOCAL ExHandle:EXHANDLE LOCAL ObjectTable:PHANDLE_TABLE invoke PsGetCurrentProcess mov currProc, eax ;mov eax, RVATOVA(currProc, ObjectTableOffset) mov eax, currProc add eax, ObjectTableOffset mov eax, [eax] mov ObjectTable, eax assume ecx:PEXHANDLE lea ecx, ExHandle mov edx, Handle mov [ecx].GenericHandleOverlay, edx assume ecx:NOTHING ;int 3 invoke XpLookupHandleTableEntry, ObjectTable, ExHandle mov Entry, eax .if Entry != 0 assume ecx:PHANDLE_TABLE_ENTRY mov ecx, Entry mov edx, GrantedAccess mov [ecx].GrantedAccess, edx assume ecx:NOTHING .endif mov eax, 0 .if Entry != 0 mov eax, 1 .endif ret SetHandleAccess endp Функция XpLookupHandleTableEntry всегда возвращает ноль. "SW" при этом принимает какое-то левое значение, и оно не равно 0,1 или 2. Есть предположения, что что-то неправильно перевёл на АСМ. Пробовал также в перехваченной NtSetInformationFile закрыть хендл через NtClose перед открытием файла. Однако это ничем хорошим не заканчивается, BSOD не заставляет себя долго ждать (после ret идет несколько инструкций в ядре, потом падает при обращении к закрытому хендлу). Также была мысль перехвата NtCreateFile. Но там нужно как-то отличать файловую систему от девайсов, портов различных. Поиск по форуму не привёл к нужному результату. Пока-что я в тупике. Что посоветуете в данном случае?
Ну, ты получишь FILE_OBJECT, а потом уже можно с ним работать, в том числе сделать ObOpenObjectByPointer и открыть хэндл. Или ты так и делал и он вернул STATUS_ACCESS_DENIED ?
ObReferenceObjectByHandle с типом *IoFileObjectType выполняется нормально. Однако, ObOpenObjectByPointer мне говорит, что не совпадают типы (STATUS_OBJECT_TYPE_MISMATCH) Странно как-то. Может, не правильно вызываю функции?. Код (Text): HNtSetInformationFile proc uses esi edi FileHandle:dword,IoStatusBlock:dword,FileInformation:dword,llength:dword, FileInformationClass:dword LOCAL Result:dword LOCAL buf[1024]:BYTE LOCAL ani:ANSI_STRING LOCAL uni:UNICODE_STRING LOCAL pobj:dword LOCAL retlen:dword LOCAL hFile:HANDLE LOCAL fileobj:PFILE_OBJECT LOCAL refHandle:HANDLE ;jmp next cmp FileInformationClass,FileDispositionInformation jne next int 3 mov edx, IoFileObjectType mov edx, [edx] mov edx, [edx] invoke ObReferenceObjectByHandle, FileHandle, GENERIC_ALL, edx, \ KernelMode, addr fileobj, NULL .if eax == STATUS_SUCCESS invoke ObOpenObjectByPointer, fileobj, OBJ_KERNEL_HANDLE, NULL, \ FILE_READ_ACCESS or FILE_WRITE_ACCESS, edx, KernelMode, \ addr refHandle ;;;;;;;;;;;;;;;;;;;;;;;;;; .if eax == STATUS_SUCCESS invoke DbgPrint, $CTA0("ref STATUS_SUCCESS\n") .endif .if eax == STATUS_ACCESS_DENIED invoke DbgPrint, $CTA0("ref STATUS_ACCESS_DENIED\n") .endif .if eax == STATUS_INSUFFICIENT_RESOURCES invoke DbgPrint, $CTA0("ref STATUS_INSUFFICIENT_RESOURCES\n") .endif .if eax == STATUS_INVALID_PARAMETER invoke DbgPrint, $CTA0("ref STATUS_INVALID_PARAMETER\n") .endif .if eax == STATUS_OBJECT_TYPE_MISMATCH invoke DbgPrint, $CTA0("ref STATUS_OBJECT_TYPE_MISMATCH\n") .endif .if eax == STATUS_PRIVILEGE_NOT_HELD invoke DbgPrint, $CTA0("ref STATUS_PRIVILEGE_NOT_HELD\n") .endif .if eax == STATUS_QUOTA_EXCEEDED invoke DbgPrint, $CTA0("ref STATUS_QUOTA_EXCEEDED\n") .endif .if eax == STATUS_UNSUCCESSFUL invoke DbgPrint, $CTA0("ref STATUS_UNSUCCESSFUL\n") .endif ;;;;;;;;;;;;;;;;;;;;;;;;;; .if eax == STATUS_SUCCESS invoke ZwClose, refHandle .endif .elseif eax == STATUS_OBJECT_TYPE_MISMATCH invoke DbgPrint, $CTA0("getobj STATUS_OBJECT_TYPE_MISMATCH\n") .elseif eax == STATUS_ACCESS_DENIED invoke DbgPrint, $CTA0("getobj STATUS_ACCESS_DENIED\n") .elseif eax == STATUS_INVALID_HANDLE invoke DbgPrint, $CTA0("getobj STATUS_INVALID_HANDLE\n") .endif ;invoke ObReferenceObjectByHandle,FileHandle,0,0,KernelMode,addr pobj,0 ;invoke ObQueryNameString,pobj,addr uni,255,addr retlen ;invoke RtlUnicodeStringToAnsiString,addr ani,addr uni,TRUE ;invoke DbgPrint, $CTA0("%s\n"), ani.Buffer ;invoke NtClose, FileHandle ;invoke MyOpenFile, addr uni ;.if eax != 0 ; mov hFile, eax ; invoke DbgPrint, $CTA0("open file okey\n") ; invoke RewriteFileByHandle, hFile ; invoke ZwClose, hFile ;.endif ;invoke SetHandleAccess, FileHandle, AC_GENERIC_READ or AC_GENERIC_WRITE ;invoke DbgPrint, $CTA0("ret is:%x"), eax ;invoke SetHandleAccess, FileHandle, AC_DELETE mov eax,STATUS_ACCESS_DENIED ret next: invoke SetHookFunk,addr NtSetInformationFile,addr HNtSetInformationFile,addr OldNtCf,0,1 invoke NtSetInformationFile,FileHandle,IoStatusBlock,FileInformation,llength, FileInformationClass mov Result,eax invoke SetHookFunk,addr NtSetInformationFile,addr HNtSetInformationFile,addr OldNtCf,1,0 exit: mov eax,Result ret HNtSetInformationFile endp
В MSDN в описании ObReferenceObjectByHandle сказано: DesiredAccess Specifies the requested types of access to the object. The interpretation of this field is dependent on the object type. Do not use any generic access rights. ObjectType а у тебя: GENERIC_ALL может в этом дело...