2010-09-11 13 views
5

życzenia StackOverflowians,Funkcja API Hook na funkcji obiektu COM?

Jak odkryte here, Windows 7 znajduje się błąd, w którym zdarzenie DISPID_BEFORENAVIGATE2 nie ognia dla instancji Windows Explorer. Zdarzenie to umożliwia powiadomienie o rozszerzeniach powłoki, gdy nawigacja ma się odbyć, i (co najważniejsze dla mnie) mają możliwość anulowania nawigacji. Szukałem obejścia od dłuższego czasu i myślę, że znalazłem jeden. Ale chciałbym poznać opinie na temat tego, jak bezpieczne.

Ostatnio dużo grałem w API, a używam go już do podpięcia kilku funkcji do mojego rozszerzenia. Zauważyłem, że istnieje function in IShellBrowser, który kontroluje nawigację. Na początku myślałem, że nie można czegoś takiego zawiesić, ale po przeczytaniu o layout of a COM object zdałem sobie sprawę, że powinno być to możliwe, po prostu pobierając wskaźnik funkcji właściwej z vtable każdej aktywnej instancji. Rzeczywiście, działa jak marzenie. Po ustawieniu haka wszystkie nawigacje we wszystkich oknach Eksploratora przebiegają przez moją funkcję objazdu i mogę zdecydować, czy je odrzucić na podstawie docelowego pidl.

Moje pytanie brzmi: czy istnieje jakikolwiek powód, dla którego NIE powinienem tego robić? Nigdy nie słyszałem o hakowaniu API używanym do przechwytywania funkcji obiektów COM. Czy istnieją okoliczności, które by nie zadziałały? Czy to jest niebezpieczne? (Co najmniej więcej niż zwykłe zahaczenie API).

Odpowiedni kod następuje. Używam minimalnej biblioteki zaczepiania, która wykorzystuje wypróbowaną i prawdziwą metodę funkcji trampolin.

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

Odpowiedz

2

Nigdy nie słyszałem o API zahaczanie wykorzystywane spinanie funkcji obiektu COM.

Funkcje członków obiektów COM nie są tak różne i mogą być w rzeczywistości wciągnięte, jeśli trzymasz się zwykłych wytycznych dotyczących zahaczania. Kilka lat temu musiałem podłączyć komponenty COM zastrzeżonego rozwiązania CRM, aby połączyć je z serwerem bazy danych. Aplikacja działała dobrze i działała dość stabilnie od kilku lat.

+0

Dzięki za pewność. =) –

+1

Ta odpowiedź jest błędna. Wciąganie COM jest bardzo szczególne, szczególnie w Internet Explorerze i nie ma nic wspólnego ze zwykłym zahaczaniem API! Obiekt COM może być zawinięty w obiekt owijki, a na końcu tylko zaczepić opakowanie. Przeczytaj linki w tym artykule: http://stackoverflow.com/questions/1505196/spying-on-com-objects – Elmue