#define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16)) VOID ShowIDTinfo( IN struct _KDPC *Dpc, IN ULONG cpuNum, IN PVOID SystemArgument1, IN PVOID SystemArgument2); typedef struct _IDTENTRY { unsigned short LowOffset; unsigned short selector; unsigned char unused_lo; unsigned char segment_type:4; //0x0E is an interrupt gate unsigned char system_segment_flag:1; unsigned char DPL:2; // descriptor privilege level unsigned char P:1; /* present */ unsigned short HiOffset; } IDTENTRY,*PIDTENTRY;
/* sidt returns idt in this format */ typedef struct _IDTINFO { unsigned short IDTLimit; unsigned short LowIDTbase; unsigned short HiIDTbase; } IDTINFO,*PIDTINFO; typedef ULONG (NTAPI *fnKeQueryActiveProcessorCount)(OUT PKAFFINITY ActiveProcessors); ULONG g_dwBuildNumber; //记录完成dpc的数量 volatile LONG g_FinshedDPC = 0; //入口函数 extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING pRegistryPath) { NTSTATUS status;
//注册驱动调用函数入口 pDriverObject->DriverUnload = (PDRIVER_UNLOAD)DriverUnload; pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]= DriverIOCtrl ; pDriverObject->MajorFunction[IRP_MJ_CLOSE]= DriverDispatch ; pDriverObject->MajorFunction[IRP_MJ_CREATE]= DriverDispatch ; pDriverObject->MajorFunction[IRP_MJ_READ]= DriverDispatch ; pDriverObject->MajorFunction[IRP_MJ_WRITE]= DriverDispatch ;
//创建设备 status = CreateDevice(pDriverObject);
ULONG count = 0; UNICODE_STRING ustr; PKDPC pdpc; PsGetVersion(0,0,&g_dwBuildNumber,0); //__asm int 3 //动态获取地址,因为获取cpu数目的方法在vista sp1即以后版本有所改变, //如果直接使用KeQueryActiveProcessorCount将导致驱动在xp下无法加载 if (g_dwBuildNumber == 2600 || g_dwBuildNumber == 6000) { RtlInitUnicodeString(&ustr,L"KeNumberProcessors"); PVOID p = MmGetSystemRoutineAddress(&ustr); if (p!=0) { count = *(ULONG *)p; } } else { KAFFINITY procs; RtlInitUnicodeString(&ustr,L"KeQueryActiveProcessorCount"); fnKeQueryActiveProcessorCount MyQueryActiveProcessorCount = (fnKeQueryActiveProcessorCount)MmGetSystemRoutineAddress(&ustr); if (MyQueryActiveProcessorCount != 0) { count = MyQueryActiveProcessorCount(&procs); }
} if (count==1) { ShowIDTinfo(0,0,0,0); } else { ULONG currrent_pro_num = KeGetCurrentProcessorNumber(); ShowIDTinfo(0,currrent_pro_num,0,0); g_FinshedDPC = 1; PKDPC temp_dpc; temp_dpc = (PKDPC)ExAllocatePoolWithTag(NonPagedPool,sizeof(KDPC)*count,'rm'); pdpc = temp_dpc; if (temp_dpc == NULL) return status; for (ULONG i = 0;i<count;i++,*temp_dpc++) { if (i!=currrent_pro_num) { //传入一个cpu号就好 KeInitializeDpc(temp_dpc,(PKDEFERRED_ROUTINE)ShowIDTinfo,(PVOID)i); KeSetTargetProcessorDpc(temp_dpc,i); KeInsertQueueDpc(temp_dpc,NULL,NULL);
}
} //等待所有的dpc历程完事儿 while(InterlockedCompareExchange(&g_FinshedDPC,count,count) != count) { __asm nop } ExFreePoolWithTag(pdpc,'rm'); }
return status; }
VOID ShowIDTinfo( IN struct _KDPC *Dpc, IN ULONG cpuNum, IN PVOID SystemArgument1, IN PVOID SystemArgument2) { IDTINFO idt_info; __asm sidt idt_info PIDTENTRY pIDTen =( PIDTENTRY)MAKELONG(idt_info.LowIDTbase,idt_info.HiIDTbase); PIDTENTRY pIDTtmp; ULONG addr; for (ULONG i=0;i<0xFF;i++) { pIDTtmp = &pIDTen[i]; addr = MAKELONG(pIDTtmp->LowOffset,pIDTtmp->HiOffset); DbgPrint("CPU:%d Index:%d Addr:0x%x DPL:%d/n",cpuNum,i,addr,pIDTtmp->DPL); }
InterlockedIncrement(&g_FinshedDPC); }