problem on decryption in ReadCompleteRoutine

I know this is an old topic here, but i still have some questions about it.
In IRP_MJ_READ dispatch routine,when (Irp->Flags & IRP_NOCACHE) and
Irp->MdlAddress is
not null, I set the complete routine.

In complete routine,my code is as below:

NTSTATUS
ReadCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{

ULONG ReadLength = Irp->IoStatus.Information;
PVOID pbuf;
PVOID pVirtual;
PMDL OriginalMDL;

DbgPrint((“Entering Read Complete Routine. the length is %d .\n”,
ReadLength));

pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);

pVirtual = ExAllocatePool( NonPagedPool, ReadLength);
RtlCopyMemory(pVirtual, pbuf, ReadLength);

// Decrypt ,just add the ASCII value by one simply
DecryptData(pVirtual, ReadLength);

OriginalMDL = Irp->MdlAddress;
Irp->MdlAddress = NULL;

//build new MDL
IoAllocateMdl( pVirtual, ReadLength, FALSE, TRUE, Irp);
MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, IoWriteAccess);

if( Irp->PendingReturned )
{

IoMarkIrpPending( Irp );

}

return Irp->IoStatus.Status;

}

The content in pVirtual is decrypted correctly, but what I read is still
the
original text.
How can I do it?

You put the decrypted data in a new buffer that is different from the
original one that is provided by application. Why would you expect
application to see the data in the new buffer? The original buffer that was
passed to IRP_MJ_READ must contain decrypted data after the processing of
the IRP is completed.

Alexei.

“kerlang” wrote in message
news:xxxxx@ntfsd…
> I know this is an old topic here, but i still have some questions about
it.
> In IRP_MJ_READ dispatch routine,when (Irp->Flags & IRP_NOCACHE) and
> Irp->MdlAddress is
> not null, I set the complete routine.
>
> In complete routine,my code is as below:
>
> NTSTATUS
> ReadCompleteRoutine(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID Context
> )
> {
>
> ULONG ReadLength = Irp->IoStatus.Information;
> PVOID pbuf;
> PVOID pVirtual;
> PMDL OriginalMDL;
>
> DbgPrint((“Entering Read Complete Routine. the length is %d .\n”,
> ReadLength));
>
> pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
>
>
> pVirtual = ExAllocatePool( NonPagedPool, ReadLength);
> RtlCopyMemory(pVirtual, pbuf, ReadLength);
>
>
> // Decrypt ,just add the ASCII value by one simply
> DecryptData(pVirtual, ReadLength);
>
>
> OriginalMDL = Irp->MdlAddress;
> Irp->MdlAddress = NULL;
>
>
> //build new MDL
> IoAllocateMdl( pVirtual, ReadLength, FALSE, TRUE, Irp);
> MmProbeAndLockPages(Irp->MdlAddress, Irp->RequestorMode, IoWriteAccess);
>
>
>
>
> if( Irp->PendingReturned )
> {
>
> IoMarkIrpPending( Irp );
>
> }
>
>
> return Irp->IoStatus.Status;
>
>
> }
>
> The content in pVirtual is decrypted correctly, but what I read is still
> the
> original text.
> How can I do it?
>
>
>
>

You mean I should copy the decrypted data to overwrite the original ones?
but when I read the former articles here , everybody said that it’s unsafe
to decrypt the original data.
if i changed my code as below, a bsod got.How can I decrypt the original
data safely?

NTSTATUS
ReadCompleteRoutine(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
ULONG ReadLength;
PCHAR pbuf;

ReadLength = Irp->IoStatus.Information;

if ( Irp->MdlAddress )
{
pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
DecryptData(pbuf, ReadLength);
}

if( Irp->PendingReturned )
{

IoMarkIrpPending( Irp );

}

return Irp->IoStatus.Status;

}

“Alexei Jelvis” дÈëÓʼþ news:xxxxx@ntfsd…
> You put the decrypted data in a new buffer that is different from the
> original one that is provided by application. Why would you expect
> application to see the data in the new buffer? The original buffer that
was
> passed to IRP_MJ_READ must contain decrypted data after the processing of
> the IRP is completed.
>
> Alexei.
>
>
>
>

I don’t know what article your refer to but I believe it discusses
encrypting data when writing but not decrypting when reading. When you are
writing encrypted data you need to switch the buffer. It is not safe to
change data being written because caller doesn’t expect this.
When you are reading the caller expects data to be changed in the buffer so
it is safe to update the data. After the IRP_MJ_READ is processed the
original buffer must contain the data you are going to expose to
application.
I don’t have enough information to tell you why you may get a blue screen. I
can see only one thing that you are doing wrong - you return
Irp->IoStatus.Status from the completion routine. Only two values are
allowed to be returned from a completion routine - STATUS_SUCCESS or
STATUS_MORE_PROCESSING_REQUIRED. In your case when you don’t want to
interrupt completion of the IRP you need to return STATUS_SUCCESS.

Alexei.

“Kathe Zhou” wrote in message
news:xxxxx@ntfsd…
> You mean I should copy the decrypted data to overwrite the original ones?
> but when I read the former articles here , everybody said that it’s unsafe
> to decrypt the original data.
> if i changed my code as below, a bsod got.How can I decrypt the original
> data safely?
>
> NTSTATUS
> ReadCompleteRoutine(
> IN PDEVICE_OBJECT DeviceObject,
> IN PIRP Irp,
> IN PVOID Context
> )
> {
> ULONG ReadLength;
> PCHAR pbuf;
>
> ReadLength = Irp->IoStatus.Information;
>
> if ( Irp->MdlAddress )
> {
> pbuf = MmGetSystemAddressForMdlSafe(Irp->MdlAddress, NormalPagePriority);
> DecryptData(pbuf, ReadLength);
> }
>
> if( Irp->PendingReturned )
> {
>
> IoMarkIrpPending( Irp );
>
> }
>
>
> return Irp->IoStatus.Status;
>
> }
>
>
>
>
>
> “Alexei Jelvis” дÈëÓʼþ news:xxxxx@ntfsd…
> > You put the decrypted data in a new buffer that is different from the
> > original one that is provided by application. Why would you expect
> > application to see the data in the new buffer? The original buffer that
> was
> > passed to IRP_MJ_READ must contain decrypted data after the processing
of
> > the IRP is completed.
> >
> > Alexei.
> >
> >
> >
> >
>
>
>