-
-
[原创]替换进程创建监视函数
-
发表于:
2009-7-18 15:50
13750
-
PsSetCreateProcessNotifyRoutine这个函数大家应该比较熟悉,这个函数提供了一种监视进程创建的绿色方法,毕竟是有文档的东西,使用起来比较安全。当然这个函数在使用时时有限制的,只能安装8个监视函数(32位的系统)。我们可以想到,系统应该有一个表来保存这几个函数的地址,以便系统调用,OK现在我们使用windbg去看看,反汇编之后发现一个和函数名同名的结构:
8062cc40 56 push esi
8062cc41 8d049d60165680 lea eax,nt!PspCreateProcessNotifyRoutine (80561660)[ebx*4]
8062cc48 50 push eax
8062cc49 e8b17d0100 call nt!ExDereferenceCallBackBlock (806449ff)
8062cc4e 56 push esi
这是一个结构不是可执行代码,我们选择内存窗口,跳到80561660这个地址看看,查看时选择LONG HEX,就会看到,根据网上的资料这个是一个EX_FAST_REF的数组,一共有8个元素。这个结构在wrk里面可以找到到,其结构是
typedef struct _EX_FAST_REF
{
union
{
PVOID Object;
ULONG_PTR RefCnt:3;
ULONG_PTR Value;
};
} EX_FAST_REF, *PEX_FAST_REF;注意里面低三位是引用计数,value是一个指针,指向一个叫做EX_CALLBACK_ROUTINE_BLOCK,的结构,这个结构里面就有回调函数的指针了,
完整结构如下:
typedef struct _EX_CALLBACK_ROUTINE_BLOCK
{
EX_RUNDOWN_REF RundownProtect;
PEX_CALLBACK_FUNCTION Function;
PVOID Context;
} EX_CALLBACK_ROUTINE_BLOCK, *PEX_CALLBACK_ROUTINE_BLOCK;为了得到这个指针,可以用移位运算:
PEX_CALLBACK_ROUTINE_BLOCK Point=(PEX_CALLBACK_ROUTINE_BLOCK)((FastRef->Value>>3)<<3);得到这个地址就简单了,只要用我们自己的函数地址代替这个地址就可以了,这样别人的监控就会失效了。我们有理由认为PsSetCreateThreadNotifyRoutine也使用了同样的机制,ok,还是反汇编一下看看,发现此时里面的数组叫做PsSetCreateThreadNotifyRoutin,现在还不确定这个函数的实现和PsSetCreateProcessNotifyRoutin相不相同,所以我们需要到wrk里面看看,反汇编PsSetCreateThreadNotifyRoutine之后发现其调用ExCompareExchangeCallBack函数,这个函数可以在wrk里面找到,然后看看,会发现机制是一样的,数组个数依然是8[0-7],好了现在你可以利用上面的方法来找到这个数组,你乐意的话就修改它。顺便把PsSetLoadImageNotifyRoutine也看看,你一看就会惊奇的发现,他们实现的机理一模一样。
废话不说了,直接贴代码:
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!