win64 内核hook API
创始人
2024-06-02 02:04:43

前言

除了 SSDT hook和Inline hook外,内核还提供其他官方的API方便我们进行hook操作从而完成一些安全软件的研发等。

举例其中以下API函数

PsSetCreateProcessNotifyRoutine

typedef VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE)(_In_ HANDLE ParentId,_In_ HANDLE ProcessId,_In_ BOOLEAN Create);NTSTATUS PsSetCreateProcessNotifyRoutine([in] PCREATE_PROCESS_NOTIFY_ROUTINE NotifyRoutine,[in] BOOLEAN                        Remove
);

PsSetCreateProcessNotifyRoutineEx


typedef VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE_EX) (_Inout_ PEPROCESS Process,_In_ HANDLE ProcessId,_Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo);NTSTATUS PsSetCreateProcessNotifyRoutineEx([in] PCREATE_PROCESS_NOTIFY_ROUTINE_EX NotifyRoutine,[in] BOOLEAN                           Remove
);

两个函数都是用于注册一个回调监听进程的创建或者退出时调用NotifyRoutine,不同的是EX后缀函数不仅可以监听而且还可以控制创建的进程结果。

参数说明
NotifyRoutine : 回调函数
Remove : 如果为TRUE ,从系统回调表中删除回调函数的注册。FALSE为注册函数到回调函数表中。

示例

我们以PsSetCreateProcessNotifyRoutineEx 为示例具体讲解。

函数返回值

STATUS_SUCCESS 成功注册
STATUS_INVALID_PARAMETER 函数已经注册过,或者注册表已经达到上限不能注册
STATUS_ACCESS_DENIED 如果没有PE格式设置 IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY标记,那么会抛出这个。

关于IMAGE_DLLCHARACTERISTICS_FORCE_INTEGRITY一些介绍可参阅:
/INTEGRITYCHECK(需要签名检查)

具体在编写驱动时加入以下标志:
在这里插入图片描述

我们最后看相关的回调函数

typedef VOID (*PCREATE_PROCESS_NOTIFY_ROUTINE_EX) (//可以通过这个获取一些进程的上下文信息_Inout_ PEPROCESS Process,//进程id_In_ HANDLE ProcessId,//如果这个参数为NULL表示程序退出。 不为NULL表示程序创建_Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo);

我编写一个相关案例实现效果如下:

(1) 打印创建/退出的进程名字
(2) 如果进程是计算器进程修改进程创建结果,使其创建失败

#include //系统隐藏API 只需要声明即可
extern "C" UCHAR * PsGetProcessImageFileName(PEPROCESS Process);//设置的进程监听的回调函数
VOID MyProcessNotify(_Inout_ PEPROCESS Process,_In_ HANDLE ProcessId,_Inout_opt_ PPS_CREATE_NOTIFY_INFO CreateInfo
) {DbgPrint("[My learning] MyProcessNotify invoke \r\n");//获取进程的名称UCHAR* ImageFileName = PsGetProcessImageFileName(Process);//如果不为空证明创建进程if (CreateInfo != NULL){DbgPrint("[My learning] MyProcessNotify create process \r\n");DbgPrint("[My learning] MyProcessNotify   %s pid: %d   path:%wZ \r\n",ImageFileName,ProcessId,CreateInfo->ImageFileName);//比较当前的进程名称是否为计算器if (RtlCompareMemory("Calculator.exe", ImageFileName, sizeof "Calculator.exe")){DbgPrint("[My learning] MyProcessNotify create process \r\n");//控制创建进程的标志为失败标志CreateInfo->CreationStatus = STATUS_INVALID_PARAMETER;}}else {//进程为空 退出进程DbgPrint("[My learning] MyProcessNotify exit process %s \r\n", ImageFileName);}}//这个函数被注册用于驱动卸载调用
VOID myUnload(struct _DRIVER_OBJECT* DriverObject
) {UNREFERENCED_PARAMETER(DriverObject);DbgPrint("[My learning]  drive myUnload \r\n");//一定设置卸载回调。不然一直会在注册表中PsSetCreateProcessNotifyRoutineEx(&MyProcessNotify, TRUE);
}//驱动被加载的时候会调用此函数
extern "C"
NTSTATUS
DriverEntry(_In_ struct _DRIVER_OBJECT* DriverObject,_In_ PUNICODE_STRING    RegistryPath
)
{//如果你没有用到参数需要告诉系统。UNREFERENCED_PARAMETER(RegistryPath);//打印信息DbgPrint("[My learning]  drive loaded\r\n ");//注册监听回调NTSTATUS stat = PsSetCreateProcessNotifyRoutineEx(&MyProcessNotify, FALSE);//打印注册结果DbgPrint("[My learning]  PsSetCreateProcessNotifyRoutineEx ret %p \r\n", stat);DriverObject->DriverUnload = myUnload;return STATUS_SUCCESS;
}

开启调试后日志:

[My learning]  drive loaded[My learning]  PsSetCreateProcessNotifyRoutineEx ret 0000000000000000 
Suspending
[My learning] MyProcessNotify invoke 
[My learning] MyProcessNotify create process 
[My learning] MyProcessNotify   taskhostw.exe pid: 2964   path:\??\C:\Windows\system32\taskhostw.exe 
[My learning] MyProcessNotify invoke 
[My learning] MyProcessNotify create process 
[My learning] MyProcessNotify   ApplicationFra pid: 2076   path:\??\C:\Windows\system32\ApplicationFrameHost.exe 
[My learning] MyProcessNotify invoke 
[My learning] MyProcessNotify create process 
[My learning] MyProcessNotify   dllhost.exe pid: 348   path:\??\C:\Windows\system32\DllHost.exe[My learning] MyProcessNotify invoke 
[My learning] MyProcessNotify create process 
[My learning] MyProcessNotify   Calculator.exe pid: 3108   path:\??\C:\Program Files\WindowsApps\Microsoft.WindowsCalculator_10.1506.19010.0_x64__8wekyb3d8bbwe\Calculator.exe 
[My learning] MyProcessNotify create process 
[My learning] MyProcessNotify invoke 
[My learning] MyProcessNotify exit process Calculator.exe 

运行后你发现你永远无法打开计算器这个应用程序,并且会出输出所有的程序创建。

回调记录表

PsSetCreateProcessNotifyRoutineEx 会构造一张表存储相关。
我们反编译相关window内核文件C:\Windows\System32\ntoskrnl.exe。

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
也就是我们清空这个表地址数据那么我们的hook计算器无法打开的操作讲失效.我们使用windbg尝试对应的操作
在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

禾芯动力发布全球品牌战略 从产... 转自:新华财经新华财经北京12月29日电(记者沈寅飞)近日,农业机器人创新企业禾芯动力在北京举办以芯...
浙江:进一步优化算力布局 引导... 转自:财联社【浙江:进一步优化算力布局 引导更多资金向人工智能企业倾斜】财联社12月29日电,浙江省...
2025年英国录得300多次地... 转自:中国新闻网 2025年英国录得300多次地震  中新网伦敦12月29日电 (记者 欧阳开宇)英...
江苏超额完成年度“住有所居”民... 中新网南京12月29日电 (记者 泱波)住房问题关乎民生福祉与发展大局。29日,记者从江苏省住房和城...
全球媒体聚焦 | 美媒:国际游... 来源:央视新闻客户端美国《旅行与旅游世界》网站12月28日发表题为《国际游客涌入中国欢度新年假期》的...