hvordan man får filnavnet sikkert og sammenligner det med Windows Minifilter-driver

Indlæg af Hanne Mølgaard Plasc

Problem



Hej jeg er ny på filterdriveren, så jeg undskylder mit grundlæggende spørgsmål. Jeg forsøger at få filnavnet fra en forudlæst funktion og kontrollere om den er lig med mit filnavn og lav en logik i henhold til denne info.


dette er min funktion:


 FLT\_PREOP\_CALLBACK\_STATUS SwapPreReadBuffers(    \_Inout\_ PFLT\_CALLBACK\_DATA Data,    \_In\_ PCFLT\_RELATED\_OBJECTS FltObjects,    \_Flt\_CompletionContext\_Outptr\_ PVOID *CompletionContext   )
{
    PFLT\_IO\_PARAMETER\_BLOCK iopb = Data->Iopb;
    FLT\_PREOP\_CALLBACK\_STATUS retValue = FLT\_PREOP\_SUCCESS\_NO\_CALLBACK;
    PVOID newBuf = NULL;
    PMDL newMdl = NULL;
    PVOLUME\_CONTEXT volCtx = NULL;
    PPRE\_2\_POST\_CONTEXT p2pCtx;
    NTSTATUS status;
    ULONG readLen = iopb->Parameters.Read.Length;
    PFLT\_FILE\_NAME\_INFORMATION NameInfo = NULL;
    UNICODE\_STRING FILE\_NAME;

 //
 //  Skip IRP\_PAGING\_IO, IRP\_SYNCHRONOUS\_PAGING\_IO and
 //  TopLevelIrp.
 //

    if ((Data->Iopb->IrpFlags & IRP\_PAGING\_IO) ||     (Data->Iopb->IrpFlags & IRP\_SYNCHRONOUS\_PAGING\_IO) ||      IoGetTopLevelIrp())
    {
         return FLT\_PREOP\_SUCCESS\_NO\_CALLBACK;
    }

    RtlInitUnicodeString( & FILE\_NAME, L"my\_file.txt" );

    status = FltGetFileNameInformation( Data,  FLT\_FILE\_NAME\_NORMALIZED | 
    FLT\_FILE\_NAME\_QUERY\_DEFAULT, &NameInfo );
    if (!NT\_SUCCESS( status )) 
    {
         DbgPrint("[-] SwapPreReadBuffers we couldn't extract \%wZ info
",  Data->Iopb->TargetFileObject->FileName);
    }


     status = FltParseFileNameInformation( NameInfo );
    if (!NT\_SUCCESS( status )) 
     {
        DbgPrint("[-] SwapPreReadBuffers we couldn't pars \%wZ info
",  Data->Iopb->TargetFileObject->FileName);            
     }


     DbgPrint("[+] pars gets me Name: \%wZ extention:  \%wZ  perentDir: \%wZ volume: \%wZ 
",  NameInfo->Name, NameInfo->Extension, NameInfo->ParentDir, NameInfo->Volume);


    if (RtlPrefixUnicodeString( &FILE\_NAME, &NameInfo->Name, TRUE ))        /* here i'm getting the blue screen*/
     {
         DbgPrint("[***] SwapPreReadBuffers we are at calles thats related to our file \%wZ 
",  Data->Iopb->TargetFileObject->FileName);                
     }
    /* continue of the code*/
 }


mit problem er, at jeg får en blå skærm, når jeg prøver at kontrollere, om filnavnet er lig med mit ønskede filnavn.
hvorfor føreren kommer her en blå skærm?


tak skal du have
grube


redigere:


jeg opdaterede min kode til dette:


 FLT\_PREOP\_CALLBACK\_STATUS SwapPreReadBuffers(    \_Inout\_ PFLT\_CALLBACK\_DATA Data,    \_In\_ PCFLT\_RELATED\_OBJECTS FltObjects,    \_Flt\_CompletionContext\_Outptr\_ PVOID *CompletionContext   )
{
    PFLT\_IO\_PARAMETER\_BLOCK iopb = Data->Iopb;
    FLT\_PREOP\_CALLBACK\_STATUS retValue = FLT\_PREOP\_SUCCESS\_NO\_CALLBACK;
    PVOID newBuf = NULL;
    PMDL newMdl = NULL;
    PVOLUME\_CONTEXT volCtx = NULL;
    NTSTATUS CbStatus = FLT\_PREOP\_SUCCESS\_NO\_CALLBACK;
    PPRE\_2\_POST\_CONTEXT p2pCtx;
    NTSTATUS status;
    ULONG readLen = iopb->Parameters.Read.Length;
    PFLT\_FILE\_NAME\_INFORMATION NameInfo = NULL;
    UNICODE\_STRING FILE\_NAME;

 //
 //  Skip IRP\_PAGING\_IO, IRP\_SYNCHRONOUS\_PAGING\_IO and
 //  TopLevelIrp.
 //

     if ((Data->Iopb->IrpFlags & IRP\_PAGING\_IO) ||
    (Data->Iopb->IrpFlags & IRP\_SYNCHRONOUS\_PAGING\_IO) ||
    IoGetTopLevelIrp()) {

    DbgPrint("[-] SwapPreReadBuffers we out , this call not for us
");
    return FLT\_PREOP\_SUCCESS\_NO\_CALLBACK;
}


status = FltGetFileNameInformation( Data,
                                    FLT\_FILE\_NAME\_NORMALIZED
                                      | FLT\_FILE\_NAME\_QUERY\_DEFAULT,
                                    &NameInfo );
if (!NT\_SUCCESS( status )) 
{
    DbgPrint("[-] SwapPreReadBuffers we couldn't extract info
");
     goto PreReadCleanup;
}

status = FltParseFileNameInformation( NameInfo );
if (!NT\_SUCCESS( status )) 
{
    DbgPrint("[-] SwapPreReadBuffers we couldn't pars info
");
     goto PreReadCleanup;
}


if (NULL == NameInfo)
{
    DbgPrint("[---] name info is actally 0
");
}
else
{
    DbgPrint("[*] address of name is \%x:\%x and address of extansion is \%x:\%x  -> buffers are: name \%x  , extension: \%x 
size of info \%d size of extension \%d
",NameInfo->Extension , &NameInfo->Extension, EXTENTION, &EXTENTION, NameInfo->Extension.Buffer , EXTENTION.Buffer ,NameInfo->Extension.Length , EXTENTION.Length);
}

if ((0 == RtlCompareUnicodeString( &EXTENTION, &NameInfo->Extension, TRUE ))) { 
    DbgPrint("[***] SwapPreReadBuffers we are at calles thats related to our file \%wZ 
",  &Data->Iopb->TargetFileObject->FileName);  
    DbgPrint("[+] pass parse
"); 
    DbgPrint("[+] pars gets me Name: \%wZ
 extention:  \%wZ
  perentDir: \%wZ
 volume: \%wZ
",  &NameInfo->Name, &NameInfo->Extension, &NameInfo->ParentDir, &NameInfo->Volume);
}
else{

    DbgPrint("[*] we pass compration check
");
      goto PreReadCleanup;
}
 //
 //  Clean up
 //
 PreReadCleanup:
    if (NameInfo) {

        FltReleaseFileNameInformation( NameInfo );
    }
    return retValue;
}


og igen fik jeg en blå skærm, dette er den analyserede kernedump:


    kd>  !analyze -v
    *******************************************************************************
    *                                                                             *
    *                        Bugcheck Analysis                                    *
    *                                                                             *
    *******************************************************************************

    PAGE\_FAULT\_IN\_NONPAGED\_AREA (50)
    Invalid system memory was referenced.  This cannot be protected by try-except,
    it must be protected by a Probe.  Typically the address is just plain bad or it
    is pointing at freed memory.
    Arguments:
    Arg1: 994af2a4, memory referenced.
    Arg2: 00000000, value 0 = read operation, 1 = write operation.
    Arg3: 82a72a17, If non-zero, the instruction address which referenced the bad memory
        address.
    Arg4: 00000000, (reserved)

    Debugging Details:
    ------------------


    READ\_ADDRESS: GetPointerFromAddress: unable to read from 829a5718
    Unable to read MiSystemVaType memory at 829851a0
     994af2a4 

    FAULTING\_IP: 
    nt!RtlCompareUnicodeStrings+3c
    82a72a17 0fb706          movzx   eax,word ptr [esi]

    MM\_INTERNAL\_CODE:  0

    CUSTOMER\_CRASH\_COUNT:  1

    DEFAULT\_BUCKET\_ID:  WIN7\_DRIVER\_FAULT

    BUGCHECK\_STR:  0x50

    PROCESS\_NAME:  cmd.exe

    CURRENT\_IRQL:  0

    TRAP\_FRAME:  a72b7974 -- (.trap 0xffffffffa72b7974)
    ErrCode = 00000000
    eax=00000003 ebx=994af2aa ecx=8da2064c edx=000000bf esi=994af2a4 edi=137f5b5e
    eip=82a72a17 esp=a72b79e8 ebp=a72b79f4 iopl=0         nv up ei pl nz ac po nc
    cs=0008  ss=0010  ds=0023  es=0023  fs=0030  gs=0000             efl=00010212
    nt!RtlCompareUnicodeStrings+0x3c:
    82a72a17 0fb706          movzx   eax,word ptr [esi]       ds:0023:994af2a4=????
    Resetting default scope

    LAST\_CONTROL\_TRANSFER:  from 8287c3d8 to 828c941b

    STACK\_TEXT:  
    a72b795c 8287c3d8 00000000 994af2a4 00000000 nt!MmAccessFault+0x106
    a72b795c 82a72a17 00000000 994af2a4 00000000 nt!KiTrap0E+0xdc
    a72b79f4 82a72b0f 994af2aa 00000003 acca4e02 nt!RtlCompareUnicodeStrings+0x3c
    a72b7a10 994a9105 994ad090 acca4d6c 00000001 nt!RtlCompareUnicodeString+0x25
    WARNING: Stack unwind information not available. Following frames may be wrong.
    a72b7a6c 8b756aeb 87587068 a72b7a8c a72b7ab8 MyDriver2+0x1105
    a72b7ad8 8b7599f0 a72b7b2c 87435e48 00000000 fltmgr!FltpPerformPreCallbacks+0x34d
    a72b7af0 8b759f01 a72b7b2c 00000000 862ff240 fltmgr!FltpPassThroughInternal+0x40
    a72b7b14 8b75a3ba 032b7b00 862ff240 00000000 fltmgr!FltpPassThrough+0x203
    a72b7b44 82872593 862ff240 87435e48 87435e48 fltmgr!FltpDispatch+0xb4
    a72b7b5c 82a6699f 87435e48 87435fd8 87590d98 nt!IofCallDriver+0x63
    a72b7b7c 82a9f2da 862ff240 87590d98 00000001 nt!IopSynchronousServiceTail+0x1f8
    a72b7c08 828791ea 862ff240 87435e48 00000000 nt!NtReadFile+0x644
    a72b7c08 773e70b4 862ff240 87435e48 00000000 nt!KiFastCallEntry+0x12a
    0013f014 00000000 00000000 00000000 00000000 0x773e70b4


    STACK\_COMMAND:  kb

    FOLLOWUP\_IP: 
    MyDriver2+1105
    994a9105 ??              ???

    SYMBOL\_STACK\_INDEX:  4

    SYMBOL\_NAME:  MyDriver2+1105

    FOLLOWUP\_NAME:  MachineOwner

    MODULE\_NAME: MyDriver2

    IMAGE\_NAME:  MyDriver2.sys

    DEBUG\_FLR\_IMAGE\_TIMESTAMP:  597b0358

    FAILURE\_BUCKET\_ID:  0x50\_MyDriver2+1105

    BUCKET\_ID:  0x50\_MyDriver2+1105

    Followup: MachineOwner
    ---------


så crush er indead i funktionen RtlCompareUnicodeString (eller i prefix version før), men jeg har ingen anelse om, hvorfor det er knust der, det ser ud som om jeg gjorde alt sammen med os.

Bedste reference


din fejl ikke i opkald RtlPrefixUnicodeString( &FILE\_NAME, &NameInfo->Name, TRUE )) - her er alt okay. din fejl i tidligere linje:


DbgPrint("[+] pars gets me Name: \%wZ extention:  \%wZ  perentDir: \%wZ volume: \%wZ 
",  
NameInfo->Name, 
NameInfo->Extension, 
NameInfo->ParentDir, 
NameInfo->Volume);


\%wZ formatet kræver peger til UNICODE\_STRING - så skal det være


DbgPrint("[+] pars gets me Name: \%wZ extention:  \%wZ  perentDir: \%wZ volume: \%wZ 
",  
&NameInfo->Name, 
&NameInfo->Extension, 
&NameInfo->ParentDir, 
&NameInfo->Volume);


også hvis FltGetFileNameInformation fejler - du må ikke bruge NameInfo efter det (det vil være 0 eller undefined). men det gør du ikke i kode


og normalt bytte buffere skal gøre, når og kun når Data->Iopb->IrpFlags & IRP\_NOCACHE - så når data læser eller skrives til lager

Andre referencer 1


Der er mange fejl her.



  1. Først og fremmest udskriver ikke ting, der kunne være NULL, kontroller dem først.
    Gå gennem strukturen FLT\_FILE\_NAME\_INFORMATION og sørg for, at alle de data, du vil udskrive, faktisk er der.

  2. Løs dine symboler i debuggeren. Sørg for, at din debugger har symbolsti indstillet til den mappe, hvor din .pdb er.

  3. Underskriv navnet i PreRead. Der er flere grunde til ikke at gøre dette, men jeg vil fortælle dig, hvad du skal gøre:


    1. I indlæg IRP\_MJ\_CREATE spørg navnet på den fil, der er åbnet. Kontroller, om det er den fil, du er interesseret i. Hvis nej, skal du bare returnere flt efterbehandling færdigbehandling ellers, hvis det er en fil, du er interesseret i at oprette en kontekst til det og gemme filenNameInformation der også, mens du er på den.



    1. Nu i PreRead, når du bliver kaldt, skal du blot bede om konteksten for filobjektet. Hvis en er til stede, betyder det, at det er en fil, du er interesseret i, så så foretager du din behandling, ellers kan du bare springe læsningen.


  4. Vær opmærksom på strengbehandlingsrutiner og IRQL. Brug ikke statiske stakstrenge til sammenligning som L 'my\_file.txt'



Du kan også vise, hvordan din variabel EXTENSION er initialiseret.