Solved

redirecting function to another version of dll

Posted on 2009-04-09
2
749 Views
Last Modified: 2013-12-14
Hi,

I would like to redirect a COM interface method into another version of same dll. I use Detours 2.1 Express to hook the function. in the snippet you can see a sample of hooking the IWebBrowser2::Navigate2 method. it works as expected but not as needed :) what I need is to call the Navigate2 method from custom dll (redirect it).

This is not a problem when it's an ordinary function like i.e. Sleep from kernel32.dll (I can use LoadLibrary, GetProcAddress or DetourFindFunction which in fact tries to use LoadLibrary...). Problem is how to call a COM interface method from custom dll. Any suggestions? Will appreciate any help. Thank you in advance.
#define CINTERFACE
 

#include <windows.h>

#include "detours.h"

#include <stdlib.h>

#include <iostream>

#include <string.h>
 

#include <ObjBase.h>

#include <ExDisp.h>
 

using namespace std;
 

//function prototype

HRESULT (__stdcall *RealNavigate2)(IWebBrowser2 *This,

								VARIANT *URL,

								VARIANT *flags,

								VARIANT *TargetFrameName,

								VARIANT *PostData,

								VARIANT *Headers) = NULL;
 

//detour function

HRESULT __stdcall NewNavigate2(IWebBrowser2 *This,

							VARIANT *URL,

							VARIANT *flags,

							VARIANT *TargetFrameName,

							VARIANT *PostData,

							VARIANT *Headers)

{

	//HERE IT CALLS THE ORIGINAL IWebBrowser2::Navigate2

	//I NEED TO REDIRECT IT TO OTHER VERSION OF SAME DLL

	cout << "hooked Navigate2 :)" << endl;

	HRESULT hr = RealNavigate2(This, URL, flags, TargetFrameName, PostData, Headers);

	return hr;

}
 
 

int main(int argc, char **argv){

	

	if(SUCCEEDED(OleInitialize(NULL))){

		

		IWebBrowser2 *pBr;

		CoCreateInstance(CLSID_InternetExplorer, NULL, CLSCTX_LOCAL_SERVER, IID_IWebBrowser2, (void**)&pBr);

		

		//assigning the target function for detouring

		RealNavigate2 = pBr->lpVtbl->Navigate2;

		

		//this part is not important, only some string processing

		string url = "http://www.google.com";

		VARIANT myURL;

		VariantInit(&myURL);

		myURL.vt = VT_BSTR;
 

		#ifndef UNICODE

		{

			wchar_t		*buffer;

			DWORD		size;
 

			size = MultiByteToWideChar(CP_ACP, 0, url.c_str(), -1, 0, 0);

			if (!(buffer = (wchar_t *)GlobalAlloc(GMEM_FIXED, sizeof(wchar_t) * size))){

				cout << "badalloc" << endl;

				getchar();

				return 0;

			}

			MultiByteToWideChar(CP_ACP, 0, url.c_str(), -1, buffer, size);

			myURL.bstrVal = SysAllocString(buffer);

			GlobalFree(buffer);

		}

		#else

		myURL.bstrVal = SysAllocString(url);

		#endif		

		

		//attaching target and detour function

		DetourTransactionBegin();

		DetourUpdateThread(GetCurrentThread());

		DetourAttach(&(PVOID&)RealNavigate2, NewNavigate2);

		DetourTransactionCommit();
 

		VARIANT vFlags;

		V_VT(&vFlags) = VT_I4;

		V_I4(&vFlags) = navOpenInNewWindow;

		

		VARIANT vEmpty;

		VariantInit(&vEmpty);
 

		//calling the target function, which gets hooked and it will jump to execution of NewNavigate2 detour function

		HRESULT hr = pBr->lpVtbl->Navigate2(pBr, &myURL, &vEmpty, &vEmpty, &vEmpty, &vEmpty);

		if (SUCCEEDED(hr))

		{

			pBr->lpVtbl->put_Visible(pBr, VARIANT_TRUE);

		}

		else

		{

			pBr->lpVtbl->Quit(pBr);

		}
 

		pBr->lpVtbl->Release(pBr);
 

		OleUninitialize();
 

		

	}

	

	return 0;

}

Open in new window

0
Comment
Question by:StraySod
2 Comments
 
LVL 39

Accepted Solution

by:
itsmeandnobodyelse earned 500 total points
Comment Utility
A COM Dll is registered in registry what means that only one (probably the youngest) version is currently active.

The only way I know to call a dll of different version (beside of explicitly loading from file) is to register it in the .manifest file of your application. AFAIK that could be done with MSI but I never did it myself. And I don't know either whether it works for COM as well (but there is a good chance cause the .manifest simply overrules normal registry entries).

Note, for using .manifest files you need XP or Vista.
0
 
LVL 7

Author Closing Comment

by:StraySod
Comment Utility
Ok, thank you for your reply :) will try it
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Introduction: Load and Save to file, Document-View interaction inside the SDI. Continuing from the second article about sudoku.   Open the project in visual studio. From the class view select CSudokuDoc and double click to open the header …
Jaspersoft Studio is a plugin for Eclipse that lets you create reports from a datasource.  In this article, we'll go over creating a report from a default template and setting up a datasource that connects to your database.
This tutorial covers a step-by-step guide to install VisualVM launcher in eclipse.
The viewer will learn how to use NetBeans IDE 8.0 for Windows to connect to a MySQL database. Open Services Panel: Create a new connection using New Connection Wizard: Create a test database called eetutorial: Create a new test tabel called ee…

772 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

14 Experts available now in Live!

Get 1:1 Help Now