【转】IDT检测 多CPU

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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值