zoukankan      html  css  js  c++  java
  • Rootkit之HOOK小结

    目前接触的HOOK总结,学习HOOK只是为了让我对内核更加熟悉,我对那些毛的病毒木马没毛兴趣。

    Windows平台上HOOK:

    应用层HOOK:
    1.消息HOOK:局部钩子、全局钩子、全局低级键盘钩子之类
    2.IAT HOOK:通过修改IAT(导入表)表中的地址
      过程就是先取DOS头,再取PE头偏移,再获取导入信息,其中的FirstThunk就是IAT偏移,再遍历,这样就找到了IAT表
    3.EAT HOOK:(这个没有实际去做,知道思路)
      详见http://bbs.pediy.com/showthread.php?t=62574

    内核级HOOK:
    内核hook基本上大同小异,都是获取相关函数的地址后修改成自己函数的地址
    1.IDT HOOK:通过修改IDT表中的ISR例程地址

     #pragma pack(push)
      #pragma pack(1) // 1字节对齐
      typedef struct _IDTR //IDT基址
    {
    USHORT limit; //范围占位
    ULONG base; //基地址占位_IDT_ENTRY类型指针
    }IDTR,*PIDTR;
    typedef struct _IDT_ENTRY
    {
    USHORT offset_low; //中断处理函数地址低位
    USHORT selector;
    UCHAR  reserved;
    UCHAR  type:4; //4位
        UCHAR  always0:1; //1位
    UCHAR  dpl:2; //2位
    UCHAR  present:1;//1位
    USHORT offset_high;//中断处理函数地址低位
    }IDT_ENTRY,*PIDT_ENTRY;//获取基址实际上是这个类型
    #pragma pack(pop) //#pragma pack(pop)

    IDT 详解
    http://blog.csdn.net/fwqcuc/article/details/5855460
    http://blog.csdn.net/fwqcuc/article/details/5855715
    IDT 多核检测
    http://hi.baidu.com/andriy_aolala/blog/item/e841c1cd72277f5b0eb34510.html

    2.SSDT HOOK:通过修改SSDT表中函数地址
    系统服务描述符表 在ntoskrnl.exe导出KeServiceDescriptorTable 这个表

    typedef struct _ServiceDescriptorTable {
    PVOID ServiceTableBase; //System Service Dispatch Table 的基地址  
    PVOID ServiceCounterTable;
    //包含着 SSDT 中每个服务被调用次数的计数器。这个计数器一般由sysenter 更新。 
    unsigned int NumberOfServices;//由 ServiceTableBase 描述的服务的数目。  
    PVOID ParamTableBase; //包含每个系统服务参数字节数表的基地址-系统服务参数表 
    }*PServiceDescriptorTable;  
    //由SSDT索引号获取当前函数地址  
    //NtOpenProcess  [[KeServiceDescriptorTable]+0x7A*4]  
    extern PServiceDescriptorTable KeServiceDescriptorTable; 

    3.Inline HOOK:通过修改ntoskrnl导出Nt函数的字节,加入JMP
    像如果u nt!NtOpenProcess函数,JMP需要5字节,选择合适的地方插入JMP到自己定义的函数即可

    4.Shadow SSDT HOOK

            正常情况下,ETHREAD中的ServiceTable,要么指向KeServiceDescriptorTable,要么指向KeServiceDescriptorTableShadow,注意这句话啊
    ETHREAD->ServiceTable从来不会直接接向GUI的那张表,而是指向整体的KeServiceDescriptorTableShadow,用windbg观察就知道了
    系统中既有KeServiceDescriptorTable也有KeServiceDescriptorTableShadow,他们各司其职,非GUI线程使用KeServiceDescriptorTable,GUI线程使用KeServiceDescriptorTableShadow,这是Windows的设计。非GUI线程如果要调用GUI服务就会用PsConvertToGuiThread把ETHREAD->ServiceTable切换为KeServiceDescriptorTableShadow,而GUI线程调用普通的Win32服务时并不需要切换,因为KeServiceDescriptorTableShadow中已经有个这张表,所以KeServiceDescriptorTableShadow可以看成是KeServiceDescriptorTable的增强版
    KeServiceDescriptorTable中第二张表之所以无效,是因为非GUI线程根本不需要这张表,所以没有填充

    #pragma PAGECODE
    DWORD Get_KeServiceDescriptorTableShadow_Addr()
    {  
    DWORD KeServiceDescriptorTableShadow=0;
    DWORD Version=GetVersion();
    switch (Version  )
    {
            case VERSION_2K:
     KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable+0xE0;
       break;
    case VERSION_2K3:
       break;
    case VERSION_XP:
     KeServiceDescriptorTableShadow=(DWORD)KeServiceDescriptorTable-0x40;//XP系统的影子描述表是-0X40
       break;
    default:
    break;
    }
    return KeServiceDescriptorTableShadow;
    }

    链接:
    http://bbs.pediy.com/showthread.php?t=56955
    http://bbs.pediy.com/showthread.php?t=65931
    http://bbs.pediy.com/showthread.php?t=82066
    http://bbs.pediy.com/showthread.php?t=98909

    5.IRP HOOK

      1) 可用办法之一:hook IofCallDriver实现irp 拦截。
      2) 可用办法之二:写一个过滤驱动,挂在你要hook其irp的那个驱动之上。
      3) 可用办法之三:直接修改你要hook其irp的那个驱动的MajorFunction函数表。

    http://bbs.pediy.com/showthread.php?t=60022

    http://bbs.pediy.com/showthread.php?t=111559

    http://bbs.pediy.com/showthread.php?t=96245

    http://bbs.pediy.com/showthread.php?t=97821

    6.Object HOOK

    当你调用NtCreateFile->IoCreateFile->ObOpenObjectByName->ObpLookupObjectName->IopParseFile->IopParseDevice
    IopParseFile最终也会调用IopParseDevice
    ObjectHook其实就是比如你要HOOK 创建打开就是OBJECT_TYPE_INITIALIZER->ParseProcedure

    http://bbs.pediy.com/showthread.php?t=128161
    http://bbs.pediy.com/showthread.php?t=134415
    http://www.xfocus.net/articles/200802/966.html
    http://forum.eviloctal.com/thread-33688-1-1.html

    7.sysenter HOOK

    通过修改MSR寄存器的值来达到hook的目的,一般的拦截方法就是通过rdmsr wrmsr 两个指令把原来的sysenter地址改成自己的sysenter地址来实现的

    NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
    {
      theDriverObject->DriverUnload  = OnUnload; 
    
      __asm {
                mov ecx, 0x176
            rdmsr                 // read the value of the IA32_SYSENTER_EIP register
            mov d_origKiFastCallEntry, eax
            mov eax, MyKiFastCallEntry     // Hook function address
            wrmsr                        // Write to the IA32_SYSENTER_EIP register
      }
    
      return STATUS_SUCCESS;
    }

    http://bbs.pediy.com/showthread.php?t=60247
    http://bbs.pediy.com/showthread.php?t=42705


    几个学习链接:
    http://bbs.pediy.com/showthread.php?t=81204
    http://bbs.pediy.com/showthread.php?t=40832
    http://bbs.pediy.com/showthread.php?t=142142
    http://bbs.pediy.com/showthread.php?t=131397

    http://bbs.pediy.com/showthread.php?t=98493

    http://bbs.pediy.com/showthread.php?t=138620

    Detours:Binary Interception of Win32 Functions
    Load Your 32-bit DLL into Another Process's Address Space Using INJLIB
    http://blog.csdn.net/coding_hello
    http://www.cnblogs.com/me-sa/articles/671862.html

    Hide your ssdt hook     http://hi.baidu.com/sagittar_4d5a/blog/item/fe735660546f3143ebf8f8df.html



    Linux平台上的HOOK:
    很多Windows上的HOOK,Linux都可以做。
    例如sys_call_table,还有IDT等等
    在linux下主要的还是netfilter中的HOOK,这个才是Linux的重点。
    包横穿netfilter系统示意图: 
    ------ →[1]------ →[route]------ →[3]------ →[4]------ → 
                  |            ^ 
                  |            |    
                  |            [route] 
                  v            | 
                  [2]           [5] 
                  |            ^ 
                  |            | 
                  v            |
    [1]:nf_ip_pre_routing:刚刚进入网络层的数据包通过此点(刚刚进行完版本号,校验和等检测), 源地址转换在此点进行; 
    [2]:nf_ip_local_in:经路由查找后,送往本机的通过此检查点,input包过滤在此点进行;
    [3]:nf_ip_forward:要转发的包通过此检测点,forword包过滤在此点进行; 
    [4]:nf_ip_post_routing:所有马上便要通过网络设备出去的包通过此检测点,内置的目的地址转换功能(包括地址伪装)在此点进行; 

    [5]:nf_ip_local_out:本机进程发出的包通过此检测点,output包过滤在此点进行。 

    Linux下gdb检测rootkit:

    http://os.51cto.com/art/201001/178676.htm
    http://linkboy.blog.51cto.com/821152/297549

     

     

     

  • 相关阅读:
    VS2008编写MFC程序--使用opencv2.4()
    November 02nd, 2017 Week 44th Thursday
    November 01st, 2017 Week 44th Wednesday
    October 31st, 2017 Week 44th Tuesday
    October 30th, 2017 Week 44th Monday
    October 29th, 2017 Week 44th Sunday
    October 28th, 2017 Week 43rd Saturday
    October 27th, 2017 Week 43rd Friday
    October 26th, 2017 Week 43rd Thursday
    October 25th, 2017 Week 43rd Wednesday
  • 原文地址:https://www.cnblogs.com/moonflow/p/2508906.html
Copyright © 2011-2022 走看看