TP技术难点:
1.双机调试
2.TesSafe自身模块硬断检测和自身CRC检测
3.DebugOjbetType权值清零
4.DebugPort清零
1解决了 2放弃 3Pass 4Pass a half
讲解3.
直接上笔记和码
nt!NtDebugActiveProcess+0x9a:
84cb8e4a 341b xor al,1Bh
nt!NtCreateDebugObject+0x60:
84cb7f53 341b xor al,1Bh
nt!NtWaitForDebugEvent+0xb5:
84cb920a 341b xor al,1Bh
nt!NtDebugContinue+0x82:
84cb94f3 341b xor al,1Bh
nt!NtRemoveProcessDebug+0x6d:
这里使系统函数调用了dbgkdebugobjecttype我们要替换他
换成我们自己造好的
#ifndef VALIDACCESSMASK
#define VALIDACCESSMASK
#define OBJECT_TO_OBJECT_HEADER( o ) CONTAINING_RECORD( (o), OBJECT_HEADER_WIN7, Body )
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();
}
#endif
[注意]传递专业知识、拓宽行业人脉——看雪讲师团队等你加入!