2010-09-11 8 views
5

Saluti StackOverflowians,API Hook su una funzione dell'oggetto COM?

come scoperto here, Windows 7 offre un bug in cui l'evento DISPID_BEFORENAVIGATE2 non viene generato per le istanze di Windows Explorer. Questo evento consente alle estensioni della shell di essere notificate quando sta per essere effettuata una navigazione e (soprattutto per me) avere l'opportunità di annullare la navigazione. Ho cercato una soluzione alternativa per un po 'di tempo, e penso di averne trovata una. Ma mi piacerebbe avere qualche opinione su quanto sia sicuro.

Ultimamente sto giocando con l'hook dell'API e lo sto già utilizzando per collegare alcune funzioni per la mia estensione. Ho notato che c'è un function in IShellBrowser che controlla la navigazione. All'inizio pensavo che non si potesse collegare qualcosa del genere, ma alla lettura dello layout of a COM object ho capito che dovrebbe essere possibile afferrando il giusto puntatore di funzione fuori dal vtable di qualsiasi istanza attiva. Abbastanza sicuro, funziona come un sogno. Dopo aver impostato il gancio, tutte le navigazioni in tutte le finestre di Explorer passano direttamente attraverso la mia funzione di deviazione, e posso decidere se rigettarle in base al loro pidl di destinazione.

Quindi la mia domanda è, c'è qualche ragione per cui NON dovrei farlo? Non ho mai sentito parlare di hook API utilizzato per agganciare le funzioni dell'oggetto COM. Ci sono circostanze che non avrebbe funzionato? È pericoloso? (Più che normale aggancio API, almeno)

Segue il codice pertinente. Sto usando MinHook, una libreria di hooking minimalista che utilizza il metodo provato e vero delle funzioni di trampolino.

typedef HRESULT (WINAPI *BROWSEOBJECT)(IShellBrowser*, PCUIDLIST_RELATIVE, UINT); 
HRESULT WINAPI DetourBrowseObject(IShellBrowser* _this, PCUIDLIST_RELATIVE pidl, UINT wFlags); 
BROWSEOBJECT fpBrowseObject = NULL; 
BROWSEOBJECT ShellBrowser_BrowseObject = NULL; 

bool Initialize() { 
    if(MH_Initialize() != MH_OK) { 
     return false; 
    } 

    // Get a reference to an existing IShellBrowser. Any instance will do. 
    // ShellBrowser enum code taken from The Old New Thing 
    IShellWindows *psw; 
    BOOL fFound = FALSE; 
    if (SUCCEEDED(CoCreateInstance(CLSID_ShellWindows, NULL, CLSCTX_ALL, IID_IShellWindows, (void**)&psw))) { 
     VARIANT v; 
     V_VT(&v) = VT_I4; 
     IDispatch *pdisp; 
     for (V_I4(&v) = 0; !fFound && psw->Item(v, &pdisp) == S_OK; V_I4(&v)++) { 
      IWebBrowserApp *pwba; 
      if (SUCCEEDED(pdisp->QueryInterface(IID_IWebBrowserApp, (void**)&pwba))) { 
       IServiceProvider *psp; 
       if (SUCCEEDED(pwba->QueryInterface(IID_IServiceProvider, (void**)&psp))) { 
        IShellBrowser *psb; 
        if (SUCCEEDED(psp->QueryService(SID_STopLevelBrowser,IID_IShellBrowser, (void**)&psb))) { 
         fFound = true; 

         // Grab the 11th entry in the VTable, which is BrowseObject 
         void** vtable = (*(void***)(psb)); 
         ShellBrowser_BrowseObject = (BROWSEOBJECT)(vtable[11]); 
         psb->Release(); 
        } 
        psp->Release(); 
       } 
       pwba->Release(); 
      } 
      pdisp->Release(); 
     } 
     psw->Release(); 
    } 

    if(fFound) { 
     if(MH_CreateHook(ShellBrowser_BrowseObject, &DetourBrowseObject, reinterpret_cast<void**>(&fpBrowseObject)) != MH_OK) { 
      return false; 
     } 
     if(MH_EnableHook(ShellBrowser_BrowseObject) != MH_OK) { 
      return false; 
     } 
    } 
    return true; 
} 

HRESULT WINAPI DetourBrowseObject(IShellBrowser* _this, PCUIDLIST_RELATIVE pidl, UINT wFlags) { 
    if(NavigateIsOkay(pidl, wFlags)) { 
     return fpBrowseObject(_this, pidl, wFlags); 
    } 
    else { 
     return S_FALSE; 
    }  
} 

risposta

2

Non ho mai sentito parlare di API aggancio utilizzato per agganciare le funzioni oggetto COM.

funzioni membro della oggetti COM non sono poi così diversi e possono in realtà essere agganciati bene se si bastone per le solite linee guida per aggancio. Alcuni anni fa, ho dovuto agganciare componenti COM di una soluzione CRM proprietaria per collegarlo a un server di database. L'applicazione ha funzionato bene e ha funzionato abbastanza stabile per diversi anni.

+0

Grazie per la rassicurazione. =) –

+1

Questa risposta è sbagliata. L'aggancio COM è molto speciale specialmente in Internet Explorer e non ha nulla in comune con l'aggancio API ordinario! Un oggetto COM può essere avvolto in un oggetto wrapper e alla fine si aggancia solo il wrapper. Leggi i collegamenti in questo articolo: http://stackoverflow.com/questions/1505196/spying-on-com-objects – Elmue