【问题标题】:sending a struct with MapViewOfFile and reading an unknown value发送带有 MapViewOfFile 的结构并读取未知值
【发布时间】:2019-08-01 02:59:45
【问题描述】:

我基本上是在尝试将我的结构转换或复制到我的其他进程部分视图,但我不断收到错误

C2760:语法错误:意外的标记“标识符”,预期的“声明”

这就是我正在做的:

type RPM(UINT_PTR ReadAddress)
{
    if (hDriver == INVALID_HANDLE_VALUE) {
        return {};
    }

    DWORD64 Bytes;
    KM_READ_REQUEST ReadRequest{};

    type response{};

    ReadRequest.ProcessId = PID;
    ReadRequest.Address = ReadAddress;
    ReadRequest.Size = sizeof(type);
    ReadRequest.Output = &response;

问题出在这里:

auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);
if (!pBuf)
{
    printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
    system("pause");
}

printf("MapViewOfFile(write) created ! \n");

我在尝试从我的内核驱动程序中读取未知值时遇到了另一个问题。它基本上读取内存,然后根据我正在读取的内容(如果它的 int、float 等)将该值更改为另一个值。

PKM_READ_REQUEST ReadInput = (PKM_READ_REQUEST)SharedSection; // cast readRequest to our struct which is in SharedSection.
void* ReadOutput = ReadInput->Output;

Status = ReadKernelMemory(Process, ReadInput->Address, ReadOutput, ReadInput->Size);

我正在尝试将其复制到我的共享部分,以便我可以从用户模式读取它,但不知道如何转换它或值是什么。

memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));

这就是我想尝试读取它的方式,但将其转换为相同的方式,因为我不想将其读取为 void,我想将其读取为从我的内核模式给出的值。

auto pBuf = MapViewOfFile(hMapFile, FILE_MAP_READ, 0, 0, 4096);
if (!pBuf)
{
    printf("OpenFileMappingA(write) fail! Error: %u\n", GetLastError());
    system("pause");
}

printf("MapViewOfFile(write) created ! \n");

顺便说一句,我在我的内核驱动程序中使用了未记录的函数mmcopyvirtualmemory

【问题讨论】:

  • MapViewOfFile 返回一个指针 (void*)。您不能将其转换为非指针类型。我建议您在继续使用未记录的函数编写内核驱动程序之前,应该了解指针和其他基本语言特性。
  • @Jonathan Potter 感谢您指出我正在学习 c++,但是我遇到了指针问题,您能否链接任何有用的教程或关于指针算法的良好文档:)

标签: c++ c winapi kernel


【解决方案1】:

1.

auto pBuf = (ReadRequest)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, 4096);

ReadRequest不是类型而是对象,如果要将文件映射地址写成structKM_READ_REQUEST,则应将返回指针转换为PKM_READ_REQUEST的类型,同时控制文件映射大小:

auto pBuf = (PKM_READ_REQUEST)MapViewOfFile(hMapFile, FILE_MAP_WRITE, 0, 0, sizeof(KM_READ_REQUEST));

这样你就可以为它设置PID,Address,SizeOutput

2.

memcpy(SharedSection, &ReadOutput, sizeof(ReadOutput));
  • ReadOutput 已经是输出值的地址,所以你不要 需要操作&
  • Sizeof(a pointer) 总是等于 4(in 32-bit) 和 8(in 64 位);
  • 你最好使用一个新的变量来存储复制的值,而不是覆盖以前的数据。

所以

type new_var;
memcpy(&new_var, ReadOutput, sizeof(KM_READ_REQUEST));

编辑:回答你的 cmets,

您可以设置单个事件来在驱动程序和 UM 之间进行通信。

应用:

hDevice = CreateFile(Device);
hEvent = CreateEvent(...);
DeviceIoControl(hDevice, IOCTL_SET_EVENT, &hEvent,...);
WaitForSingleObject(hEvent, INFINITE);

司机:

case IOCTL_SET_EVENT:
{
    HANDLE hUserEvent = *(HANDLE *)pIrp->AssociatedIrp.SystemBuffer;
    status = ObReferenceObjectByHandle(hUserEvent, EVENT_MODIFY_STATE,*ExEventObjectType, KernelMode, (PVOID*)&pDevExt->pEvent, NULL);
    ObDereferenceObject(pDevExt->pEvent);
    break;
}

然后设置事件:

KeSetEvent(pdx->pEvent,...);

【讨论】:

  • 谢谢您,但是如果您介意回答,我有一些问题 1- 现在我读到我真的不需要映射剖面视图超过 1 次,问题是 var auto pBuf 是在 2 个部分之间共享,因此我可以重写它或使用 MapViewOfFile 创建一个新的,每次我需要一个新的 var 而另一个问题是,我想在我的驱动程序和 UM 之间创建一个互斥锁以通知操作已成功所以我可以将 ReadOutput 读入我的读取内存函数我怎么能这样做,你能留下一个伪代码吗?谢谢 +rep
猜你喜欢
  • 2019-08-05
  • 1970-01-01
  • 2019-01-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-04
相关资源
最近更新 更多