IE 9 Code Hooking

c++ / delphi package - dll injection and api hooking
Post Reply
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

IE 9 Code Hooking

Post by ameetmalekar »

Hello madshi,

I am trying to hook methods such as all_get, body_get from the interface IHTMLDocument2 of mshtml.dll.
I am using HookCode for this

HookCode((PVOID)(4277513), Newbody_get, (PVOID*) &Unhookbody_get);

The pointer value(3869255) I got from "Blade API Monitor"

I am injecting the library only in child process iexplore.exe where these methods get called and not in parent process iexplore.exe.

But when I inject my dll IE get crashed :(.
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Re: IE 9 Code Hooking

Post by madshi »

The exact address may vary from one process run to the next. You should search for the address at runtime instead of hard coding it.

Look at the following demo to see how you can hook interface methods:

http://madshi.net/HookDirect3D.zip

Please note that when counting method numbers, you need to count the methods of all interfaces that the target interface was inherited from, too. E.g. you always have to add 3 for "AddRef", "Release" and "QueryInterface".
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: IE 9 Code Hooking

Post by ameetmalekar »

Hello madshi,
Thanks for reply,

I already referred the forum
viewtopic.php?f=7&t=27157&p=44051&hilit=IE9#p44051

There also I am getting the same error of IE crashing. Also I tried hooking interface methods of Direct Write, direct 2D and Direct 3D dlls but ended up with either IE crashing or no any effect. That's why I am trying with hard coded pointer first. I observed that for my PC pointer address values for these methods(all_get, body_get) are not changing for a single time. I also tried with/without initializemadCodeHook().

I am trying on win7 64bit and 32bit OS but IE9 is 32bit only. (not using IE 64 bit)
For confirming the hook I have written log in hooked methods and not changed any change parameters while unhooking. I tried writing logs before and after Unhook(Next)ing method. Logs gets created for dllmain(), but not getting created for any hooked method.

Note:- 1. Protected Mode is turned off for Internet Explorer.
2. If IE crashes with logs for any method, it also gets crash without writing logs for the same method.

Ameet
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Re: IE 9 Code Hooking

Post by madshi »

I'd suggest that you try hooking one of those interfaces in your own process first, then call the interfaces yourself and check if the hook works. This way you can test much faster, you don't need to inject a dll first, and you can step through everything in the debugger. If you can't get the hooking to work at all even in your own process, then please try to create a little (as little as possible) test project which demonstrates this problem. Ideally the test project should hook itself, only, that would make it much easier for me to find out what's wrong.
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: IE 9 Code Hooking

Post by ameetmalekar »

I am trying to hook get_all method of interface IHTMLDocument2
Here is part of the code

Code: Select all

LPVOID GetInterfaceMethod(LPVOID intf, DWORD methodIndex)
{
  return (LPVOID)(*(DWORD*)intf + methodIndex * 4);
}

HRESULT (WINAPI *Unhookget_all)(IHTMLElementCollection **p);
HRESULT WINAPI Newget_all(IHTMLElementCollection **p)
{
	HRESULT retVal=Unhookget_all(p);
	return retVal;
}
///////////////////////////////
class BHO : public IObjectWithSite, public IDispatch 
{ long ref;
IWebBrowser2* webBrowser;
IHTMLDocument* doc; IHTMLDocument2 *doc2;
IHTMLWindow2 *win2;
public:
	// IUnknown...
	HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv)
	{
		if (riid==IID_IUnknown) *ppv=static_cast<BHO*>(this); 
		else if (riid==IID_IObjectWithSite) 
			*ppv=static_cast<IObjectWithSite*>(this); 
		else if (riid==IID_IDispatch) 
			*ppv=static_cast<IDispatch*>(this); 
		else 
			return E_NOINTERFACE; 
		AddRef(); 
		return S_OK;
	} 
	ULONG STDMETHODCALLTYPE AddRef() 
	{
		InterlockedIncrement(&gref); return InterlockedIncrement(&ref);
	}
	ULONG STDMETHODCALLTYPE Release() 
	{
		int tmp=InterlockedDecrement(&ref); 
		if (tmp==0) 
			delete this; 
		InterlockedDecrement(&gref); 
		return tmp;
	}

	// IDispatch...
	HRESULT STDMETHODCALLTYPE GetTypeInfoCount(unsigned int FAR* pctinfo) 
	{
		*pctinfo=1;
		return NOERROR;
	}
	HRESULT STDMETHODCALLTYPE GetTypeInfo(unsigned int iTInfo, LCID lcid, ITypeInfo FAR* FAR*  ppTInfo) 
	{
		return NOERROR;
	}
	HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, OLECHAR FAR* FAR* rgszNames, unsigned int cNames, LCID lcid, DISPID FAR* rgDispId)
	{
		return NOERROR;
	}

	HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, LCID lcid, WORD wFlags, DISPPARAMS FAR* pDispParams, VARIANT FAR* pVarResult, EXCEPINFO FAR* pExcepInfo, unsigned int FAR* puArgErr)
	{ 
		// DISPID_DOCUMENTCOMPLETE: This is the earliest point we can obtain the "document" interface
		if (dispIdMember==DISPID_DOCUMENTCOMPLETE)
		{ 
//			MessageBoxA(NULL,"DISPID_DOCUMENTCOMPLETE","",NULL);
			if (!webBrowser) 
				return E_FAIL; 
			IDispatch *idisp; 
			webBrowser->get_Document(&idisp);
			if (idisp && !doc2) 
			{
				idisp->QueryInterface(IID_IHTMLDocument2,(void**)&doc2);
				HookCode(GetInterfaceMethod(doc2,8), Newget_all, (PVOID*) &Unhookget_all);

				char szEnter[6]={13,0,10,0,0,0};
				FILE *fp1=_wfopen(L"D:\\MyLog\\Invoke.txt",L"ab+");
				fwprintf(fp1,L"doc2-->%ld__MethodAddr-->%ld%s",*doc2,GetInterfaceMethod(doc2,8),szEnter);
				fclose(fp1);

			}
			if (idisp)
				idisp->Release();
			if (!doc2 )
			{
				release();
				return E_FAIL;
			}
			return NOERROR;
		}

		
		return NOERROR;
	}

	// IObjectWithSite...
	HRESULT STDMETHODCALLTYPE GetSite(REFIID riid, void** ppvSite) 
	{
		return E_NOINTERFACE;
	}
	HRESULT STDMETHODCALLTYPE SetSite(IUnknown* iunk)
	{ // This is called by IE to plug us into the current web window
		release();
		iunk->QueryInterface(IID_IWebBrowser2, (void**)&webBrowser);
		IConnectionPointContainer *cpc=0; 
		iunk->QueryInterface(IID_IConnectionPointContainer, (void**)&cpc);
		IConnectionPoint* cp=0; 
		if (cpc) 
			cpc->FindConnectionPoint(DIID_DWebBrowserEvents2, &cp);
		DWORD cookie; 
		HRESULT hr; if (cp) hr=cp->Advise(static_cast<IDispatch*>(this), &cookie);
		if (!webBrowser || !cpc || !cp || hr!=S_OK) 
		{
			if (cp) 
				cp->Release(); 
			if (cpc) 
				cpc->Release(); 
			release(); 
			return E_FAIL;}
		return S_OK;
	}

	// BHO...
	BHO() : ref(0), webBrowser(0), doc(0), doc2(0), win2(0) {};
	~BHO() 
	{
		release();
	}
	void release() 
	{
		if (webBrowser) 
			webBrowser->Release(); 
		webBrowser=0; 
		if (doc) 
			doc->Release(); 
		doc=0; 
		if (doc2) 
			(doc2)->Release(); 
		doc2=0; 
		if (win2) 
			win2->Release(); 
		win2=0;
	}


};
Here are some Decimal values of pointers for an instance
mshtml.dll base address->1797783552
mshtml.dll size ->12300288
mshtml.dll end address ->1810083840
*doc2 --> 1808995600
Method Addr--> 1808995632 (returned from GetInterfaceMethod(doc2,8))

