Чтение/запись занятого файла.

Тема в разделе "WASM.WIN32", создана пользователем Reddom, 20 окт 2005.

Статус темы:
Закрыта.
  1. Reddom

    Reddom New Member

    Публикаций:
    0
    Регистрация:
    20 окт 2005
    Сообщения:
    1
    Адрес:
    Оттуда
    В общем задача такова:

    Есть файл открытый каким-либо процессом в режиме эксклюзивного доступа. С помощью CreateFile не удается открыть его даже на чтение.

    Существует ли способ читать и писать в такой файл (по возможности не нарушая нормальной работы открывшей его программы).
     
  2. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Для решения этой задачи есть несколько методов:

    1) Чтение файла через Shadow Copy Provider. Работает только на NTFS и только если включена соответствующая служба.

    2) Чтение/запись файла путем поиска его хэндла в других процессах и копирования его себе. Запись возможна только если хэндл имеет соответствующие права доступа и даже чтение оказывает влияние на программу открывшую этот файл.

    Пример поиска хэндлов открытых файлов приведен в атаче.

    3) Открытие файла с флагом FILE_FLAG_BACKUP_SEMANTICS. Этот флаг позволяет открыть файл в любом случае, но прочитать можно только его атрибуты. После чего нужно вручную поправить таблицу хэндлов своего процесса и разрешить чтение/запись через полученый хэндл. Чтение файла при этом не нарушает работу открывшей его программы, а вот запись может нарушить что угодно :) Для реализации этого метода нужен драйвер.

    Для начала нам потребуется найти таблицу хэндлов процесса, указатель на нее есть в структуре EPROCESS по смещению 0x128 в Windows 2000 и 0xC4 в Windows XP.

    Затем нужно найти элемент таблицы соответствующий нужному хэндлу. Структура таблиц хэндлов у Win XP и Win 2k разная, поэтому для поиска придется использовать разный код:
    Код (Text):
    1. PHANDLE_TABLE_ENTRY
    2.     Win2kLookupHandleTableEntry(
    3.             IN PWIN2K_HANDLE_TABLE HandleTable,
    4.             IN EXHANDLE            Handle
    5.             )
    6. {
    7.     ULONG i, j, k;
    8.  
    9.     i = (Handle.Index >> 16) & 255;
    10.     j = (Handle.Index >> 8)  & 255;
    11.     k = (Handle.Index)       & 255;
    12.    
    13.     if (HandleTable->Table[i])
    14.     {
    15.        if (HandleTable->Table[i][j])
    16.        {
    17.            return &(HandleTable->Table[i][j][k]);
    18.        }  
    19.     }
    20.     return NULL;
    21. }





    Код (Text):
    1. PHANDLE_TABLE_ENTRY
    2.     XpLookupHandleTableEntry(
    3.                IN PXP_HANDLE_TABLE HandleTable,
    4.                IN EXHANDLE         Handle
    5.                )
    6. {
    7.     ULONG i, j, k;
    8.     PHANDLE_TABLE_ENTRY Entry = NULL;
    9.     ULONG TableCode = HandleTable->TableCode & ~TABLE_LEVEL_MASK;
    10.  
    11.     i = (Handle.Index >> 17) & 0x1FF;
    12.     j = (Handle.Index >> 9)  & 0x1FF;
    13.     k = (Handle.Index)       & 0x1FF;
    14.  
    15.     switch (HandleTable->TableCode & TABLE_LEVEL_MASK)
    16.     {
    17.         case 0 :
    18.           Entry = &((PHANDLE_TABLE_ENTRY)TableCode)[k];
    19.         break;
    20.        
    21.         case 1 :
    22.           if (((PVOID *)TableCode)[j])
    23.           {
    24.              Entry = &((PHANDLE_TABLE_ENTRY *)TableCode)[j][k];        
    25.           }
    26.         break;
    27.         case 2 :
    28.            if (((PVOID *)TableCode)[i])
    29.            if (((PVOID **)TableCode)[i][j])
    30.            {
    31.               Entry = &((PHANDLE_TABLE_ENTRY **)TableCode)[i][j][k];
    32.            }
    33.         break;
    34.     }
    35.     return Entry;
    36. }




    Сами структуры таблицы хэндлов для Windows 2000 и XP:
    Код (Text):
    1. typedef struct _XP_HANDLE_TABLE
    2. {
    3.     ULONG                    TableCode;
    4.     PEPROCESS                QuotaProcess;
    5.     PVOID                    UniqueProcessId;
    6.     EX_PUSH_LOCK             HandleTableLock[4];
    7.     LIST_ENTRY               HandleTableList;
    8.     EX_PUSH_LOCK             HandleContentionEvent;
    9.     PHANDLE_TRACE_DEBUG_INFO DebugInfo;
    10.     LONG                     ExtraInfoPages;
    11.     ULONG                    FirstFree;
    12.     ULONG                    LastFree;
    13.     ULONG                    NextHandleNeedingPool;
    14.     LONG                     HandleCount;
    15.     LONG                     Flags;
    16.     UCHAR                    StrictFIFO;
    17. } XP_HANDLE_TABLE, *PXP_HANDLE_TABLE;



    Код (Text):
    1. typedef struct _WIN2K_HANDLE_TABLE
    2. {
    3.     ULONG                 Flags;
    4.     LONG                  HandleCount;
    5.     PHANDLE_TABLE_ENTRY **Table;
    6.     PEPROCESS             QuotaProcess;
    7.         HANDLE                UniqueProcessId;
    8.     LONG                  FirstFreeTableEntry;
    9.         LONG                  NextIndexNeedingPool;
    10.     ERESOURCE             HandleTableLock;
    11.     LIST_ENTRY            HandleTableList;
    12.     KEVENT                HandleContentionEvent;
    13. } WIN2K_HANDLE_TABLE , *PWIN2K_HANDLE_TABLE ;




    Структура элемента таблицы хэндлов:


    Код (Text):
    1. typedef struct _HANDLE_TABLE_ENTRY
    2. {
    3.     union
    4.     {
    5.     PVOID                    Object;
    6.         ULONG                    ObAttributes;
    7.     PHANDLE_TABLE_ENTRY_INFO InfoTable;
    8.     ULONG                    Value;
    9.     };
    10.  
    11.     union
    12.     {
    13.         union
    14.     {
    15.         ACCESS_MASK GrantedAccess;
    16.  
    17.             struct
    18.         {
    19.                 USHORT GrantedAccessIndex;
    20.                 USHORT CreatorBackTraceIndex;
    21.             };
    22.         };
    23.  
    24.         LONG NextFreeTableEntry;
    25.     };
    26.  
    27. } HANDLE_TABLE_ENTRY, *PHANDLE_TABLE_ENTRY;




    После нахождения элемента нужно поправить в нем поле GrantedAccess, которое определяет права доступа данного хэндла.

    Посмотреть примеры работы с таблицей хэндлов можно в исходниках моей программы Process Hunter, все нужные хедеры - на моем сайте.











    [​IMG] 1318100116__FCopy.rar
     
  3. z0mailbox

    z0mailbox z0

    Публикаций:
    0
    Регистрация:
    3 фев 2005
    Сообщения:
    635
    Адрес:
    Russia СПБ
    4) работать с файлом через собственный драйвер (на самом деле обычная юзер-моде прога) файловой системы. единственно нужны вроде админские права на открытие \\.\PhysicalDrive?



    я помнится показывал на бугтраке копирование sam-а с живой машины еще лет пять назад...
     
Статус темы:
Закрыта.