【发布时间】:2021-08-24 14:13:58
【问题描述】:
我正在开发一个.NET 程序,它假设使用共享内存(内存映射文件)与同一台机器中的其他现有程序进行通信,现有程序本身包括一个本机dll 和.NET 包装器/桥接器dll 我可以使用它与其他程序进行通信。
问题是其他程序有很多bug,程序的源代码和dll早已不复存在,所以我的目标是重新创建其他程序。我可以反编译.NETdll,但它只是直接P/Invoke本机dll。
幸运的是,我能够使用System.IO.MemoryMappedFiles.MemoryMappedFile 查看内存映射文件,但这就是我得到的全部,我不知道当我从中调用某些函数时dll 从内存映射文件中读取数据的偏移量(大多数当时dll 只做读不写)
我还尝试在 C++ 程序中挂钩 CreateFileMapping、OpenFileMapping 和 MapViewOfFile 并在本机 dll 中调用某些函数,但这些挂钩函数仅在初始化期间调用一次,并且在调用函数时未触发dll 假设从内存映射文件中读取数据。如果我敢猜测,dll 肯定是指向内存映射文件的指针。
所以我的问题是,是否可以设置断点或检测任何进程何时尝试读取/写入内存映射文件的某些区域?例如,我想知道在我的内存映射文件中是否有读取进程或指针指向偏移量0xdeadbeef。我对替代方案持开放态度,所以如果您有更好的想法,请告诉我
【问题讨论】:
-
一个文件映射对象被创建一次,通常只映射一次。从那时起,它就像其他任何东西一样只是记忆的垃圾。可以预料,文件映射 API 调用不超过一次。要了解内存区域何时发生变化,请使用您的调试器set a data breakpoint。
-
@IInspectable 感谢您的回复,我更好地理解了为什么 API 只调用了一次。对于调试,您链接的页面显示“如果值已读取但未更改,则执行不会中断”,我需要跟踪读取的值,因为
dll主要是读取操作。它还说它不适用于“内存位置在两个或多个进程之间共享” -
从内存中读取没有明显的副作用。我不知道有一种方法(使用调试器或其他方式)可以让您获得有关内存读取的通知。记录time-travel debugging 会话可能是您最好的选择,尽管我不确定查询内存读取操作有多难。
标签: c# c++ winapi shared-memory memory-mapped-files