问题背景:
在使用HOOK来监视IE进程时,可以捕获到一些普通的DLL调用,比如loadLibrary(mshtml.dll)等。
问题描述:
当IE使用activeX时,在网页中一般这样写<object id=some classid="clsid:xxxxxxxxxx"></object>
与此同时,ie“应该是”去获取clsid在注册表中所对应的dll,然后装载它,比如这个clsid对应的是 pp.dll
问题1 我根本捕获不到LoadLibraryA(或W 或ExA或ExW)pp.dll的行为,为什么?(换句话说,ie用什么操作来装载ACTIVEX)
问题2 activeX pp.dll这个东西一般会有个DllGetObjectClass,他返回类工厂用来CreateInstance, hook它没有效果呀。
比如pp.dll暴露的接口只有DllUnloadxxx DllGetObjectClass ,一般而言只能勾他们,勾不住类工厂创建的实例里的函数,
难道非得勾住DllGetObjectClass 然后记录下类工厂,再勾住类工厂的CreateInstance,然后修改它返回的instance里面的虚函数表,然后再勾??
经实验,ie是使用CoGetClassObject获得类工厂
然后调用类工厂的CreateInstance
然后从获得的实例当中在调用方法
如果想hook 必须这三个方法都得hook住
尤其后两个,注意编译的时候要加CINTERFACE编译项,好让vptr指针暴露出来。
例子可以看msra出品的detours的第一个例子,好像叫commem。
hook代码:
获取要hook的模块:
HMODULE ole32 = GetModuleHandle(_T("ole32.dll")); if (!ole32) ole32 = LoadSystemLibrary(_T("ole32.dll")); if (ole32) { RealCoGetClassObject = (PROC_CoGetClassObject)GetProcAddress(ole32, "CoGetClassObject"); if (RealCoGetClassObject) DetourAttach(&(PVOID&)RealCoGetClassObject, HookedCoGetClassObject);
}
实现hook后的处理方法:
HRESULT WINAPI HookedCoGetClassObject(REFCLSID rclsid, DWORD dwClsContext, LPVOID pvReserved, REFIID riid, LPVOID FAR* ppv) { TCHAR szVal[MAX_PATH + 1] = { 0 }; DWORD dwType = REG_SZ, cbData = MAX_PATH; #if 1//打印object 对象的 classid { LPOLESTR lplpsz; StringFromCLSID(rclsid, &lplpsz); DUITRACE(L"xdbrclsid:%s", lplpsz); } #endif if (IsEqualCLSID(CLSID_MediaPlayer, rclsid)) { ::SHGetValue(HKEY_CLASSES_ROOT, _T("CLSID\{6BF52A52-394A-11d3-B153-00C04F79FAA6}\InprocServer32"), _T(""), &dwType, szVal, &cbData); if (szVal[0]) { CString strFile(szVal); ::ExpandEnvironmentStrings(strFile, szVal, MAX_PATH); if (!::PathFileExists(szVal)) return REGDB_E_CLASSNOTREG; static TCHAR szVer[64] = { 0 }; if (!szVer[0]) GetFileVersion(szVal, szVer, SIZEOF(szVer) - 1); if (CompareVersion(szVer, _T("11.0.0.0")) >= 0) { ::PathRemoveFileSpec(szVal); ::PathAppend(szVal, _T("MFPlat.dll")); if (!::PathFileExists(szVal)) return REGDB_E_CLASSNOTREG; } ::PathRemoveFileSpec(szVal); ::PathAppend(szVal, _T("wmploc.dll")); if (!::PathFileExists(szVal)) return REGDB_E_CLASSNOTREG; } }else if (IsEqualCLSID(CLSID_HHCtrl, rclsid)) { LPOLESTR lplpsz; StringFromCLSID(rclsid, &lplpsz); DUITRACE(L"xdbrclsid:%s", lplpsz); TCHAR szVal[MAX_PATH + 1] = { 0 }; DWORD dwType = REG_SZ, cbData = MAX_PATH; ::SHGetValue(HKEY_CLASSES_ROOT, _T("CLSID\{52A2AAAE-085D-4187-97EA-8C30DB990436}\InprocServer32"), _T(""), &dwType, szVal, &cbData); if (szVal[0]) { DUITRACE(L"xdbrclsid:%s", szVal); } }else if(IsEqualCLSID(CLSID_iWebOffice, rclsid)) { LPOLESTR lplpsz; StringFromCLSID(rclsid, &lplpsz); DUITRACE(L"xdbrclsid:%s", lplpsz); TCHAR szVal1[MAX_PATH + 1] = { 0 }; DWORD dwType = REG_SZ, cbData = MAX_PATH; // CLSID\{D89F482C-5045-4DB5-8C53-D2C9EE71D024}\InprocServer32 ::SHGetValue(HKEY_CLASSES_ROOT, _T("CLSID\{D89F482C-5045-4DB5-8C53-D2C9EE71D025}\InprocServer32"), _T(""), &dwType, szVal1, &cbData); if (szVal1[0]) { DUITRACE(L"xdbrclsid:%s", szVal1); } } else if (IsEqualCLSID(CLSID_saxfileBAD, rclsid) || IsEqualCLSID(CLSID_shiyouBAD, rclsid) ) { //url is .. return REGDB_E_CLASSNOTREG; } HRESULT hr = REGDB_E_CLASSNOTREG; if (hr != S_OK) hr = RealCoGetClassObject(rclsid, dwClsContext, pvReserved, riid, ppv); return hr;
判断classid的值:
//classid=clsid:230C3D02-DA27-11D2-8612-00A0C93EEA3C const CLSID CLSID_saxfileBAD = { 0x230C3D02, 0xDA27, 0x11D2,{ 0x86, 0x12, 0x00, 0xa0, 0xc9, 0x3e, 0xea, 0x3c } }; //{62B4D041 - 4667 - 40B6 - BB50 - 4BC0A5043A73} const CLSID CLSID_shiyouBAD = { 0x62B4D041, 0x4667, 0x40B6,{ 0xbb, 0x50, 0x4b, 0xc0, 0xa5, 0x04, 0x3a, 0x73 } };