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

     

     

     

  • 相关阅读:
    javascript获取当前日期、年份和月份等
    程序员也可以懂一点期望值管理
    数据类型,隐式转换以及json,对象,引用类型,预解析 视频教程
    两个值交互位置的几种方法
    通过Class获取标签,兼容的几种思路
    前端开发流程
    元素多层嵌套,JS获取问题
    原生JS实现分页效果2.0(新增了上一页和下一页,添加当前元素样式)
    原生JS实现分页效果1.0
    学习方法,以及时间的安排。
  • 原文地址:https://www.cnblogs.com/moonflow/p/2508906.html
Copyright © 2011-2022 走看看