get_all is the first method in IHTMLDocument2 interface
IHTMLDocument2 is inherited from IHTMLDocument which has 1 method
IHTMLDocument is inherited from IDispatch which have 4 methods
and IDispatch is inherited from IUnknown which has 3 methods

so I took the index 8(1+4+3+1-1)

Though the method getting called(in BladeAPIMonitor), not getting intercepted :(
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Re: IE 9 Code Hooking

Post by madshi »

Does HookCode return true or false? If it returns false, what does GetLastError say?
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: IE 9 Code Hooking

Post by ameetmalekar »

Code: Select all

err1=GetLastError();
BOOL retvalM=HookCode(GetInterfaceMethod(doc2,8), Newget_all, (PVOID*) &Unhookget_all);
err2=GetLastError();
HookCode returning false :(
We are getting the values as
err1 = 0
retvalM = 0
err2 = 7798786
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Re: IE 9 Code Hooking

Post by madshi »

Sadly, error code "7798786" = "0x770002" means "code not interceptable", which means that the assembly code of the function you want to hook is structured in such a way that madCodeHook can not safely hook it, without risking stability. Maybe the code is too short? madCodeHook needs the code size to be at least 6 bytes. Please check with the debugger or with a disassembler how long the code is of the function you want to hook.

Maybe you should look into manipulating the interface method table itself instead of hooking with madCodeHook? E.g. instead of reading "(LPVOID)(*(DWORD*)intf + methodIndex * 4)", you could try writing to it. But first unprotect with VirtualProtect. I've never tried this myself yet, but it might just work.
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: IE 9 Code Hooking

Post by ameetmalekar »

Thanks Madshi,

I will try manipulating vtable. But the pointer returned by HookCode is pointing to all_get method?
Is the any way to confirm this?
ameetmalekar
Posts: 29
Joined: Thu Feb 16, 2012 5:12 am

Re: IE 9 Code Hooking

Post by ameetmalekar »

I tried below method to confirm if we are pointing to proper method, but IE getting crashed.

Code: Select all

typedef HRESULT (*funcPointer)(IHTMLElementCollection**);
funcPointer myget_all;
myget_all=(funcPointer)GetInterfaceMethod(doc2,8);
IHTMLElementCollection* IECol1;
myget_all(&IECol1);
long len1;
IECol1->get_length(&len1);
madshi
Site Admin
Posts: 10764
Joined: Sun Mar 21, 2004 5:25 pm

Re: IE 9 Code Hooking

Post by madshi »

Interface methods have a hidden first "self" or "this" parameter.
Post Reply