【问题标题】:How to retrieving variable value in C++ if you know the variable address如果您知道变量地址,如何在 C++ 中检索变量值
【发布时间】:2011-07-18 08:43:20
【问题描述】:

您好,

我最近开始用 C++ 编写代码,遇到了一个我无法找到答案的问题,所以我想也许其他人可能知道答案。

如果你知道变量地址,是否可以从另一个程序中检索变量值?假设我在程序中显示了一个内存地址,例如:0x7fff5fbff758 我想(在我自己的程序中,与第一个程序无关)获取存储在该内存地址中的

这可能吗?如果是这样,有人可以解释一下如何。 提前谢谢你。

【问题讨论】:

  • 您可以使用 Nawaz 的答案,尽管要小心您从内存位置读取的内容,或者更糟糕的是写入它们而没有除内存位置之外的其他实际参考,因为如果您的代码更改,它们往往会发生变化。
  • Ask the goal, not the step。是什么让您认为您需要这样做?
  • 我进行了编辑,以明确表示这个问题是关于跨流程边界阅读的,因为答案中对此存在一些混淆。
  • 完全公平,因为即使在第二次尝试中,他仍然无法以可以回答的方式提出问题 - 他正在使用的操作系统的信息仍然缺失。看看你是如何在你自己的答案中猜测他想要做什么的。
  • 公平地说,我认为他对他所要求的了解不够,以了解他使用的操作系统很重要。这是一个一般意义上的合理问题。

标签: c++ memory pointers memory-management


【解决方案1】:

编辑:这个已经过时了,因为问题已经改变了。

如果你知道变量的类型,那是可能的。

对于一个 int 变量,你需要像这样插入行

int* addr = (int*)0x7fff5fbff758;
std::cout << *addr << std::endl;

受影响程序中的某处。

在现代操作系统中,从不同程序访问变量通常并不容易,每个进程都有自己的地址空间,因此不同进程中的相同地址可能会映射到不同的物理内存位置。

这取决于操作系统,例如在 linux 中,如果你想从不同的进程中跟踪一个进程,请参阅man ptrace。在这种情况下,您可以使用 PTRACE_PEEKDATA 读取数据。

【讨论】:

  • 在 Windows 上,您只需调用 ReadProcessMemory()。
【解决方案2】:

在大多数现代通用操作系统(Windows、Linux 等)上,您不能这样做。不同的程序在不同的进程中运行,每个进程都有自己的内存空间。一个中的地址 0x7fff5fbff758 可能指向 RAM 中的一个非常不同的位置,而不是另一个中的地址 0x7fff5fbff758(如果该地址甚至存在于另一个中)。

这就是现代操作系统具有进程间通信机制的原因,例如管道、共享内存、COM 等。

【讨论】:

    【解决方案3】:

    在当今的操作系统上,程序处理的是虚拟地址,而不是物理地址。很快,一个程序的特定地址不会指向其他程序的相同物理位置。

    要在现代操作系统上做你想做的事,你可以,例如,设置一个共享内存位置。

    但是有很多更简单的方法可以将值从一个程序传递到另一个程序。

    如果您只是出于好奇而想知道,这是一个很好的问题,您可以看看什么是“虚拟内存”。

    【讨论】:

    • 您实际上可以从没有共享内存等的不同进程中读取进程的内存位置,方法与调试器相同(“跟踪”)。
    • 我认为调试器需要“调试信息”,例如使用 gcc 的 -g 选项获得。
    • @Ubuiquité “调试信息”用于符号寻址。如果您有实际地址,则无论如何都可以阅读。但这一定就是这么简单,而且平台之间的差异很大。
    【解决方案4】:

    C++ 对此没有任何评论,无论哪种方式。这完全取决于程序运行的平台。例如,如果您使用的是 Windows,则可以使用 ReadProcessMemory() 函数来读取另一个进程的内存(假设您有足够的权限)。

    请注意,现代操作系统旨在保护进程免受相互干扰。他们这样做的方法之一是为每个进程提供自己的地址空间。如果不使用特殊的 API,进程就无法访问此空间之外的内存。

    【讨论】:

      【解决方案5】:

      这是可能的,但它是特定于操作系统的(没有通用的 C 支持)。通常,您的第二个程序需要具有调试器所拥有的权限,并使用与调试器相同的操作系统调用。

      【讨论】:

      • 大多数现代通用操作系统不是为不同的进程使用不同的虚拟内存空间吗?如果是这样,那么这实际上是不可能的(除非 OP 在 RTOS 或 Amiga 上运行)。
      • 嗯。阅读您的其余答案,我想您可以使用调试器 API 来做到这一点。虽然不是最干净的 IPC 方法。 :-)
      猜你喜欢
      • 1970-01-01
      • 2019-07-14
      • 1970-01-01
      • 2010-10-17
      • 2020-05-11
      • 2011-04-01
      • 1970-01-01
      • 2021-08-31
      • 1970-01-01
      相关资源
      最近更新 更多