2010-09-11 30 views
5

Lời chào StackOverflowians,API Hook trên một hàm đối tượng COM?

Khi phát hiện here, Windows 7 có lỗi trong trường hợp sự kiện DISPID_BEFORENAVIGATE2 không kích hoạt cho các phiên bản Windows Explorer. Sự kiện này cho phép tiện ích mở rộng vỏ được thông báo khi điều hướng sắp diễn ra và (quan trọng nhất đối với tôi) có cơ hội hủy điều hướng. Tôi đã tìm kiếm một cách giải quyết một thời gian, và tôi nghĩ rằng tôi đã tìm thấy một. Nhưng, tôi muốn nhận được một số ý kiến ​​về mức độ an toàn của nó.

Gần đây tôi đã chơi với API nhiều lần và tôi đã sử dụng nó để móc một vài chức năng cho tiện ích mở rộng của mình. Tôi nhận thấy rằng có một số function in IShellBrowser điều khiển điều hướng. Lúc đầu, tôi nghĩ rằng bạn không thể móc một cái gì đó như thế, nhưng khi đọc về các layout of a COM object tôi nhận ra nó nên có thể bằng cách chỉ cần lấy con trỏ chức năng bên phải ra khỏi vtable của bất kỳ trường hợp hoạt động. Chắc chắn, nó hoạt động như một giấc mơ. Sau khi móc được đặt, tất cả các điều hướng trong tất cả các cửa sổ Explorer chạy ngay qua chức năng đường vòng của tôi và tôi có thể quyết định có từ chối chúng dựa trên pidl đích của chúng hay không.

Vì vậy, câu hỏi của tôi là, có lý do nào tôi KHÔNG nên làm điều này không? Tôi chưa bao giờ nghe nói về API hooking được sử dụng để móc các hàm đối tượng COM. Có hoàn cảnh nào mà nó sẽ không hoạt động? Có nguy hiểm không? (Ít hơn số API thường xuyên tìm kiếm, ít nhất)

Mã có liên quan sau. Tôi đang sử dụng MinHook, một thư viện hooking tối giản sử dụng phương pháp thử và đúng của các chức năng trampoline.

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

Trả lời

2

Tôi chưa bao giờ nghe nói về API hooking sử dụng để treo các chức năng đối tượng COM.

hàm thành viên của COM Objects không thực sự là khác nhau và thực sự có thể được nối tốt nếu bạn dính vào các nguyên tắc thông thường cho hooking. Một vài năm trước, tôi đã phải kết nối các thành phần COM của một giải pháp CRM độc quyền để kết nối nó với một máy chủ cơ sở dữ liệu. Ứng dụng này hoạt động tốt và đã hoạt động khá ổn định trong nhiều năm.

+0

Cảm ơn sự bảo đảm. =) –

+1

Câu trả lời này là sai. COM hooking rất đặc biệt, đặc biệt là trong Internet Explorer và không có điểm gì chung với việc sử dụng API thông thường! Một đối tượng COM có thể được gói vào một đối tượng bao bọc và cuối cùng bạn chỉ móc trình bao bọc. Đọc các liên kết trong bài viết này: http://stackoverflow.com/questions/1505196/spying-on-com-objects – Elmue

Các vấn đề liên quan