逆向COM
转自:http://dododododo.blog.sohu.com/4524854.html
这里以com写的dll为例,介绍一下com的逆向过程.假设我们的dll实现了两个接口Iinterface1和Iinterface2,其中Iinterface1有5个方法;Iinterface2有一个方法.
前提知识:(熟悉com结构的话,可以跳过这一部分)
1,com的实质是接口与接口的实现分离.一个com组件可以实现多个接口,每一个接口包含有多个方法.(方法就是函数).
2,com从整体上看,分为com客户端,com库,com组件(也就是服务器)
3,com从实现上看包含有接口,类(即接口的实现),类工厂(作用是创建类对象),和几个dll函数。
接口的作用是向外界表明调用的方式,这是对外可见部分。类,负责实现接口,对外部可见。类工厂,负责创建类的实例,对外不可见。dll函数有DllGetClassObject,DllCanUnLoadNow,DllRegisterServer,DllUnregisterServer等,对外可见.其中最重要的是DllGetClassObject,他和类工厂的CreateInstance合作,获取接口的指针.外界获取接口指针的方式是调用COM库函数CoCreateInstance(还有其他方式).CoCreateInstance函数先调用DllGetClassObject函数,来建立类工厂对象;然后调用类工厂的函数CreateInstance,来建立类对象,进而得到接口指针.
4,对象在内存中的结构,搞不清楚会比较麻烦.
开始逆向:
我们从最DllGetClassObject着手.
1,顺着DllGetClassObject的汇编代码向下走,找到一个对new的调用.这是在建立类工厂.一般只new十几个字节.第一个 dword是用来存放类工厂指针的.然后,类工厂为了控制自己的生存时间,会使用一个Dword类型的引用记数.
2,再向下走,碰到的地一个函数,就是类工厂的初始化函数,也就是把上面分配的空间填充上固定的值.
3, 连续碰到这两条语句的时候,停下来:
call dword ptr [edx] ;调用类工厂的QueryInterface();
call dword ptr [edx+8] ;调用类工厂的Release();
类工厂的几个函数次序固定,是这样分布的:
QueryInterface
AddRef
Release
CreateInstance
LockServer
edx 里面存放的是类工厂的指针.就是指向上面这个数组.所以[edx]== QueryInterface(),[edx+8]== AddRef();[edx+0xc] == CreateInstance ! 最重要的是CreateInstance,他负责建立类的实例.
4根据第3步的edx,向上查找他的来源,找..找..找...好,发现他最终在第二步的初始化函数里面被赋值!如下面两条指令:
mov dword ptr [eax], offset pFactoryFunction
mov dword ptr [eax+4], 1
"pFactoryFunction"就是类工厂的函数数组了,也就是上面5个函数的!!
5,现在我们进去pFactoryFunction,到第四个函数,也就是CreateInstance里面去看看.这就是建立类对象的函数哦!在这里面,可以得到IID,和接口的方法.其实这个过程也就是先new一个空间,然后在初始化这个空间,再调用接口对应的方法.具体就不写了.到时候当面交流