IDA看一下

进入Internal函数
`signed __int64 __fastcall CmpRegisterCallbackInternal(__int64 Function, __int64 Context, const void **CmLegacyAltitude, char c_1, _QWORD *Cookie)
{
__int64 _Context; // rsi
__int64 _Function; // rbp
const void **_CmLegacyAltitude; // rbx`
`char _c_1; // r12`
`__int64 v9; // rax
__int64 v10; // rdi`
`__int64 v12; // rax`
`_ETW_REG_ENTRY *v13; // rax`
`unsigned int v14; // ebx`
`signed int v15; // eax`
`_ETW_REG_ENTRY *v16; // rcx`
`_Context = Context;
_Function = Function;
_CmLegacyAltitude = CmLegacyAltitude;
_c_1 = c_1;
// 这个是callback数据项
v9 = (__int64)ExAllocatePoolWithTag(PagedPool, 80ui64, 'bcMC');
v10 = v9;
if ( !v9 )
return 0xC000009Ai64;
// 开头是LIST_ENTRY,这里是初始化LIST_ENTRY
*(_QWORD *)(v9 + 8) = v9;`
`*(_QWORD *)v9 = v9;
// 这里在结尾16字节填充了同样的地址,是防止溢出的?
v12 = v9 + 64;
*(_QWORD *)(v12 + 8) = v12;`
`*(_QWORD *)v12 = v12;
// 这里是真正填写CALLBACK函数地址和参数
*(_DWORD *)(v10 + 16) = 0;`
`*(_QWORD *)(v10 + 32) = _Context;
*(_QWORD *)(v10 + 40) = _Function;
LOWORD(v12) = *(_WORD *)_CmLegacyAltitude;
*(_WORD *)(v10 + 50) = *(_WORD *)_CmLegacyAltitude;`
`*(_WORD *)(v10 + 48) = v12;
// 这里申请内存保存了CmLegacyAltitude的值
v13 = (_ETW_REG_ENTRY *)ExAllocatePoolWithTag(PagedPool, *(unsigned __int16 *)_CmLegacyAltitude, 'acMC');
*(_QWORD *)(v10 + 56) = v13;
if ( !v13 )
{
v14 = 0xC000009A;
LABEL_6:
v16 = *(_ETW_REG_ENTRY **)(v10 + 56);
if ( v16 )
ExFreePoolWithTag(v16, 0);
ExFreePoolWithTag((PVOID)v10, 0);
return v14;
}
memmove(v13, _CmLegacyAltitude[1], *(unsigned __int16 *)_CmLegacyAltitude);
// 最后将CALLBACK项传入此函数进行注册
v15 = CmpInsertCallbackInListByAltitude((_QWORD *)v10, _c_1);
*Cookie = *(_QWORD *)(v10 + 24);`
`v14 = v15;`
`if ( v15 < 0 )`
`goto LABEL_6;`
`return v14;`
`}`
进入 CmpInsertCallbackInListByAltitude,
__`int64 __fastcall CmpInsertCallbackInListByAltitude(_QWORD *a1, char a2)`
`{`
`struct _KTHREAD *v2; // rax`
`char v3; // bp`
`__int64 v4; // rbx
unsigned int v5; // esi
__int64 *v6; // rdi`
`int v7; // eax`
`__int64 *v8; // rcx
__int64 v9; // rax`
`signed __int64 v10; // rcx
__int64 v11; // rtt`
`struct _KTHREAD *v12; // rdx`
`bool v13; // zf`
`v2 = KeGetCurrentThread();`
`v3 = a2;`
`--v2->KernelApcDisable;`
`v4 = (__int64)a1;
v5 = 0;
if ( _interlockedbittestandset64((volatile signed __int32 *)&CallbackListLock, 0i64) )
ExfAcquirePushLockExclusive(&CallbackListLock);
*(_QWORD *)(v4 + 24) = ++CmpCallbackCookie;
v6 = (__int64 *)CallbackListHead;
if ( (__int64 *)CallbackListHead != &CallbackListHead )
{
do
{
v7 = RtlCompareAltitudes(v6 + 6, v4 + 48);
if ( v7 )
{
if ( v7 < 0 )
break;
}
else if ( !v3 )
{
goto LABEL_11;
}
v6 = (__int64 *)*v6;`
`}`
`while ( v6 != &CallbackListHead );`
`if ( !v7 && !v3 )`
`{`
`LABEL_11:`
`v5 = 0xC01C0011;`
`goto LABEL_13;`
`}`
`}`
`v8 = (__int64 *)v6[1];
v9 = *v8;
*(_QWORD *)(v4 + 8) = v8;
*(_QWORD *)v4 = v9;
*(_QWORD *)(v9 + 8) = v4;
*v8 = v4;
_InterlockedAdd(&CmpCallBackCount, 1u);
LABEL_13:
__asm { prefetchw byte ptr cs:CallbackListLock }`
`v10 = CallbackListLock - 16;`
`if ( (CallbackListLock & 0xFFFFFFFFFFFFFFF0ui64) <= 0x10 )`
`v10 = 0i64;`
`if ( CallbackListLock & 2`
`|| (v11 = CallbackListLock, v11 != _InterlockedCompareExchange(&CallbackListLock, v10, CallbackListLock)) )`
`{`
`ExfReleasePushLock(&CallbackListLock);`
`}`
`v12 = KeGetCurrentThread();`
`v13 = v12->KernelApcDisable++ == -1;`
`if ( v13`
`&& ($A23C80C4E4519FC60176F3D7BA3A3B67 *)v12->ApcState.ApcListHead[0].Flink != &v12->80`
`&& !v12->SpecialApcDisable )`
`{`
`KiCheckForKernelApcDelivery();`
`}`
`return v5;`
`}`
总结
在这个函数里将CALLBACK ITEM 插入了CallbackListHead 链表。
CALLBACK ITEM 数据结构总结:
typedef struct CALLBACK_ITEM
{
LIST_ENTRY Item;
ULONG_PTR Unkonwn[2];
ULONG_PTR Context;
ULONG_PTR Function;
UNICODE_STRING Altitude;
ULONG_PTR Unkonwn[2];
}


1294

被折叠的 条评论
为什么被折叠?



