Today I started experimenting with some kernel driver. It is supposed to read/write virtual memory. I have done some basic implementation in C# but it does not return desired values:
[Flags]
public enum EIOControlCode : uint
{
// FILE_DEVICE_UNKNOWN = 0x00000022
// METHOD_BUFFERED = 0
IO_READ_REQUEST = (0x00000022 << 16) | (0x0701 << 2) | 0 | (0 << 14),
IO_WRITE_REQUEST = (0x00000022 << 16) | (0x0702 << 2) | 0 | (0 << 14),
IO_GET_ID_REQUEST = (0x00000022 << 16) | (0x0703 << 2) | 0 | (0 << 14),
IO_GET_MODULE_REQUEST = (0x00000022 << 16) | (0x0704 << 2) | 0 | (0 << 14)
}
[StructLayout(LayoutKind.Sequential)]
public struct KERNEL_READ_REQUEST
{
public ulong ProcessId;
public ulong Address;
public ulong Response;
public ulong Size;
public KERNEL_READ_REQUEST(ulong _ProcessId, ulong _Address, ulong _Response, ulong _Size)
{
ProcessId = _ProcessId;
Address = _Address;
Response = _Response;
Size = _Size;
}
}
[DllImport("Kernel32.dll", SetLastError = true, EntryPoint = "DeviceIoControl")]
public static extern bool DeviceIoControlRead(
SafeFileHandle hDevice,
EIOControlCode IoControlCode,
ref KERNEL_READ_REQUEST InBuffer,
int nInBufferSize,
out KERNEL_READ_REQUEST OutBuffer,
int nOutBufferSize,
out uint pBytesReturned,
IntPtr Overlapped
);
KERNEL_READ_REQUEST ReadRequest = new KERNEL_READ_REQUEST();
ReadRequest.ProcessId = ProcessId;
ReadRequest.Address = ReadAddress;
ReadRequest.Size = Size;
if (DeviceIoControlRead(driverHandle, EIOControlCode.IO_READ_REQUEST, ref ReadRequest, 32, out ReadRequest, 32, out Bytes, IntPtr.Zero))
{
// Returning 0
return ReadRequest.Response;
}
else
{
return 0;
}
Does anyone has a clue why it is not working? It is returning the same ReadRequest values as they were initialized.
Thank you.
EDIT: Actually I tried debugging the driver (which works normal through c++ interface) and it turns out that the ReadRequest.Adress value is passed to driver as 0. How it is possible?
EDIT2: I updated struct and some other code:
[StructLayout(LayoutKind.Explicit, CharSet = CharSet.Unicode)]
public struct KERNEL_READ_REQUEST
{
[FieldOffset(0)] public UInt32 ProcessId;
[FieldOffset(8)] public UInt32 Address;
[FieldOffset(16)] public UInt32 Response;
[FieldOffset(24)] public UInt32 Size;
}
Driver output:
The return value is actually the address?
EDIT3:
Actually it seems like to work with just LayoutKind.Sequential
and UInt32
. Yeeeeey.
User contributions licensed under CC BY-SA 3.0