【文章标题】:Hook Com接口函数
【文章作者】:yhswwr(SilenceRet)
【作者QQ】:3412259
【编写语言】:C++
【使用工具】:VS2008.VC++9
【本文链接】:http://bbs.pediy.com/showthread.php?p=1266677
【参考链接】:http://bbs.pediy.com/showthread.php?p=1266677
【作者声明】:该贴仅供参考,失误之处请指教 转载请注名出处
DWORD* CHook::GetComProcAddrPointer( HMODULE hMod,LPCTSTR szClsGuid,LPCTSTR szDispatchGuid,LPCTSTR szFunctionName,LPSTR szErrMsg/*=NULL*/ )
{
DWORD *pdwResult=NULL;
USES_CONVERSION;
CString strDispatchGuid(szDispatchGuid);
//得到模块全路径
CStringW strDllFilePathW;
DWORD dwSize=::GetModuleFileNameW(hMod,strDllFilePathW.GetBuffer(1025),1024);
strDllFilePathW.ReleaseBuffer(dwSize);
//载入TypeLib
ITypeLib *pLib;
HRESULT ret=::LoadTypeLib(strDllFilePathW,&pLib);
if (ret!=S_OK)
{
if(szErrMsg) strcpy(szErrMsg,"载入TypeLib失败");
return pdwResult;
}
//得到接口函数偏移
int nFunctionOffset=-1;
int nTypeInfoCount=pLib->GetTypeInfoCount();
for (int i=0;i<nTypeInfoCount;i++)
{
ITypeInfo *pTypeInfo;
ret=pLib->GetTypeInfo(i,&pTypeInfo);
TYPEATTR* pta;
ret=pTypeInfo->GetTypeAttr(&pta);
if (pta->typekind==TKIND_DISPATCH)
{
CString strGuid;
strGuid.Format(_T("{%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X}"),
pta->guid.Data1,pta->guid.Data2,pta->guid.Data3
,pta->guid.Data4[0],pta->guid.Data4[1],pta->guid.Data4[2],pta->guid.Data4[3],
pta->guid.Data4[4],pta->guid.Data4[5],pta->guid.Data4[6],pta->guid.Data4[7]);
if (strDispatchGuid.CompareNoCase(strGuid)==0) //比较DispatchGuid
{
int nFunCount=pta->cFuncs;
for (int j=0;j<nFunCount;j++)
{
FUNCDESC* pfd;
pTypeInfo->GetFuncDesc(j, &pfd);
BSTR bstrName;
pTypeInfo->GetDocumentation(pfd->memid, &bstrName,NULL, NULL, NULL);
pTypeInfo->ReleaseFuncDesc(pfd);
CString strFunName(W2A(bstrName));
if (strFunName.CompareNoCase(szFunctionName)==0) //比较函数名
{
nFunctionOffset=j;
break;
}
}
}
}
pTypeInfo->ReleaseTypeAttr(pta);
if (nFunctionOffset!=-1) break;
}
if (nFunctionOffset==-1)
{
if(szErrMsg) strcpy(szErrMsg,"查找接口函数失败");
return pdwResult;
}
typedef int (WINAPI *DllGetClassObjectPtr)(REFCLSID, REFIID, LPVOID*);
//得到DllGetClassObject函数地址
DllGetClassObjectPtr pDllGetClassObject = (DllGetClassObjectPtr)GetProcAddress(hMod, "DllGetClassObject");
CoInitialize(NULL);
CLSID rclsid;
IID riid;
::CLSIDFromString(A2W(szClsGuid), &rclsid);//类ID
::IIDFromString(A2W(szDispatchGuid), &riid);//接口ID
IClassFactory *pICF = NULL;//类工厂接口指针
if(pDllGetClassObject(rclsid, IID_IClassFactory, (void**)(&pICF))==S_OK)//获取类工厂接口指针
{
DWORD *pClassObject=NULL;
if(pICF->CreateInstance(NULL, riid, (void**)&pClassObject)==S_OK)//创建COM对象
{
pdwResult=(DWORD *)*pClassObject+nFunctionOffset;
}else{
if(szErrMsg) strcpy(szErrMsg,"创建COM对象失败");
}
pICF->Release();
}else{
if(szErrMsg) strcpy(szErrMsg,"获取类工厂接口指针失败");
}
CoUninitialize();
return pdwResult;
}
DWORD CHook::HookComFunction( HMODULE hMod,LPCTSTR szClsGuid,LPCTSTR szDispatchGuid,LPCTSTR szFunctionName,DWORD dwNewFunAddr )
{
CHAR szErrMsg[64]={0};
DWORD *pAddress=GetComProcAddrPointer(hMod,szClsGuid,szDispatchGuid,szFunctionName,szErrMsg);
if (!pAddress) MsgErrorAndExitProcess(szErrMsg);
DWORD dwResult=*pAddress;
DWORD dwTmp=dwNewFunAddr;
CMemory::WriteMemory((DWORD)pAddress,(BYTE *)&dwTmp,4);
return dwResult;
}
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!