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

 

 

 

posted @ 2012-05-19 15:16  yarpee  阅读(934)  评论(0编辑  收藏  举报