[原创]新手无hook进程保护及过签名分析
无hook实现进程保护
第一部分:ObRegisterCallbacks使用
第二部分:跳过签名限制分析
ObRegisterCallbacks使用
本文在windows7 内核太中实现无hook进程保护。现在网上找的例子基本上都是针对windows 32位系统的,也基本上都是教你用ssdt hook,inline hook去挂钩NtOpenProcess,NtTerminateProcess等系统调用,百度一大堆。当然在windows 64位系统中是不可能的,在64位系统中加载驱动必须要有签名。而且不可能去hook SSDT GDT等,否则将触发异常 紧接着系统蓝屏。因为PG(PatchGuard)保护着系统内核,除非能跳过验证。
在系统中还是用标准的回调注册函数ObRegisterCallbacks()比较好,这个函数只在XP以后才添加进去(还有对应的ObUnRegisterCallbacks删除回调),查看WDK对该函数的描述
ObRegisterCallbacks
The ObRegisterCallbacks routine registers a list of callback routines for thread and process handle operations.
NTSTATUS?
??ObRegisterCallbacks(
????IN?POB_CALLBACK_REGISTRATION??CallBackRegistration,
????OUT?PVOID??*RegistrationHandle
????);
Parameters
CallBackRegistration
A pointer to an OB_CALLBACK_REGISTRATION structure that specifies the list of callback routines and other registration information.
RegistrationHandle
A pointer to a variable that receives a value that identifies the set of registered callback routines. The caller passes this value to the ObUnRegisterCallbacks routine to unregister the set of callbacks.
再看看这个函数的一个参数OB_CALLBACK_REGISTRATION结构
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_REGISTERATION
typedef?struct?_OB_OPERATION_REGISTRATION?{
??__in?POBJECT_TYPE??*ObjectType;
??__in?OB_OPERATION??Operations;
??__in?POB_PRE_OPERATION_CALLBACK??PreOperation;
??__in?POB_POST_OPERATION_CALLBACK??PostOperation;
}?OB_OPERATION_REGISTRATION,?*POB_OPERATION_REGISTRATION;
第一个成员msdn上要求填写PsProcessType或者 PsThreadType
第二个成员OB_OPERATION_HANDLE_CREATE或者OB_OPERATION_HANDLE_DUPLICATTE。
第三个成员是操作前回调函数指针,这个是我们要关注的 别的自己看msdn去都有。定义如下
OB_PREOP_CALLBACK_STATUS?
??ObjectPreCallback(
????__in?PVOID??RegistrationContext,
????__in?POB_PRE_OPERATION_INFORMATION??OperationInformation
????);
第四个成员是操作后回调函数指针。定义如下
VOID?
??ObjectPostCallback(
????__in?PVOID??RegistrationContext,
????__in?POB_POST_OPERATION_INFORMATION??OperationInformation
????);
下面附上一段设置回调函数的
void SetCallback()
{
NTSTATUS status;
OB_CALLBACK_REGISTRATION obReg;
OB_OPERATION_REGISTRATION opReg;
memset(&obReg,0,sizeof(obReg));
obReg.Version=ObGetFilterVersion();
obReg.OperationRegistrationCount=1;
obReg.RegistrationContext=NULL;
RtlInitUnicodeString(&obReg.Altitude,L"321000");
memset(&opReg,0,sizeof(opReg));//Init Struct
opReg.ObjectType=PsProcessType;
opReg.Operations=OB_OPERATION_HANDLE_CREATE|OB_OPERATION_HANDLE_DUPLICATE;
opReg.PreOperation=(POB_PRE_OPERATION_CALLBACK)&preCall;
// opReg.PostOperation=(POB_POST_OPERATION_CALLBACK)&PostCall;
obReg.OperationRegistration=&opReg;
status=ObRegisterCallbacks(&obReg,&obHandle);
if(status==STATUS_SUCCESS)
DbgPrint("回调创建号成功\n");
else
DbgPrint("回调创建失败%X",status);
}
回调函数代码

编译好运行起来

跳过签名限制分析
发现创建回调的时候失败了 返回了错误码0xC0000022查看msdn
The callback routines do not reside in a signed kernel binary image.
这个回调函数得签名过才能正确添加回调函数,其实这个限制也只针对32系统,因为在正常情况下x64的必须要签名过才能加载驱动程序^_^。
bp ObRegisterCallbacks
跟进去经过调试发现在函数内部调用_MmVerifyCallbackFunction()然后就跳出去设置eax等于0xc0000022就返回了。
windbg 看代码不方便,直接IDA反汇编ntoskrnl.exe

再跟进这个函数,这个函数代码不多 简单的从这个函数的函数最后面的eax寄存器逆推回去 选中后面的变量逆推到代码

不知道这个MiLookupDataTableEntry是干什么用的,eax也不知道返回了点什么,逆向水平有限(而且在ReactOs里找到了源码^_^)直接在ReactOs观赏源码原来是返回了PLDR_DATA_TABLE_ENTRY 这个结构的头通过windbg查看该结构 +0x34处是Flag
也就说判断这个flag是否为0x20
那么就只需要修改下标志位就可以了代码如下

这样驱动加载进去回调就设置成功了
这种方法过验证 自己玩玩还是可以的 但是用到
产品中还是老实点买个签名比较好况且代码中也用了
好多硬编码。
效果如下

我是一枚菜,我知道大神不喜欢喷人所以才来分享点心得

待会儿我就整理成文档和源码一起上传
