瑞客论坛 www.ruike1.com
D032-驱动对抗Process
Object保护勾子
完美过掉【瑞客论坛
www.ruike1.com】
D032
D032-对抗Object勾子,完美过掉
2021在线班
郁金香灬老师 QQ 150330575
交流群:158280115
学习目标:
突破TP,NP等游戏保护跨进程写只读内存方法
ExInitializeFastMutex 初始化
ExAcquireFastMutex 请求使用 WaitForSingleObject
//要同步数据
ExReleaseFastMutex 释放
typedef struct _OB_CALLBACK_REGISTRATION {
_In_ USHORT Version;
_In_ USHORT OperationRegistrationCount;
_In_ UNICODE_STRING Altitude;
_In_ PVOID RegistrationContext;
_In_ OB_OPERATION_REGISTRATION *OperationRegistration;
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
_OB_CALLBACK_REGISTRATION->Altitude
如果你不熟悉Altiutde,它只是一个数字值,表示应该调用回调的顺序。
较高的数字最先访问
较低的数字最后访问
#include <ntifs.h>
#include <ntddk.h>
#include "ObRegisterCallBacksByPass.h"
extern PSHORT NtBuildNumber;
BOOLEAN ObRegisterCallBacksInit(PDRIVER_OBJECT pDriverObject);
BOOLEAN ObGetCallBacksAltitude(WCHAR* szDriverName, PUNICODE_STRING usAltitudeString, BOOLEAN bGetProcess);
void ObRegisterUnload();
//获取未文档化的函数
PVOID GetUndocumentFunctionAddress(IN PUNICODE_STRING pFunName,
IN PUCHAR pStartAddress,
IN UCHAR* pFeatureCode,
IN ULONG FeatureCodeNum,
ULONG SerSize,
UCHAR SegCode,
ULONG AddNum,
BOOLEAN ByName);
BOOLEAN IsMyProcess();//判断是否是可以过保护的进程
OB_PREOP_CALLBACK_STATUS First_CallBack(IN PVOID RegistrationContext, IN POB_PRE_OPERATION_INFORMATION OperationInformation);
OB_PREOP_CALLBACK_STATUS Last_CallBack(IN PVOID RegistrationContext, IN POB_PRE_OPERATION_INFORMATION OperationInformation);
#define DRIVER_TAG 'yjx'
#define DPRINT(format, ...) DbgPrintEx(DPFLTR_IHVDRIVER_ID, DPFLTR_ERROR_LEVEL, format, __VA_ARGS__)
ULONG ObjectCallbackListOffset = 0;
NTKERNELAPI UCHAR* PsGetProcessImageFileName(PEPROCESS Process);
typedef struct _LDR_DATA
{
/*0x000*/ struct _LIST_ENTRY InLoadOrderLinks;
/*0x010*/ struct _LIST_ENTRY InMemoryOrderLinks;
/*0x020*/ struct _LIST_ENTRY InInitializationOrderLinks;
/*0x030*/ VOID* DllBase;
/*0x038*/ VOID* EntryPoint;
/*0x040*/ ULONG32 SizeOfImage;
/*0x044*/ UINT8 _PADDING0_[0x4];
/*0x048*/ struct _UNICODE_STRING FullDllName;
/*0x058*/ struct _UNICODE_STRING BaseDllName;
/*0x068*/ ULONG32 Flags;
/*0x06C*/ UINT16 LoadCount;
/*0x06E*/ UINT16 TlsIndex;
union
{
/*0x070*/ struct _LIST_ENTRY HashLinks;
struct
{
/*0x070*/ VOID* SectionPointer;
/*0x078*/ ULONG32 CheckSum;
/*0x07C*/ UINT8 _PADDING1_[0x4];
};
};
union
{
/*0x080*/ ULONG32 TimeDateStamp;
/*0x080*/ VOID* LoadedImports;
};
/*0x088*/ struct _ACTIVATION_CONTEXT* EntryPointActivationContext;
/*0x090*/ VOID* PatchInformation;
/*0x098*/ struct _LIST_ENTRY ForwarderLinks;
/*0x0A8*/ struct _LIST_ENTRY ServiceTagLinks;
/*0x0B8*/ struct _LIST_ENTRY StaticLinks;
/*0x0C8*/ VOID* ContextInformation;
/*0x0D0*/ UINT64 OriginalBase;
/*0x0D8*/ union _LARGE_INTEGER LoadTime;
}LDR_DATA, *PLDR_DATA;
//这里字节对齐要采用默认,不要按1对齐,这样才符合32位和64位结构体
typedef struct _LDR_DATA_TABLE_ENTRY
{
LIST_ENTRY InLoadOrderLinks;
LIST_ENTRY InMemoryOrderLinks;
LIST_ENTRY InInitializationOrderLinks;
PVOID DllBase;
PVOID EntryPoint;
ULONG SizeOfImage;
UNICODE_STRING FullDllName;
UNICODE_STRING BaseDllName;
ULONG Flags;
USHORT LoadCount;
USHORT TlsIndex;
union
{
LIST_ENTRY HashLinks;
struct
{
PVOID SectionPointer;
ULONG CheckSum;
};
};
union
{
struct
{
ULONG TimeDateStamp;
};
struct
{
PVOID LoadedImports;
};
};
struct _ACTIVATION_CONTEXT * EntryPointActivationContext;
PVOID PatchInformation;
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;
typedef struct _OPERATION_INFO_ENTRY
{
LIST_ENTRY ListEntry;
OB_OPERATION Operation;
ULONG Flags;
PVOID Object;
POBJECT_TYPE ObjectType;
ACCESS_MASK AccessMask;
ULONG32 time;
} OPERATION_INFO_ENTRY, *POPERATION_INFO_ENTRY;
typedef struct _CALL_BACK_INFO
{
ULONG64 Unknow;
ULONG64 Unknow1;
UNICODE_STRING AltitudeString;
LIST_ENTRY NextEntryItemList; //(callbacklist) 跟上面开头的那个一样 存储下一个callbacklist
ULONG64 Operations;
PVOID ObHandle; //存储详细的数据 版本号 POB_OPERATION_REGISTRATION AltitudeString 也就是本身节点CALL_BACK_INFO 注销时也使用这个 注意是指针 //CALL_BACK_INFO
PVOID ObjectType;
ULONG64 PreCallbackAddr;
ULONG64 PostCallbackAddr;
}CALL_BACK_INFO, *PCALL_BACK_INFO;
typedef struct _OB_CALLBACK
{
LIST_ENTRY ListEntry;
ULONG64 Operations;
PCALL_BACK_INFO ObHandle;
ULONG64 ObjTypeAddr;
ULONG64 PreCall;
ULONG64 PostCall;
} OB_CALLBACK, *POB_CALLBACK;
LIST_ENTRY g_OperationListHead;
FAST_MUTEX g_OperationListLock;//给 g_OperationListHead 加的同步手段 互斥体
PVOID g_UpperHandle = NULL;
PVOID g_LowerHandle = NULL;
UINT32 GetCurrentProcessID()
{
return PsGetCurrentProcessId();
}
// 是自己的进程 可以过保护
BOOLEAN IsMyProcess()
{
PEPROCESS Process = NULL;
Process = PsGetCurrentProcess();
//KeQuerySystemTime(1);
if (_strnicmp("150330575.exe", PsGetProcessImageFileName(Process), strlen("150330575.exe")) == 0)
{
return TRUE;// OB_PREOP_SUCCESS;
}
else
{
return FALSE;
}
}
//内核获取系统启动计数
ULONG MyGetTickCount()
{
LARGE_INTEGER la;
ULONG MyInc;
MyInc = KeQueryTimeIncrement(); //返回滴答数频率
//下方 KeQueryTickCount 的宏的原型.
KeQueryTickCount(&la);
la.QuadPart *= MyInc;
la.QuadPart /= 10000;
return la.LowPart;
}
//APC_LEVEL=1;
OB_PREOP_CALLBACK_STATUS Last_CallBack(IN PVOID RegistrationContext, IN POB_PRE_OPERATION_INFORMATION OperationInformation)
{
POPERATION_INFO_ENTRY NewEntry = NULL;
if (PsGetCurrentProcess() == PsInitialSystemProcess)
return OB_PREOP_SUCCESS;
if (OperationInformation->ObjectType == PsThreadType)
return OB_PREOP_SUCCESS;
if (IsMyProcess())
{
NewEntry = (POPERATION_INFO_ENTRY)ExAllocatePoolWithTag(NonPagedPool, sizeof(OPERATION_INFO_ENTRY), DRIVER_TAG);
if (NewEntry)
{
NewEntry->Operation = OperationInformation->Operation;
NewEntry->Flags = OperationInformation->Flags;
NewEntry->Object = OperationInformation->Object;
NewEntry->ObjectType = OperationInformation->ObjectType;
//保存请求的权限 防止被保护回调 修改 DuplicateHandle OpenProcess
NewEntry->AccessMask = 0x1fffff;//OperationInformation->Parameters->CreateHandleInformation.DesiredAccess; /// Same for duplicate handle
NewEntry->time = MyGetTickCount();// KeQuerySystemTime(1);
ExAcquireFastMutex(&g_OperationListLock);//同步快速互斥体 获取所有权
InsertTailList(&g_OperationListHead, &NewEntry->ListEntry);//保存节点
KdPrint(("yjx:Last_CallBack 保存权限=%llX PID=%llX time=%llX line=%lld\n",
(ULONG64)OperationInformation->Parameters->CreateHandleInformation.DesiredAccess,//原权限 保存
(ULONG64)PsGetCurrentProcessId(),
(ULONG64)NewEntry->time,
(ULONG64)__LINE__));
ExReleaseFastMutex(&g_OperationListLock);//同步快速互斥体 释放所有权
}
}
UNREFERENCED_PARAMETER(RegistrationContext);
return OB_PREOP_SUCCESS;
}
OB_PREOP_CALLBACK_STATUS First_CallBack(IN PVOID RegistrationContext, IN POB_PRE_OPERATION_INFORMATION OperationInformation)
{
PLIST_ENTRY ListEntry;
UNREFERENCED_PARAMETER(RegistrationContext);
if (IsMyProcess())
{
ExAcquireFastMutex(&g_OperationListLock);//获取同步所有权
for (ListEntry = g_OperationListHead.Flink; ListEntry != &g_OperationListHead; ListEntry = ListEntry->Flink)
{
POPERATION_INFO_ENTRY Entry = (POPERATION_INFO_ENTRY)ListEntry;
if (Entry->Operation == OperationInformation->Operation &&
Entry->Flags == OperationInformation->Flags &&
Entry->Object == OperationInformation->Object &&
Entry->ObjectType == OperationInformation->ObjectType)
{
//
ULONG32 newAccess = OperationInformation->Parameters->CreateHandleInformation.DesiredAccess;
ULONG32 oldAccess = Entry->AccessMask;
KdPrint(("yjx:SYS First_CallBack PID=%llX <原权限=%llX,新权限=%llX>----->time=%llX line=%d\n",
(ULONG64)PsGetCurrentProcessId(),
(ULONG64)(Entry->AccessMask),//原权限
(ULONG64)newAccess,
(ULONG64)Entry->time, (ULONG64)__LINE__)); //新权限
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = Entry->AccessMask; //恢复权限请求OpenProcess
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = Entry->AccessMask; //恢复权限请求 DuplicateHandle
//移出结点
RemoveEntryList(&Entry->ListEntry);
ExFreePoolWithTag(Entry, DRIVER_TAG);
goto Release;
}
}
Release:
ExReleaseFastMutex(&g_OperationListLock);//释放同步所有权
//ok
}
return OB_PREOP_SUCCESS;
}
OB_OPERATION_REGISTRATION ObUpperOperationRegistration[] =
{
{ NULL, OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, Last_CallBack, NULL },//进程的
{ NULL, OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, Last_CallBack, NULL },//线程的
};
OB_OPERATION_REGISTRATION ObLowerOperationRegistration[] =
{
{ NULL, OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, First_CallBack, NULL },//进程的
{ NULL, OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE, First_CallBack, NULL },//线程的
};
// XignCode3 回调码 380800
// EAC 回调码 327530
// BE 回调码 363220
OB_CALLBACK_REGISTRATION UpperCallbackRegistration =
{
OB_FLT_REGISTRATION_VERSION,
2,
RTL_CONSTANT_STRING(L"880000"),//高的
NULL,
ObUpperOperationRegistration
};
OB_CALLBACK_REGISTRATION LowerCallcackRegistration =
{
OB_FLT_REGISTRATION_VERSION,
2,
RTL_CONSTANT_STRING(L"10000"),//低的
NULL,
ObLowerOperationRegistration
};
void ObRegisterUnload()
{
if (NULL != g_LowerHandle)
ObUnRegisterCallbacks(g_LowerHandle);
if (NULL != g_UpperHandle)
ObUnRegisterCallbacks(g_UpperHandle);
while (!IsListEmpty(&g_OperationListHead))
ExFreePoolWithTag(RemoveHeadList(&g_OperationListHead), DRIVER_TAG);
}
BOOLEAN ObRegisterCallBacksInit(PDRIVER_OBJECT pDriverObject)
{
NTSTATUS Status = STATUS_SUCCESS;
PLDR_DATA ldr;
ldr = (PLDR_DATA)pDriverObject->DriverSection;
ldr->Flags |= 0x20;
InitializeListHead(&g_OperationListHead);//初始化链表头
ExInitializeFastMutex(&g_OperationListLock);//初始化快速互斥体
ObUpperOperationRegistration[0].ObjectType = PsProcessType;
//新添加的
ObUpperOperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
ObUpperOperationRegistration[1].ObjectType = PsThreadType;
//新添加的
ObUpperOperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
Status = ObRegisterCallbacks(&UpperCallbackRegistration, &g_UpperHandle);
if (!NT_SUCCESS(Status))
{
g_UpperHandle = NULL;
goto Exit;
}
ObLowerOperationRegistration[0].ObjectType = PsProcessType;
//新添加的
ObLowerOperationRegistration[0].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
ObLowerOperationRegistration[1].ObjectType = PsThreadType;
//新添加的
ObLowerOperationRegistration[1].Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE;
Status = ObRegisterCallbacks(&LowerCallcackRegistration, &g_LowerHandle);
if (!NT_SUCCESS(Status))
{
g_LowerHandle = NULL;
goto Exit;
}
Exit:
if (!NT_SUCCESS(Status))
ObRegisterUnload();
return NT_SUCCESS(Status) ? TRUE : FALSE;
}