c ++ - Mini-filter modtager konstant værdi fra brugertilstandsapplikation

Indlæg af Hanne Mølgaard Plasc

Problem



Jeg har et problem, hvor jeg sender en besked til bruger-tilstand fra kernel-tilstand ved hjælp af FltSendMessage, der forventer et svar. Den struktur, der bestås, indeholder et int, der er indstillet til enten 0 eller 1. Brugermodus svar ved at indstille dette flag og kalder FilterReplyMessage.Men når meddelelsen er modtaget af kernen, er dens værdi altid 56. Uanset hvilket nummer jeg satte flagget til i brugertilstand, modtager kernen altid værdien 56. Jeg er forvirret med hvor min fejl er.


Jeg har forsøgt at ændre datatypen af ​​passFlag fra int til andre typer (USHORT osv.), Som jeg vidste ville nok ikke gøre en forskel, men det var værd at prøve.


Fordi kernebeskeden er besvaret med succes (Kontrollerer brugerfunktionen HRESULT returnerer ingen fejl og der er ingen timeout, så hvis der ikke modtages noget, vil systemet hænge, ​​hvilket det ikke gør), jeg ved, at fejlen skal være, når bufferne bliver bestået mellem bruger-tilstand og kernel-tilstand. Jeg kan ikke synes at finde årsagen til, at passFlag ikke tolkes korrekt i kernel-mode.


Kan nogen hjælpe?


Fælles struktur:


typedef struct \_REPLY\_MESSAGE\_STRUCT {

    // Message header.
    FILTER\_REPLY\_HEADER header;

        // Flag to be set 
        // by user mode.
        int passFlag;

}REPLY\_MESSAGE\_STRUCT, *PREPLY\_MESSAGE\_STRUCT; 


Kernekode:


DbgPrint("Sending Message...
");

    replyBuffer.passFlag = 0;
    ULONG replySize = ((ULONG)sizeof(replyBuffer.header)) + ((ULONG)sizeof(replyBuffer));
    REPLY\_MESSAGE\_STRUCT replyBuffer;

    // Note: Try-catch statement has been omitted in this question to save time.
    // In the actual code there is a try-catch statement surrounding FltSendMessage.
    status = FltSendMessage(imageFilterData.filterHandle,
                    &imageFilterData.clientPort,
                    (PVOID)&sendingBuffer.messageBuffer,
                    sizeof(sendingBuffer.messageBuffer),
                    (PVOID)&replyBuffer,
                    &replySize,
                    0
                    );
    // Always returns 56
    // When a reply has been received.
    DbgPrint("Message received: \%i
", replyBuffer.passFlag);


Brugerkode:


// User-mode buffer is the same size as kernel-mode buffer.
ULONG replySize = ((ULONG)sizeof(replyBuffer.header)) + ((ULONG)sizeof(replyBuffer));
replyMessage.header.MessageId = messageFromKernel.header.MessageId;
REPLY\_MESSAGE\_STRUCT replyMessage;

// User-mode setting flag.
replyMessage.passFlag = 1;

// Flag is changed to 1 successfully.
printf("Test: \%i
", replyMessage.passFlag);

// Reply is sent successfully, but flag value on kernel end is always 56
hResult = FilterReplyMessage(port,
    &replyMessage.header,
    replySize);

\_com\_error err2(hResult);

errorMessage = err2.ErrorMessage();

// No errors.
printf("Result: \%s
", errorMessage);


Hvad jeg har prøvet:



  • Ændring af datatypen af ​​passFlag.

  • Gå gennem hvert trin før og efter FltSendMessage og FilterReply besked for at finde ud af om værdien ændres, før den sendes tilbage til kernen.


Bedste reference


du bruger fejldata i opkald FltSendMessage: [12]


ReplyBuffer er peger på brugerdefinerede brugerdefinerede data. det må ikke begynde fra FILTER\_REPLY\_HEADER
SenderBuffer er peger på brugerdefinerede brugerdefinerede data. det må ikke begynde fra FILTER\_MESSAGE\_HEADER


Først og fremmest behøver du definere strukturer , der deles mellem kerne- og brugertilstand, til besked og svar. for eksempel [13]


struct SCANNER\_NOTIFICATION {
    // any custom data
    int someData;

};

struct SCANNER\_REPLY {
    // any custom data
    int passFlag;
};


og i kernel mode du direkte bruge det som er:


SCANNER\_NOTIFICATION send;
SCANNER\_REPLY reply;
ULONG ReplyLength = sizeof(reply);

FltSendMessage(*, *, &send, sizeof(send), &reply, &ReplyLength, *);


i brugermodus du skal definere 2 yderligere strukturer: [14]


struct SCANNER\_MESSAGE : public FILTER\_MESSAGE\_HEADER, public SCANNER\_NOTIFICATION {};

struct SCANNER\_REPLY\_MESSAGE : public FILTER\_REPLY\_HEADER, public SCANNER\_REPLY {};


(jeg bruger c ++ stil her, når her bruges c stil)
og i brugermodus skal vi bruge næste, for eksempel: [15]


SCANNER\_MESSAGE* mesage;
FilterGetMessage(*, mesage, sizeof(SCANNER\_MESSAGE), *);


og


    SCANNER\_REPLY\_MESSAGE reply;
    reply.MessageId = mesage->MessageId;
    FilterReplyMessage(*, &reply, sizeof(reply));