首页
社区
课程
招聘
[原创]inline-hook和object双HOOK联合调用拒绝WIN打开服务
发表于: 2011-1-23 01:14 10739

[原创]inline-hook和object双HOOK联合调用拒绝WIN打开服务

2011-1-23 01:14
10739

inline-hook和object双HOOK联合调用拒绝WIN打开服务

     看标题其实很简单我也没有找到比较合适的标题,所以各位大牛们别嘲笑小弟就好,
原理很简单,其实就是找到个和对象有关的系统频繁调用的函数实现双HOOK就行啦,
我选折ObCreateObject函数下手,关于OBJECTHOOK的文章参考一下我的前篇科普篇
http://bbs.pediy.com/showthread.php?t=128161
我们先看下ObCreateObject函数原型先
NTSTATUS
ObCreateObject (
    __in KPROCESSOR_MODE ProbeMode,            // 决定是否要验证参数
    __in POBJECT_TYPE ObjectType,              // 对象类型指针
    __in POBJECT_ATTRIBUTES ObjectAttributes,  // 对象的属性, 最终会转化成ObAllocateObject需要的OBJECT_CREATE_INFORMATION结构
    __in KPROCESSOR_MODE OwnershipMode,        // 内核对象?用户对象?
    __inout_opt PVOID ParseContext,            // 这参数没用
    __in ULONG ObjectBodySize,                 // 对象体大小
    __in ULONG PagedPoolCharge,                //
    __in ULONG NonPagedPoolCharge,             //
    __out PVOID *Object                        // 接收对象体的指针
    )
这里面有1个结构和一个对象对我们比较有用ObjectAttributes和ObjectType
ObjectType那那个科普帖已经介绍了,下面简单介绍一下这个结构
_OBJECT_ATTRIBUTES { ULONG  Length;//结构长
HANDLE  RootDirectory;    //对象所在目录
PUNICODE_STRING  ObjectName;   //对象名
ULONG  Attributes;    //属性标志
PVOID  SecurityDescriptor;   
PVOID  SecurityQualityOfService;
} OBJECT_ATTRIBUTES, *POBJECT_ATTRIBUTES;
这里面最重要还是ObjectType
直接上代码吧,太乱 因为是笔记

#include<ntddk.h>
#include<windef.h>

VOID Hook();
VOID WPOFF();
VOID WPON();
typedef struct _OBJECT_TYPE_INITIALIZER {
  USHORT Length;
  BOOLEAN UseDefaultObject;
  BOOLEAN CaseInsensitive;
  ULONG InvalidAttributes;
  GENERIC_MAPPING GenericMapping;
  ULONG ValidAccessMask;
  BOOLEAN SecurityRequired;
  BOOLEAN MaintainHandleCount;
  BOOLEAN MaintainTypeList;
  POOL_TYPE PoolType;
  ULONG DefaultPagedPoolCharge;
  ULONG DefaultNonPagedPoolCharge;
  PVOID DumpProcedure;
  PVOID OpenProcedure;
  PVOID CloseProcedure;
  PVOID DeleteProcedure;
  PVOID ParseProcedure;
  PVOID SecurityProcedure;
  PVOID QueryNameProcedure;
  PVOID OkayToCloseProcedure;
} OBJECT_TYPE_INITIALIZER, *POBJECT_TYPE_INITIALIZER;

typedef struct _OBJECT_TYPE {
  ERESOURCE Mutex;
  LIST_ENTRY TypeList;
  UNICODE_STRING Name;
  PVOID DefaultObject;
  ULONG Index;
  ULONG TotalNumberOfObjects;
  ULONG TotalNumberOfHandles;
  ULONG HighWaterNumberOfObjects;
  ULONG HighWaterNumberOfHandles;
  OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
  ULONG Key;
#endif
} OBJECT_TYPE, *POBJECT_TYPE;

