#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);
}