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

HOOK COM中的疑问?

2014-6-12 19:55
3257
首先感谢http://bbs.pediy.com/showthread.php?t=185397这篇文章的作者,
头文件:
1
2
3
4
5
#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看看效果:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//////////////////////////////////////////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入口函数:
1
2
3
4
5
6
7
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


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

[注意]看雪招聘,专注安全领域的专业人才平台!

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

账号登录
验证码登录

忘记密码?
没有账号?立即免费注册