2009-01-22 15 views
2

問題掛鉤到Explorer.exe的代碼,但被撞毀在進入回調函數:函數指針在Visual Studio 2005中不正確的代碼開始於1個字節偏移

Unhandled exception at 0x60055b50 (redacted.dll) in explorer.exe: 0xC0000005: Access violation writing location 0x548b0cca.

調用堆棧:

 
>  redacted.dll!myCallWndProcRetCallback(int nCode=0x00000000, unsigned int wParam=0x00000000, long lParam=0x015afa58) Line 799 C++ 
     [email protected]() + 0x31 bytes  
     [email protected]() + 0x5e bytes 
     [email protected]() + 0x24 bytes 
     [email protected]() + 0x13 bytes  
     [email protected]() + 0xc bytes 
     [email protected]() + 0x49 bytes  
     explorer.exe!CTaskBand::_FindIndexByHwnd() + 0x21 bytes  
     explorer.exe!CTaskBand::_HandleShellHook() + 0x48 bytes  
     explorer.exe!CTaskBand::v_WndProc() + 0x660 bytes  
     explorer.exe!CImpWndProc::s_WndProc() + 0x3f bytes 

的Visual Studio 2005提供了以下拆解:

 
--- c:\projects\redacted.cpp ------------------------- 
//------------------------------------------------------------------------------ 
LRESULT CALLBACK myCallWndProcRetCallback(int nCode, WPARAM wParam, LPARAM lParam) { 
60055B50 inc   dword ptr [ebx+548B0CC4h] 
60055B56 and   al,18h 
60055B58 mov   eax,dword ptr [g_callWndProcRetHook (600B9EE8h)] 
60055B5D push  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 add   esp,0Ch 
    if (nCode == HC_ACTION && lParam != NULL) { 
60055B54 mov   edx,dword ptr [esp+18h] 
60055B58 mov   eax,dword ptr [g_callWndProcRetHook (600B9EE8h)] 
60055B5D push  esi 

這個貌似正確的拆卸,但它比上面的反彙編晚了1個字節!你可以看到從0x60055B58開始的指令是一樣的。

因此,它看起來像鏈接器說函數在0x60055B50,但代碼實際上從0x60055B51開始。我已經確認前者是設置到Windows鉤子的回調。所以當Windows回調函數時,它會執行錯誤的代碼。

我的問題是鏈接器如何得到這個錯誤?我做了重建,問題消失了,似乎是隨機的。當/ FORCE:MULTIPLE鏈接器選項有效時,如果沒有它,則不會爲此回調報告鏈接錯誤。

後期增加:這可能與DLL的重定位或重新綁定有關嗎?如果重定位關閉了1個字節,這可能會導致問題?

回答

0

重定位幾乎不會被關閉1個字節; .dll映像必須與VirtualAlloc返回的分配粒度對齊,在大多數機器上該分配應該爲64k。

此代碼有效多久?如果它是隨機的,那麼可能會懷疑/ FORCE:MULTIPLE 。或者你可以使用Incredibuild ...

+0

是的,我正在使用Incredibuild。你看到這個問題了嗎? – AlexGP 2009-01-23 05:24:45