COM
U1S1这玩意学的特别痛苦=。=
经过好几天消化才搞懂了大概
有些地方写错了还请指正。
Component Object Model (COM) Internals
COM是微软的一种开发标准,遵循这种标准开发出来的组件叫做COM组件,无论是什么语言只要遵循这种标准就能调用该组件提供的接口。
COM出现的原因是为了IPC(进程间通信),这种IPC之前就有叫做OLE(Object Linking and Embedding),但这不是最早的,最早的是DDE(Dynamic Data Exchange),因为这种东西比较麻烦并难以理解,所以COM被微软开发出来让其使用更加方便更容易理解。
It bridge the gap between different languages and processes。
所有COM都遵循IUnknown接口标准为了解决Casting Problem
主要有俩个功能,一个是引用计数,因为被不同的语言调用,还有一个是GUID,这是解决Casting Problem,因为GUID都是唯一的,name不是。
注册的组件再注册表中有个CLSID
这边提一下GUID,CLSID,IID,UUID
UUID是一个算法
GUID标志COM组件
CLSID标志类
IID显而易见就是接口了
其实是一个东西的不同表示
这边解释了客户端如何得到接口
dll中导出函数DllGetClassObject,传入Class ID,如果dll知道会返回一个factory object然后就能CoCreateInstanceEx获取接口
STA 一个对象只能由一个线程访问(通过对象的接口指针调用其方法),其他线程不得访问这个对象,因此对于这个对象的所有调用都是同步了的,对象的状态(也就是对象的成员变量的值)肯定是正确变化的,不会出现线程访问冲突而导致对象状态错误。其他线程要访问这个对象,必须等待,直到那个唯一的线程空闲时才能调用对象。
MTA 一个对象可以被多个线程访问,即这个对象的代码在自己的方法中实现了线程保护,保证可以正确改变自己的状态。这对于作为业务逻辑组件或干后台服务的组件非常适合。因为作为一个分布式的服务器,同一时间可能有几千条服务请求到达,如果排队进行调用,那么将是不能想像的。
上图代码可以dump出在你电脑上所有可交互的对象
跨进程时与前面的很像,只不过把windows messaging换成了ALPC Channel
DCOM Activator是用来管理COM对象的初始化
当客户端发送请求想要创建类,他会与System Activator交互
如果需要的话RPCSS会创建新的进程,如果已经存在的话就会直接使用了
接着就会把接口封装后返回然后客户端就能链接
System Activator主要有上面俩个函数一个用来和服务端一个用来和客户端交互
processhacker看句柄表的时候很常见OLE开头的ALPC PORT,这是用来定位COM对象的RPC端口的
上面是类似COM中的DACL
后面有些没有搞懂。。。这边就不写了,过几天深入研究下
COM编写与调用
创建项目
新建项添加ATL简单对象
然后再temp.h中声明函数
接着去cpp中实现
然后定义接口
直接编译,报错不需要管,进文件夹看到dll后管理员权限打开CMD输入以下命令
再打开工具就能看到我们注册的组件了
下面来调用我们的COM组件
首先设置属性允许跨平台语言
接着添加引用,就是之前我们注册的dll
接着确定namespace
查询Com组件命名空间,双击引用中需要的文件打开对象浏览器,点击带{}符号项,得到命名空间Namespace XXX,然后在按钮的点击事件对应代码所在的.cpp源文件中添加命名空间,如下
在对象浏览器查询所需函数所在类名,然后在按钮点击事件对应代码中使用该类生成相应对象,即可调用所需函数。
成功
COM逆向
右击点create instance
接着Operations->Marshal->View Properties
这边已经可以看到pid了
点view,需要配置一下dll路径,这边自行下载SDK
可以看到FUCOM+0x9CC0
逆向开始
还有一些要配合windbg使用因为没有符号
可以windbg附加上然后命令输入
1 |
|
类似这样
把输出放到这,工具会自动帮你“融合”一波放到剪切板
然后就能还原了。