我有一个更具理论性的问题,包括指针和内存分配
让我们说例如我有一个正在运行的进程,它已经分配了从0x01到0x03的2个字节
如果我想从那个内存中读取,我可能会使用ReadProcessMemory
但是我特意给出了什么指针?是它是一个相对指针还是一个绝对指针?
让我们说这个指针是相对的,所以我用一个指向0x00的指针调用ReadProcessMemory
但Windows如何知道进程内存的开始位置和结束位置?
Windows是否必须保存内存属于(或被分配)进程的点的地址?
但Windows在哪里保存这些信息,以及它如何知道保存信息的位置?我听说过一种叫做“基指针”的东西。我想这就是我要找的东西。
内存属于进程的地方。
好的,但现在让我说我想复制一个进程的内存(硬盘驱动器可能?)来清理我的内存一段时间。然后我想把内存放回原来的位置,但是我不能告诉windows'从0x00c到0x80c'分配2048个字节。
我不得不说'在某处分配2048个字节'然后Windows告诉我那个'在哪里' '是。
但是,如果我再次重新启动我的应用程序,我将不得不告诉它'hello进程,你的整个内存不再是0x01,它现在是0x0c'。
有没有办法解决这个问题?也许c#或c ++或只是一个意见(同样是一个理论问题。不管是好还是坏,只是可能吗?)。
答案 0 :(得分:1)
好的,但现在让我说我想复制一个进程的内存(硬盘驱动器可能?)来清理我的内存一段时间。然后我想把内存放回原来的位置,但我不能告诉windows'从0x00c到0x80c分配2048个字节'。
简单地自己分配内存。 Windows是一个虚拟内存系统。如果它无法将东西放入物理内存中,那么它只会将内存分页回磁盘。你不需要做任何工作来导致这种情况发生。
编辑:在对评论的更多回复中,如果您想要实际解除分配其他进程使用的内存,那么您完全没有运气。您无法可靠地确定目标进程如何使用该内存,并且由于访问冲突,您可能会立即终止目标进程。
此外,Windows NT和衍生产品上的所有内存分配都归结为VirtualAlloc函数,这些函数只能在调用进程的上下文中使用 - 您无法强制其他进程为您执行此操作。
我想你可以自己编写一个内核驱动程序,它会将随机垃圾写入内存管理器,使其按照你想要的方式运行,但至少你会导致目标进程失败,并且很可能会失败。整个系统。
但同样,你的问题从根本上没有意义,因为Windows 已经做出决定这样就将进程的内存转移到磁盘而言。 Windows是virtual memory系统,特定的内存位置仅在现有流程的上下文中有意义。
答案 1 :(得分:1)
好问题。这里有一些你可能感兴趣的东西......
对于初学者,您不能释放其他进程的内存,也不能将其写入磁盘。基本上你看不到我们的触摸或对其他进程的记忆做任何事情。但是,假设你做了,不知何故,现在你想恢复它...你担心你不能在以前的同一个地方重新分配它,那么如何找到你可以分配它的位置以及如何做你告诉过程它现在的位置。答案是你不需要 - 你可以在任何你想要的地方分配它,即使另一个进程已经在使用该地址。 (请记住,这都是假设,因为你甚至无法开始做你想做的事。)
每个进程都可以访问所有内存,假设从零到4GB。 (我们对此处的细节不感兴趣。)进程A可以在0x0处分配内存,因此进程B也可以。每个进程都认为它的内存为0x0,但实际上并不是这样。
进程看不到物理内存地址。它看到了“虚拟内存地址空间”。由硬件支持的操作系统维护一个表,该表将物理内存地址映射到虚拟地址。每个进程都有一个这样的表。当进程A分配其第一个字节时,操作系统可能会在物理内存中将该字节分配为0x1000,然后在进程A的页表中写入一个条目,表示“虚拟0x0000 =物理0x1000”。从现在开始,每当进程A引用地址0x0000时,硬件(不是操作系统)在表中查找0x0000并发现它实际上意味着0x1000,并且读取/写入为0x1000。当进程B分配其第一个字节时,操作系统可能会在物理地址0x2000处分配它,但在B的页表中分配虚拟地址0x0000。这就是两个进程同时使用相同地址的方式。
(显然我遗漏了很多细节,包括用户模式的内存管理器。)
所以,对你的问题。如果你以某种方式释放了所有B的内存并且现在想要恢复它,你可以将它恢复到之前的位置(在B的虚拟地址空间中)。它可能在物理内存中有所不同,但你不需要了解或关心这一点,你不需要告诉进程B它。