首页
社区
课程
招聘
HOOK COM中的疑问?
发表于: 2014-6-12 19:55 3138

HOOK COM中的疑问?

2014-6-12 19:55
3138
首先感谢http://bbs.pediy.com/showthread.php?t=185397这篇文章的作者,
头文件:
#include<atlconv.h>
#include<atlstr.h>
#pragma comment(lib,"shell32.lib")
#pragma comment(lib,"ole32.lib")
#pragma comment(lib,"msvcrtd.lib")

HOOK部分,想优先尝试HOOK掉IShellLink->SetPath看看效果:
//////////////////////////////////////////HOOK COM 部分///////////////////////////////////
 //Hook 得到接口函数地址指针(模块,类GUID,接口GUID,函数名,失败返回的错误消息)返回值:接口函数地址指针
  static DWORD* GetComProcAddrPointer(HMODULE hMod,LPCTSTR szClsGuid,LPCTSTR szDispatchGuid,LPCTSTR szFunctionName,LPSTR szErrMsg=NULL);
  
  //Hook HookCom接口(模块,类GUID,接口GUID,函数名,新函数地址)返回值:原函数地址
  static DWORD HookComFunction(HMODULE hMod,LPCTSTR szClsGuid,LPCTSTR szDispatchGuid,LPCTSTR szFunctionName,DWORD dwNewFunAddr);

static DWORD* 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;
}

static DWORD 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;
}

//调用
typedef HRESULT  (WINAPI *PFNSETPATHA)( LPCTSTR pszFile);
PFNSETPATHA OldSetPath;

HRESULT TrueSetPath(LPCTSTR pszFile)
{
	MessageBox(0,pszFile,L"成功HOOK",0);
	return OldSetPath(pszFile);
}

DLL入口函数:
	 switch( fdwReason ) 
    { 
        case DLL_PROCESS_ATTACH:
			OldSetPath=(PFNSETPATHA)HookComFunction(LoadLibrary(L"ole32.dll"),L"{00021401-0000-0000-C000-000000000046}",L"{000214F9-0000-0000-C000-000000000046}",L"SetPath",(DWORD)TrueSetPath);
            break;
			//IShellLink--IID_IShellLink--接口GUID---000214F9-0000-0000-C000-000000000046
			//CLSID_ShellLink---类GUID---00021401-0000-0000-C000-000000000046


请大侠们看下哪里出了问题,最后祝大家世界杯开心。

[课程]Linux pwn 探索篇!

收藏
免费 0
支持
分享
最新回复 (0)
游客
登录 | 注册 方可回帖
返回
//