Сегодня я начал экспериментировать с некоторым драйвером ядра . Предполагается чтение / запись виртуальной памяти. Я сделал некоторые базовые реализации в 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, которые были инициализированы.
Спасибо.
EDIT:
На самом деле я попытался отладить драйвер (который работает нормально через интерфейс c ++), и получается, что значение ReadRequest.Adress передается драйверу как 0. Как это возможно?
EDIT2:
Я обновил структуру и некоторый другой код:
[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](https://i.stack.imgur.com/Jj5Jq.png)
Возвращаемое значение на самом деле адрес?
EDIT3:
На самом деле кажется, что он работает только с LayoutKind.Sequential
и UInt32
. Yeeeeey.