为什么你不能访问另一个进程的地址空间?

时间:2022-12-27 21:13:32

Say I send a pointer as an argument to another program:

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

program.exe -mypointer

and try to use it in that program, it won't work. After some research (i.e asking at Lounge C++ ) I found that since Windows 95, you can't access the address space of another program. In older versions of Windows it was allowed. My question is, why did Microsoft disallow it? What were the problems or disadvantages of doing this?

试着在程序中使用它,它不会工作。经过一些研究(我。我发现由于windows95,你无法访问另一个程序的地址空间。在旧版本的Windows中是允许的。我的问题是,微软为什么不允许它?这样做有什么问题或缺点?

P.S Is it still possible through some work-around to do this in new versions of Windows?

P。在Windows的新版本中,是否仍然可以通过一些变通方法来实现这一点?

5 个解决方案

#1


13  

Because being able to access the address space of other processes means that you can crash them by, for example, changing their memory contents randomly.

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

The whole point of protected mode is to protect processes from each other. See the memory protection Wikipedia page for some more details. In the bad old days before protection, it was a lot easier to write code that fiddled with other processes.

保护模式的重点是保护进程彼此。有关更多细节,请参见*的内存保护页面。在保护之前的糟糕日子里,编写代码修改其他进程要容易得多。

The downside of that is that it was a lot easier for some a bug in MS Word to not just crash MS Word but also Excel, Borland C, your PI digit calculator that had been running for the last six weeks, and even the operating system itself.

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

You still can get access to another process address space but you basically have to run at higher privileges to do this. For example, this is how debuggers allow you to run a process and access all its memory for debugging purposes.

您仍然可以访问另一个进程地址空间,但是您基本上必须以更高的权限运行才能做到这一点。例如,调试器允许您运行一个进程并访问它的所有内存,以便进行调试。

The calls ReadProcessMemory and WriteProcessMemory allow you to do this, along with many other debugging functions.

调用ReadProcessMemory和WriteProcessMemory允许您这样做,以及许多其他调试函数。

#2


9  

16-bit Windows did some truly amazing feats of memory management, but it was hampered by being designed for a processor without memory management, namely the i8086 of the original PC (hardware folks may not that the original PC used an i8088, which was identical except for width of data bus).

16位Windows在内存管理方面确实取得了一些令人惊叹的成就,但由于它是为没有内存管理的处理器而设计的,也就是原始PC的i8086(硬件人员可能不认为原始PC使用了i8088,除了数据总线的宽度之外,i8088是相同的),它受到了阻碍。

So, in 16-bit Windows processes shared the same view of memory.

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

One problem with that is that the common memory address space isn't that large, really, when umpteen processes want to own their own chunks of it.

其中一个问题是,当umpteen进程想要拥有它们自己的块时,普通内存地址空间并不是那么大。

In addition it makes it rather too easy for processes to stumble on each others' feet.

此外,它使进程很容易在彼此的脚上磕磕绊绊。

Windows offered some partial solutions, such as the ability for a process to inform Windows about when it was actually using some memory (the process would then "lock" that memory region), which meant that Windows could move memory contents around to make room when needed, but it was all voluntary, and not very safe either.

Windows提供了部分解决方案,如流程的能力告知Windows时实际使用一些内存(过程将“锁”,内存区域),这意味着窗口可以移动内存内容在需要的时候腾出空间,但这都是自愿的,并不是很安全。

So, 32-bit Windows, Windows NT, utilized the newer processor's memory management to automate the best practices that 16-bit Windows programs should have used. In essence, a process deals only with logical addresses, which the processor automatically translates down to physical addresses (which the process never sees). Well, on the 32-bit PC the translation is a two step affair, i.e. there's an internal intermediate address form, but that's complication you don't need to know about.

因此,32位Windows, Windows NT,利用新处理器的内存管理来自动执行16位Windows程序应该使用的最佳实践。本质上,进程只处理逻辑地址,处理器自动将其转换为物理地址(进程从未看到)。在32位的PC上翻译是两个步骤的事情,也就是说,有一个内部的中间地址形式,但这是你不需要知道的复杂情况。

One nice consequence of this hardware-supported address translation is that a process can be completely insulated from knowledge of which physical addresses it uses. For example, it's easy to have two processes of the same program. They think they're dealing with the same addresses, but those are only logical addresses; in reality, their logical addresses are translated down to different physical addresses, so that they're not stomping on each others' memory areas.

这种硬件支持的地址转换的一个很好的结果是,进程可以完全与它所使用的物理地址的知识隔离开来。例如,一个程序很容易有两个进程。他们认为他们在处理相同的地址,但这些只是逻辑地址;实际上,它们的逻辑地址被转换为不同的物理地址,这样它们就不会在彼此的内存区域上产生冲突。

And one consequence that we with 20-20 hindsight can say is not so nice, is that the translation scheme allows virtual memory, e.g. to simulate RAM by using disk space. Windows can copy memory contents to disk, and then use that area of physical memory for something else. When the process that used that memory area writes to or reads from it, Windows engages in some frenetic activity to load the data back from disk, into some memory area (could be the same, or other), and map the process' logical addresses there. The upshot of this is that in low memory conditions, the PC is transformed from an electronic beastie to a mechanical beastie, performing thousands and millions times slooooower. Ungood -- but when RAM sizes were small people thought virtual memory was neat.

20-20后见之明的结论之一是,转换方案允许使用虚拟内存,例如使用磁盘空间模拟RAM。Windows可以将内存内容复制到磁盘,然后将该物理内存区域用于其他内容。当使用该内存区域的进程对其进行写入或读取时,Windows会进行一些*的活动,将数据从磁盘加载回某些内存区域(可能是相同的,或者是其他的),并在其中映射进程的逻辑地址。这样做的结果是,在内存不足的情况下,PC会从电子机器人变成机械机器人,执行成千上万次slooooower。不好——但是当内存大小很小的时候,人们认为虚拟内存很好。

The main problem with virtual memory in today's Windows is that in practice it's almost impossible to turn that darn thing off. Even if there's only one "main" program running, and there's much more than adequate physical RAM available, Windows will proactively swap data to disk to be ready for when possibly that process may need even more logical memory. However, if this were fixed then something else would most probably appear in its stead; such is the nature of the Universe.

虚拟内存的主要问题在今天的窗户是在实践中几乎是不可能关掉那该死的事情。即使只有一个“主要”项目运行,有更充足的物理RAM可用,Windows将主动交换数据到磁盘时要准备好可能是这一过程可能需要更多的逻辑内存。然而,如果这是固定的,那么其他的东西很可能会代替它出现;这就是宇宙的本质。

Cheers & hth.,

欢呼声& hth。

#3


6  

Your premise is incorrect. You most certainly can read the memory of another process in Windows. You just can't do it be dereferencing a pointer because each process has a different view of memory. This is necessary for a variety of reasons, but the most important one is to prevent a bug in one program from corrupting other executing programs. (Another one is to prevent address space from being a scarce resource.)

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

#4


4  

You make it sound like you think memory protection is a bad thing!?

你让它听起来好像你认为保护记忆是件坏事!?

Uncontrolled access of one process's memory from another would generally lead to bugs, crashes, undefined behaviour, and more critically perhaps would be an open door to malware and viruses. You may write two processes that cooperate through shared memory nicely, but equally any other process either by error or maliciously could also access it. Moreover it would be very easy also to trash the OS kernel itself.

不受控制地从另一个进程访问一个进程的内存通常会导致错误、崩溃、不明确的行为,更关键的是,这可能会为恶意软件和病毒打开大门。您可以编写两个通过共享内存协作的进程,但同样,任何其他进程,无论是错误还是恶意,都可以访问它。此外,也很容易对OS内核本身进行垃圾处理。

Win16 ran originally as a graphical environment rather than a true OS on top of MS-DOS and was designed to work on early 16 bit x86 processors without an MMU to allow memory protection. The Win32S API was introduced later into Windows 3.x which provided a subset of Win32 features on Win16. Windows32 (originally Windows NT then concurrently Windows 95) takes advantages of features introduced with the 80386 to provide each process with its own memory environment invisible to any other except by invitation.

Win16最初是作为一个图形环境运行的,而不是在MS-DOS之上的一个真正的操作系统,它被设计为可以在没有MMU的16位x86处理器上运行,以支持内存保护。Win32S API后来被引入Windows 3。它提供了Win16上Win32特性的子集。Windows32(最初是windowsnt并发windows95)利用了80386引入的特性,为每个进程提供了自己的内存环境,除了邀请之外,其他进程都看不到这个内存环境。

This is what made Windows NT more robust that Win3.x. Windows 95 did not make full use of the protection mechanisms presumably for some level backward compatibility, so while more robust that Win3.x, it was not nearly as crash-proof as NT. Windows XP was the first "consumer" Windows OS to use the Windows NT/Windows 2000 code base, and discard much (but not all) of the Windows 95/MS-DOS compatibility baggage.

这就是Windows NT比Win3.x更健壮的原因。Windows 95并没有充分利用保护机制来实现某种程度的向后兼容性,因此Win3更加健壮。Windows XP是第一个使用Windows NT/Windows 2000代码库的“消费者”Windows操作系统,并抛弃了Windows 95/MS-DOS兼容性的大部分(但不是全部)。

If you wish to share data between processes the correct way to do it is through any recognised IPC mechanism. One such method is in fact through a memory mapped file, which is exactly a shared memory block, but with access controls so not just any process can see the memory.

如果您希望在进程之间共享数据,正确的方法是通过任何公认的IPC机制。一个这样的方法实际上是通过一个内存映射文件,它实际上是一个共享内存块,但是有访问控制,所以不是所有进程都能看到内存。

#5


2  

Well if you can mess around in the ram area of other processes it's an easy task to crash it. E.g you just have to set some pointer to NULL and the process will be gone. And well RAM are "private" parts of every process and you don't want anyone to access them won't you? Yes there is some way to access that probably if you do some kernel debugging.

如果你可以在其他进程的ram区域中乱涂乱画,那就很容易崩溃。E。你只需要将指针设置为NULL就行了。RAM是每个进程的“私有”部分你不希望任何人访问它们,不是吗?是的,如果您做一些内核调试,可能会有一些方法来访问它。

#1


13  

Because being able to access the address space of other processes means that you can crash them by, for example, changing their memory contents randomly.

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

The whole point of protected mode is to protect processes from each other. See the memory protection Wikipedia page for some more details. In the bad old days before protection, it was a lot easier to write code that fiddled with other processes.

保护模式的重点是保护进程彼此。有关更多细节,请参见*的内存保护页面。在保护之前的糟糕日子里,编写代码修改其他进程要容易得多。

The downside of that is that it was a lot easier for some a bug in MS Word to not just crash MS Word but also Excel, Borland C, your PI digit calculator that had been running for the last six weeks, and even the operating system itself.

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

You still can get access to another process address space but you basically have to run at higher privileges to do this. For example, this is how debuggers allow you to run a process and access all its memory for debugging purposes.

您仍然可以访问另一个进程地址空间,但是您基本上必须以更高的权限运行才能做到这一点。例如,调试器允许您运行一个进程并访问它的所有内存,以便进行调试。

The calls ReadProcessMemory and WriteProcessMemory allow you to do this, along with many other debugging functions.

调用ReadProcessMemory和WriteProcessMemory允许您这样做,以及许多其他调试函数。

#2


9  

16-bit Windows did some truly amazing feats of memory management, but it was hampered by being designed for a processor without memory management, namely the i8086 of the original PC (hardware folks may not that the original PC used an i8088, which was identical except for width of data bus).

16位Windows在内存管理方面确实取得了一些令人惊叹的成就,但由于它是为没有内存管理的处理器而设计的,也就是原始PC的i8086(硬件人员可能不认为原始PC使用了i8088,除了数据总线的宽度之外,i8088是相同的),它受到了阻碍。

So, in 16-bit Windows processes shared the same view of memory.

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

One problem with that is that the common memory address space isn't that large, really, when umpteen processes want to own their own chunks of it.

其中一个问题是,当umpteen进程想要拥有它们自己的块时,普通内存地址空间并不是那么大。

In addition it makes it rather too easy for processes to stumble on each others' feet.

此外,它使进程很容易在彼此的脚上磕磕绊绊。

Windows offered some partial solutions, such as the ability for a process to inform Windows about when it was actually using some memory (the process would then "lock" that memory region), which meant that Windows could move memory contents around to make room when needed, but it was all voluntary, and not very safe either.

Windows提供了部分解决方案,如流程的能力告知Windows时实际使用一些内存(过程将“锁”,内存区域),这意味着窗口可以移动内存内容在需要的时候腾出空间,但这都是自愿的,并不是很安全。

So, 32-bit Windows, Windows NT, utilized the newer processor's memory management to automate the best practices that 16-bit Windows programs should have used. In essence, a process deals only with logical addresses, which the processor automatically translates down to physical addresses (which the process never sees). Well, on the 32-bit PC the translation is a two step affair, i.e. there's an internal intermediate address form, but that's complication you don't need to know about.

因此,32位Windows, Windows NT,利用新处理器的内存管理来自动执行16位Windows程序应该使用的最佳实践。本质上,进程只处理逻辑地址,处理器自动将其转换为物理地址(进程从未看到)。在32位的PC上翻译是两个步骤的事情,也就是说,有一个内部的中间地址形式,但这是你不需要知道的复杂情况。

One nice consequence of this hardware-supported address translation is that a process can be completely insulated from knowledge of which physical addresses it uses. For example, it's easy to have two processes of the same program. They think they're dealing with the same addresses, but those are only logical addresses; in reality, their logical addresses are translated down to different physical addresses, so that they're not stomping on each others' memory areas.

这种硬件支持的地址转换的一个很好的结果是,进程可以完全与它所使用的物理地址的知识隔离开来。例如,一个程序很容易有两个进程。他们认为他们在处理相同的地址,但这些只是逻辑地址;实际上,它们的逻辑地址被转换为不同的物理地址,这样它们就不会在彼此的内存区域上产生冲突。

And one consequence that we with 20-20 hindsight can say is not so nice, is that the translation scheme allows virtual memory, e.g. to simulate RAM by using disk space. Windows can copy memory contents to disk, and then use that area of physical memory for something else. When the process that used that memory area writes to or reads from it, Windows engages in some frenetic activity to load the data back from disk, into some memory area (could be the same, or other), and map the process' logical addresses there. The upshot of this is that in low memory conditions, the PC is transformed from an electronic beastie to a mechanical beastie, performing thousands and millions times slooooower. Ungood -- but when RAM sizes were small people thought virtual memory was neat.

20-20后见之明的结论之一是,转换方案允许使用虚拟内存,例如使用磁盘空间模拟RAM。Windows可以将内存内容复制到磁盘,然后将该物理内存区域用于其他内容。当使用该内存区域的进程对其进行写入或读取时,Windows会进行一些*的活动,将数据从磁盘加载回某些内存区域(可能是相同的,或者是其他的),并在其中映射进程的逻辑地址。这样做的结果是,在内存不足的情况下,PC会从电子机器人变成机械机器人,执行成千上万次slooooower。不好——但是当内存大小很小的时候,人们认为虚拟内存很好。

The main problem with virtual memory in today's Windows is that in practice it's almost impossible to turn that darn thing off. Even if there's only one "main" program running, and there's much more than adequate physical RAM available, Windows will proactively swap data to disk to be ready for when possibly that process may need even more logical memory. However, if this were fixed then something else would most probably appear in its stead; such is the nature of the Universe.

虚拟内存的主要问题在今天的窗户是在实践中几乎是不可能关掉那该死的事情。即使只有一个“主要”项目运行,有更充足的物理RAM可用,Windows将主动交换数据到磁盘时要准备好可能是这一过程可能需要更多的逻辑内存。然而,如果这是固定的,那么其他的东西很可能会代替它出现;这就是宇宙的本质。

Cheers & hth.,

欢呼声& hth。

#3


6  

Your premise is incorrect. You most certainly can read the memory of another process in Windows. You just can't do it be dereferencing a pointer because each process has a different view of memory. This is necessary for a variety of reasons, but the most important one is to prevent a bug in one program from corrupting other executing programs. (Another one is to prevent address space from being a scarce resource.)

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

#4


4  

You make it sound like you think memory protection is a bad thing!?

你让它听起来好像你认为保护记忆是件坏事!?

Uncontrolled access of one process's memory from another would generally lead to bugs, crashes, undefined behaviour, and more critically perhaps would be an open door to malware and viruses. You may write two processes that cooperate through shared memory nicely, but equally any other process either by error or maliciously could also access it. Moreover it would be very easy also to trash the OS kernel itself.

不受控制地从另一个进程访问一个进程的内存通常会导致错误、崩溃、不明确的行为,更关键的是,这可能会为恶意软件和病毒打开大门。您可以编写两个通过共享内存协作的进程,但同样,任何其他进程,无论是错误还是恶意,都可以访问它。此外,也很容易对OS内核本身进行垃圾处理。

Win16 ran originally as a graphical environment rather than a true OS on top of MS-DOS and was designed to work on early 16 bit x86 processors without an MMU to allow memory protection. The Win32S API was introduced later into Windows 3.x which provided a subset of Win32 features on Win16. Windows32 (originally Windows NT then concurrently Windows 95) takes advantages of features introduced with the 80386 to provide each process with its own memory environment invisible to any other except by invitation.

Win16最初是作为一个图形环境运行的,而不是在MS-DOS之上的一个真正的操作系统,它被设计为可以在没有MMU的16位x86处理器上运行,以支持内存保护。Win32S API后来被引入Windows 3。它提供了Win16上Win32特性的子集。Windows32(最初是windowsnt并发windows95)利用了80386引入的特性,为每个进程提供了自己的内存环境,除了邀请之外,其他进程都看不到这个内存环境。

This is what made Windows NT more robust that Win3.x. Windows 95 did not make full use of the protection mechanisms presumably for some level backward compatibility, so while more robust that Win3.x, it was not nearly as crash-proof as NT. Windows XP was the first "consumer" Windows OS to use the Windows NT/Windows 2000 code base, and discard much (but not all) of the Windows 95/MS-DOS compatibility baggage.

这就是Windows NT比Win3.x更健壮的原因。Windows 95并没有充分利用保护机制来实现某种程度的向后兼容性,因此Win3更加健壮。Windows XP是第一个使用Windows NT/Windows 2000代码库的“消费者”Windows操作系统,并抛弃了Windows 95/MS-DOS兼容性的大部分(但不是全部)。

If you wish to share data between processes the correct way to do it is through any recognised IPC mechanism. One such method is in fact through a memory mapped file, which is exactly a shared memory block, but with access controls so not just any process can see the memory.

如果您希望在进程之间共享数据,正确的方法是通过任何公认的IPC机制。一个这样的方法实际上是通过一个内存映射文件,它实际上是一个共享内存块,但是有访问控制,所以不是所有进程都能看到内存。

#5


2  

Well if you can mess around in the ram area of other processes it's an easy task to crash it. E.g you just have to set some pointer to NULL and the process will be gone. And well RAM are "private" parts of every process and you don't want anyone to access them won't you? Yes there is some way to access that probably if you do some kernel debugging.

如果你可以在其他进程的ram区域中乱涂乱画,那就很容易崩溃。E。你只需要将指针设置为NULL就行了。RAM是每个进程的“私有”部分你不希望任何人访问它们,不是吗?是的,如果您做一些内核调试,可能会有一些方法来访问它。