typedef struct _OBJECT_DIRECTORY_ENTRY_WIN7{
struct _OBJECT_DIRECTORY_ENTRY_WIN7 *ChainLink;
PVOID Object;
ULONG HashValue;
} OBJECT_DIRECTORY_ENTRY_WIN7, *POBJECT_DIRECTORY_ENTRY_WIN7;
typedef struct _OBJECT_TYPE_INITIALIZER_WIN7 {
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 ;
} OBJECT_TYPE_INITIALIZER_WIN7, *POBJECT_TYPE_INITIALIZER_WIN7;
typedef struct _OBJECT_CREATE_INFORMATION_WIN7 {
ULONG Attributes;
HANDLE RootDirectory;
KPROCESSOR_MODE ProbeMode;
ULONG PagedPoolCharge;
ULONG NonPagedPoolCharge;
ULONG SecurityDescriptorCharge;
PVOID SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQos;
SECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_CREATE_INFORMATION_WIN7, *POBJECT_CREATE_INFORMATION_WIN7;
typedef struct _OBJECT_TYPE_WIN7 {
LIST_ENTRY TypeList;
//
: _LIST_ENTRY
UNICODE_STRING Name;
//
: _UNICODE_STRING
PVOID DefaultObject;
//
: Ptr32 Void
ULONG Index;
//
: UChar
ULONG TotalNumberOfObjects;
//
: Uint4B
ULONG TotalNumberOfHandles;
//
: Uint4B
ULONG HighWaterNumberOfObjects;
//
: Uint4B
ULONG HighWaterNumberOfHandles;
//
: Uint4B
OBJECT_TYPE_INITIALIZER_WIN7 TypeInfo;
//
: _OBJECT_TYPE_INITIALIZER
PVOID TypeLock;
//
: _EX_PUSH_LOCK
ULONG Key;
//
: Uint4B
LIST_ENTRY CallbackList;
//
: _LIST_ENTRY
} OBJECT_TYPE_WIN7, *POBJECT_TYPE_WIN7;
typedef struct _OBJECT_HEADER_WIN7 {
//
对象头部的指针计数,对对象头指针引用的计数
LONG_PTR PointerCount;
union {
//
句柄引用计数
LONG_PTR HandleCount;
PVOID NextToFree;
};
POBJECT_TYPE Type;
//OBJECT_HEADER_NAME_INFO
相对于此结构的偏移
UCHAR NameInfoOffset;
//OBJECT_HEADER_HANDLE_INFO
相对于此结构的偏移
UCHAR HandleInfoOffset;
//OBJECT_HEADER_QUOTA_INFO
相对于此结构的偏移
UCHAR QuotaInfoOffset;
UCHAR Flags;
union {
//
创建对象是用于创建对象附加头的结构
//
里面保存了和附加对象头类似的信息
PVOID ObjectCreateInfo;
PVOID QuotaBlockCharged;
};
PSECURITY_DESCRIPTOR SecurityDescriptor;
QUAD Body;
} OBJECT_HEADER_WIN7, *POBJECT_HEADER_WIN7;
EXTERN_C
{
NTKERNELAPI
NTSTATUS
ObCreateObjectType(
__in PUNICODE_STRING TypeName,
__in POBJECT_TYPE_INITIALIZER_WIN7 ObjectTypeInitializer,
__in_opt PSECURITY_DESCRIPTOR SecurityDesorintor,
__in POBJECT_TYPE_WIN7 *ObjectType
);
NTKERNELAPI
PVOID
ObGetObjectType(
__in PVOID pObject
);
}
ULONG DbgkDebugObjectType=NULL;
ULONG DbgkMyDebugObjectType=NULL;
POBJECT_TYPE_WIN7 MyDebugObjectType=NULL;
OBJECT_TYPE_INITIALIZER_WIN7 ObjectTypeInitializer;
void CreateMyDebugObjectType(POBJECT_TYPE_WIN7 tmpObjectType,UNICODE_STRING MyObjectTypeName)
{
RtlZeroMemory(&ObjectTypeInitializer,sizeof(ObjectTypeInitializer));
ObjectTypeInitializer.Length=tmpObjectType->TypeInfo.Length;
ObjectTypeInitializer.ObjectTypeCode=tmpObjectType->TypeInfo.ObjectTypeCode;
ObjectTypeInitializer.InvalidAttributes=tmpObjectType->TypeInfo.InvalidAttributes;
ObjectTypeInitializer.GenericMapping=tmpObjectType->TypeInfo.GenericMapping;
ObjectTypeInitializer.ValidAccessMask=(PVOID) 0x001fffff;
ObjectTypeInitializer.RetainAccess=tmpObjectType->TypeInfo.RetainAccess;
ObjectTypeInitializer.PoolType=tmpObjectType->TypeInfo.PoolType;
ObjectTypeInitializer.DefaultPagedPoolCharge=tmpObjectType->TypeInfo.DefaultPagedPoolCharge;
ObjectTypeInitializer.DefaultNonPagedPoolCharge=tmpObjectType->TypeInfo.DefaultNonPagedPoolCharge;
ObjectTypeInitializer.DumpProcedure=tmpObjectType->TypeInfo.DumpProcedure;
ObjectTypeInitializer.OpenProcedure=tmpObjectType->TypeInfo.OpenProcedure;
ObjectTypeInitializer.CloseProcedure=tmpObjectType->TypeInfo.CloseProcedure;
ObjectTypeInitializer.DeleteProcedure=tmpObjectType->TypeInfo.DeleteProcedure;
ObjectTypeInitializer.ParseProcedure=tmpObjectType->TypeInfo.ParseProcedure;
ObjectTypeInitializer.SecurityProcedure=tmpObjectType->TypeInfo.SecurityProcedure;
ObjectTypeInitializer.QueryNameProcedure=tmpObjectType->TypeInfo.QueryNameProcedure;
ObjectTypeInitializer.OkayToCloseProcedure=tmpObjectType->TypeInfo.OkayToCloseProcedure;
ObCreateObjectType(&MyObjectTypeName,&ObjectTypeInitializer,(PSECURITY_DESCRIPTOR)NULL,&MyDebugObjectType);
}
void InitMyDebugOjbetType(ULONG pObjectType)
{
UNICODE_STRING MyObjectTypeName;
POBJECT_TYPE_WIN7 tmpObjectType=(POBJECT_TYPE_WIN7)*(ULONG *)pObjectType;
RtlInitUnicodeString(&MyObjectTypeName,L
"MyDebugObject"
);
if
(MyDebugObjectType==NULL)
{
CreateMyDebugObjectType(tmpObjectType,MyObjectTypeName);
DbgPrint(
"CreateMyDebugObjectType is succeed!!\n"
);
}
if
(MyDebugObjectType!=NULL)
{
//
*(DWORD *)pObjectType=(ULONG)MyFirstType;
DbgPrint(
"pObObjectType is %x !\n"
,(ULONG *)pObjectType);
}
else
{
DbgPrint(
"CreateMyDebugObjectType is failed!\n"
);
}
}
bool PickUpObjectType(ULONG pObjectType,PWCH Name)
{
UNICODE_STRING CmpName;
POBJECT_TYPE_WIN7 tmpObjectType=(POBJECT_TYPE_WIN7)*(ULONG *)pObjectType;
CmpName.Length=tmpObjectType->Name.Length;
CmpName.Buffer=Name;
//
如果字符串2超过字符串1长度,那么不管超出部分怎么填都是对的
//DbgPrint
(
"TestObjectType is %S!\n"
,CmpName.Buffer);
if
(RtlEqualUnicodeString(&tmpObjectType->Name,&CmpName,FALSE))
{
return
true
;
}
return
false
;
}
POBJECT_TYPE GetObpTypeObjectType_Win7()
{
PUCHAR addr,p;
UNICODE_STRING usObCreateObjectType;
POBJECT_TYPE _ObpTypeObjectType=NULL;
RtlInitUnicodeString(&usObCreateObjectType,L
"ObCreateObjectType"
);
addr=(PUCHAR)MmGetSystemRoutineAddress(&usObCreateObjectType);
ASSERT(addr!=NULL);
DbgPrint(
"ObCreateObjectType=0x%08x\n"
,addr);
for
(p=addr;p<addr+PAGE_SIZE;p++)
{
if
((*(PUCHAR)p==0xa1) && (*(PUCHAR)(p+5)==0xbb))
{
_ObpTypeObjectType=(POBJECT_TYPE)(*(PULONG)(p+1));
DbgPrint(
"ObpTypeObjectType=0x%08x\n"
,_ObpTypeObjectType);
return
_ObpTypeObjectType;
}
}
if
(p==addr+PAGE_SIZE)
DbgPrint(
"Cannot find ObpTypeObjectType!\n"
);
return
NULL;
}
void EnumObjectType_Win7()
{
ULONG OffsetObjectTypeName;
ULONG OffsetCreatorInfoObject;
ULONG OffsetObjectIndexObjectType;
POBJECT_TYPE ObpTypeObjectType;
ULONG ObjectTypeTable[50]={0};
int i=0;
ULONG_PTR TypeObjectAddr;
PLIST_ENTRY TypeObjectCreatorInfo;
PLIST_ENTRY NextEntry;
RTL_OSVERSIONINFOW VersionInformation;
RtlGetVersion(&VersionInformation);
if
(VersionInformation.dwMajorVersion==6)
//win7
{
OffsetObjectTypeName=0x08;
OffsetCreatorInfoObject=0x28;
OffsetObjectIndexObjectType=0x14;
ObpTypeObjectType=GetObpTypeObjectType_Win7();
}
for
(i=0;i<50;i++)
{
ObjectTypeTable[i]=(ULONG)ObpTypeObjectType+sizeof(ULONG)*i;
}
i=3;
TypeObjectAddr=*(PULONG_PTR)ObpTypeObjectType;
TypeObjectCreatorInfo=(PLIST_ENTRY)(TypeObjectAddr-OffsetCreatorInfoObject);
NextEntry=TypeObjectCreatorInfo;
while
(NextEntry->Flink!=TypeObjectCreatorInfo)
{
if
(PickUpObjectType(ObjectTypeTable[i],L
"DebugObject"
))
{
InitMyDebugOjbetType(ObjectTypeTable[i]);
}
if
(PickUpObjectType(ObjectTypeTable[i],L
"MyDebugObject"
))
{
DbgkMyDebugObjectType=ObjectTypeTable[i];
DbgPrint(
"DbgkMyDebugObjectType is %x !\n"
,DbgkMyDebugObjectType);
}
DbgPrint(
"TypeAddr=0x%08x,TypeName=%wZ,TypeIndex=%d\n"
,
(ULONG_PTR)NextEntry+OffsetCreatorInfoObject,
(PUNICODE_STRING)((ULONG_PTR)NextEntry+OffsetCreatorInfoObject+OffsetObjectTypeName),
*(PUCHAR)((ULONG_PTR)NextEntry+OffsetCreatorInfoObject+OffsetObjectIndexObjectType));
NextEntry=NextEntry->Flink;
i++;
}
}
void DeleteMyDebugObjectType()
{
if
(MyDebugObjectType!=NULL)
{
//ObMakeTemporaryObject
(MyDebugObjectType);
ObfDereferenceObject(MyDebugObjectType);
}
}
void PatchDebugObjectType()
{
DbgkDebugObjectType=(ULONG)GetSSDTFunctionAddr(96)+0x9a;
DbgkDebugObjectType=*(PULONG)DbgkDebugObjectType;
ULONG PassNtDebugActiveProcess=(ULONG)GetSSDTFunctionAddr(96)+0x9a;
ULONG PassNtCreateDebugObject=(ULONG)GetSSDTFunctionAddr(61)+0x60;
ULONG PassNtWaitForDebugEvent=(ULONG)GetSSDTFunctionAddr(387)+0xb5;
ULONG PassNtDebugContinue=(ULONG)GetSSDTFunctionAddr(97)+0x82;
ULONG PassNtRemoveProcessDebug=(ULONG)GetSSDTFunctionAddr(289)+0x6d;
DbgPrint(
"DbgkDebugObjectType is %x!\n"
,*(PULONG)DbgkDebugObjectType);
DbgPrint(
"PassNtDebugActiveProcess is %x!\n"
,*(PULONG)PassNtDebugActiveProcess);
DbgPrint(
"PassNtCreateDebugObject is %x!\n"
, *(PULONG)PassNtCreateDebugObject);
DbgPrint(
"PassNtCreateDebugObject is %x!\n"
,*(PULONG)PassNtWaitForDebugEvent);
DbgPrint(
"PassNtWaitForDebugEvent is %x!\n"
,*(PULONG)PassNtDebugContinue);
DbgPrint(
"PassNtRemoveProcessDebug is %x!\n"
,*(PULONG)PassNtRemoveProcessDebug);
DbgPrint(
"DbgkMyDebugObjectType is %x!\n"
,DbgkMyDebugObjectType);
if
(DbgkMyDebugObjectType!=NULL)
{
WPOFF();
KIRQL uKirql;
uKirql =KeRaiseIrqlToSynchLevel();
*(PULONG)PassNtDebugActiveProcess=DbgkMyDebugObjectType;
*(PULONG)PassNtCreateDebugObject=DbgkMyDebugObjectType;
*(PULONG)PassNtWaitForDebugEvent=DbgkMyDebugObjectType;
*(PULONG)PassNtDebugContinue=DbgkMyDebugObjectType;
*(PULONG)PassNtRemoveProcessDebug=DbgkMyDebugObjectType;
KeLowerIrql(uKirql);
WPON();
DbgPrint(
"PatchDebugObjectType is succeed!\n"
);
}
else
{
DbgPrint(
"PatchDebugObjectType is failed!\n"
);
}
}
void UnPatchDebugObjectType()
{
ULONG PassNtDebugActiveProcess=(ULONG)GetSSDTFunctionAddr(96)+0x9a;
ULONG PassNtCreateDebugObject=(ULONG)GetSSDTFunctionAddr(61)+0x60;
ULONG PassNtWaitForDebugEvent=(ULONG)GetSSDTFunctionAddr(387)+0xb5;
ULONG PassNtDebugContinue=(ULONG)GetSSDTFunctionAddr(97)+0x82;
ULONG PassNtRemoveProcessDebug=(ULONG)GetSSDTFunctionAddr(289)+0x6d;
if
(DbgkDebugObjectType!=NULL)
{
WPOFF();
KIRQL uKirql;
uKirql =KeRaiseIrqlToSynchLevel();
*(PULONG)PassNtDebugActiveProcess=DbgkDebugObjectType;
*(PULONG)PassNtCreateDebugObject=DbgkDebugObjectType;
*(PULONG)PassNtWaitForDebugEvent=DbgkDebugObjectType;
*(PULONG)PassNtDebugContinue=DbgkDebugObjectType;
*(PULONG)PassNtRemoveProcessDebug=DbgkDebugObjectType;
KeLowerIrql(uKirql);
WPON();
DbgPrint(
"UnPatchDebugObjectType is succeed!\n"
);
}
else
{
DbgPrint(
"UnPatchDebugObjectType is failed!\n"
);
}
}
void AntiValidAccessMask()
{
EnumObjectType_Win7();
PatchDebugObjectType();
}
void UnAntiValidAccessMask()
{
UnPatchDebugObjectType();
DeleteMyDebugObjectType();
}