首页
社区
课程
招聘
[原创]XP/Win7上无硬编码枚举了各种NotifyRoutine和CmpCallback
发表于: 2010-5-7 15:37 10231

[原创]XP/Win7上无硬编码枚举了各种NotifyRoutine和CmpCallback

2010-5-7 15:37
10231

目前大多数做法似乎是从PsSetCreateProcessNotifyRoutine等导出的地址开始,
用特征码搜索保存Notify的数组来枚举,
缺点是不够通用

我的思路是,先注册一个自己的NotifyRoutine,
然后从CmUnRegisterCallback等导出函数地址开始查找自己登录的函数地址,
从而找到保存Notify的数组,

这样做也有缺点,在XP最多登录8个processnotify,如果超过了,
我这个方法就没法用了~~~


PspLoadImageNotifyRoutine,PspCreateThreadNotifyRoutine,
PspCreateProcessNotifyRoutine
这三个的找法是一样的,xp和win7也没什么区别,都是一个数组


值得一提的是CmpCallback的找法,xp和win7有很大的区别,
xp里面是个数组,到了win7变成了队列了

我的逆向水平很弱,着实花了一段时间,才看出这个队列的结构。。。

唯一的硬编码是数组的最大个数,
比如CreateProcessNotify


[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 7
支持
分享
最新回复 (5)
雪    币: 75
活跃值: (688)
能力值: ( LV6,RANK:90 )
在线值:
发帖
回帖
粉丝
2
额,
值得一提的是CmpCallback的找法,xp和win7有很大的区别,
xp里面是个数组,到了win7变成了队列了

看reactos源码时,见到它使用队列来完成的,还以为楼主弄错了00!反汇编了下,这里还真跟xp不一样00!
2010-5-7 17:30
0
雪    币: 284
活跃值: (106)
能力值: ( LV9,RANK:160 )
在线值:
发帖
回帖
粉丝
3
补充一个更加完整的cmpcallback检测及卸载资料,楼上的只是检测并没有提供卸载的实现方法,注册表回调就算得到函数地址你也没啥用途,还是卸载不了,关键是得到cookie……
http://hi.baidu.com/%D0%A1%C2%B9%BD%A3/blog/item/d5e6f57442ba2617b151b940.html
2010-5-7 18:12
0
雪    币: 451
活跃值: (78)
能力值: ( LV12,RANK:470 )
在线值:
发帖
回帖
粉丝
4
引用的文字都保存到论坛一份

从CmUnRegisterCallback进去在XP有一个_CmpCallBackVector数组,数目为100,数组元素为

typedef struct _EX_FAST_REF
{
union
{
PVOID Object;
ULONG_PTR RefCnt:3;
ULONG_PTR Value;
};
} EX_FAST_REF, *PEX_FAST_REF;

其中的Object指向的结构为

typedef struct _EX_CALLBACK_ROUTINE_BLOCK
{
EX_RUNDOWN_REF RundownProtect;
PEX_CALLBACK_FUNCTION Function;
PVOID Context;//
} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;

而Context结构指向

typedef struct _CM_ARRY_XP
{
LARGE_INTEGER Cookie;//
LIST_ENTRY ListEntry1;//8
ULONG UnKnown1;//16
ULONG UnKnown2;//20
ULONG UnKnown3;//24
ULONG UnKnown4;//28
ULONG UnKnown5;//32
LIST_ENTRY ListEntry2;//36
ULONG UnKnown;//44
ULONG Context;//48
ULONG UnKnown6;
}CM_CONTEXT,*PCM_CONTEXT;

取得Cookie就可以实现卸载了……在XP这个Cookie居然就是注册时的系统时间……

上面那种方式很明显寻址效率超低,所以Windows7下就做了改进了,没有使用数组而是一个链表:

_CallbackListHead,这个链表连接在下面结构的第一项里(就是ListEntryHead):

typedef struct _CM_NOTIFY_ENTRY
{
LIST_ENTRY ListEntryHead;///初始化时指向自己
ULONG UnKnown1;//+8
ULONG UnKnown2;//12
LARGE_INTEGER Cookie;//16
ULONG Context;//+24
ULONG Function;//+28
ULONG Altitudes;//32
PVOID BufferPointer;//36
LIST_ENTRY ListEntry1;//40初始化时指向自己,没搞清楚到底指哪去
}CM_NOTIFY_ENTRY,*PCM_NOTIFY_ENTRY;

要卸载只需要遍历这个双向链表,取得Cookie就可以了……Windows7下那个Cookie值好像是去一个全局变量里取,没搞懂是在哪里设置的
2010-5-7 18:35
0
雪    币: 492
活跃值: (53)
能力值: ( LV6,RANK:80 )
在线值:
发帖
回帖
粉丝
5
我去你的博客看了,多谢大牛逆向的完整的结构啊~~~
2010-5-7 18:49
0
雪    币: 234
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
楼主的想法很巧妙啊....不错..我没有想到...
2010-7-2 19:35
0
游客
登录 | 注册 方可回帖
返回
//