繁体   English   中英

是否可以检查内存地址是否有效?

[英]Is it possible to check if a memory address is valid?

一位客户带着他们丢失了源代码的应用程序来找我。 加载某些文件时,此应用程序似乎随机崩溃。 我怀疑这个问题是由于竞争条件造成的,其中一个指针被删除,然后要么没有设置为 NULL,要么没有检查有效性。

当使用 OllyDBG 逐步完成程序集时,我发现崩溃总是发生在同一个位置,所以这有点强化我的理论。 这是它有时崩溃的装配线,有时是关键字。

MOV EDI,DWORD PTR DS:[EAX]

是否可以通过本机汇编或通过内联汇编调用(或类似的东西)提取地址的 C++ 来验证内存地址是否有效并且存在?

C++ 中没有通用的标准方法来验证内存地址。 也没有我所知道的这样的组装说明。

在内存映射系统(例如任何现代操作系统)上,您可以使用系统特定的 API 检查是否已为进程映射地址。 从 C++ 的角度来看,映射到进程的地址并不能保证该地址有效,但未映射的地址肯定是无效的。

此外,即使可以发现一个地址是有效的,也不能告诉您您期望的对象是在该地址中还是在其他地方。


在 C++ 语言1之外,还有一些用于验证内存访问的工具。 例如 Valgrind 和编译器提供地址清理器和内存清理器。 大多数情况下,这些有助于检测不会导致程序崩溃的无效访问。 但它们通常也可以提供有关该内存的附加信息。

1如果您有权访问源。

我怀疑这个问题是由于比赛条件造成的

能够验证内存地址并不能解决这个问题。 您应该做的1是使用调试器找出正在访问的对象,找到访问该对象的所有位置。 如果这些地方中的任何一个没有持有可能同时访问该对象的所有其他地方共有的互斥锁,那么这就是你的错误。

1如果您有权访问源。

丢失了源代码

如果您有大量预算,那么您可以尝试对其进行逆向工程并尝试弄清楚它在做什么。 我不会屏住呼吸; 最好将其宣布为失败的原因。

每个人都提供了一些很好的回应。 不幸的是,在这种情况下,客户不愿意为软件的完全重新开发付费。

我设法否定了崩溃......在确定崩溃发生的确切位置后,我使用了将代码注入到 JMP 到自定义 C++ 函数。 C++ 函数使用 __try __except 块。 在 Try 我放置了问题汇编代码,如果问题代码导致崩溃,__except 会捕获它。 之后,只需分析问题代码在做什么以及何时开始执行其他操作,然后在捕获异常时跳转到问题函数的“其他”部分的开头。

它并不能准确地检测内存位置是否有效,而只是在导致异常时跳过代码。 希望这最终对某人有所帮助...

是的,可以验证指针的内容。 但是,验证目标是否正确则比较困难。

为了验证指针,您需要:

  1. 有效地址范围表(实现的地址及其范围)。
    例如,在嵌入式系统上,解码的地址可能并非在所有位置都有内存或设备。
  2. 对于支持分页或虚拟内存的操作系统,您需要弄清楚程序内存区域的限制(由操作系统给出)。 操作系统可能会占用您的可执行文件的一部分并将它们与硬盘驱动器上的代码交换。
  3. 对于支持虚拟内存的操作系统,您必须确定允许指针访问的“虚拟”内存中的哪个位置。 阅读有关内存映射文件的信息。
  4. 在某些平台上,地址 0x0000 是有效地址。 验证您的目标平台上是否存在这种情况。

恕我直言,可以验证指针内容,但验证可能非常复杂。

更喜欢使用引用。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM