|
本帖最后由 HoviDelphic 于 2010-7-15 17:18 编辑
最近网上浏览资料时,发现好多关于object hook 自己闲来无事 测试整理了一下,主要借鉴论坛上的各个大牛,测试通过2k到win7。代码附上:
#include <wdm.h>
#define NUMBER_HASH_BUCKETS 37
typedef struct _XP_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;
} 2K_XP_OBJECT_TYPE_INITIALIZER, *PXP_OBJECT_TYPE_INITIALIZER;
typedef struct _VISTA_OBJECT_TYPE_INITIALIZER
{
USHORT Length ;
USHORT type ;
//+0x002 ObjectTypeFlags : UChar
//+0x002 CaseInsensitive : Pos 0, 1 Bit
//+0x002 UnnamedObjectsOnly : Pos 1, 1 Bit
//+0x002 UseDefaultObject : Pos 2, 1 Bit
//+0x002 SecurityRequired : Pos 3, 1 Bit
//+0x002 MaintainHandleCount : Pos 4, 1 Bit
//+0x002 MaintainTypeList : Pos 5, 1 Bit
PVOID ObjectTypeCode ;
PVOID InvalidAttributes ;
GENERIC_MAPPING GenericMapping ;
PVOID ValidAccessMask ;
PVOID RetainAccess ;
POOL_TYPE PoolType ;
PVOID DefaultPagedPoolCharge ;
PVOID DefaultNonPagedPoolCharge ;
PVOID DumpProcedure ;
PVOID OpenProcedure ;
PVOID CloseProcedure ;
PVOID DeleteProcedure ;
PVOID ParseProcedure ;
PVOID SecurityProcedure ;
PVOID QueryNameProcedure ;
USHORT OkayToCloseProcedure ;
}VISTA_OBJECT_TYPE_INITIALIZER ,*PVISTA_OBJECT_TYPE_INITIALIZER;
typedef struct _XP_OBJECT_TYPE {
ERESOURCE Mutex;
LIST_ENTRY TypeList;
UNICODE_STRING Name; // Copy from object header for convenience
PVOID DefaultObject;
ULONG Index;
ULONG TotalNumberOfObjects;
ULONG TotalNumberOfHandles;
ULONG HighWaterNumberOfObjects;
ULONG HighWaterNumberOfHandles;
2K_ XP_OBJECT_TYPE_INITIALIZER TypeInfo;
#ifdef POOL_TAGGING
ULONG Key;
#endif //POOL_TAGGING
} XP_OBJECT_TYPE, *PXP_OBJECT_TYPE;
typedef struct _VISTA_OBJECT_TYPE
{
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
PVOID Index ;
PVOID TotalNumberOfObjects ;
PVOID TotalNumberOfHandles ;
PVOID HighWaterNumberOfObjects;
PVOID HighWaterNumberOfHandles;
VISTA_OBJECT_TYPE_INITIALIZER TypeInfo ;
ERESOURCE Mutex ;
EX_PUSH_LOCK TypeLock ;
PVOID Key ;
EX_PUSH_LOCK ObjectLocks ;
LIST_ENTRY CallbackList ;
}VISTA_OBJECT_TYPE ,*PVISTA_OBJECT_TYPE;
typedef struct _WIN7_OBJECT_TYPE
{
LIST_ENTRY TypeList ;
UNICODE_STRING Name ;
PVOID DefaultObject ;
ULONG Index ;
ULONG TotalNumberOfObjects ;
ULONG TotalNumberOfHandles ;
ULONG HighWaterNumberOfObjects ;
ULONG HighWaterNumberOfHandles ;
VISTA_OBJECT_TYPE_INITIALIZER TypeInfo ;
EX_PUSH_LOCK TypeLock ;
PVOID Key ;
LIST_ENTRY CallbackList ;
}WIN7_OBJECT_TYPE,*PWIN7_OBJECT_TYPE;
typedef struct _OBJECT_DIRECTORY_ENTRY {
struct _OBJECT_DIRECTORY_ENTRY *ChainLink;
PVOID Object;
} OBJECT_DIRECTORY_ENTRY, *POBJECT_DIRECTORY_ENTRY;
typedef struct _OBJECT_DIRECTORY {
struct _OBJECT_DIRECTORY_ENTRY *HashBuckets[ NUMBER_HASH_BUCKETS ];
struct _OBJECT_DIRECTORY_ENTRY **LookupBucket;
BOOLEAN LookupFound;
USHORT SymbolicLinkUsageCount;
struct _DEVICE_MAP *DeviceMap;
} OBJECT_DIRECTORY, *POBJECT_DIRECTORY;
//结构体主要是通过windbg 得到,有不足希望大家指点。由于小弟很笨不习惯数字表达,直接上结构体。
PVOID OldParseKey=NULL;
VOID zfw_InitReistHook()
{
UNICODE_STRING RegPath ;
OBJECT_ATTRIBUTES oba ;
HANDLE RegKeyHandle ;
NTSTATUS status ;
PVOID KeyObject ;
PVOID CmpKeyObjectType;
ULONG mTemp=0;
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 ))
{
return ;
}
//首先随便打开一个注册表键,得到对象
status=ObReferenceObjectByHandle(RegKeyHandle,
GENERIC_READ,
NULL,
KernelMode,
&KeyObject,
0);
if (!NT_SUCCESS(status ))
{
ZwClose(RegKeyHandle);
return ;
}
if(g_WindowVer==win7)//写时,发现win7的object_header没有了object_type,但是多了一个Index,
//原以为和其他结构一样是便宜,结果XXX,哎呀,google 原
//ObTypeIndexTable 中 的Index,万幸有ObGetObjectType,哈哈
if(zf_ObGetObjectType)
CmpKeyObjectType=ObGetObjectType(KeyObject);
}
}
else
{
__asm
{
push eax
mov eax,KeyObject
mov eax,[eax-0x10]
mov CmpKeyObjectType,eax
pop eax
}
}
//get the key object type
//获得注册表键对象类型,即CmpKeyObjectType
if(g_WindowVer==win7)
{
OldParseKey = ((PWIN7_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure ;
}else if(g_WindowVer==vista)
OldParseKey = ((PVISTA_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure ;
else
OldParseKey=((PXP_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure ;
if (!MmIsAddressValid(OldParseKey))
{
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;
}
__asm
{
cli;
mov eax, cr0;
and eax, not 10000h;
mov cr0, eax;
}
if(g_WindowVer==win7)
{
((PWIN7_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure=zfw_FakeParseKey ;
}else if(g_WindowVer>vista)
((PVISTA_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure = zfw_FakeParseKey;
else
((PXP_OBJECT_TYPE)CmpKeyObjectType)->TypeInfo.ParseProcedure = zfw_FakeParseKey;
__asm
{
mov eax, cr0;
or eax, 10000h;
mov cr0, eax;
sti;
}
//进行HOOK
ObDereferenceObject(KeyObject);
ZwClose(RegKeyHandle);
return ;
}
zfw_FakeParseKey的代码不用写了吧,牛哥们都帮忙了。
【本帖最后由HoviDelphic修改,修改原因:代码着色】 |
评分
-
查看全部评分
|