Memory 运行时内存(EXE、DLL)损坏

Memory 运行时内存(EXE、DLL)损坏,memory,dll,exe,checksum,corruption,Memory,Dll,Exe,Checksum,Corruption,我有一个应用程序(用delphi编译),它检查这个程序使用的内存加载模块(DLL和exe)的校验和。我正在检查DLL和exe的代码(文本)部分和重定位表部分 有时随着时间的推移,我得到了不同的校验和。它们在不同的DLL或exe上随机运行。有时它们出现在代码部分,有时出现在重新定位部分。它们看起来像这样: 代码部分: 重新定位表部分: 看起来总是这样。它总是在8字节的偏移量中,看起来像32个变化(具有一些相同的值)。我们也尝试将十六进制转换为汇编语言,但代码并没有任何意义。在重定位代码中也没有

我有一个应用程序(用delphi编译),它检查这个程序使用的内存加载模块(DLL和exe)的校验和。我正在检查DLL和exe的代码(文本)部分和重定位表部分

有时随着时间的推移,我得到了不同的校验和。它们在不同的DLL或exe上随机运行。有时它们出现在代码部分,有时出现在重新定位部分。它们看起来像这样:

代码部分:

重新定位表部分:

看起来总是这样。它总是在8字节的偏移量中,看起来像32个变化(具有一些相同的值)。我们也尝试将十六进制转换为汇编语言,但代码并没有任何意义。在重定位代码中也没有汇编程序。从不在同一个地址。通常也在不同的系统DLL中


什么会以这种方式损坏内存?是否存在一些软件来捕捉此类事件?有什么想法吗

有各种类型的软件喜欢将代码注入每个正在运行的进程。其中一些,如TeamViewer、防病毒程序和其他恶意软件,可能会修改受害者进程加载的模块,以便钩住某些系统功能。这是一种可能的解释

另一种解释可能是简单的重新定位,当一个模块无法在其首选基址加载时,因为地址范围将与已在使用的内存重叠(例如,动态分配或被另一个模块占用)。因此,修改DLL加载顺序可能会导致某些模块有时重新定位,有时则不会。第一段中提到的DLL注入是可能的原因之一

根据您的评论:仅查看两个部分十六进制转储,就很难判断损坏是有意义的/有目的的(比如由某个特定目标的软件引起的)还是随机的

即使是明显的随机腐败也可能是故意造成的,比如一些恶意软件试图通过堆喷洒、堆栈粉碎或类似方式获得牵引力。或者它可能是模块故障的结果,比如JPEG库被格式错误的图片绊倒

别忘了硬件故障。。。在热浪中运行有压力的程序时,我们的内存会出现断断续续的位翻转。当内存条在高负载下加热时,或者电源压力过大,输出质量开始下降时,也可能发生类似的情况

对不起,没有更多的数据,除了猜测之外,没有人能提供什么

然而,有些事情你可以自己调查,因为你完全可以控制程序。您显示的损坏转储(代码和重定位表)属于通常不可写的部分。如果您可以确定受影响的部分确实是只读的(例如通过),则可以排除程序中正常代码出现故障的假设,只留下恶意软件、god模式代码(驱动程序)故障和硬件故障

注意:允许目视检查正在运行的进程的内存,而无需使用
VirtualQuery()
编写代码

在Windows 95&Co.下,出现了一个特殊的问题,因为当修改其中一个映射时,内核在其他进程的地址空间中“回收”可执行文件的映射映像,而不采用写时复制(这意味着在所有其他进程中也可以看到该更改)

但这不应该发生在从NT衍生而来的Windowzen系列中,也就是从Windows 2000开始(是的,我们仍然有一个这样的产品在运行,因为它有一个用于昂贵定制硬件的特殊接口卡)。我之所以提到这个问题,只是因为它是一个例子,说明了正常的代码做正常的事情是如何在没有任何意义的情况下破坏损坏段的写保护的


如果损坏的部分没有写保护,那么您应该调查原因并修复问题。如果所有其他方法都失败,请使用。如果正常代码意外尝试写入受保护的段,则这将导致程序出现故障并终止,为此目的启动的程序可能会在出现故障时拍摄程序的快照(小型转储)。

我已关闭系统,没有网络,没有团队查看器,没有防病毒软件。我每2分钟检查一次DLL和exe。有时,它会运行数周而不关机,直到腐蚀occours。我重新计算addreses,所以它总是相同的校验和。一旦加载到内存中,这一点就不会改变,因为没有新的应用程序正在启动。“而且重新安置表不应该改变。”长颈鹿狮子:我已经修改了我的答案,以说明新的信息。什么数据会有用?我可以提供额外的数据。@Giraffe Lion:理想的情况是在腐败前后进行小型转储,但有些事情需要首先调查。请阅读我添加的有关VirtualQuery&Co的段落。我们使用windows 64位。但应用程序是32位的。我们尝试使用vmmap、OllyDbg和processexplorer。我们什么也没找到。文本/代码被读取/执行。重新定位表被读取。程序使用directx 9。我们有之前和之后的转储,但我不能张贴由于应用性质。我们怎么能从垃圾堆里找到东西?很难发现错误,因为很难(耗时)重现