CFrameWndEx

[戻る]
きゆろひ 2009/08/27(木) 05:15:05
お世話になります。

VS2008 pro SP1でMFC SDIプロジェクトを作成してテストしていましたところ
実行ファイルがウィルスバスター2009から
 NtUserSetWindowsHookEx
 DLL (プログラムライブラリ) インジェクション
の不正変更があるとの警告を受けました

NtUserSetWindowsHookExとはSetWindowsHookExの使用のことかもしれないと
プロジェクトを検索したところ
プロジェクトを作成する際にコマンドバー(メニュー/ツールバー/リボン)で
クラシックメニューを使用するを選択せずに、デフォルトのメニューバーと
ツールバーを使用するを選択するとCMainFrameがCFrameWndExから生成され
このウィンドウの生成のCreatEx内でSetWindowsHookExを使用していることが
わかりました。

SetWindowsHookExとウィルスバスターの関係も理解しておりませんが、
この現象を無視してリリースをしたら、ウィルス入りソフトと誤解をうけかねません。

CMainFrameをCFrameWndから派生するように変更して現象の再現があるかを
これから検証するのですが、なにか技術的なご教授をいただければありがたいです。

開発:動作環境
VisualStudio 2008 pro SP1 C++ MFC SDIプロジェクト
OS:Windows Vista Ultimate SP2
   WindowsXP Pro SP3
セキュリティソフト ウィルスバスター 2009

あんたの環境が感染しているんじゃないの?的な回答はなしでお願いします。
(頭はちょっと感染しているかもしれませんが)

仲澤@失業者 2009/08/27(木) 11:53:09
ウイルス検出ソフトが不正検出と判定するようだと、話題になってますね。

継承関係は
CWnd
  +CFrameWnd
     +CMDIFrameWnd
        +CFrameWndEx

となっているので、CFrameWndにすると、最新フレームワークの機能の
ほとんどが使用できなくなるようです。

VS2008でウイザードでプロジェクトを生成した場合は、結構苦しむかも
しれません。

tetrapod 2009/08/27(木) 14:07:43
ごっごる先生に NtUserSetWindowsHookEx を尋ねてみたら大量ヒット
TeraTerm Sleipnir 等有名ソフトでも発生しているようだ。

そのソフトは[DLL インジェクションに使いうる手段]と同じ機能を使っているよ、
という警告らしい。ウイルスバスターの過剰反応だね。
俺なら気にしない。

きゆろひ 2009/08/28(金) 02:33:14
「高」レベルの警告ダイアログがデカデカと表示されるわけですから、一般ユーザーは
まず使用を敬遠するでしょうし、ソフトなお客様からのNGは確実で、ウィルスバスタ
ーが悪いという言い訳はまず通じません。

私的には環境が整うまではCFrameWndExの使用の見合わせ、必要な機能なら自作する方向
で、マイクロソフトな人とバスターな人に問題解決をゆだねたいのですが、ほんとに
SetWindowsHookExの使用でウィルスバスターが反応しているのか、資料も再現率もデー
タが足りなすぎます。

そういった点でのご教授がございましたらよろしくお願いします。

ryo 2009/08/28(金) 08:36:45
厳しいお客様が相手なら、
ネット上で、「掲示板で言ってた」やら
「どこかの誰かが個人で調べたデータ」は通用しないのではないでしょうか

マイクロソフトか、トレンドマイクロに直接聞くのが一番確実だと思います

gak 2009/08/28(金) 17:09:50
> 資料も再現率もデータが足りなすぎます
有用なデータとなるかは別として、俺の同僚が経験した1例を紹介。

プログラムコードから空のFDドライブにアクセスする処理を行うと、「ディスクを挿入し
てください」というメッセージを OS が(コチラは望んでいないのに)勝手に出す。
それを防ぐため SetErrorMode() APIでシステムが出すエラーメッセージを制限していた
が、ウイルスバスター2008環境で実行すると NtUserSetWindowsHookEx 警告が出る。

この現象について
・SetErrorMode() が関数内部で SetWindowsHookEx() を呼んでいる可能性がある
・SetWindowsHookEx() 関数は使い様によっては他アプリを乗っ取る事も可能な関数
・そのため、ウイルスバスター2008は SetWindowsHookEx() を呼んでいるアプリを警告対
 象にしている可能性がある
・ただ、実際に SetWindowsHookEx() を利用して悪い事をやってるかどうかの判断は難し
 いので、とりあえず怪しい奴がいたら報告するので悪い奴かどうかの判断は貴方がして
 くれという方針(ホワイトリスト)を採っているのかも
・「このアプリが問題無い事は保証しますので、設定で警告対象から外してください」
という対応をお客には取ったそうだ。

この話の通りならば、ウイルスバスターの過剰反応でこちらに非は無い、と俺も思う。
アンチウィルスソフトと云えども全能では無いのだから、その過剰反応のために
CFrameWndEx を使わないという選択肢は取りたくないなぁ。

きゆろひ 2009/08/29(土) 01:37:59
ryo様

