首页
论坛
专栏
课程

[调试逆向] [系统底层] [求助]逆向 COM 组件时,如何确定虚函数表的顺序?

2019-7-5 23:30 454

[调试逆向] [系统底层] [求助]逆向 COM 组件时,如何确定虚函数表的顺序?

2019-7-5 23:30
454
我正在逆向 Windows 系统下的一组未公开 API ,这个组件实际容量非常庞大,目前逆向的效率上出了比较大的问题……
这组 API 没有任何文档,当然也没有类型库给咱用,因为是系统组件,我拿到了比较完整的符号文件,大部分工作就变得比较简单了,我轻易地找到了接口的实现类,查询接口的调用也都成功了,接口实现的函数有一大抄,我把接口定义都转移到我的工程里,但是要调用需要正确的虚函数表位置,关于函数顺序的问题就出来了。

请问如果拿到了 COM 的 coclass 实现,我 Query 到的组件实例的虚函数表里的顺序是怎样的呢?我看了一下,似乎并不是按照 IDA 默认的顺序(没有让函数名排序时的顺序)。

就比如说实际上虚函数表里,除了继承了 IUnknown 的三个函数之外,第一个函数是初始化函数 Initialize(我调用成功了,应该不会错),在IDA的函数列表里它却处于中下位置……
感觉虚函数逆向方面的网上资料不是很多,也没找到我想要的东西,我基本上的一个答案是“顺序因编译器而异”。微软想必使用了 MSVC 来编译,这个都好确定。

还有的话,静态难以确定函数顺序,我也尝试过使用调试器,按理来讲只要加载了符号文件就应该能看到,但是似乎不论如何都不太对劲,我把接口的指针强转当成函数指针的数组来遍历,输出发现都是比较古怪的地址,用内存查看器、汇编查看对应位置,基本都是问号,是不可访问的内存。我好像只有一次见到过正确的某个系统 dll 的偏移地址。我也给出我的代码,按理来讲不至于写错,太奇怪了。

UINT cnt = 0;
// pInterface is correct.
// There are 30 functions in this interface
for (LPVOID* ppfn = (LPVOID*)pInterface; cnt < 30; cnt++, ppfn++) {
    wprintf(L"Func : %p\n", *ppfn);
}

// Output (Stdout)
Func : 00007FFE3DD56EF0
Func : 90002B0058870157
Func : 000002010000000B
Func : 0000000100000003
Func : 000002000000000A
Func : 00007F0100000003
Func : 0000000000000010
Func : 0000020000000012
Func : 0000020000000002
Func : 000002010000000A
Func : 0000000000530078
Func : 90002C0058BC014A
Func : 000002010000000B
Func : 0000000100000003
Func : 000002000000000A
Func : 00007F0100000003
Func : 0000000000000010
Func : 0000020000000012
Func : 0000020000000002
Func : 000002010000000A
Func : 0000000000000000
Func : 90002D0058B90141
Func : 00000257429A8290
Func : 00000257429D6880
Func : 0000000000000000
Func : 483571811D44957B
Func : DEA41261B1D00AB7
Func : 0000327800000000
Func : 483571811D44957B
Func : DEA41261B1D00AB7


如果不能确定这个顺序,一个一个把函数试下来效率就低得无法接受……有大佬能为我指条路吗?万分感谢!


[公告]安全服务和外包项目请将项目需求发到看雪企服平台:https://qifu.kanxue.com

最后于 2019-7-5 23:31 被highwindex编辑 ,原因:
最新回复 (1)
highwindex 2019-7-6 00:06
2
1
非常抱歉,我自己解决了问题,原来是接口指针转换到虚函数表指针的时候少写了一层,这里应该改作:
UINT cnt = 0;
for (FARPROC* ppfn = *(FARPROC**)pCbsSession; cnt < 30; cnt++, ppfn++) {
    wprintf(L"Func : %p\n", *ppfn);
}
我已经成功使用 VS 调试器查看到了具体的函数信息,小弟只是个 newbie,多有打扰,还请见谅!:)
游客
登录 | 注册 方可回帖
返回