browser icon
You are using an insecure version of your web browser. Please update your browser!
Using an outdated browser makes your computer unsafe. For a safer, faster, more enjoyable user experience, please update your browser today or try a newer browser.

关于窗口隐藏

Posted by on 2008 年 02 月 11 日

你可以任意转载本文,但请在转载后的文章中注明作者和原始链接。
媒体约稿请联系 titilima_AT_163.com(把“_AT_”换成“@”)。

出于各种目的,很多窗口都会对自身进行保护和隐藏,以使一些其他的进程无法通过特征来找到自己——这里说的隐藏就是指隐藏自己的特征,以避开诸如FindWindow、EnumWindows等API的查找。比较典型的例子包括一些Anti-Rootkit工具、IM和网游的登录窗口等等。现在通用的方法是随机生成字符串作为窗口标题(IceSword、SREng)或处理WM_NCPAINT自绘标题条(Rootkit Unhooker、QQ医生)等等。
但是,随机字符串不够美观,自绘标题条很难达到系统默认的效果,因此这两种方法皆非我所欲也。所幸,Windows窗口标题的管理和绘制机制给我们提供了一个捷径。
由CreateWindow(Ex)创建的窗口,会将窗口标题字符串保存在内存中的某处。DefWindowProc在处理WM_NCPAINT的时候,会向窗口发送WM_GETTEXT消息获取标题字符串,然后进行绘制。而在默认情况对WM_GETTEXT的处理,则是返回的CreateWindow(Ex)保存的某处。那么,我们只要特殊处理WM_GETTEXT就可以了。下面列出代码片段:

C++代码
  1. TCHAR g_szText[] = _T("FindMe!");   
  2.   
  3. LRESULT CALLBACK WndProc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam)   
  4. {   
  5.     static BOOL bNcPaint = FALSE;   
  6.   
  7.     LRESULT ret = 0;   
  8.     switch (uMsg)   
  9.    {   
  10.     case WM_GETTEXT:   
  11.        {   
  12.            if (bNcPaint)   
  13.            {   
  14.                LPTSTR p = reinterpret_cast<LPTSTR>(lParam);   
  15.                lstrcpyn(p, g_szText, static_cast<int>(wParam));   
  16.                ret = lstrlen(g_szText);   
  17.            }   
  18.        }   
  19.        break;   
  20.     case WM_NCPAINT:   
  21.     case WM_NCACTIVATE:   
  22.        {   
  23.            bNcPaint = TRUE;   
  24.        }   
  25.         // fall   
  26.     default:   
  27.        ret = DefWindowProc(hwnd, uMsg, wParam, lParam);   
  28.     }   
  29.     bNcPaint = FALSE;   
  30.     return ret;   
  31. }  

完整代码见附件。

附件:findme.zip

订阅本站

7 Comments

  • At 2008.02.15 19:31, sislcb said:

    老马,你好。

    假如我是第三方的软件,想使其他程序通过findwindow无法找到某个窗口,但这个窗口的程序不是我写的,这时候有什么办法呢?谢谢了!

    • At 2008.02.15 20:29, 李马 said:

      To sislcb:
      可以试试加载驱动,挂钩SSDT Shadow的NtUserFindWindowEx。

      • At 2008.02.16 13:07, sislcb said:

        哦,原来是这个函数啊!!
        非常感谢了!!!

        • At 2008.03.28 00:06, sislcb said:

          马哥,请问下spy++的原来是什么啊?
          不是通过EnumWindow,FindWindow,WindowFromPoint来获得窗口和句柄吗?
          谢谢了!!

          • At 2008.03.28 13:53, sislcb said:

            马哥,他应该是通过GetWindow和GetWindowText来获得的,但是我Hook了NtUserInternalGetWindowText,不过没什么效果,有没有什么好的方法可以过这个呢。

            • At 2008.03.28 14:17, 李马 said:

              To sislcb:
              挂钩NtUserFindWindowEx可以防止其它程序调用FindWindow来查找你指定的窗口。
              spy++应该就是通过你所说的方式来枚举窗口的。注意,屏蔽NtUserInternalGetWindowText并不一定能达到你隐藏窗口文本的目的,因为程序可能通过发送WM_GETTEXT来获取窗口文本。

              • At 2008.03.28 14:42, sislcb said:

                恩,是的
                要防GetWindowText,就需要马哥的方法了。
                对付GetWindow貌似没什么好办法

                (Required)
                (Required, will not be published)