Проблема с NtQueryDirectoryFile

Discussion in 'WASM.WIN32' started by electron, Sep 6, 2005.

  1. electron

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    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

    Blog Posts:
    0
    Joined:
    Oct 3, 2003
    Messages:
    738
    Location:
    Ukraine
    обьяви

    PFILE_BOTH_DIRECTORY_INFORMATION fileInf,NextOff;



    вместо LPSTR

    может тогда легче станет :derisive:
    Code (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

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    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

    Blog Posts:
    0
    Joined:
    Jul 22, 2005
    Messages:
    290




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



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







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

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    32




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



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

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

    Ms Rem New Member

    Blog Posts:
    0
    Joined:
    Apr 17, 2005
    Messages:
    1,057
    Location:
    С планеты "Земля"
    Удивительно как этот код вообще где-то работает. В нем нет ни проверок на успешность вызова NtQueryDirectoryFile ни обработки других классов информации ни даже корректной обработки всех ситуаций возникающих при скрытии.

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


    Code (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

    Blog Posts:
    0
    Joined:
    Apr 17, 2005
    Messages:
    1,057
    Location:
    С планеты "Земля"
    И кстати, зачем ты в своем коде использовал спинлоки? От них в данном случае все только тормозить будет.

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

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    32
    Спасибо всем,особенно Ms-Rem'у.
     
  9. MegaZu

    MegaZu New Member

    Blog Posts:
    0
    Joined:
    Jul 22, 2005
    Messages:
    290
    можна и так


    Code (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

    Blog Posts:
    0
    Joined:
    Jul 22, 2005
    Messages:
    290
    Не успел =)
     
  11. electron

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    32




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

    MegaZu New Member

    Blog Posts:
    0
    Joined:
    Jul 22, 2005
    Messages:
    290


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

    Offset += FileDirectoryInfo->NextEntryOffset;



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

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    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

    Blog Posts:
    0
    Joined:
    Apr 17, 2005
    Messages:
    1,057
    Location:
    С планеты "Земля"


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

    MegaZu New Member

    Blog Posts:
    0
    Joined:
    Jul 22, 2005
    Messages:
    290




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

    electron New Member

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    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

    Blog Posts:
    0
    Joined:
    May 26, 2005
    Messages:
    32


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

    Ms Rem New Member

    Blog Posts:
    0
    Joined:
    Apr 17, 2005
    Messages:
    1,057
    Location:
    С планеты "Земля"
    От уменьшения размеров переменных в стеке ничего лучше не станет, а вот читабельность кода весьма важный фактор.

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

    MegaZu New Member

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

    Ms Rem New Member

    Blog Posts:
    0
    Joined:
    Apr 17, 2005
    Messages:
    1,057
    Location:
    С планеты "Земля"
    Кстати, варианты с while(((PFILE_BOTH_DIRECTORY_INFORMATION)FileInformation)->NextEntryOf fset != 0) неправильны.

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