IFS, как узнать имя файла

Тема в разделе "WASM.WIN32", создана пользователем int21h, 9 окт 2004.

  1. int21h

    int21h New Member

    Публикаций:
    0
    Регистрация:
    9 окт 2004
    Сообщения:
    4
    Нужно написать программу, которая перехватывала бы обращения к файлам, и в некоторых случаях запрещала бы к ним доступ. Для этого написал VxD'шник, который юзает IFSMgr_InstallFileSystemApiHook. Всё работает, только не знаю как прочитать имя файла.



    Вот цитата из руководства:
    Код (Text):
    1.  
    2. hook_procedure:
    3.         push ebp
    4.         mov ebp,esp
    5.         sub esp,20h
    6.     ; С этого места, мы можем найти параметры
    7.     ; используя стек
    8.     ; ebp+00h -> сохраненное значение EBP.
    9.     ; ebp+04h -> адрес возврата.
    10.     ; ebp+08h -> адрес FSD функции, которая вызывается для
    11.     ;                    этого API.
    12.     ; ebp+0Ch -> номер функции, которую пытаются выполнить
    13.     ; ebp+10h -> номер диска, на котором все происходит (1
    14. =A:,
    15.     ;                    -1 если UNC)
    16.     ; ebp+14h -> тип диска
    17.     ; ebp+18h -> кодовая страница, в которой юзер набрал
    18. свою      
    19.     ;                    строку-    BCS_ANSI = ANSI, BCS_OEM = OEM
    20.     ; ebp+1Ch -> указатель на структуру вызова IFS менеджера              
    21.     ;                    (IOREQ)
    22.  


    Потом в eax они записывают адрес строки в UNICODE, в которой содержиться путь к фалу:
    Код (Text):
    1.  
    2. mov     eax,[ebp+1Ch]
    3. mov     eax,[eax+0Ch]           ; EAX = Указатель на строку
    4.  


    Но по этому адресу не фига нету, одни вопросы (если смотреть в SoftIce). И адрес странный - 0ffffbbbh.

    Подскажите, как узнать путь к файлу из обработчика IFS.
     
  2. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Возможно, стоит предпринять следующие шаги: адрес может быть верным, но страница с именем файла выгружена - при первом обращении к ней диспечер получит 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
     
  3. int21h

    int21h New Member

    Публикаций:
    0
    Регистрация:
    9 окт 2004
    Сообщения:
    4
    Нет, страница не может быть выгружена, т.к. это обработчик всех событий файловой системы,

    он должен работать очень быстро. К тому же я попробывал сделать, как ты пишешь - несколько раз срабатывает исключение 0eh (page fault), а потом комп просто виснет.

    Скорей всего неправильно указан адрес, или я чего то не понимаю.

    Может есть ещё какие-нибудь способы перехвата обращений к файлам???
     
  4. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    К тому же я попробывал сделать, как ты пишешь



    Ты имеешь в виду перехват сервиса IFSMgr_Ring0_FileIO

    с помощью вызова hook device service ?
     
  5. int21h

    int21h New Member

    Публикаций:
    0
    Регистрация:
    9 окт 2004
    Сообщения:
    4
    нет, я имею в виду:



    адрес может быть верным, но страница с именем файла выгружена - при первом обращении к ней диспечер получит page fault и догрузит ее (достаточно в приложении перед CreateFile прочесть байт из имени файла), можно вызвать в тестовой проге CreateFile, запомнить адрес и искать его в этих структурах или (если kernel копирует его в tmp буфер) следить за ним через bpm.



     
  6. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Хмм. Если хочешь, я могу попробовать твой код у себя.
     
  7. int21h

    int21h New Member

    Публикаций:
    0
    Регистрация:
    9 окт 2004
    Сообщения:
    4
    Давай. Только это пока не VxD, а exe, переходит в Ring0 через

    LDT. VxD я потом напишу, если разберусь с этим. Компилируется обычным TASM.exe и Link32.exe.

    Там в начале бесконечный цикл, чтоб поймать прогу SoftIce'ом.

    Сильно не пугайся, код не оптимизирован, т.к. писал просто, чтоб проверить как это

    всё работает. Начинай смотреть сразу с обработчика (процедура New).


    Код (Text):
    1.  
    2. .586p
    3. text segment
    4. assume cs:text,ds:text
    5. begin:
    6.  
    7.     mov ecx,3       ;бесконечный цикл
    8.     loop begin     
    9.  
    10.  
    11. ; дальше идёт процедура перехода в RING0 через LDT
    12.  
    13.     mov edi,eax
    14.     push 4
    15.     push 0bff70000h
    16.     mov eax,edi
    17.     add eax,(offset winnt-offset begin)
    18.     push eax
    19.     mov edx,esp
    20.     mov eax,10ah
    21.     int 2eh
    22.     cmp dword ptr [eax],0
    23.     je ntyes
    24.     jmp ntno
    25.  
    26. ntyes:
    27.  
    28. ntno:
    29. ;--------------Ring3=>Ring0-----------
    30.     sgdt psevd
    31.     mov eax,dword ptr [edi+offset psevd-offset begin+2]
    32.     xor esi,esi
    33.     sldt si
    34.     add eax,esi
    35.     mov bh,byte ptr [eax+7]
    36.     mov bl,byte ptr [eax+4]
    37.     shl ebx,10h
    38.     mov bx,word ptr [eax+2]
    39.  
    40.     lea esi,[edi+offset slus-offset begin]
    41.  
    42.     mov eax,offset ring0
    43.     mov word ptr [esi],ax
    44.     shr eax,10h
    45.     mov word ptr [esi+6],ax
    46.  
    47.     mov eax,dword ptr [esi]
    48.     mov dword ptr [ebx],eax
    49.     mov eax,dword ptr [esi+4]
    50.     mov dword ptr [ebx+4],eax
    51. ;--------------------Call ring0--------------------
    52. ;На этом call в SoftIce нужно нажать F8
    53.  
    54. db 09ah
    55. dd 0
    56. dw 07h
    57.  
    58. ;--------------------Ring0------------------------
    59. Ring0:         
    60.  
    61. ; здесь начинается самое интересное
    62.  
    63.  
    64.  
    65.     push 100h           ; Это параметры, не помню что они значат
    66.     push 1f4h
    67.     int 20h         ; Вызов VxD сервиса для выделения памяти
    68.     db 4fh,00h,01h,00,83h,0C4h,08h  
    69.                 ;eax= адрес выделенной памяти
    70.  
    71. ;Дальше идёт копирование обработчика
    72.  
    73.     mov ecx,offset newend-offset new        ;ecx=размер обработчика
    74.     xor edx,edx
    75. loop123:
    76.     mov bl,byte ptr  [edi+offset new+edx-offset begin]  ;откуда
    77.     mov byte ptr [eax+edx],bl           ;куда
    78.     inc edx                
    79.     loop loop123
    80.  
    81. ;в обработчик записывается адрес буфера для преобразованной строки
    82.  
    83.     mov edi,eax
    84.     add edi, offset filename-offset new
    85.     mov dword ptr [eax+offset file_addr-offset new], edi
    86.  
    87. ;---------------Ifs-------------------------------------
    88. ;Вызов VxDCall IFSMgr_InstallFileSystemApiHook для установки обработчика
    89.     mov ebx,eax
    90.     push eax
    91.     int 20h
    92.     db 67h,00,40h,00
    93.     add esp,4
    94.     mov esi,eax
    95.     mov eax,[esi]
    96.  
    97.     mov dword ptr [offset call1-offset new+ebx],eax
    98.  
    99. ; Здесь следует в SoftIce установить bpx eax, чтоб вылазил на обработчике
    100.  
    101.     retf
    102.  
    103. ; Набрать в SoftIce Exit
    104.  
    105. ;---------------------------Обработчик событий IFS
    106. New:
    107.  
    108.     push ebp
    109.     mov ebp,esp
    110.     pusha
    111.  
    112.  
    113. ;===================================================================== ==========================
    114. ;идёт подготовка параметров для вызова VxDCall UniToBCSPath (перевод UNICODE в ASCII)
    115.     xor eax,eax
    116.     push    eax                     ; EAX = 0 -> Конвертируем в ASCII
    117.     mov     eax,100h
    118.     push    eax                     ; EAX = Размер конвертируемой строки
    119.  
    120. ;----------вот здесь трабла
    121.     mov     eax,[ebp+1ch]  
    122.     mov     eax,[eax+0Ch]   ; EAX = Указатель на строку, здесь не фига нету
    123. ;----------------------------
    124.     push    eax
    125.     db 0bfh     ;mov edi, адрес буфера filename, куда будет писаться ASCII строка
    126. file_addr: dd 0        
    127.     push    edi                    
    128.  
    129.     int 20h     ;VxDCall переводит UNICODE в ASCII, происходит page fault
    130.     db 41h, 00, 40h, 00
    131.     add     esp,10h                
    132.  
    133. ;===================================================================== ==========================
    134.  
    135.     popa
    136.     pop ebp
    137.  
    138. ;Вызов системного обработчика
    139.     db 0eah
    140. call1:  dd 0
    141.     dw 28h
    142.  
    143.  
    144. filename:
    145.     db 100h dup(0)
    146.  
    147. newend:
    148.  
    149.  
    150.  
    151.  
    152. ;==========-Data-================
    153. psevd df 0
    154.  
    155. slus:   dw 0,28h
    156.             db 0
    157.         db 0ech
    158.     dw 0
    159.  
    160. winnt: dd 0
    161. ends
    162. end begin
    163.  
     
  8. Chingachguk

    Chingachguk New Member

    Публикаций:
    0
    Регистрация:
    2 сен 2002
    Сообщения:
    340
    Значит, так. Твой код не писал, написал свой в обычном VxD. Действительно, на входе после команд:


    Код (Text):
    1.   mov  eax,[ebp+1Ch]
    2.   mov  eax,[eax+0Ch]




    в eax указатель то на unicode-name file (правда, там идет какой-то начальный символ, но ты разберешься, я думаю сам), то явно не то - 0FFFFFBBBh. Дело видимо вот в чем:


    Код (Text):
    1. ; ebp+0Ch -> [b]номер функции[/b], которую пытаются выполнить




    Для нормальных указателей тут сидит 2Ch, в то же время как для левоты - 12h. Не знаю, что значат эти номера функции, но ИМХА, дело в этом.