├── README.md └── driver.c /README.md: -------------------------------------------------------------------------------- 1 | # KeReadProcessMemory 2 | 3 | # How to Use 4 | Create a user-land app that implements DeviceIOControl, then send the IOCTL request. 5 | 6 | # Writing Memory 7 | If you swap source and target, you can instead write to that area in memory. MmCopyVirtualMemory states "copies bytes from one address to another". Instead of writing to the current buffer, instead just write to another program's memory space. This will be useful when wanting to inject shellcode. Simply reverse until you find a function that is called frequently. Or even with a bit of work, inject a module into that process. 8 | -------------------------------------------------------------------------------- /driver.c: -------------------------------------------------------------------------------- 1 | #include < ntifs.h > 2 | #include < ntddk.h > 3 | #include < ntstrsafe.h > 4 | #include < stdlib.h > 5 | 6 | #define IOCTL_DUMP_MEM CTL_CODE(FILE_DEVICE_UNKNOWN, 0x999, METHOD_OUT_DIRECT, FILE_ANY_ACCESS) 7 | 8 | PDEVICE_OBJECT pDeviceObject; 9 | UNICODE_STRING dev, dos; 10 | 11 | DRIVER_DISPATCH Create; 12 | DRIVER_DISPATCH IOCTL; 13 | DRIVER_DISPATCH Close; 14 | DRIVER_UNLOAD Unload; 15 | 16 | void Unload(PDRIVER_OBJECT pDriverObject) { 17 | IoDeleteSymbolicLink( & dos); 18 | IoDeleteDevice(pDriverObject - > DeviceObject); 19 | } 20 | 21 | NTSTATUS Create(PDEVICE_OBJECT DeviceObject,PIRP irp) 22 | { 23 | irp->IoStatus.Status=STATUS_SUCCESS; 24 | irp->IoStatus.Information=0; 25 | 26 | IoCompleteRequest(irp,IO_NO_INCREMENT); 27 | return STATUS_SUCCESS; 28 | } 29 | 30 | NTSTATUS Close(PDEVICE_OBJECT DeviceObject,PIRP irp) 31 | { 32 | irp->IoStatus.Status=STATUS_SUCCESS; 33 | irp->IoStatus.Information=0; 34 | 35 | IoCompleteRequest(irp,IO_NO_INCREMENT); 36 | return STATUS_SUCCESS; 37 | } 38 | 39 | struct { 40 | int PID; 41 | void * Addr; 42 | void * Value; 43 | int Bytes; 44 | } 45 | MemReq; 46 | 47 | NTSTATUS NTAPI MmCopyVirtualMemory 48 | ( 49 | PEPROCESS SourceProcess, 50 | PVOID SourceAddress, 51 | PEPROCESS TargetProcess, 52 | PVOID TargetAddress, 53 | SIZE_T BufferSize, 54 | KPROCESSOR_MODE PreviousMode, 55 | PSIZE_T ReturnSize 56 | ); 57 | 58 | NTSTATUS KeReadProcessMemory(HANDLE PID, PVOID SourceAddress, PVOID TargetAddress, SIZE_T Size) { 59 | SIZE_T Result; 60 | PEPROCESS SourceProcess, TargetProcess; 61 | PsLookupProcessByProcessId(PID, & SourceProcess); 62 | TargetProcess = PsGetCurrentProcess(); 63 | __try { 64 | //ProbeForRead(SourceAddress, Size, 1); 65 | MmCopyVirtualMemory(SourceProcess, SourceAddress, TargetProcess, TargetAddress, Size, KernelMode, & Result); 66 | return STATUS_SUCCESS; 67 | } 68 | __except(EXCEPTION_EXECUTE_HANDLER) { 69 | return STATUS_ACCESS_DENIED; 70 | } 71 | } 72 | 73 | NTSTATUS IOCTL(PDEVICE_OBJECT DeviceObject, PIRP irp) { 74 | PUCHAR UserBuffer; 75 | PIO_STACK_LOCATION io; 76 | 77 | io = IoGetCurrentIrpStackLocation(irp); 78 | switch (io - > Parameters.DeviceIoControl.IoControlCode) { 79 | case IOCTL_DUMP_MEM: 80 | memcpy( & MemReq, irp - > AssociatedIrp.SystemBuffer, sizeof(MemReq)); 81 | UserBuffer = (PUCHAR) MmGetSystemAddressForMdlSafe(irp - > MdlAddress, NormalPagePriority); 82 | if (UserBuffer && MemReq.Addr != NULL) { 83 | KeReadProcessMemory((HANDLE) MemReq.PID, MemReq.Addr, (PVOID) UserBuffer, MemReq.Bytes); 84 | } 85 | KeFlushIoBuffers(irp - > MdlAddress, TRUE, FALSE); 86 | irp - > IoStatus.Information = 0; 87 | break; 88 | default: 89 | 90 | irp - > IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST; 91 | irp - > IoStatus.Information = 0; 92 | 93 | IoCompleteRequest(irp, IO_NO_INCREMENT); 94 | return STATUS_INVALID_DEVICE_REQUEST; 95 | } 96 | irp - > IoStatus.Status = STATUS_SUCCESS; 97 | irp - > IoStatus.Information = 0; 98 | IoCompleteRequest(irp, IO_NO_INCREMENT); 99 | return STATUS_SUCCESS; 100 | } 101 | 102 | NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObject, PUNICODE_STRING pRegistryPath) { 103 | RtlInitUnicodeString( & dev, L "\\Device\\GITHUB_ComplexityDev"); 104 | RtlInitUnicodeString( & dos, L "\\DosDevices\\ComplexityDev"); 105 | 106 | IoCreateDevice(pDriverObject, 0, & dev, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, & pDeviceObject); 107 | IoCreateSymbolicLink( & dos, & dev); 108 | 109 | IoSetDeviceInterfaceState(pRegistryPath, TRUE); 110 | 111 | pDriverObject - > MajorFunction[IRP_MJ_CREATE] = Create; 112 | pDriverObject - > MajorFunction[IRP_MJ_DEVICE_CONTROL] = IOCTL; 113 | pDriverObject - > MajorFunction[IRP_MJ_CLOSE] = Close; 114 | 115 | pDriverObject - > DriverUnload = Unload; 116 | 117 | pDeviceObject - > Flags |= DO_DIRECT_IO; 118 | pDeviceObject - > Flags &= ~DO_DEVICE_INITIALIZING; 119 | 120 | return STATUS_SUCCESS; 121 | } 122 | --------------------------------------------------------------------------------