【问题标题】:Why does this program sometimes crash, and sometimes not?为什么这个程序有时会崩溃,有时不会?
【发布时间】:2011-06-24 04:37:03
【问题描述】:

以下程序会关闭显示器。当我运行它时,它有时会崩溃,但有时不会。反汇编只是指向一个像0x00011000这样的随机位置,并没有真正的信息。

如果我重新编译程序并运行它,重新编译的版本在我测试它时运行良好。但是下次我真的需要使用它时,它又崩溃了,我需要重新编译它……让我一开始就后悔这样做了。

我不知道如何始终如一地重现错误。(也就是说,除了在我最需要它时运行它并看着它崩溃。) p>

什么可能导致该程序随机崩溃?

#include <Windows.h>
#include <tchar.h>

int WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int)
{
    return SendMessage(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
}

我使用的是 Windows 7 x64,并将其编译为 32 位程序。我相信我在 64 位上尝试过同样的事情并得到了同样的结果,尽管我不能 100% 确定。


编辑 1:

  • 如果有人真的复制了这个,请发表评论告诉我,我很好奇其他人是否可以复制这个。

  • 我目前正在自己​​测试一个稍微精简的版本(不依赖于 C 运行时):

    #include <Windows.h>
    #pragma comment(linker, "/NoDefaultLib")
    #pragma comment(linker, "/Entry:mainCRTStartup")
    #pragma comment(linker, "/Subsystem:Windows")
    
    int mainCRTStartup()
    {
        return SendMessageW(HWND_BROADCAST, WM_SYSCOMMAND, SC_MONITORPOWER, 2);
    }
    
    /*
    Base64 version of this program, in case you want to use it:
    TVqQAAMAAAAEAAAA//8AALgAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAwAAAAA4fug4AtAnNIbgBTM0hVGhpcyBwcm9ncmFtIGNhbm5vdCBiZSBydW4gaW4gRE9TIG1vZGUuDQ0KJAAAAAAAAAABkN3fRfGzjEXxs4xF8bOMhv7ujEbxs4xF8bKMRPGzjIb+0IxE8bOMhv7pjETxs4xSaWNoRfGzjAAAAAAAAAAAUEUAAEwBAQBYIgROAAAAAAAAAADgAA8BCwEHCgACAAAAAAAAAAAAAAgQAAAAEAAAACAAAAAAQAAAEAAAAAIAAAQAAAAAAAAABAAAAAAAAAAAIAAAAAIAAAAAAAACAAAEAAAQAAAQAAAAABAAABAAAAAAAAAQAAAAAAAAAAAAAAAoEAAAKAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAudGV4dAAAAHQAAAAAEAAAAAIAAAACAAAAAAAAAAAAAAAAAAAgAABgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABYEAAAAAAAAGoCaHDxAABoEgEAAGj//wAA/xUAEEAA99gbwPfYw8zMUBAAAAAAAAAAAAAAaBAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFgQAAAAAAAAQgJTZW5kTWVzc2FnZVcAAFVTRVIzMi5kbGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==
    */
    

    目前,这个版本可以工作......但是当我重新编译它时,前一个版本也是如此。如果事实证明这个没有崩溃,我会在这里发布。

  • 如果你想重现这个,我的建议是:编译程序,让它腌一两天。 :) 当您使用计算机一段时间后,请尝试运行该程序几次...当我尝试这样做时,我通常会收到错误,直到我重新编译该程序。


编辑 2:

出于某种原因,只要您想人们展示一个问题,它就会神奇地得到解决。同上这里的情况。我将继续尝试重现该错误,但目前,它似乎工作正常。 :\(我怀疑这可能是因为安装了 Windows 7 SP1,但我真的很怀疑……如果我发现我会在这里发帖。)

对不起大家...


编辑 3:

好吧...碰巧,每当您需要重现错误时,您都不能。 :|

不过,至少我发现了一些别的东西:似乎发送消息的正确窗口是GetShellWindow()返回的窗口。希望这对其他人有用。

【问题讨论】:

  • +1。这真是一团糟。你到底是怎么偶然发现这颗宝石的?
  • @Mikola:当然,我使用了科学过程!所有的发现不都是这样的吗?!
  • 您可以尝试将return SendMessage 更改为仅返回0,并将SendMessage 放在它之前的行...
  • 当您真正需要环境工作时,它还有什么不同?例如正在运行的其他进程?
  • 理论:另一个应用程序正在执行 DLL 注入、窗口挂钩,或者有一种创造性的方式来进入所有进程。 (只需查看 S.O. 上询问如何完成此操作的问题数量!)安全软件因这样做而臭名昭著,因为它们想“帮助”您的过程。注入你的进程的代码可能有一个隐藏的窗口和一个错误的钩子。连接 windbg 并运行 lmvm 命令(我认为是这样)以查看崩溃时正在运行的所有 DLL。

标签: winapi sendmessage


【解决方案1】:

也许您已经看到了这一点,但this article by Windows god Raymond Chen 的要点是不建议以这种方式使用 HWND_BROADCAST。我通过comments 在一个不应命名的站点上找到了这个,大意是您在此处使用的示例代码虽然很流行,但不是处理显示器断电的正确方法。

这并不能解释为什么你看到的正是你所看到的,但它确实提供了一些证据表明有问题的代码是可疑的。

【讨论】:

    【解决方案2】:

    配置您的病毒扫描程序,让应用程序不受影响,不干扰它。

    您的应用距离evil winmain 太近,无法在此处忽略病毒扫描程序。

    【讨论】:

      【解决方案3】:

      唯一有意义的事情。如果你重新编译它,你的说法是它正在散列 exe 并以某种方式干扰它。 100 次中有 99 次是病毒扫描程序 - 但你说你没有?

      1. 您构建了 exe。它的哈希值为 0x1234。
      2. 您运行它。病毒扫描程序对其进行哈希处理,让它运行,然后确定它正在做一些它不喜欢的事情(例如向所有窗口广播关闭消息)。
      3. 您再次运行它。病毒扫描程序说“看起来 0x1234 又开始了;我要对其进行修补以阻止它广播关闭消息,或者我会完全停止它的运行”。
      4. 您重建了 exe。它有一个 0x4321 的新哈希(哈希更改仅仅是因为它有一个新的创建/修改日期)。
      5. 回到 2。

      【讨论】:

        猜你喜欢
        • 2017-04-01
        • 2021-07-23
        • 1970-01-01
        • 2011-04-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多