ProtocolCharacteris->Name.Length + 0xC6, 'bpDN'); RtlZeroMemory(&p_protocol->ProtocolCharacteristics, ProtocolCharacteris->Name.Length + size); RtlCopyMemory(&(p_protocol->ProtocolCharacteristics), ProtocolCharacteris, size); //Upcase协议名 p_protocol->ProtocolCharacteristics.Name.Buffer = (PVOID)((ULONG)p_protocol+0xc4); RtlUpcaseUnicodeString(&p_protocol->ProtocolCharacteristics.Name, &ProtocolCharacteris->Name, FALSE); 在 NdisRegisterProtocol 中先申请了一片非分页内存,用来保存 NDIS_PROTOCOL_BLOCK 结构,NDIS_PROTOCOL_BLOCK 的大小是 0xC4,但却分配了 0xC6+ Name.Length个内存,结构本代码段的最后两句代码,笔者猜测是NdisRegisterProtocol 把协议名保存在 NDIS_PROTOCOL_BLOCK 结构后面,并且用 0x2 个“00”来截断 UNICODE_STRING。 2. p_protocol->WorkItem.WorkerRoutine = g_ndisCheckProtocolBindings; p_protocol->WorkItem.Parameter = p_protocol; p_protocol->WorkItem.List.Flink = NULL; KeInsertQueue(g_ndisWorkerQueue, &(p_protocol->WorkItem)); 这一部分设置了 WorkerRoutine 为 ndisCheckProtocolBindings,之后用 KeInsertQueue 把本协议块的 WorkItem 加入到 ndisWorkerQueue 中,之后 NDIS 会创建 一个 ndisWorkerThread 线程,然后以 WorkItem.Parameter 为参数调用 WorkItem.WorkerRoutine ,即 ndisCheckProtocolBindings 。对于 ndisCheckProtocolBindings笔者没有进行分析,望有分析出来的读者,能跟笔者交流。 3. KeAcquireSpinLock(g_ndisProtocolListLock, &OldIrql); p_protocol->NextProtocol = *(ULONG*)g_ndisProtocolList;
*(ULONG*)g_ndisProtocolList = p_protocol;
KeReleaseSpinLock(p_protocol->Ref.SpinLock, OldIrql);
__declspec(naked)
mov eax, [ebx+1] |