-
-
[原创]某驱动里面的摘取系统注册表回调的方法
-
发表于:
2013-3-30 23:54
14351
-
换工作环境了,比以前自由多了,这几天没多少事,之前分析过了这个驱动一直没有还原,这2天抽空还原了一下,大牛飘过~~
基本原理:
在自己驱动里面调用CMRegistercallback注册一个回调函数,然后在回调函数里面根据
ebx寄存器里面存储的是当前回调函数_EX_CALLBACK结构地址,而这一地址又一定在系统的回调链上的这一特性, 在XP系统上找到CmpCallBackVector 首地址,在Vista以上系统上找到CallbackListHead 首地址,然后依次遍历下了,找到CallBackFunction和Cookie,然后有了CallBackFunction 就能找到模块名称,根据Cookie就能进行注册表回调的摘取了~~~
先补充下XP下的CmpCallBackVector的节点怎么找打Cookie和Funtion的方法:
CmpCallBackVector--> Node.Object
--->EX_CALLBACK_ROUTINE_BLOCK
-->CM_CALLBACK_CONTEXT_BLOCKXP
在EX_CALLBACK_ROUTINE_BLOCK 找到CallBackFuntion
在CM_CALLBACK_CONTEXT_BLOCK中找到Context和Cookie
ebx在指向的是当前函数注册的在nt!CmpCallBackVector里面的节点位置
由于在XP系统上CmpCallBackVector里面存放的是EX_FAST_REF指针,因此从当前位置一直向
低内存位置查找DWORD值,直到为0,即为CmpCallBackVector的第一结构
从EX_FASTREF.object-->EX_CALLBACK_ROUTINE_BLOCK使用如下函数
PVOID FORCEINLINE MyFastRefGetObject (EX_FAST_REF FastRef)
{
return (PVOID) (FastRef.Value & ~MAX_FAST_REFS);
}
#if defined (_WIN64)
#define MAX_FAST_REFS 15
#else
#define MAX_FAST_REFS 7
#endif
_EX_CALLBACK CmpCallBackVector[100];
typedef struct _EX_CALLBACK
{
EX_FAST_REF RoutineBlock;
} EX_CALLBACK, *PEX_CALLBACK;
typedef struct _EX_FAST_REF
{
union {
PVOID Object;
#if defined (_WIN64)
ULONG_PTR RefCnt : 4;
#else
ULONG_PTR RefCnt : 3;
#endif
ULONG_PTR Value;
};
} EX_FAST_REF, *PEX_FAST_REF;
typedef struct _EX_CALLBACK_ROUTINE_BLOCKXP
{
EX_RUNDOWN_REF RundownProtect;
[COLOR="Red"]PEX_CALLBACK_FUNCTION Function;[/COLOR]
PVOID Context;
PVOID pValid;
}EX_CALLBACK_ROUTINE_BLOCKXP, *PEX_CALLBACK_ROUTINE_BLOCKXP;
typedef struct _CM_CALLBACK_CONTEXT_BLOCK {
[COLOR="Red"]LARGE_INTEGER Cookie; [/COLOR]
LIST_ENTRY ThreadListHead;
EX_PUSH_LOCK ThreadListLock;
PVOID CallerContext;
} CM_CALLBACK_CONTEXT_BLOCK, *PCM_CALLBACK_CONTEXT_BLOCK;
LIST_ENTRY* CallbackListHead ;
typedef struct _CM_CALLBACK_CONTEXT_BLOCKEX-------// 0x30
{
struct _LIST_ENTRY CallbackListEntry; // +0x0(0x8)
ULONG PreCallListCount; // +0x8(0x4)
ULONG pda; // Pad
LARGE_INTEGER Cookie; // +0x10(0x8)
void* CallerContext; // +0x18(0x4)
long (__stdcall * Function)(void*, void*, void*); // +0x1c(0x4)
struct _UNICODE_STRING Altitude; // +0x20(0x8)
struct _LIST_ENTRY ObjectContextListHead; // +0x28(0x8)
}CM_CALLBACK_CONTEXT_BLOCKEX,*P_CM_CALLBACK_CONTEXT_BLOCKEX;
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!