typedef struct _OBJECT_CREATE_INFORMATION {
  ULONG Attributes;
  HANDLE RootDirectory;
  PVOID ParseContext;
  KPROCESSOR_MODE ProbeMode;
  ULONG PagedPoolCharge;
  ULONG NonPagedPoolCharge;
  ULONG SecurityDescriptorCharge;
  PSECURITY_DESCRIPTOR SecurityDescriptor;
  PSECURITY_QUALITY_OF_SERVICE SecurityQos;
  SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION, *POBJECT_CREATE_INFORMATION;

typedef struct _OBJECT_HEADER {
  LONG PointerCount;
  union {
    LONG HandleCount;
    PSINGLE_LIST_ENTRY SEntry;
  };
  POBJECT_TYPE Type;
  UCHAR NameInfoOffset;
  UCHAR HandleInfoOffset;
  UCHAR QuotaInfoOffset;
  UCHAR Flags;
  union
  {
    POBJECT_CREATE_INFORMATION ObjectCreateInfo;
    PVOID QuotaBlockCharged;
  };
  
  PSECURITY_DESCRIPTOR SecurityDescriptor;
  QUAD Body;
} OBJECT_HEADER, *POBJECT_HEADER;
POBJECT_TYPE pType= NULL;
POBJECT_HEADER addrs=NULL;
PVOID OldParseProcedure = NULL;
BYTE *pAddrs=NULL;
ULONG Ret=0;
ULONG hookaddr=0;

NTSTATUS NewParseProcedure(IN PVOID ParseObject,
             IN PVOID ObjectType,
             IN OUT PACCESS_STATE AccessState,
             IN KPROCESSOR_MODE AccessMode,
             IN ULONG Attributes,
             IN OUT PUNICODE_STRING CompleteName,
             IN OUT PUNICODE_STRING RemainingName,
             IN OUT PVOID Context OPTIONAL,
             IN PSECURITY_QUALITY_OF_SERVICE SecurityQos OPTIONAL,
             OUT PVOID *Object)
{
     NTSTATUS Status;
         
    KdPrint(("object is hook\n"));

  __asm
  {
      push eax
      push Object
      push SecurityQos
      push Context
      push RemainingName
      push CompleteName
      push Attributes
      movzx eax, AccessMode
      push eax
      push AccessState
      push ObjectType
      push ParseObject
      call OldParseProcedure
      mov Status, eax
      pop eax

      
  }
  return Status;

}
VOID Hook1()
{

        _asm{
           pushf
           pusha
           mov eax,pType
           cmp eax,0
           jz ggdd //空就跳
           add eax,0x9c
           cmp [eax],0 //打开服务为空就跳
           jz  ggdd
           mov eax,[eax]
           cmp eax,NewParseProcedure // 已经HOOK了就跳
           jz ggdd
           mov OldParseProcedure,eax
           mov ebx,NewParseProcedure
           mov eax,pType
           add eax,0x9c
           mov [eax],ebx
          
ggdd:
           popa
           popf
        }

}
__declspec(naked)  void __stdcall MyHook()
{
         _asm{
       
          push eax
          mov eax,[ebp+0xc] //获取ObjectType
          mov pType,eax
          call [hookaddr]
          pop eax
          push ecx
          push ebx
          push esi
          push edi
          jmp [Ret]
      
        }

   
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegistryPath)
{
   NTSTATUS status;
  
   hookaddr=(ULONG)Hook1;
   
   Hook();
   
   return STATUS_SUCCESS;
}
VOID Hook()
{   
         ULONG ObjAddrs,jmpAddrs;
         UNICODE_STRING  name;
         KIRQL  Irql;
         char code[5]={0xe9,0,0,0,0};
     RtlInitUnicodeString(&name,L"ObCreateObject");
     pAddrs=(BYTE*)MmGetSystemRoutineAddress(&name);
         if(pAddrs==NULL)
         {
           DbgPrint("pAaddrs is NULL\n");
         }
         DbgPrint("pAaddrs is:%08X\n",pAddrs);
         ObjAddrs=(ULONG)pAddrs;
         ObjAddrs=ObjAddrs+6;
         Ret=ObjAddrs+5;
         DbgPrint("pAaddrs is:%08X\n",ObjAddrs);
     DbgPrint("Ret is:%08X\n",Ret);
         jmpAddrs=(ULONG)MyHook-ObjAddrs-5;
         *(ULONG*)(code+1)=jmpAddrs;
     
     WPOFF();
     
      Irql=KeRaiseIrqlToDpcLevel();
      RtlCopyMemory(ObjAddrs,code,5);
     KeLowerIrql(Irql);
      WPON();  
     
}

VOID WPOFF()
{
  __asm
  {
    cli
    mov eax,cr0
    and eax,not 10000h
    mov cr0,eax
  }
}

VOID WPON()
{
  __asm
  {
    mov eax,cr0
    or eax,10000h
    mov cr0,eax
    sti
  }
}

以上代码有危险性,因为比较极端,请大家在虚拟机上运行 我的测试环境是 windows_xp_professional_with_service_pack_3
1.有如下症状所有文件不能打开,右键选中打开的选项消失。如果需要分析工具请先运行再加载驱动
2.所有驱动不能加载,包括任务管理器 CMD 不能打开
3.无法关机和重启。
希望大家不要把代码运用到恶意程序上,其实也没多少技术含量,只是比较极端而已。如有BUG
欢迎大牛们指正,共同学习 共同进步嘛






[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!

上传的附件:
收藏
免费 7
支持
分享
最新回复 (6)
雪    币: 220
活跃值: (15)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
呵呵 不错 支持一下。
2011-1-23 01:45
0
雪    币: 154
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
感谢分享
2011-1-23 02:00
0
雪    币: 71
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
不错

支持一下
2011-1-23 08:29
0
雪    币: 284
活跃值: (16)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
5
有码还是顶一下
2011-1-23 08:44
0
雪    币: 656
活跃值: (448)
能力值: ( LV12,RANK:360 )
在线值:
发帖
回帖
粉丝
6
收藏下.......
2011-1-23 12:19
0
雪    币: 24
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
收、学、谢!
2011-1-23 20:56
0
游客
登录 | 注册 方可回帖
返回
//