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

前言

除了 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尝试对应的操作
在这里插入图片描述
在这里插入图片描述

相关内容

热门资讯

中证A500ETF摩根(560... 8月22日,截止午间收盘,中证A500ETF摩根(560530)涨1.19%,报1.106元,成交额...
A500ETF易方达(1593... 8月22日,截止午间收盘,A500ETF易方达(159361)涨1.28%,报1.104元,成交额1...
何小鹏斥资约2.5亿港元增持小... 每经记者|孙磊    每经编辑|裴健如 8月21日晚间,小鹏汽车发布公告称,公司联...
中证500ETF基金(1593... 8月22日,截止午间收盘,中证500ETF基金(159337)涨0.94%,报1.509元,成交额2...
中证A500ETF华安(159... 8月22日,截止午间收盘,中证A500ETF华安(159359)涨1.15%,报1.139元,成交额...
科创AIETF(588790)... 8月22日,截止午间收盘,科创AIETF(588790)涨4.83%,报0.760元,成交额6.98...
创业板50ETF嘉实(1593... 8月22日,截止午间收盘,创业板50ETF嘉实(159373)涨2.61%,报1.296元,成交额1...
港股异动丨航空股大幅走低 中国... 港股航空股大幅下跌,其中,中国国航跌近7%表现最弱,中国东方航空跌近5%,中国南方航空跌超3%,美兰...
电网设备ETF(159326)... 8月22日,截止午间收盘,电网设备ETF(159326)跌0.25%,报1.198元,成交额409....
红利ETF国企(530880)... 8月22日,截止午间收盘,红利ETF国企(530880)跌0.67%,报1.034元,成交额29.0...