我尝试在驱动程序中从内核模式使用以下代码:

NTSTATUS NTAPI MmCopyVirtualMemory
(
    PEPROCESS SourceProcess,
    PVOID SourceAddress,
    PEPROCESS TargetProcess,
    PVOID TargetAddress,
    SIZE_T BufferSize,
    KPROCESSOR_MODE PreviousMode,
    PSIZE_T ReturnSize
);

我通过以下方式使用它:
PEPROCESS process;
NTSTATUS status;
unsigned int readValue;

// get notepad.exe process -> Notepad is opened already and this is the ID from Task Mgr
status = PsLookupProcessByProcessId((HANDLE)7252, &process);

if (!NT_SUCCESS(status))
{
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "\n\n ## Lookup By Id failed. ##\n\n");
    if (status == STATUS_INVALID_CID)
    {
        DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "\n\n ## Id could not be found. ##\n\n");
    }
    goto Exit;
}

SIZE_T cbBytesReturned;
status = MmCopyVirtualMemory(process, 0x00, PsGetCurrentProcess(), &readValue, sizeof(unsigned int), KernelMode, &cbBytesReturned);

if (!NT_SUCCESS(status))
{
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "\n\n ## MemCopy failed. ##\n\n");
}
else
{
    DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, "\n\n ## MemCopy DONE ##\n\n");
}

ObfDereferenceObject(process);

目前,这失败了。我假设0x00指向我正在读取的进程的内存的第一个字节。我是错的还是相对的,这意味着进程+ 0x00是第一个内存位置?

最佳答案

我不确定为什么您认为您的代码会正常工作,因此MmCopyVirtualMemory的输入值不正确。

  • 您正在为第二个参数传递NULL指针。如果您不提供有效地址,Windows内核应该如何知道要从SourceProcess复制的内存在哪里?
  • 您正在将指针地址作为第四个参数传递给局部变量,但是第四个参数应该是在您所针对的过程(第三个参数)下有效的指针地址。用于第四个参数的指针地址应该是您要将从SourceAddress复制的内存(在SourceProcess的虚拟内存中)放入TargetProcess的位置。
  • 对于第五个参数,您正在传递无符号整数的大小吗?这也是不正确的。

  • 我相信第五个参数(BufferSize)应该是要从SourceAddress复制到TargetAddress的内存量的长度。如果是这种情况,请确保TargetAddress上有足够的空间-撒一点盐。

    我建议您看一下您在原始文章中分享的函数原型(prototype),然后重新检查您的代码,然后再试一次,在这里接受我的评论,并对例程进行更多研究。

    但是请记住,MmCopyVirtualMemory没有正式记录,在任何生产级源代码中使用它都会冒风险。我强烈建议您,如果这不仅仅是一个教育实验,请重新考虑您的选择,因为稳定且记录在案的代码通常很重要。

    09-25 21:32