📄 functions.c
字号:
NTSTATUS NtStatus;
*pdwStringLength = 0;
/*
* We want to acquire the instance mutex so we can manipulate the buffer indepdent of other
* threads (in our process and other processes).
*
* We want to wait so that we cannot be interrupted and we will not wake up to process APC's.
*
*/
NtStatus = KeWaitForMutexObject(&pExampleList->kInstanceBufferMutex, Executive, KernelMode, FALSE, NULL);
if(NT_SUCCESS(NtStatus))
{
DbgPrint("Start Index = %i Stop Index = %i Size Of Buffer = %i\n", pExampleList->uiStartIndex, pExampleList->uiStopIndex, sizeof(pExampleList->pCircularBuffer));
/*
* To copy the buffer created in user mode to the kernel buffer we need to determine
* where the circular buffer pointers are.
*
* [***** ************************]
* Stop Start
*
* If the Start index is farther than the Stop index then we can assume that memory from the Start to the
* index (including wrapping). So Start - (Stop + 1) = Valid Length. We want to add 1 to the Stop index
* so that we do not get Start == Stop since this is reserved for empty buffer.
*
*/
DbgPrint("Example_WriteData = %i > %i\n", pExampleList->uiStartIndex, (pExampleList->uiStopIndex + 1));
if(pExampleList->uiStartIndex > (pExampleList->uiStopIndex + 1))
{
UINT uiCopyLength = MIN((pExampleList->uiStartIndex - (pExampleList->uiStopIndex + 1)), uiLength);
DbgPrint("uiCopyLength = %i (%i, %i)\n", uiCopyLength, (pExampleList->uiStartIndex - (pExampleList->uiStopIndex + 1)), uiLength);
if(uiCopyLength)
{
RtlCopyMemory(pExampleList->pCircularBuffer + pExampleList->uiStopIndex, pData, uiCopyLength);
pExampleList->uiStopIndex += uiCopyLength;
*pdwStringLength = uiCopyLength;
bDataWritten = TRUE;
}
}
else
{
UINT uiLinearLengthAvailable;
UINT uiCopyLength;
/*
* To copy the buffer created in user mode to the kernel buffer we need to determine
* where the circular buffer pointers are.
*
* [ **************** ]
* Start Stop
*
* If the Start index is before the Stop Index we can assume that the memory from the Start index
* to the STop Index is full. Thus, we first want to copy linear memory from the stop index
* to the end of the buffer.
*
* To complicate matters, we don't want Start == Stop since this will signify an empty buffer in our
* simple example. So, what we do is that if the Start Index == 0, instead of using
* buffer size - Stop Index and wrapping the Stop Index we simply add 1 to Stop Index so that we
* get a smaller area and we won't wrap around.
*
*/
if(pExampleList->uiStartIndex <= pExampleList->uiStopIndex)
{
if(pExampleList->uiStartIndex == 0)
{
uiLinearLengthAvailable = sizeof(pExampleList->pCircularBuffer) - (pExampleList->uiStopIndex + 1);
}
else
{
uiLinearLengthAvailable = sizeof(pExampleList->pCircularBuffer) - pExampleList->uiStopIndex;
}
uiCopyLength = MIN(uiLinearLengthAvailable, uiLength);
DbgPrint("uiCopyLength %i = MIN(uiLinearLengthAvailable %i, uiLength %i)\n", uiCopyLength, uiLinearLengthAvailable, uiLength);
if(uiCopyLength)
{
RtlCopyMemory(pExampleList->pCircularBuffer + pExampleList->uiStopIndex, pData, uiCopyLength);
pExampleList->uiStopIndex += uiCopyLength;
*pdwStringLength = uiCopyLength;
bDataWritten = TRUE;
if(pExampleList->uiStopIndex == sizeof(pExampleList->pCircularBuffer))
{
pExampleList->uiStopIndex = 0;
DbgPrint("pExampleList->uiStopIndex = 0 %i - %i = %i\n", uiLength , uiCopyLength, (uiLength - uiCopyLength));
if((uiLength - uiCopyLength) > 0)
{
UINT uiSecondCopyLength = MIN(pExampleList->uiStartIndex - (pExampleList->uiStopIndex + 1), uiLength - uiCopyLength);
DbgPrint("uiSecondCopyLength = 0 %i\n", uiSecondCopyLength);
if(uiSecondCopyLength)
{
RtlCopyMemory(pExampleList->pCircularBuffer + pExampleList->uiStopIndex, pData, uiSecondCopyLength);
pExampleList->uiStopIndex += uiSecondCopyLength;
*pdwStringLength = uiCopyLength + uiSecondCopyLength;
bDataWritten = TRUE;
}
}
}
}
}
}
DbgPrint("Start Index = %i Stop Index = %i Size Of Buffer = %i\n", pExampleList->uiStartIndex, pExampleList->uiStopIndex, sizeof(pExampleList->pCircularBuffer));
KeReleaseMutex(&pExampleList->kInstanceBufferMutex, FALSE);
}
return bDataWritten;
}
/**********************************************************************
*
* Example_ReadData
*
* This is called to read data from the circular buffer.
* This function does not block and will not wait for data, so
* no data will simply fail this call. If any data at all
* is read then we will return success with the number of bytes
* read.
*
**********************************************************************/
BOOLEAN Example_ReadData(PEXAMPLE_LIST pExampleList, PCHAR pData, UINT uiLength, UINT *pdwStringLength)
{
BOOLEAN bDataRead = FALSE;
NTSTATUS NtStatus;
*pdwStringLength = 0;
/*
* We want to acquire the instance mutex so we can manipulate the buffer indepdent of other
* threads (in our process and other processes).
*
* We want to wait so that we cannot be interrupted and we will not wake up to process APC's.
*
*/
NtStatus = KeWaitForMutexObject(&pExampleList->kInstanceBufferMutex, Executive, KernelMode, FALSE, NULL);
if(NT_SUCCESS(NtStatus))
{
DbgPrint("Start Index = %i Stop Index = %i Size Of Buffer = %i\n", pExampleList->uiStartIndex, pExampleList->uiStopIndex, sizeof(pExampleList->pCircularBuffer));
/*
* To copy the buffer created in kernel mode to the user buffer we need to determine
* where the circular buffer pointers are.
*
* [ **************** ]
* Start Stop
*
* If the start index is before the stop index we have a linear buffer we can copy.
*
*/
DbgPrint("Start Index = %i Stop Index = %i Size Of Buffer = %i\n", pExampleList->uiStartIndex, pExampleList->uiStopIndex, sizeof(pExampleList->pCircularBuffer));
if(pExampleList->uiStartIndex < pExampleList->uiStopIndex)
{
UINT uiCopyLength = MIN(pExampleList->uiStopIndex - pExampleList->uiStartIndex, uiLength);
if(uiCopyLength)
{
RtlCopyMemory(pData, pExampleList->pCircularBuffer + pExampleList->uiStartIndex, uiCopyLength);
pExampleList->uiStartIndex += uiCopyLength;
*pdwStringLength = uiCopyLength;
bDataRead = TRUE;
}
}
else
{
/*
* To copy the buffer created in kernel mode to the user buffer we need to determine
* where the circular buffer pointers are.
*
* [**** **************]
* Stop Start
*
* If the stop index is before the start index we have a nonlinear buffer we can copy.
* We want to copy all the way to the end if we can. Then we wrap around, if the
* Start and Stop are equal, we have an empty buffer now. If they are not then we
* have more memory to copy. We must always respect the buffer size provided by user mode though.
*
*/
if(pExampleList->uiStartIndex > pExampleList->uiStopIndex)
{
UINT uiLinearLengthAvailable = sizeof(pExampleList->pCircularBuffer) - pExampleList->uiStartIndex;
UINT uiCopyLength = MIN(uiLinearLengthAvailable, uiLength);
uiCopyLength = MIN(uiLinearLengthAvailable, uiLength);
if(uiCopyLength)
{
RtlCopyMemory(pData, pExampleList->pCircularBuffer + pExampleList->uiStartIndex, uiCopyLength);
pExampleList->uiStartIndex += uiCopyLength;
*pdwStringLength = uiCopyLength;
bDataRead = TRUE;
if(pExampleList->uiStartIndex == sizeof(pExampleList->pCircularBuffer))
{
pExampleList->uiStartIndex = 0;
if(uiLength - uiCopyLength > 0)
{
UINT uiSecondCopyLength = MIN(pExampleList->uiStopIndex - pExampleList->uiStartIndex, uiLength - uiCopyLength);
if(uiSecondCopyLength)
{
RtlCopyMemory(pData, pExampleList->pCircularBuffer + pExampleList->uiStartIndex, uiCopyLength);
pExampleList->uiStartIndex += uiSecondCopyLength;
*pdwStringLength = uiCopyLength + uiSecondCopyLength;
bDataRead = TRUE;
}
}
}
}
}
}
DbgPrint("Start Index = %i Stop Index = %i Size Of Buffer = %i\n", pExampleList->uiStartIndex, pExampleList->uiStopIndex, sizeof(pExampleList->pCircularBuffer));
KeReleaseMutex(&pExampleList->kInstanceBufferMutex, FALSE);
}
return bDataRead;
}
/**********************************************************************
*
* Example_IsStringTerminated
*
* Simple function to determine a string is NULL terminated.
*
**** We could validate also the characters in the string are printable! ***
*
**********************************************************************/
BOOLEAN Example_IsStringTerminated(PCHAR pString, UINT uiLength, UINT *pdwStringLength)
{
BOOLEAN bStringIsTerminated = FALSE;
UINT uiIndex = 0;
DbgPrint("Example_IsStringTerminated(0x%0x, %d)\r\n", pString, uiLength);
*pdwStringLength = 0;
while(uiIndex < uiLength && bStringIsTerminated == FALSE)
{
if(pString[uiIndex] == '\0')
{
*pdwStringLength = uiIndex + 1; /* Include the total count we read, includes the NULL */
bStringIsTerminated = TRUE;
DbgPrint(" String Is Terminated!\r\n");
}
else
{
uiIndex++;
}
}
return bStringIsTerminated;
}
/**********************************************************************
*
* Example_HandleSampleIoctl_DirectInIo
*
* Sample IOCTL TO Handle Direct In I/O
*
*
**********************************************************************/
NTSTATUS Example_HandleSampleIoctl_DirectInIo(PIRP Irp, PIO_STACK_LOCATION pIoStackIrp, UINT *pdwDataWritten)
{
NTSTATUS NtStatus = STATUS_UNSUCCESSFUL;
PCHAR pInputBuffer;
PCHAR pOutputBuffer;
UINT dwDataRead = 0, dwDataWritten = 0;
PCHAR pReturnData = "IOCTL - Direct In I/O From Kernel!";
UINT dwDataSize = sizeof("IOCTL - Direct In I/O From Kernel!");
DbgPrint("Example_HandleSampleIoctl_DirectInIo Called \r\n");
/*
* METHOD_IN_DIRECT
*
* Input Buffer = Irp->AssociatedIrp.SystemBuffer
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -