【问题标题】:Why can't you access the address space of another process since Windows 95?为什么自 Windows 95 起不能访问另一个进程的地址空间?
【发布时间】:2011-12-22 12:47:44
【问题描述】:

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

program.exe -mypointer

并尝试在该程序中使用它,它不会工作。经过一些研究(即在 Lounge C++ 处询问),我发现从 Windows 95 开始,您无法访问另一个程序的地址空间。在旧版本的 Windows 中是允许的。我的问题是,为什么微软不允许它?这样做有什么问题或缺点?

P.S 是否仍然可以通过一些变通方法在新版本的 Windows 中做到这一点?

【问题讨论】:

  • 好吧,允许任何人访问(意外或目的)允许哪些问题?如果有一个 32 位地址空间(IA-32 没有扩展),可以为程序分配的最大总内存是多少?阅读virtual memory 可能是一个开始......
  • “自从发明了可锁的门,为什么你不能进入邻居的家?”​​span>
  • 我记得在没有内存保护的操作系统上开发软件——每次你运行你试图开发/调试的(仍然有问题的)程序时,你都冒着野指针写入崩溃的风险不仅是您自己的程序,还有其他程序,甚至整个操作系统,都需要硬重启。如果你真的很幸运,你会损坏文件系统驱动程序,这反过来会损坏硬盘驱动器的内容,然后你会丢失正在处理的程序的源代码并且必须重新开始(重新安装后从头开始的操作系统)。美好时光! :)

标签: c++ c windows winapi pointers


【解决方案1】:

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

保护模式的整个要点是保护进程相互之间。有关更多详细信息,请参阅memory protection Wikipedia page。在保护之前的糟糕日子里,编写与其他进程打交道的代码要容易得多。

这样做的缺点是,对于 MS Word 中的一些错误,不仅会导致 MS Word 崩溃,还会导致 Excel、Borland C、过去六周运行的 PI 数字计算器甚至崩溃,这要容易得多。操作系统本身。

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

调用ReadProcessMemoryWriteProcessMemory 以及许多其他debugging functions 允许您执行此操作。

【讨论】:

    【解决方案2】:

    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 从电子野兽转变为机械野兽,运行速度慢了数千倍。不好——但是当 RAM 很小的时候,人们认为虚拟内存很整洁。

    当今 Windows 中虚拟内存的主要问题是,实际上几乎不可能关闭这个该死的东西。即使只有一个“主”程序在运行,并且可用的物理 RAM 远远超过足够的物理 RAM,Windows 也会主动将数据交换到磁盘,以便在该进程可能需要更多逻辑内存时做好准备。但是,如果解决了这个问题,那么很可能会出现其他东西。这就是宇宙的本质。

    【讨论】:

    • +1。顺便说一句,如果 windows 可以利用任意数量的磁盘空间作为 虚拟内存 ,为什么我们会收到“您的系统已用完可用内存”错误?
    • @IntermediateHacker: (1) 32 位 Windows(至少是 XP,正如我所见——他们可能已经改变了这一点)不能只使用“任何数量”的磁盘空间。当页面文件大小 + RAM 大小超过可用地址空间(即 4GB,不更改引导设置)时,它似乎会发疯。此外,(2) 默认情况下,Windows 对页面文件的大小有自己的想法(基于驱动器的大小和您拥有的 RAM 大小)。您可以随意更改此数字,但 Windows 不会因为您需要更多内存而更改其最大值的概念。
    • 哦,关闭虚拟内存并不难。在Win7中,调出系统属性,在左侧找到“高级属性”的链接。这将调出旧对话框。从那里,转到高级选项卡,然后单击性能设置。转到那里的“高级”选项卡,然后单击“更改...”。您可以告诉 Windows 为页面文件使用多少空间,或者如果您足够勇敢,则根本不使用页面文件。 (使用虚拟内存的系统可能会变得很慢,但在这种情况消失之前仍然可以使用。没有停止做某事的系统,通常只是请求内存。)
    • +1 喜欢提到过于激进的磁盘交换行为
    【解决方案3】:

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

    【讨论】:

      【解决方案4】:

      你说得好像你认为内存保护是一件坏事!?

      一个进程的内存不受控制地从另一个进程访问通常会导致错误、崩溃、未定义的行为,更关键的是,可能会为恶意软件和病毒打开大门。您可以编写两个通过共享内存很好地协作的进程,但同样任何其他进程错误或恶意也可以访问它。此外,破坏操作系统内核本身也很容易。

      Win16 最初是作为图形环境而不是 MS-DOS 之上的真正操作系统运行的,并且旨在在没有 MMU 的早期 16 位 x86 处理器上运行以允许内存保护。 Win32S API 后来被引入到 Windows 3.x 中,它在 Win16 上提供了一部分 Win32 功能。 Windows32(最初是 Windows NT,然后是 Windows 95)利用 80386 引入的功能为每个进程提供自己的内存环境,除非受到邀请,否则任何其他进程都不可见。

      这就是使 Windows NT 比 Win3.x 更强大的原因。 Windows 95 没有充分利用保护机制,大概是为了某种程度的向后兼容性,因此虽然比 Win3.x 更强大,但它的防崩溃能力却不如 NT。 Windows XP 是第一个使用 Windows NT/Windows 2000 代码库的“消费者”Windows 操作系统,摒弃了很多(但不是全部)Windows 95/MS-DOS 兼容性包袱。

      如果您希望在进程之间共享数据,正确的做法是通过任何recognised IPC mechanism。一种这样的方法实际上是通过内存映射文件,它完全是一个共享内存块,但具有访问控制,因此不仅仅是任何进程都可以看到内存。

      【讨论】:

        【解决方案5】:

        好吧,如果您可以在其他进程的 ram 区域中乱七八糟,那么让它崩溃是一件容易的事。例如,您只需将一些指针设置为 NULL,该过程就会消失。而且RAM是每个进程的“私有”部分,您不希望任何人访问它们,不是吗?是的,如果您进行一些内核调试,可能有一些方法可以访问它。

        【讨论】:

          猜你喜欢
          • 2018-06-11
          • 1970-01-01
          • 1970-01-01
          • 2011-11-08
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多