跟踪调试COM组件的接口----Editbyhklzt刚一开始,对于COM组件的接口,真的不知如何下手,就更谈不上调试IE里的某个ActiveX控件了。在Snake的熏陶下,我经过一翻努力,终于找到了一种方法可以跟踪调试COM组件的接口。为了跟踪调试COM组件的接口,这里需要先了解一些基本知识。Idispatch接口如下:interfaceIDispatch:IUnknown{virtualHRESULTGetTypeInfoCount(UINT*pctinfo)=0;virtualHRESULTGetTypeInfo(UINTitinfo,LCIDlcid,ITypeInfo**pptinfo)=0;virtualHRESULTGetIDsOfNames(REFIIDriid,LPOLESTR*rgszNames,UINTcNames,LCIDlcid,DISPID*rgdispid)=0;virtualHRESULTInvoke(DISPIDdispidMember,REFIIDriid,LCIDlcid,WORDwFlags,DISPPARMS*pdispparams,VARIANT*pvarResult,EXCEPINFO*pexcepinfo,UINT*puArgErr)=0;}1、GetTypeInfoCount():用于获取自动化组件支持的ITypeInfo接口的数目。2、GetTypeInfo():用于获取指针ITypeInfo接口的指针,通过该指针将能够判断自动化服务程序所提供的自动化支持。3、GetIDsOfNames():读取一个函数的名称并返回其调度ID(DISPID)。DISPID*rgdisped:是一个long类型的数据,对于IDispatch的一个特定实现,此DISPID值应该是唯一的。REFIIDriid:为保留参数,必须设置为IID_NULL,在rgszNames中指定了成员的函数名及其参数,由cNames标识了名字的个数,lcid参数用于指定本地化标识,得到的DISPID将保存到rgdispid中。4、Invoke():提供了访问自动化对象暴露出来的方法和属性的方法。将DISPID作为函数指针数组的索引传入dispidMember参数,Invoke()将实现一组按此索引来访问的函数。riid和lcid的含义与在GetIDsOfNames()中的定义相同,分别为保留参数和本地化标识。WORDwFlags:指定了要访问的是接口的属性还是方法DISPPARMS*pdispparams:包括了方法和属性调用的参数数组、DISPID数组以及数组中参数个数等信息。VARIANT*pvarResult:保存返回值信息。EXCEPINFO*pexcepinfo:指向一个有效的异常信息结构UINT*PuArgErr:包含了第一个产生错误的参数指针。综合以上,可以了解到:通过GetIDsOfNames()和Invoke()的结合使用,将可以根据函数名称对方法和属性进行调用。这样,函数地址、AddRef()、Release()以及接口指针等细节问题将无需考虑。基于以上的分析,对于COM里面某个函数的定位思路是:由于在调用COM里面某个函数时,会去分发,然后再调用COM里面的函数,那么,我们就在它分发的时候先把它拦截下来,之后再单步跟入某个函数。好。那么就在它分发的时候拦截下来!但是,它是在哪分发呢?呵呵,在这里不用你去找啦,我已经找出来了,关键函数:DispCallFunc,位于OLEAUT32.dll。如下图:至于为什么不是在COM库:OLE32.dll里面,已经很明显了。分发的地方现在是已经拦截下来了,但是,COM里面的某个函数还没定位出来呀?跟下来吧。在DispCallFunc函数一直“步过”,直到见到Callnearecx时,我们就来到了进入COM里面某个函数的边缘了!那还等什么?就差一步“步进”,就来到了COM里面的某个函数的入口点了。简单不?下面来一个实例。使用工具:COMRaider,OD目标:vuln.dll(COMRaider里面的一个测试DLL)开始:1、先确认vuln.dll已经被注册过了,如果没有,则需要注册:regsvr32X:\idefense\comraider\vuln.dll2、运行COMRaider,单击“Start”,如图1:图13、单击“Next”,选择vuln.dll文件,来到如图2:图24、随便选择一个成员函数,这里选择Method3,在其上面右击,选择“Fuzzmember”,如图3图35、单击“Next”图46、随便选择一个文件名,在其上面右击,选择“LaunchinOlly”,此时,会调用Olly来加载它,加载完毕后,断点在入口点了。7、在OD里,选择菜单“查看”-“可执行模块”,或者按Alt+E,如图5:图58、双击OLEAUT32,然后按CTRL+N,在里面找到DispCallFunc函数,选择它,按F2为其设断点。如图6、7图6在此按CTRL+N图7选择DispCallFunc,按F2设断至此,准备工作已经完毕。下面进行关键步骤。9、按F9,让它运行起来,稍等一会,OD马上就把DispCallFunc给拦截下来了。图810、一直按F8,单步步过进行跟踪,直到见到Callnearecx时,停下来,如图:图911、到此,我们已经来到了进入COM组件里面某个函数入口的边缘了,单步步进。图10哈哈,再单步,我们就进入到了此函数的入口点。图11怎么样?跟踪COM的某个函数简单吧?赶快试下其他的COM吧!