[NTOSKRNL:CC] Pin Support Protocols :: added functions

Completed Implementation for::
*CcPreparePinWrite
*CcMapData
*CcAllocateObcb
Reconstructed/Guessed OBCB Structure
This commit is contained in:
Dibyamartanda Samanta 2024-08-01 15:23:57 +02:00 committed by CodingWorkshop Signing Team
parent dac01f6510
commit a40c3d4200
Signed by: CodingWorkshop Signing Team
GPG Key ID: 6DC88369C82795D2

View File

@ -14,8 +14,52 @@
extern "C"
/* Move Typedef later to cctypes in sdk */
/* NOTE: This structure have reconstructed analyzing CcAllocateObcb, might be icomplete to one in Windows NT Kernel*/
/* We just need API Compatibility, so it doesn't matter */
typedef struct _OBCB
{
short NodeTypeCode;
short NodeByteSize;
ULONG ByteLength;
LARGE_INTEGER FileOffset;
struct PCC_BCB Bcbs[1];
long __PADDING__[1];
} OBCB, *POBCB;
/*Internal Function*/
POBCB
NTAPI
CcAllocateObcb(
_In_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length,
_In_ PCC_BCB Bcb)
{
/*Calculate the size needed for the OBCB*/
SIZE_T AllocationSize = sizeof(OBCB) + ((Length + PAGE_SIZE - 1 + FileOffset->LowPart - *reinterpret_cast<ULONG*>(reinterpret_cast<ULONG_PTR>(FirstBcb) & ~1UL) - *reinterpret_cast<ULONG*>((reinterpret_cast<ULONG_PTR>(FirstBcb) & ~1UL) + sizeof(ULONG))) >> PAGE_SHIFT) * sizeof(PVOID);
/*Allocate memory for the OBCB*/
POBCB NewObcb = reinterpret_cast<POBCB>(ExAllocatePoolWithTag(NonPagedPool,AllocationSize,'cObC'));
if (NewObcb == nullptr)
{
return nullptr;
}
/* Initialize the OBCB */
RtlZeroMemory(NewObcb, AllocationSize);
NewObcb->NodeByteSize = static_cast<USHORT>(AllocationSize);
NewObcb->NodeTypeCode = 762;
NewObcb->ByteLength = Length;
NewObcb->FileOffset = *FileOffset;
NewObcb->Bcbs[0] = Bcb;
return NewObcb;
}
BOOLEAN
NTAPI
@ -183,48 +227,44 @@ CcUnpinFileDataEx(
}
BOOLEAN
VECTORCALL
CcPinFileData(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN IsReadOnly,
IN BOOLEAN IsWriteOnly,
IN ULONG Flags,
OUT PCC_BCB *Bcb,
OUT PVOID *BaseAddress,
OUT PLARGE_INTEGER BeyondLastByte)
{
// Unimplemented
}
BOOLEAN
NTAPI
CcMapData(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
OUT PVOID *Bcb,
OUT PVOID *Buffer)
_In_ In PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length,
_In_ ULONG Flags,
_Out_ PVOID *Bcb,
_Out_ PVOID *Buffer)
{
//Unimplemented
PVOID LocalBuffer = nullptr;
/* Call CcMapDataCommon to perform the actual mapping */
if (!CcMapDataCommon(FileObject,FileOffset,Length,Flags,Bcb,&LocalBuffer))
{
return false;
}
/* Check if we need to read the data */
if (!(Flags & MAP_NO_READ))
{
/* Read the data */
if (!CcMapAndRead(Length, 0, true, LocalBuffer))
{
return false;
}
}
/* Set Bcb to point after the LocalBuffer */
*Bcb = reinterpret_cast<PVOID>(reinterpret_cast<ULONG_PTR>(LocalBuffer) + sizeof(PVOID));
/* Set the output Buffer */
*Buffer = LocalBuffer;
return true;
}
BOOLEAN
FASTCALL
CcMapDataCommon(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN ULONG Flags,
OUT PVOID *Bcb,
OUT PVOID *Buffer)
{
//Unimplemented
}
BOOLEAN
NTAPI
@ -254,15 +294,74 @@ CcPinRead(
BOOLEAN
NTAPI
CcPreparePinWrite(
IN PFILE_OBJECT FileObject,
IN PLARGE_INTEGER FileOffset,
IN ULONG Length,
IN BOOLEAN Zero,
IN ULONG Flags,
OUT PVOID *Bcb,
OUT PVOID *Buffer)
_In_ PFILE_OBJECT FileObject,
_In_ PLARGE_INTEGER FileOffset,
_In_ ULONG Length,
_In_ BOOLEAN Zero,
_In_ ULONG Flags,
_Out_ PVOID *Bcb,
_Out_ PVOID *Buffer)
{
//Unimplemented
LARGE_INTEGER LocalFileOffset = *FileOffset;
LARGE_INTEGER BeyondLastByte ={0};
ULONG RemainingLength = Length;
POBCB localbcb = nullptr;
PCC_BCB *localbcbPtr = nullptr;
PVOID LocalBuffer = nullptr;
BOOLEAN Result = false;
if (Flags & PIN_WAIT)
{
return CcMapDataForOverwrite(FileObject, FileOffset, Length, Bcb, Buffer);
}
/*Pinning Loop*/
while(true)
{
if (localbcb)
{
if (localbcbPtr == reinterpret_cast<PCC_BCB>(&localbcb))
{
localbcb = CcAllocateObcb(&LocalFileOffset, RemainingLength, localbcb);
localbcbPtr = localbcb->Bcbs;
*Buffer = LocalBuffer;
}
RemainingLength += LocalFileOffset.QuadPart - BeyondLastByte.QuadPart;
LocalFileOffset.QuadPart = BeyondLastByte.QuadPart;
localbcbPtr++;
}
if (!CcPinFileData(FileObject, &LocalFileOffset,RemainingLength,false,false,Flags,localbcbPtr,&LocalBuffer, &BeyondLastByte))
{
/* Pinning failed */
if (localbcb)
{
CcUnpinData(localbcb);
}
return false;
}
if(BeyondLastByte.QuadPart < LocalFileOffset.QuadPart + RemainingLength)
break;
}
if (localbcbPtr == reinterpret_cast<PCC_BCB*>(&localbcb))
{
*Buffer = LocalBuffer;
}
if (Zero)
{
RtlZeroMemory(*Buffer, Length);
}
CcSetDirtyPinnedData(localbcb, nullptr);
*Bcb = localbcb;
return true;
}
VOID
@ -295,7 +394,7 @@ CcUnpinData(
PCC_BCB Bcb = reinterpret_cast<PCC_BCB>(BcbPtr);
BOOLEAN WRITE_FLAG = NULL;
if (reinterpret_cast<ULONG_PTR>((Bcb & 1))
if (reinterpret_cast<ULONG_PTR>((Bcb) & 1))
{
WRITE_FLAG = TRUE;
Bcb = reinterpret_cast<PCC_BCB>(reinterpret_cast<ULONG_PTR>(Bcb) & ~(1));
@ -329,7 +428,7 @@ CcUnpinDataForThread(IN PVOID BcbPtr,
PCC_BCB Bcb = BcbPtr;
BOOLEAN WRITE_FLAG = NULL;
if (reinterpret_cast<ULONG_PTR>((Bcb & 1))
if (reinterpret_cast<ULONG_PTR>((Bcb) & 1))
{
WRITE_FLAG = TRUE;
Bcb = reinterpret_cast<PCC_BCB>(reinterpret_cast<ULONG_PTR>(Bcb) & ~(1));