📄 dvkrnldata.c
字号:
inputLength = irpStack->Parameters.DeviceIoControl.InputBufferLength;
outputLength = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
inputBuffer = Irp->AssociatedIrp.SystemBuffer;
outputBuffer = Irp->AssociatedIrp.SystemBuffer;
switch (irpStack->Parameters.DeviceIoControl.IoControlCode)
{
case KRNLDATA_IO_READ_MEM:
status = dvKrnlDataReadMem(
deviceExtension,
inputBuffer,
inputLength,
outputBuffer,
outputLength,
&dwRealLen);
break;
case KRNLDATA_IO_IDT:
status = dvKrnlDataGetIDT(
deviceExtension,
outputBuffer,
outputLength,
&dwRealLen);
break;
case KRNLDATA_IO_SST:
status = dvKrnlDataGetSST(
deviceExtension,
outputBuffer,
outputLength,
&dwRealLen);
break;
case KRNLDATA_IO_PHYSICAL:
status = dvKrnlDataGetPhysical(
deviceExtension,
inputBuffer,
inputLength,
outputBuffer,
outputLength,
&dwRealLen);
break;
case KRNLDATA_IO_HIDE_PROC:
status = dvKrnlDataHideProc(
deviceExtension,
inputBuffer,
inputLength);
break;
case KRNLDATA_IO_STOP_HIDE:
EndHook();
status = STATUS_SUCCESS;
break;
case KRNLDATA_IO_WRITE_MEM:
default:
status = STATUS_INVALID_DEVICE_REQUEST;
break;
}
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = dwRealLen;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataShutdownDispatch
// Dispatch routine for IRP_MJ_SHUTDOWN requests.
//
// Arguments:
// IN DeviceObject
// pointer to the device object for our device
//
// IN Irp
// the shutdown IRP
//
// Return Value:
// NT status code.
//
NTSTATUS dvKrnlDataShutdownDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
PDVKRNLDATA_DEVICE_EXTENSION deviceExtension;
dvKrnlDataDebugPrint(DBG_GENERAL, DBG_TRACE, __FUNCTION__"++. IRP %p", Irp);
deviceExtension = (PDVKRNLDATA_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
status = STATUS_NOT_IMPLEMENTED;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoCompleteRequest (Irp, IO_NO_INCREMENT);
dvKrnlDataDebugPrint(DBG_GENERAL, DBG_TRACE, __FUNCTION__"--. IRP %p STATUS %x", Irp, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataReadMem
// 读取内核地址的内存值
//
// argument
// IN pDeviceCtx 自己定义的设备扩展结构
// IN pInput 输入数据的缓存地址
// IN dwInput 输入数据的长度
// OUT pOutput 输出数据的缓存地址,目前采用BUFFERD方式,故与pInput地址相同
// IN dwOutput 输出缓存的大小
// OUT pdwOutLen 实际输出的长度
//
// return
// NT status code
//
NTSTATUS dvKrnlDataReadMem(
IN PDVKRNLDATA_DEVICE_EXTENSION pDeviceCtx,
IN PVOID pInput,
IN DWORD dwInput,
OUT PVOID pOutput,
IN DWORD dwOutput,
OUT PDWORD pdwOutLen
)
{
NTSTATUS status;
PDVKRNLDATA_MEM_REQUEST pMemReq = NULL;
PVOID pAddr = NULL;
DWORD dwLen = 0;
dvKrnlDataDebugPrint(
DBG_IO,
DBG_TRACE,
__FUNCTION__"++. pInput %p dwInput %d pOutput %p dwOutput %d", pInput, dwInput, pOutput, dwOutput);
pMemReq = (PDVKRNLDATA_MEM_REQUEST)pInput;
if(dwInput < sizeof(DVKRNLDATA_MEM_REQUEST))
{
status = STATUS_INVALID_PARAMETER;
goto out;
}
pAddr = pMemReq->pAddress;
dwLen = pMemReq->dwRequestLen;
if(dwLen > dwOutput)
{
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
dvKrnlDataDebugPrint(DBG_IO, DBG_INFO, "Address: %08X, Len: %X", pAddr, dwLen);
__try
{
RtlCopyMemory(pOutput, pAddr, dwLen);
*pdwOutLen = dwLen;
status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
*pdwOutLen = 0;
status = STATUS_INVALID_PARAMETER;
}
out:
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. WrittenLen %d STATUS %x", *pdwOutLen, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataGetIDT
// 获取系统的中断描述表(IDT)
//
// argument
// IN pDeviceCtx 自己定义的设备扩展结构
// OUT pOutput 输出数据的缓存地址
// IN dwOutput 输出缓存的大小
// OUT pdwOutLen 实际输出的长度
//
// return
// NT status code
//
NTSTATUS dvKrnlDataGetIDT(
IN PDVKRNLDATA_DEVICE_EXTENSION pDeviceCtx,
OUT PVOID pOutput,
IN DWORD dwOutput,
OUT PDWORD pdwOutLen
)
{
NTSTATUS status;
IDTR idtr;
DWORD dwLen = 0;
int nIDTRSize = sizeof(IDTR);
dvKrnlDataDebugPrint(
DBG_IO,
DBG_TRACE,
__FUNCTION__"++. pOutput %p dwOutput %d", pOutput, dwOutput);
//获取idt基址
__asm
{
sidt idtr
}
//输出idt信息
dvKrnlDataDebugPrint(DBG_IO, DBG_INFO, "IDTLimit: %X, IDTBase: %08X", idtr.IDTLimit, idtr.IDTBase);
if(nIDTRSize > dwOutput)
{
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
//输出的信息组成: IDTR + IDT_ENTRY[]
RtlCopyMemory(pOutput, &idtr, nIDTRSize);
if((idtr.IDTLimit * sizeof(IDT_ENTRY) + nIDTRSize) < dwOutput)
{
dwLen = idtr.IDTLimit * sizeof(IDT_ENTRY);
}
else
{
dwLen = dwOutput - nIDTRSize;
}
__try
{
RtlCopyMemory((PVOID)((DWORD)pOutput + nIDTRSize), idtr.IDTBase, dwLen);
*pdwOutLen = (dwLen + nIDTRSize);
status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
*pdwOutLen = 0;
status = STATUS_INVALID_PARAMETER;
}
out:
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. WrittenLen %d STATUS %x", *pdwOutLen, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataGetSST
// 通过服务描述表(SDT)读取ntoskrnl.exe的服务索引表(SST)
//
// argument
// IN pDeviceCtx 自己定义的设备扩展结构
// OUT pOutput 输出数据的缓存地址
// IN dwOutput 输出缓存的大小
// OUT pdwOutLen 实际输出的长度
//
// return
// NT status code
//
NTSTATUS dvKrnlDataGetSST(
IN PDVKRNLDATA_DEVICE_EXTENSION pDeviceCtx,
OUT PVOID pOutput,
IN DWORD dwOutput,
OUT PDWORD pdwOutLen
)
{
NTSTATUS status;
PSYSTEM_SERVICE_TABLE pNtosSST;
int nSSTSize = sizeof(SYSTEM_SERVICE_TABLE);
dvKrnlDataDebugPrint(
DBG_IO,
DBG_TRACE,
__FUNCTION__"++. pOutput %p dwOutput %d", pOutput, dwOutput);
pNtosSST = &(KeServiceDescriptorTable->ntoskrnl);
//输出ntoskrnl的SST信息
dvKrnlDataDebugPrint(
DBG_IO, DBG_INFO,
"ServiceTable: %08X, ArgumentTable: %08X, ServiceLimit: %X",
pNtosSST->ServiceTable,
pNtosSST->ArgumentTable,
pNtosSST->ServiceLimit);
if(nSSTSize + (sizeof(PVOID) + sizeof(BYTE)) * pNtosSST->ServiceLimit > dwOutput)
{
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
//输出的信息组成: SST + ServiceTable[] + ArgumentTable[]
__try
{
RtlCopyMemory(pOutput, pNtosSST, nSSTSize);
(DWORD)pOutput += nSSTSize;
RtlCopyMemory(pOutput, pNtosSST->ServiceTable, (pNtosSST->ServiceLimit) * sizeof(PVOID));
(DWORD)pOutput += (pNtosSST->ServiceLimit) * sizeof(PVOID);
RtlCopyMemory(pOutput, pNtosSST->ArgumentTable, (pNtosSST->ServiceLimit) * sizeof(BYTE));
*pdwOutLen = nSSTSize + (sizeof(PVOID) + sizeof(BYTE)) * pNtosSST->ServiceLimit;
status = STATUS_SUCCESS;
}
__except(EXCEPTION_EXECUTE_HANDLER)
{
*pdwOutLen = 0;
status = STATUS_INVALID_PARAMETER;
}
out:
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. WrittenLen %d STATUS %x", *pdwOutLen, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataGetPhysical
// 调用MmGetPhysicalAddress函数来获取线性地址对应的物理地址
//
// argument
// IN pDeviceCtx 自己定义的设备扩展结构
// IN pInput 输入数据的缓存地址
// IN dwInput 输入数据的长度
// OUT pOutput 输出数据的缓存地址,目前采用BUFFERD方式,故与pInput地址相同
// IN dwOutput 输出缓存的大小
// OUT pdwOutLen 实际输出的长度
//
// return
// NT status code
//
NTSTATUS dvKrnlDataGetPhysical(
IN PDVKRNLDATA_DEVICE_EXTENSION pDeviceCtx,
IN PVOID pInput,
IN DWORD dwInput,
OUT PVOID pOutput,
IN DWORD dwOutput,
OUT PDWORD pdwOutLen
)
{
NTSTATUS status;
PVOID pLineAddr = NULL;
PHYSICAL_ADDRESS PhysicalAddr;
dvKrnlDataDebugPrint(
DBG_IO,
DBG_TRACE,
__FUNCTION__"++. pInput %p dwInput %d pOutput %p dwOutput %d", pInput, dwInput, pOutput, dwOutput);
if(dwInput < sizeof(PVOID) || dwOutput < sizeof(PHYSICAL_ADDRESS))
{
status = STATUS_BUFFER_TOO_SMALL;
goto out;
}
pLineAddr = *(PPVOID)pInput;
dvKrnlDataDebugPrint(DBG_IO, DBG_INFO, "Line Address: %p", pLineAddr);
//首先检查地址是否合法,然后获取对应的物理地址ULARGE_INTEGER型,64位
if(MmIsAddressValid(pLineAddr))
{
PhysicalAddr = MmGetPhysicalAddress(pLineAddr);
RtlCopyMemory(pOutput, &PhysicalAddr, sizeof(PHYSICAL_ADDRESS));
*pdwOutLen = sizeof(PHYSICAL_ADDRESS);
status = STATUS_SUCCESS;
}
else
{
dvKrnlDataDebugPrint(DBG_IO, DBG_INFO, "invlaid address");
*pdwOutLen = 0;
status = STATUS_INVALID_PARAMETER;
}
out:
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. WrittenLen %d STATUS %x", *pdwOutLen, status);
return status;
}
///////////////////////////////////////////////////////////////////////////////////////////////////
// dvKrnlDataHideProc
// 通过Hook ZwQuerySystemInformation来隐藏指定PID的进程
//
// argument
// IN pDeviceCtx 自己定义的设备扩展结构
// IN pInput 输入数据的缓存地址
// IN dwInput 输入数据的长度
//
// return
// NT status code
//
NTSTATUS dvKrnlDataHideProc(
IN PDVKRNLDATA_DEVICE_EXTENSION pDeviceCtx,
IN PVOID pInput,
IN DWORD dwInput
)
{
NTSTATUS status;
DWORD dwHidePID;
dvKrnlDataDebugPrint(
DBG_IO,
DBG_TRACE,
__FUNCTION__"++. pInput %p dwInput %d", pInput, dwInput);
if(dwInput < sizeof(DWORD))
{
status = STATUS_INVALID_PARAMETER;
goto out;
}
dwHidePID = *(DWORD *)pInput;
dvKrnlDataDebugPrint(DBG_IO, DBG_INFO, "Hide PID: %08X", dwHidePID);
StartHook(dwHidePID);
status = STATUS_SUCCESS;
out:
dvKrnlDataDebugPrint(DBG_IO, DBG_TRACE, __FUNCTION__"--. STATUS %x", status);
return status;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -