找回密码
 加入我们

QQ登录

只需一步,快速开始

搜索
查看: 12360|回复: 9

IRP HOOK检测

 火.. [复制链接]

5

主题

39

回帖

1

精华

铂金会员

积分
1567
发表于 2011-1-13 22:34:19 | 显示全部楼层 |阅读模式
被大牛们刺激的差不多了,静下心态来后打算写一个ark,告诉自己慢慢来,今天写写一个IRPHook检测部分
  1. static        CHAR *Major_Information[]=
  2. {
  3.         "IRP_MJ_CREATE"//+0
  4.         ,"IRP_MJ_CREATE_NAMED_PIPE"//+1
  5.         ,"IRP_MJ_CLOSE"//+2
  6.         ,"IRP_MJ_READ"//+3
  7.         ,"IRP_MJ_WRITE"//+4
  8.         ,"IRP_MJ_QUERY_INFORMATION"//+5
  9.         ,"IRP_MJ_SET_INFORMATION"//+6
  10.         ,"IRP_MJ_QUERY_EA"//+7
  11.         ,"IRP_MJ_SET_EA"//+8
  12.         ,"IRP_MJ_FLUSH_BUFFERS"//+9
  13.         ,"IRP_MJ_QUERY_VOLUME_INFORMATION"//+a
  14.         ,"IRP_MJ_SET_VOLUME_INFORMATION"//b
  15.         ,"IRP_MJ_DIRECTORY_CONTROL"//+c
  16.         ,"IRP_MJ_FILE_SYSTEM_CONTROL"//+d
  17.         ,"IRP_MJ_DEVICE_CONTROL"//+e
  18.         ,"IRP_MJ_INTERNAL_DEVICE_CONTROL"//+f
  19.         ,"IRP_MJ_SHUTDOWN"//+10
  20.         ,"IRP_MJ_LOCK_CONTROL"//+11
  21.         ,"IRP_MJ_CLEANUP"//+12
  22.         ,"IRP_MJ_CREATE_MAILSLOT"//+13
  23.         ,"IRP_MJ_QUERY_SECURITY"
  24.         ,"IRP_MJ_SET_SECURITY"
  25.         ,"IRP_MJ_POWER"
  26.         ,"IRP_MJ_SYSTEM_CONTROL"
  27.         ,"IRP_MJ_DEVICE_CHANGE"
  28.         ,"IRP_MJ_QUERY_QUOTA"
  29.         ,"IRP_MJ_SET_QUOTA"
  30.         ,"IRP_MJ_PNP"
  31. //        ,""

  32. };
  33. VOID        ListIrpHook(PUNICODE_STRING                pDriverName)
  34. {
  35.         PSYSTEM_MODULE_INFORMATION        pSysbuffer;
  36.         PVOID        pMem=NULL;
  37.         ULONG        tmp=0,num,i,j;
  38.         PDRIVER_OBJECT        pDriObj;
  39.         NTSTATUS        ntstatus;
  40.         CHAR        pMyDriver[250]={0};
  41.         ObReferenceObjectByName(pDriverName        ,OBJ_CASE_INSENSITIVE,0,0,IoDriverObjectType        ,KernelMode,NULL,&pDriObj);
  42.        
  43.         ZwQuerySystemInformation(SystemModuleInformation        ,pMem        ,0        ,&tmp);
  44.         if(tmp        >0)
  45.         {
  46.                 pMem        =(PSYSTEM_MODULE_INFORMATION)ExAllocatePool(PagedPool        ,tmp);
  47.                 ntstatus        =        ZwQuerySystemInformation(SystemModuleInformation        ,pMem        ,tmp        ,&tmp);
  48.                 if (NT_SUCCESS(ntstatus))
  49.                 {
  50.                         pSysbuffer        =        (PSYSTEM_MODULE_INFORMATION)((ULONG)pMem+4);
  51.                         num        =*(PULONG)pMem;
  52.                         for (i=0;i<num;i++)
  53.                         {
  54.                                 if ((ULONG)pDriObj->DriverStart>(ULONG)pSysbuffer[i].Base        &&        (ULONG)pDriObj->DriverStart<(ULONG)pSysbuffer[i].Base        +        pSysbuffer[i].Size)
  55.                                 {
  56.                                         strcpy(pMyDriver        ,(CHAR*)(pSysbuffer[i].ImageName+pSysbuffer[i].ModuleNameOffset));       
  57.                                         break;
  58.                                 }
  59.                         }
  60.                         for (i=0;i<28;i++)
  61.                         {
  62.                                         for (j=0;j<num;j++)
  63.                                         {
  64.                                                 if(j        ==        0)
  65.                                                         continue;
  66.                                                 if ((ULONG)pDriObj->MajorFunction[i]>(ULONG)pSysbuffer[j].Base        &&        (ULONG)pDriObj->MajorFunction[i]<(ULONG)pSysbuffer[j].Base        +pSysbuffer[j].Size)
  67.                                                 {
  68.                                                         //命中模块
  69.                                                         if (_strnicmp((CHAR*)(pSysbuffer[j].ImageName        +        pSysbuffer[j].ModuleNameOffset),pMyDriver        ,sizeof(pMyDriver))        !=        0)
  70.                                                                 DbgPrint("%s\n",Major_Information[i]);
  71.                                                 }
  72.                                         }
  73.                         }
  74.                         ExFreePool(pMem);
  75.                 }
  76.         }
  77.         return        ;
  78. }

  79. VOID        ScanIrpHook()
  80. {
  81.         WCHAR        uRoot[]        =L"\\Driver";
  82.         WCHAR        uTmp[256]={0};
  83.         OBJECT_DIRECTORY_INFORMATION        *pDir;
  84.         ULONG        nLength=0x400;
  85.         UNICODE_STRING        unRoot;
  86.         OBJECT_ATTRIBUTES        attrobj;
  87.         HANDLE        pDirectory;
  88.         NTSTATUS        ntstatus;
  89.         //CHAR                pBuffer[1000]        =        {0};
  90.         ULONG                tmp=0,temp=0;
  91.         RtlInitUnicodeString(&unRoot        ,        uRoot);
  92.         InitializeObjectAttributes(&attrobj        ,&unRoot        ,OBJ_CASE_INSENSITIVE ,NULL        ,NULL);
  93.         ntstatus        =        ZwOpenDirectoryObject(&pDirectory        ,DIRECTORY_QUERY        ,&attrobj);
  94.         if (NT_SUCCESS(ntstatus))
  95.         {
  96.                        
  97.                         do
  98.                         {
  99.                                 pDir                =(POBJECT_DIRECTORY_INFORMATION)ExAllocatePool(PagedPool        ,nLength);
  100.                                 ntstatus        =        ZwQueryDirectoryObject(pDirectory        ,        pDir,nLength        ,FALSE        ,TRUE                ,&temp        ,&tmp);
  101.                                 if(ntstatus        ==STATUS_MORE_ENTRIES ||        ntstatus        ==STATUS_BUFFER_TOO_SMALL )
  102.                                 {
  103.                                         nLength*=2;
  104.                                         ExFreePool((PVOID)pDir);
  105.                                 }
  106.                                 else        if(ntstatus        ==STATUS_SUCCESS)
  107.                                 {
  108.                                         break;
  109.                                 }
  110.                                 else
  111.                                 {
  112.                                         ExFreePool(pDir);
  113.                                         DbgPrint("Error\n");
  114.                                         return;
  115.                                 }
  116.                         } while (1);
  117.                         //DbgPrint("~~~%S\n",pDir->Name.Buffer);
  118.                         while(pDir->Name.Length        &&        pDir->TypeName.Length)
  119.                         {
  120.                                         wcscpy(uTmp,L"\\Driver\");
  121.                                         wcscat(uTmp,pDir->Name.Buffer);
  122.                                         DbgPrint("%S\n",uTmp);
  123.                                         RtlInitUnicodeString(&unRoot        ,uTmp);
  124.                                         ListIrpHook(&unRoot);
  125.                                        
  126.                                         pDir++;
  127.                         }
  128.                        
  129.         }
  130.         else
  131.                         DbgPrint("Don't        Dump!\n");
  132.         return        ;
  133. }
复制代码

评分

参与人数 1 +20 +20 水晶币 +20 +20 收起 理由
Tesla.Angela + 20 + 20 + 20 + 20 精品文章

查看全部评分

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-1-13 23:20:08 | 显示全部楼层
是原创的吗?如果是的话, 您再发一篇就能进核心会员了。

5

主题

39

回帖

1

精华

铂金会员

积分
1567
 楼主| 发表于 2011-1-14 10:15:54 | 显示全部楼层
半原创吧,看了人家的思路后自己写的。。。。

评分

参与人数 1 +100 +100 水晶币 +100 +100 收起 理由
Tesla.Angela + 100 + 100 + 100 + 100 鼓励原创

查看全部评分

5

主题

39

回帖

1

精华

铂金会员

积分
1567
 楼主| 发表于 2011-1-14 10:17:53 | 显示全部楼层
不求进核心。。。
感觉和你们相差太多了。。。我只有继续学习。。。
ps:Tesla.Angela,看了你在黑客防线的文章,感觉真的很厉害呀。。。所以是来膜拜你的!

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-1-14 11:16:50 | 显示全部楼层
回复 nbboy 的帖子

进核心会员跟技术无关,是对热心者的一种奖励。
另外我的技术也不怎么样,只是没事爱写点程序来锻炼一下自己的编程水平而已。

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-1-14 11:23:05 | 显示全部楼层
回复 nbboy 的帖子
看了人家的思路后自己写的。。。。

很好,算一篇。

5

主题

39

回帖

1

精华

铂金会员

积分
1567
 楼主| 发表于 2011-1-14 18:37:37 | 显示全部楼层
本帖最后由 nbboy 于 2011-1-14 18:47 编辑

承蒙Tesla.Angela 的厚爱。。。。。本帖算是一篇。。。但是我感觉。。。。
又因为这篇和上篇的原理都是一样的。还是没有考虑隐藏驱动的问题。。。用最简单的
方法来获得驱动列表。如果别人这里坐下文章,那我的代码就瞎眼了。。。。:dizzy:
在写ark的过程中接受了很多新知识,昨晚写了IRPHOOK检测之后仔细想想。。。
IDT&GDT也可以这样检测?
今天没课就把代码实现了下基本和xuetr检测出来的差不多。。。那我猜它的原理也差不多吧。。。。过段时间反正也要a它的。到时候就知道了!;P
  1. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>IDT        Hook        Scan        Struct
  2. #define MAKELONG(a, b) ((unsigned long) (((unsigned short) (a)) | ((unsigned long) ((unsigned short) (b))) << 16))

  3. #define MAX_IDT_ENTRIES 0xFF
  4. #pragma pack(1)

  5. // entry in the IDT, this is sometimes called
  6. // an "interrupt gate"
  7. typedef struct
  8. {
  9.         unsigned short LowOffset;
  10.         unsigned short selector;
  11.         unsigned char unused_lo;
  12.         unsigned char segment_type:4;   //0x0E is an interrupt gate
  13.         unsigned char system_segment_flag:1;
  14.         unsigned char DPL:2;          // descriptor privilege level
  15.         unsigned char P:1;             /* present */
  16.         unsigned short HiOffset;
  17. } IDTENTRY;

  18. /* sidt returns idt in this format */
  19. typedef struct
  20. {
  21.         unsigned short IDTLimit;
  22.         unsigned short LowIDTbase;
  23.         unsigned short HiIDTbase;
  24. } IDTINFO;

  25. #pragma pack()

  26. typedef                struct        _IDT_HOOK_TYPE_
  27. {
  28.                 CHAR        ImageName[255];
  29.                 ULONG        ModAddress;
  30.                 ULONG        FunAddress;
  31.                 BOOLEAN        IsHook;//是否被Hook的标志,默认是被Hook了,下面会填写
  32. }IDT_HOOK_TYPE,*PIDT_HOOK_TYPE;

  33. IDT_HOOK_TYPE        g_IdtHookInfo[MAX_IDT_ENTRIES];
  34. //>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>IDT                Hook        Scan        End
  35. BOOLEAN                DumpIdtHook()
  36. //把模块信息填写HookType结构
  37. {
  38.                 IDTINFO                IdtHeader;
  39.                 IDTENTRY        *pIdtEntry;
  40.                 NTSTATUS        ntstatus;
  41.                 BOOLEAN                IsHook        =        TRUE;
  42.                 ULONG                i,tmp,pRoutineAddr,j,num;
  43.                 //ANSI_STRING        ansiStr;
  44.                 PSYSTEM_MODULE_INFORMATION                        pModuleInfo;
  45.                 PVOID                pMem;
  46.                 memset(g_IdtHookInfo        ,0        ,sizeof(IDT_HOOK_TYPE)*MAX_IDT_ENTRIES);
  47.                 _asm
  48.                 {
  49.                         sidt IdtHeader                //主要这条指令,可以从系统中获取IDT表的信息
  50.                 }
  51.                 pIdtEntry        =(IDTENTRY*)        MAKELONG(IdtHeader.LowIDTbase        ,IdtHeader.HiIDTbase        );
  52.                 ZwQuerySystemInformation(SystemModuleInformation        ,pMem        ,0        ,&tmp);
  53.                 if(tmp        >0)
  54.                 {
  55.                         pMem        =(PSYSTEM_MODULE_INFORMATION)ExAllocatePool(PagedPool        ,tmp);
  56.                         ntstatus        =        ZwQuerySystemInformation(SystemModuleInformation        ,pMem        ,tmp        ,&tmp);
  57.                         pModuleInfo        =        (PSYSTEM_MODULE_INFORMATION)((ULONG)pMem        +        4);
  58.                         num                        =        *(PULONG)pMem        ;
  59.                                 for (i=0        ;i<MAX_IDT_ENTRIES        ;i++)
  60.                                 {
  61.                                         IsHook        =        TRUE        ;
  62.                                         pRoutineAddr        =(ULONG)        MAKELONG(pIdtEntry[i].LowOffset,pIdtEntry[i].HiOffset);
  63.                                         if(pRoutineAddr        !=        0)
  64.                                         {
  65.                                                 for (j=0        ;j<num        ;j++)
  66.                                                 {
  67.                                                         if (pRoutineAddr >        (ULONG)pModuleInfo[j].Base&&pRoutineAddr        <(ULONG)pModuleInfo[j].Base        +        pModuleInfo[j].Size)
  68.                                                         {
  69.                                                                
  70.                                                                 strcpy(g_IdtHookInfo[i].ImageName,(CHAR*)(pModuleInfo[j].ImageName+pModuleInfo[j].ModuleNameOffset));
  71.                                                                 g_IdtHookInfo[i].ModAddress        =        (ULONG)pModuleInfo[j].Base;
  72.                                                                 g_IdtHookInfo[i].FunAddress        =        pRoutineAddr        ;
  73.                                                                 IsHook        =        FALSE;
  74.                                                                 break        ;
  75.                                                         }
  76.                                                 }
  77.                                                 if (IsHook        ==        TRUE)
  78.                                                 {
  79.                                                         DbgPrint("Module        Start        Address                %.8x\n",SearchModule(pRoutineAddr));
  80.                                                         g_IdtHookInfo[i].FunAddress=pRoutineAddr;
  81.                                                         g_IdtHookInfo[i].IsHook        =TRUE;
  82.                                                 }
  83.                                         }
  84.                                         else
  85.                                         {
  86.                                         g_IdtHookInfo[i].ModAddress=        0;
  87.                                         g_IdtHookInfo[i].FunAddress=        0;
  88.                                         g_IdtHookInfo[i].IsHook        =        0;//本来就没有Routine的
  89.                                         }
  90.                                 }
  91.                                 return                TRUE        ;
  92.                 }
  93.                 return        FALSE        ;
  94. }

  95. BOOLEAN                ScanIdtHook()
  96. {
  97.         ULONG        i;
  98.         CHAR        *tmp[2]={"Hook"        ,"        "};
  99.         if(DumpIdtHook()        ==        TRUE)
  100.         {
  101.                         for (i=0        ;i<MAX_IDT_ENTRIES        ;i++)
  102.                         {
  103.                                 DbgPrint("%d:        %s         %.8x                %s\n",i        ,g_IdtHookInfo[i].ImageName,g_IdtHookInfo[i].ModAddress,(g_IdtHookInfo[i].IsHook        ==        TRUE?tmp[0]        :tmp[1]));
  104.                         }
  105.                         return        TRUE        ;
  106.         }
  107.         return        FALSE        ;
  108. }

  109. ULONG        SearchModule(ULONG                pFunAddr)
  110. {
  111.                 ULONG        pPageTest,pNoPageTest,tmp;
  112.                 ULONG        peheader        ,i;
  113.                 if(pFunAddr        ==        0)
  114.                         return        0;
  115.                 pPageTest        =        (ULONG)ExAllocatePoolWithTag(PagedPool        ,4        ,'Nb');
  116.                 //        有可能函数地址是在堆中分配的,这样的情况我们就不向前遍历
  117.                 //pNoPageTest        =        (ULONG)ExAllocatePoolWithTag(NonPagedPool        ,4        ,'Nb');
  118.                 //DbgPrint("PagePool        %x,NoPagePool        %x\n",(ULONG)pPageTest        ,(ULONG)pNoPageTest);
  119.                 pPageTest        =        pPageTest        &        0xf0000000;
  120.                 tmp                        =        pFunAddr        &        0xf0000000;
  121.                 if(tmp        ==        pPageTest)
  122.                         return        1;
  123.                 __try
  124.                 {
  125.                         i=0;
  126.                         do
  127.                         {
  128.                                 i++;
  129.                                 if(i        ==        0x80000)
  130.                                 {
  131.                                         //DbgPrint("没有搜索到\n");
  132.                                         break;
  133.                                 }
  134.                                 if(MmIsAddressValid((PVOID)(pFunAddr        +        i))        ==        TRUE)
  135.                                 {
  136.                                         if(*(PSHORT)(pFunAddr+i)        ==        IMAGE_DOS_SIGNATURE)
  137.                                         {       
  138.                                                 if(MmIsAddressValid((PVOID)(pFunAddr        +        i+0x3c))        ==        TRUE)
  139.                                                 {
  140.                                                         peheader        =*(PULONG)(pFunAddr        +        i+0x3c)+(pFunAddr        +        i);
  141.                                                         if(MmIsAddressValid((PVOID)peheader))
  142.                                                         {
  143.                                                                 if(*(PULONG)(peheader)        ==        IMAGE_NT_SIGNATURE)
  144.                                                                         return        (pFunAddr+i);
  145.                                                         }
  146.                                                 }
  147.                                         }
  148.                                 }
  149.                         } while (1);
  150.                 }
  151.                 __except(EXCEPTION_EXECUTE_HANDLER)
  152.                 {
  153.                         ;;
  154.                         DbgPrint("Exception                \n");
  155.                         DbgBreakPoint();
  156.                 }
  157.                
  158.                 return        0;
  159. }
复制代码
当然这里还要提一个问题,xuetr没有提供从恶意模块的函数得到恶意模块的地址的功能。。。。
截图1295001515.jpg
所以这里它,写着未知模块!但是想想从函数得到模块的情况的却很复杂,,,因为这个函数可以是堆中分配的。。。
或是不是。。。那得到这个模块的地址可行吗?上面的SearchModule我试图得到它的模块,结构很多情况下奔溃了
:dizzy:
截图1295001895.jpg
另外如果要提供一个信息对比的话。那显然要分析下ntoskrnl.exe了。。。这里我也找不到保护模式下的中断表。。。。

评分

参与人数 1 +100 +100 水晶币 +100 +100 收起 理由
Tesla.Angela + 100 + 100 + 100 + 100 精品文章 继续努力

查看全部评分

857

主题

2632

回帖

2

精华

管理员

此生无悔入华夏,  长居日耳曼尼亚。  

积分
36130
发表于 2011-1-14 19:08:22 | 显示全部楼层
楼主真爱研究技术,加分支持!!!
希望楼主再接再厉!

29

主题

134

回帖

4

精华

论坛元老

积分
5970
QQ
发表于 2011-1-18 16:30:35 | 显示全部楼层
楼主发一下获得real irp地址的方法吧

0

主题

68

回帖

0

精华

铜牌会员

积分
94
发表于 2015-1-10 10:27:05 | 显示全部楼层
谢谢分享
您需要登录后才可以回帖 登录 | 加入我们

本版积分规则

快速回复 返回顶部 返回列表