Нужно написать программу, которая перехватывала бы обращения к файлам, и в некоторых случаях запрещала бы к ним доступ. Для этого написал VxD'шник, который юзает IFSMgr_InstallFileSystemApiHook. Всё работает, только не знаю как прочитать имя файла. Вот цитата из руководства: Код (Text): hook_procedure: push ebp mov ebp,esp sub esp,20h ; С этого места, мы можем найти параметры ; используя стек ; ebp+00h -> сохраненное значение EBP. ; ebp+04h -> адрес возврата. ; ebp+08h -> адрес FSD функции, которая вызывается для ; этого API. ; ebp+0Ch -> номер функции, которую пытаются выполнить ; ebp+10h -> номер диска, на котором все происходит (1 =A:, ; -1 если UNC) ; ebp+14h -> тип диска ; ebp+18h -> кодовая страница, в которой юзер набрал свою ; строку- BCS_ANSI = ANSI, BCS_OEM = OEM ; ebp+1Ch -> указатель на структуру вызова IFS менеджера ; (IOREQ) Потом в eax они записывают адрес строки в UNICODE, в которой содержиться путь к фалу: Код (Text): mov eax,[ebp+1Ch] mov eax,[eax+0Ch] ; EAX = Указатель на строку Но по этому адресу не фига нету, одни вопросы (если смотреть в SoftIce). И адрес странный - 0ffffbbbh. Подскажите, как узнать путь к файлу из обработчика IFS.
Возможно, стоит предпринять следующие шаги: адрес может быть верным, но страница с именем файла выгружена - при первом обращении к ней диспечер получит page fault и догрузит ее (достаточно в приложении перед CreateFile прочесть байт из имени файла), можно вызвать в тестовой проге CreateFile, запомнить адрес и искать его в этих структурах или (если kernel копирует его в tmp буфер) следить за ним через bpm. Есть еще вариант использовать сервис VMM: 0090h hook device service EAX = service ID (high word = VxD ID, low = service number) ESI -> new handler Для перехвата функции IFS открытия файла: IFSMgr_Ring0_FileIO This service provides a register-based VxD callable interface to the common file system functions ... [ESI] Flat pointer to the pathname of the file to be opened/created. Carry flag clear, operation was successful
Нет, страница не может быть выгружена, т.к. это обработчик всех событий файловой системы, он должен работать очень быстро. К тому же я попробывал сделать, как ты пишешь - несколько раз срабатывает исключение 0eh (page fault), а потом комп просто виснет. Скорей всего неправильно указан адрес, или я чего то не понимаю. Может есть ещё какие-нибудь способы перехвата обращений к файлам???
К тому же я попробывал сделать, как ты пишешь Ты имеешь в виду перехват сервиса IFSMgr_Ring0_FileIO с помощью вызова hook device service ?
нет, я имею в виду: адрес может быть верным, но страница с именем файла выгружена - при первом обращении к ней диспечер получит page fault и догрузит ее (достаточно в приложении перед CreateFile прочесть байт из имени файла), можно вызвать в тестовой проге CreateFile, запомнить адрес и искать его в этих структурах или (если kernel копирует его в tmp буфер) следить за ним через bpm.
Давай. Только это пока не VxD, а exe, переходит в Ring0 через LDT. VxD я потом напишу, если разберусь с этим. Компилируется обычным TASM.exe и Link32.exe. Там в начале бесконечный цикл, чтоб поймать прогу SoftIce'ом. Сильно не пугайся, код не оптимизирован, т.к. писал просто, чтоб проверить как это всё работает. Начинай смотреть сразу с обработчика (процедура New). Код (Text): .586p text segment assume cs:text,ds:text begin: mov ecx,3 ;бесконечный цикл loop begin ; дальше идёт процедура перехода в RING0 через LDT mov edi,eax push 4 push 0bff70000h mov eax,edi add eax,(offset winnt-offset begin) push eax mov edx,esp mov eax,10ah int 2eh cmp dword ptr [eax],0 je ntyes jmp ntno ntyes: ntno: ;--------------Ring3=>Ring0----------- sgdt psevd mov eax,dword ptr [edi+offset psevd-offset begin+2] xor esi,esi sldt si add eax,esi mov bh,byte ptr [eax+7] mov bl,byte ptr [eax+4] shl ebx,10h mov bx,word ptr [eax+2] lea esi,[edi+offset slus-offset begin] mov eax,offset ring0 mov word ptr [esi],ax shr eax,10h mov word ptr [esi+6],ax mov eax,dword ptr [esi] mov dword ptr [ebx],eax mov eax,dword ptr [esi+4] mov dword ptr [ebx+4],eax ;--------------------Call ring0-------------------- ;На этом call в SoftIce нужно нажать F8 db 09ah dd 0 dw 07h ;--------------------Ring0------------------------ Ring0: ; здесь начинается самое интересное push 100h ; Это параметры, не помню что они значат push 1f4h int 20h ; Вызов VxD сервиса для выделения памяти db 4fh,00h,01h,00,83h,0C4h,08h ;eax= адрес выделенной памяти ;Дальше идёт копирование обработчика mov ecx,offset newend-offset new ;ecx=размер обработчика xor edx,edx loop123: mov bl,byte ptr [edi+offset new+edx-offset begin] ;откуда mov byte ptr [eax+edx],bl ;куда inc edx loop loop123 ;в обработчик записывается адрес буфера для преобразованной строки mov edi,eax add edi, offset filename-offset new mov dword ptr [eax+offset file_addr-offset new], edi ;---------------Ifs------------------------------------- ;Вызов VxDCall IFSMgr_InstallFileSystemApiHook для установки обработчика mov ebx,eax push eax int 20h db 67h,00,40h,00 add esp,4 mov esi,eax mov eax,[esi] mov dword ptr [offset call1-offset new+ebx],eax ; Здесь следует в SoftIce установить bpx eax, чтоб вылазил на обработчике retf ; Набрать в SoftIce Exit ;---------------------------Обработчик событий IFS New: push ebp mov ebp,esp pusha ;===================================================================== ========================== ;идёт подготовка параметров для вызова VxDCall UniToBCSPath (перевод UNICODE в ASCII) xor eax,eax push eax ; EAX = 0 -> Конвертируем в ASCII mov eax,100h push eax ; EAX = Размер конвертируемой строки ;----------вот здесь трабла mov eax,[ebp+1ch] mov eax,[eax+0Ch] ; EAX = Указатель на строку, здесь не фига нету ;---------------------------- push eax db 0bfh ;mov edi, адрес буфера filename, куда будет писаться ASCII строка file_addr: dd 0 push edi int 20h ;VxDCall переводит UNICODE в ASCII, происходит page fault db 41h, 00, 40h, 00 add esp,10h ;===================================================================== ========================== popa pop ebp ;Вызов системного обработчика db 0eah call1: dd 0 dw 28h filename: db 100h dup(0) newend: ;==========-Data-================ psevd df 0 slus: dw 0,28h db 0 db 0ech dw 0 winnt: dd 0 ends end begin
Значит, так. Твой код не писал, написал свой в обычном VxD. Действительно, на входе после команд: Код (Text): mov eax,[ebp+1Ch] mov eax,[eax+0Ch] в eax указатель то на unicode-name file (правда, там идет какой-то начальный символ, но ты разберешься, я думаю сам), то явно не то - 0FFFFFBBBh. Дело видимо вот в чем: Код (Text): ; ebp+0Ch -> [b]номер функции[/b], которую пытаются выполнить Для нормальных указателей тут сидит 2Ch, в то же время как для левоты - 12h. Не знаю, что значат эти номера функции, но ИМХА, дело в этом.