自Windows 95以来,为什么不能访问其他进程的地址空间?

App*_*ker 7 c c++ windows winapi pointers

假设我将指针作为参数发送给另一个程序:

program.exe -mypointer
Run Code Online (Sandbox Code Playgroud)

并尝试在该程序中使用它,它将无法正常工作.经过一些研究(即在C++休息室询问),我发现自Windows 95以来,您无法访问其他程序的地址空间.在旧版本的Windows中,它是允许的.我的问题是,为什么微软不允许这样做?这样做有什么问题或缺点?

PS是否仍然可以通过一些解决方法在新版本的Windows中执行此操作?

pax*_*blo 14

因为能够访问其他进程的地址空间意味着您可以通过例如随机更改其内存内容来使其崩溃.

的保护模式是保护流程彼此.有关更多详细信息,请参阅内存保护Wikipedia页面.在保护之前的糟糕旧时代,编写摆弄其他进程的代码要容易得多.

这样做的缺点是,MS Word中的一些错误要比MS Word崩溃容易得多,而且Excel,Borland C,你过去六周运行的PI数字计算器,甚至是操作系统都要容易得多.本身.

您仍然可以访问另一个进程地址空间,但您基本上必须以更高的权限运行才能执行此操作.例如,这是调试器允许您运行进程并访问其所有内存以进行调试的方式.

调用ReadProcessMemoryWriteProcessMemory允许您执行此操作以及许多其他调试功能.


Che*_*Alf 9

16位Windows做了一些真正惊人的内存管理功能,但它被设计用于没有内存管理的处理器,即原始PC的i8086(硬件人员可能不是原来的PC使用i8088,这是相同的除了数据总线的宽度).

因此,在16位Windows进程中共享相同的内存视图.

其中一个问题是公共内存地址空间并不大,实际上,当无数进程想要拥有它们自己的块时.

此外,它使得流程很容易在彼此的脚上绊倒.

Windows提供了一些部分解决方案,例如进程能够通知Windows实际使用某些内存的时间(该进程将"锁定"该内存区域),这意味着Windows可以移动内存内容以便腾出空间需要,但这都是自愿的,也不是很安全.

因此,32位Windows,Windows NT,利用较新的处理器内存管理来自动化16位Windows程序应该使用的最佳实践.本质上,一个进程只处理逻辑地址,处理器自动将其转换为物理地址(进程永远不会看到).好吧,在32位PC上,翻译是一个两步的事情,即有一个内部中间地址形式,但这是你不需要知道的复杂性.

这种硬件支持的地址转换的一个好结果是,一个进程可以完全不知道它使用哪个物理地址.例如,很容易有两个相同程序的进程.他们认为他们正在处理相同的地址,但那些只是逻辑地址; 实际上,它们的逻辑地址被转换为不同的物理地址,因此它们不会踩在彼此的内存区域上.

我们用20-20后见之明可以说不太好的一个结果是翻译方案允许虚拟内存,例如通过使用磁盘空间来模拟RAM.Windows可以将内存内容复制到磁盘,然后将该物理内存区域用于其他内容.当使用该内存区域的进程写入或读取它时,Windows会参与一些疯狂的活动,将数据从磁盘加载回某些内存区域(可能是相同的或其他内容区域),并映射进程的逻辑地址那里.这样做的结果是,在低内存条件下,PC从电子兽转变为机械兽,执行数千和数百万次的懒人.Ungood - 但当RAM大小很小时,人们认为虚拟内存很整洁.

在今天的Windows中,虚拟内存的主要问题在于,在实践中,几乎不可能将这种虚假的东西关掉.即使只有一个"主"程序运行,并且有比提供足够的物理RAM更多,Windows会主动交换数据到磁盘以备可能时,该过程可能需要更多的逻辑记忆.但是,如果这个问题得到解决,那么其他东西最有可能出现; 这就是宇宙的本质.

干杯&hth.,


Dav*_*rtz 6

你的前提是不正确的.你当然可以在Windows中读取另一个进程的内存.你只是不能解除引用指针,因为每个进程都有不同的内存视图.出于各种原因这是必要的,但最重要的是防止一个程序中的错误破坏其他正在执行的程序.(另一个是防止地址空间成为稀缺资源.)