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;
}
}
Cảm ơn sự bảo đảm. =) –
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