64位内核第二讲,进程保护之对象钩子
时间:2022-05-06
本文章向大家介绍64位内核第二讲,进程保护之对象钩子,主要内容包括64位内核第二讲,进程保护.、二丶给软件添加保护熟悉API和结构体、三丶给软件添加权限保护代码.、四丶去掉保护.、基本概念、基础应用、原理机制和需要注意的事项等,并结合实例形式分析了其使用技巧,希望通过本文能帮助到大家理解应用这部分内容。
64位内核第二讲,进程保护.
一丶什么是保护.
什么是保护. 比如我们安装了xxx杀毒软件.那么此时你用任务管理器关闭.是关闭不了的.原因是内核已经做了保护.
那么去掉保护的前提就是你要给自己的软件做保护.
比如我们给计算器做保护. 例如下图.
做保护.以前的病毒作者.都是想要退出xxx杀毒软件. 什么方法都能做. 所以杀软为了防止这一情况发生,直接把打开进程的API进行HOOK即可.
但是别忘了.还可以拷贝句柄.所以杀软防不住.只能在内核做保护.
二丶给软件添加保护熟悉API和结构体
给软件添加保护很简单. 也是调用API进行操作.
API:
ObRegisterCallbacks 注册进程和线程处理回调
NTSTATUS
ObRegisterCallbacks(
IN POB_CALLBACK_REGISTRATION CallBackRegistration,
OUT PVOID *RegistrationHandle
);
第一个是个结构体,我们想要进行的操作都放在这个结构中
第二个是个二级指针,我们给一个即可
结构体:
typedef struct _OB_CALLBACK_REGISTRATION {
__in USHORT Version; //版本号
__in USHORT OperationRegistrationCount; //回调个数. 可以一次蹙着多个回调. 和最后一个参数绑定的. 如果一次注册多个.则最后一个参数需要给数组保存,最后参数是一个结构体.
__in UNICODE_STRING Altitude; // 指定的驱动程序的Uncode字符串. 可以看WDK文档给.
__in PVOID RegistrationContext; // 回调函数的参数.如果你给可以在这里给.
__in OB_OPERATION_REGISTRATION *OperationRegistration;//回调函数信息结构体,如果个数有多个,你需要定义为数组.
} OB_CALLBACK_REGISTRATION, *POB_CALLBACK_REGISTRATION;
结构体中回调函数结构体.
typedef struct _OB_OPERATION_REGISTRATION {
__in POBJECT_TYPE *ObjectType; //对象的类型.你注册回调函数的类型 PsProcessType 和 PsThreadType 分别是进程回调和线程回调.
__in OB_OPERATION Operations; //注册回调的操作方式, 一个是创建进程. 一个是拷贝进程句柄. OB_OPERATION_HANDLE_CREATEA ,OB_OPERATION_HANDLE_DUPLICATE
__in POB_PRE_OPERATION_CALLBACK PreOperation;//创建之前回调函数的地址,在这里给. 每一个回调都包含什么信息在这个结构体中给出.
__in POB_POST_OPERATION_CALLBACK PostOperation;//创建之后回调函数的地址. 和上面不一样,一个是创建之前,你的回调回来,一个是创建之后你的回调函数回来.
} OB_OPERATION_REGISTRATION, *POB_OPERATION_REGISTRATION;
回调函数原型
OB_PREOP_CALLBACK_STATUS
ObjectPreCallback(
__in PVOID RegistrationContext, //回调函数的参数,上面通过结构体给的.
__in POB_PRE_OPERATION_INFORMATION OperationInformation //进程或者线程创建的信息结构体
);
进程或者线程信息结构体.
typedef struct _OB_PRE_OPERATION_INFORMATION {
__in OB_OPERATION Operation; //句柄的操作类型, 是上面我们给的.
union {
__in ULONG Flags;
struct {
__in ULONG KernelHandle:1;
__in ULONG Reserved:31;
};
};
__in PVOID Object; //对象指针,如果你给的是监控进程,那么这个对象就是EPROCESS,如果是线程,那么这个对象就是ETHREAD
__in POBJECT_TYPE ObjectType; //对象类型. 可能是PsThreadType 也可能是 PsProcessType
__out PVOID CallContext;
__in POB_PRE_OPERATION_PARAMETERS Parameters; //创建或者创建之后的参数信息结构体.
} OB_PRE_OPERATION_INFORMATION, *POB_PRE_OPERATION_INFORMATION;
参数信息结构体
typedef union _OB_PRE_OPERATION_PARAMETERS {
__inout OB_PRE_CREATE_HANDLE_INFORMATION CreateHandleInformation; //创建句柄,则成员会给这个赋值
__inout OB_PRE_DUPLICATE_HANDLE_INFORMATION DuplicateHandleInformation; //拷贝句柄,则给这个成员赋值.
} OB_PRE_OPERATION_PARAMETERS, *POB_PRE_OPERATION_PARAMETERS;
创建句柄结构体
typedef struct _OB_PRE_CREATE_HANDLE_INFORMATION {
__inout ACCESS_MASK DesiredAccess; //创建的权限是什么. 如果我们给 0则没有任何权限,则进程不能创建.
__in ACCESS_MASK OriginalDesiredAccess; //原始的权限.
} OB_PRE_CREATE_HANDLE_INFORMATION, *POB_PRE_CREATE_HANDLE_INFORMATION;
拷贝句柄结构体信息
__inout ACCESS_MASK DesiredAccess; //权限,我们自己控制
__in ACCESS_MASK OriginalDesiredAccess; //原始权限
__in PVOID SourceProcess; //拷贝句柄的时候,源对象指针.
__in PVOID TargetProcess; //目的对象指针.
} OB_PRE_DUPLICATE_HANDLE_INFORMATION, * POB_PRE_DUPLICATE_HANDLE_INFORMATION;
结构体看着挺多,其实挺简单的.
三丶给软件添加权限保护代码.
void InstallHook()
{
NTSTATUS status; //NT状态
OB_CALLBACK_REGISTRATION obReg;
OB_OPERATION_REGISTRATION obOper;
obOper.ObjectType = PsProcessType; //监控的类型
obOper.Operations = OB_OPERATION_HANDLE_CREATE | OB_OPERATION_HANDLE_DUPLICATE; //监控创建还是拷贝(创建包括打开)
obOper.PreOperation = ObjectPreCallback;//创建的时候回调函数地址
obOper.PostOperation = NULL; //创建后的回调函数地址
RtlInitUnicodeString(&obReg.Altitude, L"60000");//初始化驱动类型
obReg.Version = OB_FLT_REGISTRATION_VERSION; //指定版本.
obReg.OperationRegistrationCount = 1; //回调结构体(里面放着回调函数指针)的个数
obReg.RegistrationContext = NULL; //回调函数的参数
obReg.OperationRegistration = &obOper; //回调函数结构体
//注册对象回调
status = ObRegisterCallbacks(&obReg, &g_pRegistrationHandle);
dprintf("[Hello] ObRegisterCallbacks status=%drn", status);
PVOID g_pRegistrationHandle;
OB_PREOP_CALLBACK_STATUS ObjectPreCallback(__in PVOID RegistrationContext,
__in POB_PRE_OPERATION_INFORMATION OperationInformation)
{
PEPROCESS Process;
UCHAR *pszImageName = NULL;
Process = OperationInformation->Object; //因为监控的对象类型是进程,所以对象则是EPROCESS
pszImageName = PsGetProcessImageFileName(Process); //获取名字
if (strstr(pszImageName, "calc") != NULL) //判断我们的进程
{
if (OperationInformation->Operation == OB_OPERATION_HANDLE_CREATE)//判断句柄操作是不是创建.
{
OperationInformation->Parameters->CreateHandleInformation.DesiredAccess = 0; //如果是创建或者打开,则权限则给0,那么我们的程序就不会关闭了.
dprintf("[ObjectPreCallback] Create ImageName=%srn", pszImageName);
}
else if (OperationInformation->Operation == OB_OPERATION_HANDLE_DUPLICATE) //判断是否是拷贝句柄.
{
OperationInformation->Parameters->DuplicateHandleInformation.DesiredAccess = 0;//同上.
dprintf("[ObjectPreCallback] Duplicate ImageName=%srn", pszImageName);
}
}
return OB_PREOP_SUCCESS; //如果是驱动,必须返回这个.
}
通过上面的代码,我们的计算器则会被保护.那么此时我们编译之后安装驱动那么软件就和刚开始那样,不能进行关闭进程了.
你如果关闭计算器,重新打开则打开不了了,
如果你启动计算器之后,在安驱动,那么计算机就同上图所示,关闭不了了.
四丶去掉保护.
去掉保护,那么我们就要逆向 设置对象回调的这个API了.
那么简单的演示则是用PChunter去掉.我们的程序就可以关闭了.
如果有时间,则逆向一下,找到数组. 找到表,抹掉即可.
去掉之后则可以退出了. 包括xxx杀毒.
- 微信文件微起底
- Go语言TCP Socket编程--1
- Go语言TCP Socket编程--2
- 服务器 数据库设计技巧--1
- CVE-2015-0235:Linux glibc高危漏洞的检测及修复方法
- zabbix监控在lnmp环境下编译安装小记
- 【重磅】百度开源分布式深度学习平台,挑战TensorFlow (教程)
- WordPress评论ajax动态加载,解决静态缓存下评论不更新问题
- WordPress显示访客UA信息:Show UserAgent纯代码轻度汉化版
- WordPress开启颜色评论但不造成XSS漏洞的小方法
- WordPress强迫症技巧:让文章(ID)地址完美连续(障眼法)
- iOS内存管理:从MRC到ARC实践
- MySQL错误修复:Table xx is marked as crashed and last (automatic?) repair failed
- PHP跨站脚本攻击(XSS)漏洞修复方法(一)
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 如何将第三方服务注册集成到 Istio ?
- 【Pod Terminating原因追踪系列】之 containerd 中被漏掉的 runc 错误信息
- 【Pod Terminating原因追踪系列之二】exec连接未关闭导致的事件阻塞
- CD+服务网格灰度发布实践,一文带你体验如何编排更灵活
- 花十分钟的时间武装你的代码库
- 对HTML-input的一些思考和理解
- 【投稿】刀哥:Rust学习笔记 1
- 【Rust日报】2020-08-13 关于群集(Bevy)引擎ECS框架中system的语法糖是怎么实现的
- 最新情报:所有的递归都可以改写成非递归?
- 算法篇:树之转换为二叉搜索树
- 算法篇:树之倒数k个节点
- 揭开链表的真面目
- Coder,我怀疑你并不会枚举
- 掌握坐标轴的log转换
- 连通域的原理与Python实现