以下是重构后的内容:
参考资料:
目录:
1. 流程图文介绍
2. 驱动入口点 DriverEntry
3. 驱动高低版本区别
4. 驱动接口使用
5. HookPort_InitSDT
1. 流程图文介绍
1. Hook前后的对比图
2. HookPort的工作流程
HookPort 负责构造一份空白的 Hook 模板(不负责编写对应的 Fake 函数,导出给 SalfProtectionX 用)
可以理解为老板(HookPort)小弟(SelfProtectionX)
理论上我们是可以有无数个 SelfProtectionX,但是大数字最大限制 16 个
Hook 模板结构如下(单向链表结构):
举个例子:
假设我们一共有 SelfProtection1、SelfProtection2 两个驱动设置了对应的 Fake_CraeteProcess 函数
原始 CreateProcess-->KiFastCallEntry-->Filter_CreateProcess 代理函数-->HookPort_DoFilter
循环将链表中所有 Fake 函数取出来并执行,直到链表下一个为零终止
必须全部所有 Fake 函数合法返回才算正确,其中一个返回错误都算错误
2. 驱动入口点 DriverEntry
2.1 如何调试
首先输入:sxe ld xxxxx.sys 中断
然后输入:lmvm xxxxx 获取基地址,后面基地址+偏移
2.2 代码逻辑流程
1. 获取系统版本信息,假设是 win10 将 Global_Version_Win10_Flag 变量置1
2. 安全模式下禁止启动
3. 创建 \\Device\\***HookPort 设备和 \\DosDevices\\***HookPort 符号链接
4. 设备 DeviceExtension 驱动接口,为 3600SelfProtection 服务
5. 注册 IRP_MJ_CREATE、IRP_MJ_CLOSE、IRP_MJ_DEVICE_CONTROL
6. 执行 HookPort_InitSDT 函数,该函数实现功能如下:
6.1 设置内核 API 过滤函数
6.2 挂钩 KiFastCallEntry
6.3 创建线程、进程、模块回调
6.4 IAT 方式挂钩 KeUserModeCallback,可以拦截 DLL 注入、键盘劫持等等。
7. 初始化驱动导出接口
以下是根据您提供的内容重构的代码:
```
//************************************
// 函数名称: DriverEntry
// 函数说明:驱动程序入口
// 作 者:Mr.M
// 参考网址:
// 作成日期:2019/11/29
// 返 回 值: NTSTATUS
// 参 数: IN PDRIVER_OBJECT DriverObj
// 参 数: IN PUNICODE_STRING RegPath
//************************************
NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject, PUNICODE_STRING RegPath)
{
NTSTATUS Status;
UNICODE_STRING SymbolicLinkName;
UNICODE_STRING DestinationString;
PDEVICE_OBJECT DeviceObject = NULL;
Global_DriverObject = (ULONG)DriverObject;
//1、获取版本信息
Status = HookPort_PsGetVersion();
if (!NT_SUCCESS(Status))
{
return Status;
}
//2、安全模式下不启动
if (*(PULONG*)InitSafeBootMode == 1)
{
Status = RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, HookPort_Minimal);
}
else if (*(PULONG*)InitSafeBootMode == 2)
{
HookPort_KiSystemService(DriverObject);
Status = ZwDisplayString(&SymbolicLinkName, L"Hook Port");
}
return Status;
}
```
以下是重构后的代码:
```cpp
if (*(ULONG*)InitSafeBootMode <= 1u || *(ULONG*)InitSafeBootMode > 3u)
{
return STATUS_NOT_SAFE_MODE_DRIVER;
}
Status = RtlCheckRegistryKey(RTL_REGISTRY_CONTROL, HookPort_Network);
if (Status < 0)
{
return STATUS_NOT_SAFE_MODE_DRIVER;
}
// 2、创建设备
RtlInitUnicodeString(&DestinationString, HookPort_DeviceName);
RtlInitUnicodeString(&SymbolicLinkName, HookPort_LinkName);
Status = IoCreateDevice(DriverObject, sizeof(HOOKPORT_EXTENSION), &DestinationString, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &DeviceObject);
if (!NT_SUCCESS(Status))
{
KdPrint((TEXT("HookPort: DriverEntry IoCreateDevice failed,err=%08x
"), Status));
return Status;
}
// 3、给设备创建一个符号链接
Status = IoCreateSymbolicLink(&SymbolicLinkName, &DestinationString);
if (!NT_SUCCESS(Status)){
}
```
以下是重构后的代码:
```cpp
KdPrint((L"HookPort: DriverEntry IoCreateSymbolicLink failed,err=%08x
", Status));
IoDeleteDevice(DeviceObject);
return Status;
}
// 4、DeviceControl都是些开启调试信息相关的直接无视
DriverObject->MajorFunction[IRP_MJ_CREATE] = (PDRIVER_DISPATCH)HookPort_Create;
DriverObject->MajorFunction[IRP_MJ_CLOSE] = (PDRIVER_DISPATCH)HookPort_Close;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = (PDRIVER_DISPATCH)HookPort_DeviceControl;
// 5、初始化部分各种hook、创建进程、线程回调等等
if (!NT_SUCCESS(HookPort_InitSDT()))
{
IoDeleteSymbolicLink(&SymbolicLinkName);
IoDeleteDevice(DeviceObject);
return STATUS_UNSUCCESSFUL;
}
// 6、初始化导出接口函数
HookPort_InitDeviceExtInterface(DeviceObject);
// 7、根据条件判断是否启用FakeKiSystemService的hook,初始化扩展结构,导出给另外一个sys使用,360HookPort驱动加载成功
bool enableHook = /* 根据条件判断 */;
if (enableHook)
{
HookPort_19230();
}
KdPrint((L"360HookPort驱动加载成功\t
"));
DriverObject->DriverUnload = DriverUnload;
return STATUS_SUCCESS;
}
```
我们发现一个问题,就是有多少个fake函数就定义了多少个相同的代理函数。我们还发现代理函数的逻辑基本相同,只是参数个数不一致。
高版本中,除了个别感兴趣的其他都采用通用函数模板处理。通用函数模板包括以下五部分:
1. Hook方式(加密解密4已经有图文介绍了13章):数字hook点如下:
```cpp
// 保存特征指令之后的那个地址,即钩子处理之后的返回地址
//840541a4 2be1 sub esp, ecx
//此时address = 840541a4
//840541a6 c1e902 shr ecx, 2
//此时g_KiFastCallEntry_360HookPoint = 840541a6
//840541a9 8bfc mov edi, esp
//此时g_KiFastCallEntry_Fake_rtn_address = 840541a9
```
hook方式有两种:IdtHook4号中断和InlineHook。
2. 驱动接口使用:注意HookPort只是初始化接口,是导出给N个类似于SelfProtection的驱动使用。导出接口结构体定义如下:
```cpp
/*
// sizeof(HOOKPORT_EXTENSION) = 0x18
设备扩展包含了添加规则的接口
1、其他驱动需要增加规则时只需要获取Hookport的驱动扩展访问里面的HookPort_FilterRule_Init初始化一条规则
2、HookPort_SetFilterSwitchFunction 设置规则过滤函数
3、HookPort_SetFilterRuleFlag 设置开关表示启动 or 关闭
State 启动标识
HookPort_FilterRule_Init 初始化规则,新建规则会加到规则链中
HookPort_SetFilterSwitchFunction 设置规则过滤函数
*/
```
HookPort_SetFilterRuleFlag 设置规则开关
HookPort_SetFilterRuleName 设置规则名字
Value3F1 该驱动版本
```c
typedef struct _HOOKPORT_EXTENSION
{
_DWORD State;
_DWORD HookPort_FilterRule_Init;
_DWORD HookPort_SetFilterSwitchFunction;
_DWORD HookPort_SetFilterRule;
_DWORD HookPort_SetFilterRuleName;
_DWORD Value3F1;
} HOOKPORT_EXTENSION, *PHOOKPORT_EXTENSION;
// 初始化导出接口
ULONG NTAPI HookPort_InitDeviceExtInterface(IN PDEVICE_OBJECT DeviceObject)
{
PHOOKPORT_EXTENSION pHookPortExt;
pHookPortExt = DeviceObject->DeviceExtension;
pHookPortExt->State = (PULONG)3;
pHookPortExt->HookPort_FilterRule_Init = HookPort_AllocFilterRuleTable; // 初始化规则
pHookPortExt->HookPort_SetFilterSwitchFunction = HookPort_SetFilterSwitchFunction; // 设置规则过滤函数
pHookPortExt->HookPort_SetFilterRule = HookPort_SetFilterRule; // 设置规则开关
}
```
以下是重构后的代码:
```cpp
pHookPortExt->HookPort_SetFilterRuleName = HookPort_SetFilterRuleName; //设置规则名字
pHookPortExt->Value3F1 = 0x3F1; //版本
return pHookPortExt;
}
```
使用方法:
关闭:
5、HookPort_InitSDT