問題のコードは explorer.exe にフックされますが、コールバック関数へのエントリでクラッシュしていました。
explorer.exe の 0x60055b50 (redacted.dll) で未処理の例外: 0xC0000005: アクセス違反の書き込み場所 0x548b0cca.
コールスタック:
> redacted.dll!myCallWndProcRetCallback(int nCode=0x00000000, unsigned int wParam=0x00000000, long lParam=0x015afa58) 行 799 C++ user32.dll!_DispatchHookW@16() + 0x31 バイト user32.dll!_fnHkINLPCWPRETSTRUCTW@20() + 0x5e バイト user32.dll!___fnDWORD@4() + 0x24 バイト ntdll.dll!_KiUserCallbackDispatcher@12() + 0x13 バイト user32.dll!_NtUserMessageCall@28() + 0xc バイト user32.dll!_SendMessageW@16() + 0x49 バイト explorer.exe!CTaskBand::_FindIndexByHwnd() + 0x21 バイト explorer.exe!CTaskBand::_HandleShellHook() + 0x48 バイト explorer.exe!CTaskBand::v_WndProc() + 0x660 バイト explorer.exe!CImpWndProc::s_WndProc() + 0x3f バイト
Visual Studio 2005 では、次の逆アセンブリが行われました。
--- c:\projects\redacted.cpp ------------------------- //------------------------------------------------ ------------------------------ LRESULT CALLBACK myCallWndProcRetCallback(int nCode, WPARAM wParam, LPARAM lParam) { 60055B50 inc dword ptr [ebx+548B0CC4h] 60055B56 と al,18h 60055B58 mov eax,dword ptr [g_callWndProcRetHook (600B9EE8h)] 60055B5D プッシュ esi
そして0x548B0CC4あたりのメモリはすべて?????? マップされたメモリではないため、クラッシュします。
myCallWndProcRetCallback の開始時のマシン コードは次のとおりです。
0x60055B50: ff 83 c4 0c 8b 54 24 18 a1 e8 9e 0b 60 56 52 57 50 ff 15 8c a6 09 60 5f 5e 83 c4 08 c2 0c 00 cc 8b 4c 24 04 8b 01 8b 50
ただし、Visual Studio では、この関数に対して次の逆アセンブリが提供される場合もあります。
--- c:\projects\redacted.cpp ------------------------- 60055B51 esp,0Ch を追加 if ( nCode == HC_ACTION && lParam != NULL) { 60055B54 mov edx,dword ptr [esp+18h] 60055B58 mov eax,dword ptr [g_callWndProcRetHook (600B9EE8h)] 60055B5D プッシュ esi
これは正しい逆アセンブルのように見えますが、上記の逆アセンブルよりも 1 バイト遅れています。0x60055B58 以降の命令は同じであることがわかります。
そのため、リンカは関数が 0x60055B50 にあると言っているように見えますが、コードは実際には 0x60055B51 から始まります。前者は Windows フックに設定されたコールバックであることを確認しました。そのため、Windows が関数にコールバックすると、不正なコードが実行されます。
私が持っている質問は、リンカーがこれをどのように誤解する可能性があるかということです? 再構築を行ったところ、問題はなくなりました。ランダムなようです。/FORCE:MULTIPLE リンカー オプションが有効であった時点で、このコールバックに対してリンク エラーは報告されません。
遅い追加: これは、DLL の再配置またはリベースに関連している可能性がありますか? 再配置が 1 バイトずれていた場合、これが問題の原因になる可能性がありますか?