驱动程序未返回任何值

时间:2019-05-01 13:09:31

标签: c# windows driver dllimport

今天,我开始尝试some kernel driver。应该读取/写入虚拟内存。我已经在C#中完成了一些基本的实现,但是没有返回期望的值:

[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;
}

有人知道它为什么不起作用吗? 它会返回与初始化时相同的ReadRequest值。

谢谢。

编辑: 实际上,我尝试调试驱动程序(通过c ++接口正常工作),结果证明ReadRequest.Adress值作为0传递给驱动程序。

EDIT2: 我更新了struct和其他一些代码:

[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;
}

驱动程序输出:

screenshot

返回值实际上是地址吗?

EDIT3: 实际上,似乎只使用LayoutKind.SequentialUInt32。 Yeeeeey。

0 个答案:

没有答案