2

問題のコードは 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 バイトずれていた場合、これが問題の原因になる可能性がありますか?

4

1 に答える 1

0

再配置が 1 バイトずれることはほとんどありません。.dll イメージは、ほとんどのマシンで 64k になる VirtualAlloc によって返される割り当ての粒度に合わせる必要があります。

このコードはどのくらい機能しましたか? ランダムな場合は、/FORCE:MULTIPLEが疑わしい可能性があります。または、Incredibuild を使用している可能性があります...

于 2009-01-22T23:59:27.480 に答える