#include "Io.h"
VOID KSleep(LONG MilliSecond)
{
LARGE_INTEGER Interval = { 0 };
Interval.QuadPart = DELAY_ONE_MILLISECOND;
Interval.QuadPart *= MilliSecond;
KeDelayExecutionThread(KernelMode, 0, &Interval);
}
KIRQL Open() // 关
{
KIRQL irql = KeRaiseIrqlToDpcLevel();
UINT64 cr0 = __readcr0();
cr0 &= 0xfffffffffffeffff;
__writecr0(cr0);
_disable();
return irql;
}
void Close(KIRQL irql) //开
{
UINT64 cr0 = __readcr0();
cr0 |= 0x10000;
_enable();
__writecr0(cr0);
KeLowerIrql(irql);
}
NTSTATUS ReadPhysicalMemory(ULONGLONG startaddress, UINT_PTR bytestoread, PVOID output)
{
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
PMDL outputMDL;
outputMDL = IoAllocateMdl(output, (ULONG)bytestoread, FALSE, FALSE, NULL);
__try
{
MmProbeAndLockPages(outputMDL, KernelMode, IoWriteAccess);
}
__except (1)
{
IoFreeMdl(outputMDL);
return STATUS_UNSUCCESSFUL;
}
/*__try
{
RtlInitUnicodeString(&physmemString, physmemName);
InitializeObjectAttributes(&attributes, &physmemString, OBJ_CASE_INSENSITIVE, NULL, NULL);
ntStatus = ZwOpenSection(&physmem, SECTION_ALL_ACCESS, &attributes);
if (ntStatus == STATUS_SUCCESS)
{
SIZE_T length;
PHYSICAL_ADDRESS viewBase;
UINT_PTR offset;
UINT_PTR toread;
viewBase.QuadPart = (ULONGLONG)(startaddress);
length = 0x2000;
toread = bytestoread;
memoryview = NULL;
ntStatus = ZwMapViewOfSection(
physmem, //sectionhandle
NtCurrentProcess(), //processhandle (should be -1)
&memoryview, //BaseAddress
0L, //ZeroBits
length, //CommitSize
&viewBase, //SectionOffset
&length, //ViewSize
ViewShare,
0,
PAGE_READWRITE);
if ((ntStatus == STATUS_SUCCESS) && (memoryview != NULL))
{
if (toread > length)
toread = length;
if (toread)
{
__try
{
offset = (UINT_PTR)(startaddress)-(UINT_PTR)viewBase.QuadPart;
if (offset + toread > length)
{
return STATUS_UNSUCCESSFUL;
}
else
{
RtlCopyMemory(output, &memoryview[offset], toread);
}
ZwUnmapViewOfSection(NtCurrentProcess(), memoryview);
}
__except (1)
{
return STATUS_UNSUCCESSFUL;
}
}
}
else
{
return STATUS_UNSUCCESSFUL;
}
ZwClose(physmem);
};
}
__except (1)
{
DbgPrint("Error while reading physical memory\n");
}*/
ntStatus = STATUS_SUCCESS;
MmUnlockPages(outputMDL);
IoFreeMdl(outputMDL);
return ntStatus;
}
#pragma alloc_text( NOPAGE,ReadProcess)
VOID ReadProcess(HANDLE Pid,ULONG Addr, UINT_PTR bytestoread, PVOID output)
{
NTSTATUS nStatus;
PEPROCESS pEProcess = NULL;
KAPC_STATE KAPC = { 0 };
PHYSICAL_ADDRESS PhyAddr;
BOOLEAN bIsAttached = FALSE;
nStatus = PsLookupProcessByProcessId(Pid, &pEProcess);
if (!NT_SUCCESS(nStatus))
{
return;
}
KeStackAttachProcess(pEProcess,&KAPC);
bIsAttached = TRUE;
if (MmIsAddressValid((PVOID)Addr) == 0)
{
goto TABLE1;
}
PhyAddr = MmGetPhysicalAddress((PVOID)Addr);
PVOID Temp = MmMapIoSpace(PhyAddr, bytestoread, 0);
RtlCopyMemory(output, Temp, bytestoread);
MmUnmapIoSpace(Temp, bytestoread);
TABLE1:
if (bIsAttached != FALSE)
{
KeUnstackDetachProcess(&KAPC);
}
if (pEProcess != NULL)
{
ObDereferenceObject(pEProcess);
pEProcess = NULL;
}
}
NTSTATUS CreateIoObject(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DriverObjectName = RTL_CONSTANT_STRING(DEVICE_OBJECT_NAME);
UNICODE_STRING DriverLinkName = RTL_CONSTANT_STRING(DRIVER_LINK_NAME);
PDEVICE_OBJECT DeivceObject = NULL;
NTSTATUS Status = STATUS_UNSUCCESSFUL;
Status = IoCreateDevice(DriverObject, 0, &DriverObjectName, FILE_DEVICE_UNKNOWN, 0, FALSE, &DeivceObject);
if (!NT_SUCCESS(Status))
{
DbgPrint("CreateDeviceFail\n");
return Status;
}
Status = IoCreateSymbolicLink(&DriverLinkName, &DriverObjectName);
if (!NT_SUCCESS(Status))
{
DeivceObject = NULL;
DbgPrint("CreateSymbolicLinkFail\n");
return Status;
}
Status = STATUS_SUCCESS;
return Status;
}
VOID UnLoad(PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING DriverLinkName;
PDEVICE_OBJECT Tmp_DriverOject = NULL;
PDEVICE_OBJECT Delete = NULL;
RtlInitUnicodeString(&DriverLinkName, DRIVER_LINK_NAME);
IoDeleteSymbolicLink(&DriverLinkName);
Delete = DriverObject->DeviceObject;
while (Delete != NULL)
{
Tmp_DriverOject = Delete->NextDevice;
IoDeleteDevice(Delete);
Delete = Tmp_DriverOject;
}
//PsRemoveLoadImageNotifyRoutine(LoadImageRoutine);
}
NTSTATUS PassThroughDispatch(PDEVICE_OBJECT DriverOject, PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}
VOID SetDispatch(PDRIVER_OBJECT DriverObject)
{
if (!NT_SUCCESS(CreateIoObject(DriverObject)))
{
DbgPrint("CreateIoObjectDriverObject Error");
return;
}
for (ULONG i = 0; i<IRP_MJ_MAXIMUM_FUNCTION; i++)
{
DriverObject->MajorFunction[i] = PassThroughDispatch; //函数指针
}
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = ControlThroughDispatch;
DriverObject->DriverUnload = UnLoad;
}
NTSTATUS ControlThroughDispatch(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
NTSTATUS Status = STATUS_UNSUCCESSFUL;
ULONG_PTR Informaiton = 0;
PVOID InputData = NULL;
ULONG InputDataLength = 0;
PVOID OutputData = NULL;
ULONG OutputDataLength = 0;
ULONG IoControlCode = 0;
PIO_STACK_LOCATION IoStackLocation = IoGetCurrentIrpStackLocation(Irp); //Irp堆栈
IoControlCode = IoStackLocation->Parameters.DeviceIoControl.IoControlCode;
InputData = Irp->AssociatedIrp.SystemBuffer;
OutputData = Irp->AssociatedIrp.SystemBuffer;
InputDataLength = IoStackLocation->Parameters.DeviceIoControl.InputBufferLength;
OutputDataLength = IoStackLocation->Parameters.DeviceIoControl.OutputBufferLength;
switch (IoControlCode)
{
case READ_PROCESS:
{
if (InputData != NULL && InputDataLength > 0)
{
if (OutputData != NULL)
{
p_Read Read = (p_Read)InputData;
SIZE_T OutSize = 0;
ReadProcess((HANDLE)Read->pid, Read->Addr, Read->Size, OutputData);
Informaiton = Read->Size;
Status = STATUS_SUCCESS;
}
break;
}
}
case GET_DLL_BASE:
{
if (OutputData != NULL)
{
memcpy(OutputData, CShellBase, sizeof(int));
Informaiton = sizeof(int);
Status = STATUS_SUCCESS;
break;
}
}
default:
break;
}
Irp->IoStatus.Status = Status; //Ring3 GetLastError();
Irp->IoStatus.Information = Informaiton;
IoCompleteRequest(Irp, IO_NO_INCREMENT); //将Irp返回给Io管理器
return Status; //Ring3 DeviceIoControl()返回值
}
VOID LoadImageRoutine(IN PUNICODE_STRING FullImageName,
IN HANDLE ProcessId, // where image is mapped
IN PIMAGE_INFO ImageInfo)
{
if (wcsstr(FullImageName->Buffer, L"\\CShell.dll") != NULL)
{
CShellBase = ImageInfo->ImageBase;
}
}