Frage

Der betreffende Code Haken in explorer.exe wurde aber über den Eintritt in die Callback-Funktion Absturz:

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

Aufrufhierarchie:

>     redacted.dll!myCallWndProcRetCallback(int nCode=0x00000000, unsigned int wParam=0x00000000, long lParam=0x015afa58)  Line 799  C++
      user32.dll!_DispatchHookW@16()  + 0x31 bytes    
      user32.dll!_fnHkINLPCWPRETSTRUCTW@20()  + 0x5e bytes  
      user32.dll!___fnDWORD@4()  + 0x24 bytes   
      ntdll.dll!_KiUserCallbackDispatcher@12()  + 0x13 bytes      
      user32.dll!_NtUserMessageCall@28()  + 0xc bytes 
      user32.dll!_SendMessageW@16()  + 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 ergab folgende Zerlegung:

--- 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  

und der Speicher um 0x548B0CC4 ist alles ?????? so ist sie nicht Speicher abgebildet, daher auch der Absturz.

Der Maschinencode zu Beginn des myCallWndProcRetCallback ist dies:

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 

Aber Visual Studio gibt auch manchmal die folgende Zerlegung für diese Funktion:

--- 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  

Das sieht aus wie die richtige Demontage, aber es ist aus 1 Byte später als die Demontage oben! Sie können sehen, die Anweisungen der gleiche von 0x60055B58 sind weiter.

So sieht es aus wie der Linker sagt die Funktion bei 0x60055B50 ist aber der Code tatsächlich beginnt bei 0x60055B51. Ich habe die ehemalige bestätigt der Rückruf in den Windows-Haken gesetzt ist. Also, wenn Windows ruft zurück in die Funktion führt sie schlechten Code.

Die Frage, die ich habe, ist, wie der Linker diese falsch bekommen? Ich habe eine wieder aufzubauen und das Problem ging weg, so scheint es zufällig. Zum Zeitpunkt der / FORCE: MULTIPLE Linker-Option war in der Tat ohne sie jedoch keinen Verbindungsfehler wird für diesen Rückruf berichtet

.

Eine späte Zugabe: Könnte dies die Verlagerung oder Rebasieren eine DLL in Beziehung gesetzt werden? Wenn die Verlagerung weg von 1 Byte ist, könnte dies vielleicht das Problem verursachen?

War es hilfreich?

Lösung

Relocations fast nie weg von 1 Byte sein; das DLL-Bild wird von VirtualAlloc wieder in die Granularität der Zuweisungen ausgerichtet werden, die 64k auf den meisten Maschinen sein sollte.

Wie lange hat dieser Code funktioniert? Wenn es zufällig ist dann die / FORCE: MULTIPLE könnte verdächtig sein. Oder Sie könnten IncrediBuild verwenden ...

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top