>ネット上で、「掲示板で言ってた」やら
>「どこかの誰かが個人で調べたデータ」は通用しないのではないでしょうか
>マイクロソフトか、トレンドマイクロに直接聞くのが一番確実だと思います

その通りです。解決できなければ聞く予定ですが、そのためには単純な再現コードなど
を用意して、簡潔にお聞きしないといけないですよね。
(私は急いでいませんし、間違いかもしれないので慎重でありたいと思っています)
掲示板で皆様の意見を聴くのはそういった準備のひとつです。

gak様

同僚様が経験した1例は大変参考になります。ありがとうございました。

>この話の通りならば、ウイルスバスターの過剰反応でこちらに非は無い、と俺も思う。
>アンチウィルスソフトと云えども全能では無いのだから、その過剰反応のために
>CFrameWndEx を使わないという選択肢は取りたくないなぁ。

お仕事としてプログラムを作る立場で、「ウイルスバスターを使用している一般の人に
も売れる製品を作りたい」と、思うならウイルスバスターが安全と認めない作法のプロ
グラムは作れないですよね。
ただ、今のところは、ここでは私の推測だけで皆様にCFrameWndExの使用で問題は出てい
ませんかとお聞きしているところですので、CFrameWndExを使っちゃいけないと過剰反応
する前に、使用している人の間で「問題ないよ」「あるかも」といったお話が聞けるこ
とはとてもありがたいです。

きゆろひ 2009/08/30(日) 01:27:05
CFrameWndExだけじゃなくて、CFileDialog、GetSaveFileNameでファイルを保存する場合
も再現するようです。

GetSaveFileName()なんてSDKにまで警告が出るところが理解不能 
VC++ 2008だけの問題じゃないのでしょうか?

きゆろひ 2009/08/30(日) 02:22:48
メモ書きみたいになりますが、CFrameWndExをCFrameWndに変更するだけでは足りなかっ
たようですので、以下を追加して再現を確認しています。

CXXXXAppがCWinAppExから派生されていましたのでCWinAppに変更しました。

CXXXXApp::InitInstanceに生成されていた以下の行を削除しました

 INITCOMMONCONTROLSEX InitCtrls;
 InitCtrls.dwSize = sizeof(InitCtrls);
 InitCtrls.dwICC = ICC_WIN95_CLASSES;
 InitCommonControlsEx(&InitCtrls);

 InitContextMenuManager();
 InitKeyboardManager();
 InitTooltipManager();
 CMFCToolTipInfo ttParams;
 ttParams.m_bVislManagerTheme = TRUE;
 theApp.GetTooltipManager()->SetTooltipParams(AFX_TOOLTIP_TYPE_ALL,
                              RUNTIME_CLASS(CMFCToolTipCtrl), &ttParams);

 ghAccelTable = LoadAccelerators(AfxGetInstanceHandle(),
 MAKEINTRESOURCE(IDR_MAINFRAME));

 VC6.0が生成したInitInstanceと比較して、必要なさそうなところを
 一式という感じです。

上記の対応でエラーとなったViewの処理を削除しました。

void CXXXXView::OnRButtonUp(UINT nFlags, CPoint point)
{
    ClientToScreen(&point);
    OnContextMenu(this, point);
}

void CXXXXView::OnContextMenu(CWnd* pWnd, CPoint point)
{
    theApp.GetContextMenuManager()->ShowPopupMenu(IDR_POPUP_EDIT,
                     point.x, point.y, this, TRUE);
}

これでも、再現したらお手上げ(かも)です。

きゆろひ 2009/08/30(日) 11:25:21
CWinAppEx→CWinAppの変更を行いましたが、GetSaveFileNameでファイルを保存する際に
再現しましたので、Explorer-style Save dialog boxに変更して再現するか確認してい
ます。

きゆろひ 2009/08/31(月) 02:20:56
[[解決]]
GetOpenFileNameのほうですが、Explorer-style Save dialog boxでも再現しました。

フックプロシジャーを以下にして
UINT CALLBACK FileSaveOFNHookProc(HWND hdlg,UINT uiMsg,WPARAM wParam,LPARAM 
lParam)
{
    return DefWindowProc(hdlg, uiMsg, wParam, lParam) ;
}
ofn.Flags = OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_ENABLEHOOK ;
ofn.lpfnHook = FileSaveOFNHookProc;
でGetOpenFileNameを発行

ところが、
ofn.Flags = 
OFN_OVERWRITEPROMPT|OFN_HIDEREADONLY|OFN_EXPLORER|OFN_ENABLEHOOK|OFN_SHOWHELP ;
としたところ、今のところ再現しません。
(再現率が下がってるだけの可能性が高いですが)

CFrameWndExもGetOpenFileNameも、これ以上ここでの回答は得られそうにないので、後
はryoさんの助言に従って、インシデントを一つ使ってマイクロソフトさんに確認するこ
とにします。

とゆうことで「解決」です。
ありがとうございました。

きゆろひ 2009/09/03(木) 05:47:16
追記

Explorer-style もファイルの読み出し、保存ともに条件がそろえば再現率100%でした。
問題解決までの当面の対応としてold-styleのダイアログを使用することにしました。

古いスレッドには追加発言できません。