Проблема с NtQueryDirectoryFile

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

  1. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32
    Пишу программу по Ms-Rem'ой статье про Ring-0.Возникла проблема с функцией NtQueryDirectoryFile.Ставлю на неё перехват при малом количестве файлов,отображаемых Explorer'ом всё OK, но стоит зайти в папку где много файлов комп уходит в reboot.Вот код функции перехвата:



    NTSTATUS NewNtQueryDirectoryFile (

    IN HANDLE FileHandle,

    IN HANDLE Event OPTIONAL,

    IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,

    IN PVOID ApcContext OPTIONAL,

    OUT PIO_STATUS_BLOCK IoStatusBlock,

    OUT PVOID FileInformation,

    IN ULONG FileInformationLength,

    IN FILE_INFORMATION_CLASS FileInformationClass,

    IN BOOLEAN ReturnSingleEntry,

    IN PUNICODE_STRING FileName OPTIONAL,

    IN BOOLEAN RestartScan)

    {

    ULONG NextOff=0;

    KIRQL irql = KeGetCurrentIrql();

    LPSTR fileInf=FileInformation;

    Result=TrueNtQueryDirectoryFile(FileHandle,Event,ApcRoutine,ApcContex t,IoStatusBlock,FileInformation,FileInformationLength,FileInformationC lass,ReturnSingleEntry,FileName,RestartScan);

    KeAcquireSpinLock(&MySpinLock,&irql);





    switch(FileInformationClass)

    {

    case 0x0003:

    while((((PFILE_BOTH_DIRECTORY_INFORMATION)fileInf)->NextEntryOffset)!= 0)

    {

    NextOff=((PFILE_BOTH_DIRECTORY_INFORMATION)fileInf)->NextEntryOffset;

    fileInf+=((PFILE_BOTH_DIRECTORY_INFORMATION)fileInf)->NextEntryOffset;





    }



    break;

    default:

    break;

    }

    KeReleaseSpinLock(&MySpinLock,irql);

    return Result;



    }



    Если закомментировать while то всё OK.Спасибо.
     
  2. _staier

    _staier New Member

    Публикаций:
    0
    Регистрация:
    3 окт 2003
    Сообщения:
    738
    Адрес:
    Ukraine
    обьяви

    PFILE_BOTH_DIRECTORY_INFORMATION fileInf,NextOff;



    вместо LPSTR

    может тогда легче станет :derisive:
    Код (Text):
    1.  
    2.  
    3. PFILE_BOTH_DIRECTORY_INFORMATION fileInf;
    4.  
    5. while(!fileInf->NextEntryOffset)
    6. {
    7.  
    8.   ((char*)fileInf)+=fileInf->NextEntryOffset;
    9.  
    10. }
    11.  




    и смотри в отладчике , что там и как :derisive:
     
  3. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32
    ""и смотри в отладчике , что там и как :derisive:""



    Можно ли SoftIce'ом приаттачится к драйверу.Если это так то plz черканите пару строк как это можно сделать.



    "обьяви

    PFILE_BOTH_DIRECTORY_INFORMATION fileInf,NextOff; "





    Могу ошибаться,но как мне кажется,в твоём случае придётся инициализировать два объекта,размером со структуру PFILE_BOTH_DIRECTORY_INFORMATION,которые займут 2xsizeof(PFILE_BOTH_DIRECTORY_INFORMATION)в памяти.В моём же случае 2xsizeof(ULONG),что меньше.
     
  4. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290




    Почему мы всё равно в конце концов работаем с указателями...



    А если делать парсинг не только FileBothDirectoryInformation, а ещё FileDirectoryInformation, FileFullDirectoryInformation, FileNamesInformation ?? В таком случае 2 двордами можно спокойно обойтись. Хотя для лучшей читабельности кода можна и все структуры обьявить.







    sizeof(PFILE_BOTH_DIRECTORY_INFORMATION) == sizeof(ULONG)
     
  5. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32




    Да, ну и сморозил же я,только сейчас дошло.



    Но можно сохранить дворд если не объявлять fileInf,а сделать так:

    FileInformation+=((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)-> NextEntryOffset;
     
  6. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Удивительно как этот код вообще где-то работает. В нем нет ни проверок на успешность вызова NtQueryDirectoryFile ни обработки других классов информации ни даже корректной обработки всех ситуаций возникающих при скрытии.

    Держи пример обработчика который скрывает все файлы имена которых начинаются с "_"


    Код (Text):
    1. NTSTATUS
    2.   NewZwQueryDirectoryFile(
    3.         IN HANDLE FileHandle,
    4.         IN HANDLE Event OPTIONAL,
    5.         IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
    6.         IN PVOID ApcContext OPTIONAL,
    7.         OUT PIO_STATUS_BLOCK IoStatusBlock,
    8.         OUT PVOID FileInformation,
    9.         IN ULONG FileInformationLength,
    10.         IN FILE_INFORMATION_CLASS FileInformationClass,
    11.         IN BOOLEAN ReturnSingleEntry,
    12.         IN PUNICODE_STRING FileName OPTIONAL,
    13.         IN BOOLEAN RestartScan)
    14. {
    15.     NTSTATUS status = TrueZwQueryDirectoryFile(FileHandle,
    16.                                                Event,
    17.                                                ApcRoutine,
    18.                                                ApcContext,
    19.                                                IoStatusBlock,
    20.                                                FileInformation,
    21.                                                FileInformationLength,
    22.                                                FileInformationClass,
    23.                                                ReturnSingleEntry,
    24.                                                FileName,
    25.                                                RestartScan);
    26.  
    27.     if (NT_SUCCESS(status))
    28.     {
    29.         PFILE_FULL_DIRECTORY_INFORMATION FileDirectoryInfo, LastFileDirectoryInfo;
    30.         PFILE_FULL_DIRECTORY_INFORMATION LastFileFullDirectoryInfo, FileFullDirectoryInfo;
    31.         PFILE_BOTH_DIRECTORY_INFORMATION LastFileBothDirectoryInfo, FileBothDirectoryInfo;
    32.         PFILE_NAMES_INFORMATION          LastFileNamesInfo, FileNamesInfo;
    33.  
    34.         ULONG Offset = 0;
    35.  
    36.         switch (FileInformationClass)
    37.         {
    38.             case FileDirectoryInformation :
    39.                 FileDirectoryInfo = NULL;
    40.                 do
    41.                 {
    42.                     FileDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
    43.                     LastFileDirectoryInfo = FileDirectoryInfo;
    44.  
    45.                     if (FileDirectoryInfo->FileName[0] == 0x5F00)
    46.                     {
    47.                         if (!FileDirectoryInfo->NextEntryOffset)
    48.                         {
    49.                             if (LastFileDirectoryInfo) LastFileDirectoryInfo->NextEntryOffset = 0;
    50.                             else status = STATUS_NO_SUCH_FILE;
    51.                             return status;
    52.                         } else
    53.                         if (LastFileDirectoryInfo) LastFileDirectoryInfo->NextEntryOffset += FileDirectoryInfo->NextEntryOffset;                       
    54.                     }
    55.  
    56.                     Offset += FileDirectoryInfo->NextEntryOffset;
    57.  
    58.                 } while (FileDirectoryInfo->NextEntryOffset);
    59.  
    60.             break;
    61.  
    62.             case FileFullDirectoryInformation :
    63.                 FileFullDirectoryInfo = NULL;
    64.                 do
    65.                 {
    66.                     LastFileFullDirectoryInfo = FileFullDirectoryInfo;
    67.                     FileFullDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
    68.  
    69.                     if (FileFullDirectoryInfo->FileName[0] == 0x5F00)
    70.                     {
    71.                         if (!FileFullDirectoryInfo->NextEntryOffset)
    72.                         {
    73.                             if (LastFileFullDirectoryInfo) LastFileFullDirectoryInfo->NextEntryOffset = 0;
    74.                             else status = STATUS_NO_SUCH_FILE;
    75.                             return status;
    76.                         } else
    77.                         if (LastFileFullDirectoryInfo) LastFileFullDirectoryInfo->NextEntryOffset += FileFullDirectoryInfo->NextEntryOffset;
    78.                     }
    79.  
    80.                     Offset += FileFullDirectoryInfo->NextEntryOffset;
    81.  
    82.                 } while (FileFullDirectoryInfo->NextEntryOffset);
    83.             break;
    84.  
    85.             case FileBothDirectoryInformation :
    86.                 FileBothDirectoryInfo = NULL;
    87.                 do
    88.                 {
    89.                     LastFileBothDirectoryInfo = FileBothDirectoryInfo;
    90.                     FileBothDirectoryInfo = (PVOID)((ULONG)FileInformation + Offset);
    91.                     if (FileBothDirectoryInfo->FileNameLength > 1 && FileBothDirectoryInfo->FileName[0] == 0x5F00)
    92.                     {
    93.                         if (!FileBothDirectoryInfo->NextEntryOffset)
    94.                         {
    95.                             if (LastFileBothDirectoryInfo) LastFileBothDirectoryInfo->NextEntryOffset = 0;
    96.                             else status = STATUS_NO_SUCH_FILE;
    97.                             return status;
    98.                         } else
    99.                         if (LastFileBothDirectoryInfo) LastFileBothDirectoryInfo->NextEntryOffset += FileBothDirectoryInfo->NextEntryOffset;
    100.                     }
    101.  
    102.                     Offset += FileBothDirectoryInfo->NextEntryOffset;
    103.  
    104.                 } while (FileBothDirectoryInfo->NextEntryOffset);
    105.             break;
    106.  
    107.             case FileNamesInformation :
    108.                 FileNamesInfo = NULL;
    109.                 do
    110.                 {
    111.                     LastFileNamesInfo = FileNamesInfo;
    112.                     FileNamesInfo = (PVOID)((ULONG)FileInformation + Offset);
    113.                     if (FileNamesInfo->FileName[0] == 0x5F00)
    114.                     {
    115.                         if (!FileNamesInfo->NextEntryOffset)
    116.                         {
    117.                             if(LastFileNamesInfo) LastFileNamesInfo->NextEntryOffset = 0;
    118.                             else status = STATUS_NO_SUCH_FILE;
    119.                             return status;
    120.                         } else
    121.                         if (LastFileNamesInfo) LastFileNamesInfo->NextEntryOffset += FileNamesInfo->NextEntryOffset;
    122.                     }
    123.  
    124.                     Offset += FileNamesInfo->NextEntryOffset;
    125.                 } while (FileNamesInfo->NextEntryOffset);
    126.             break;
    127.         }
    128.     }
    129.  
    130.     return status;
    131. }
     
  7. Ms Rem

    Ms Rem New Member

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

    Синхронизация тут не нужна, так как никто другой не будет обращаться к модифицируемой информации.
     
  8. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32
    Спасибо всем,особенно Ms-Rem'у.
     
  9. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290
    можна и так


    Код (Text):
    1. ULONG Offset = 0;
    2. ULONG PrevItem;
    3.  
    4. while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0)
    5. {
    6. Offset = (ULONG)FileInformation;
    7. (ULONG)FileInformation = Offset + ((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOffset;
    8. }
     
  10. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290
    Не успел =)
     
  11. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32




    Предпологал,что другой код обращается в NewZwQueryDirectoryFile и что-то меняет в ней.Ещё раз спасибо.
     
  12. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290


    Наверное должно быть так ?)

    Offset += FileDirectoryInfo->NextEntryOffset;



    А то сейчас скажет что там еррор =)
     
  13. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32




    Да, но зачем нам Offset:

    //ULONG Offset = 0;

    ULONG PrevItem;



    while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0)

    {

    //Offset = (ULONG)FileInformation;

    (ULONG)FileInformation +=((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOffset ;

    }
     
  14. Ms Rem

    Ms Rem New Member

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


    Если о обращается, то меняет другую копию информации, а не ту что ты редактируешь.
     
  15. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290




    Возврат на предыдущую ячейку.
     
  16. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32


    Тогда так(экономим один дворд :)):



    //ULONG Offset = 0;

    ULONG PrevItem;



    while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0)

    {

    //Offset = (ULONG)FileInformation;

    PrevItem=((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntr yOffset;

    (ULONG)FileInformation +=((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOffset ;

    }
     
  17. electron

    electron New Member

    Публикаций:
    0
    Регистрация:
    26 май 2005
    Сообщения:
    32


    да тоже самое только с PrevItem.Опять сморозил.
     
  18. Ms Rem

    Ms Rem New Member

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

    Раньше я тоже писал подобным стилем, но сейчас взглянул на свои исходники годовой давности и понял что нифига в них не понимаю. Вот теперь стараюсь читабельный код писать.
     
  19. MegaZu

    MegaZu New Member

    Публикаций:
    0
    Регистрация:
    22 июл 2005
    Сообщения:
    290
    Да ну ладно ... , ты хочеш сэкономить 4 байта, тогда когда хотел юзать спинлоки и потерять время =)
     
  20. Ms Rem

    Ms Rem New Member

    Публикаций:
    0
    Регистрация:
    17 апр 2005
    Сообщения:
    1.057
    Адрес:
    С планеты "Земля"
    Кстати, варианты с while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0) неправильны.

    Так как может быть ситуация, когда в папке только один файл который и нужно скрывать, в этом случае его NextEntryOffset == 0 и он не будет скрыт.