void BackupSysServiceTable();
NTSTATUS installHook(ULONG oldService, ULONG newService);
NTSTATUS unstallHook(ULONG oldService);
NTSTATUS MyNtTerminateProcess(__in_opt HANDLE ProcessHandle, __in NTSTATUS ExitStatus);
void DisableWrite();
void EnableWrite();
NTSTATUS CreateSymbolicLinkFunc();
NTSTATUS CreateDeviceFunc(PDRIVER_OBJECT obj);
void DriverUnloadFunc(PDRIVER_OBJECT obj);
NTSTATUS DriverEntry(PDRIVER_OBJECT obj, PUNICODE_STRING path);
/
/
设备名称
/
/
符号链接名称
/
/
KSYSTEM_SERVICE_TABLE 和 KSERVICE_TABLE_DESCRIPTOR
/
/
用来定义 SSDT 结构
typedef struct _KSYSTEM_SERVICE_TABLE
{
PULONG ServiceTableBase;
/
/
SSDT (System Service Dispatch Table)的基地址
PULONG ServiceCounterTableBase;
/
/
用于 checked builds, 包含 SSDT 中每个服务被调用的次数
ULONG NumberOfService;
/
/
服务函数的个数, NumberOfService
*
4
就是整个地址表的大小
ULONG ParamTableBase;
/
/
SSPT(System Service Parameter Table)的基地址
} KSYSTEM_SERVICE_TABLE,
*
PKSYSTEM_SERVICE_TABLE;
/
/
一个为导出的结构体
typedef struct _KSERVICE_TABLE_DESCRIPTOR
{
KSYSTEM_SERVICE_TABLE ntoskrnl;
/
/
ntoskrnl.exe 的服务函数
KSYSTEM_SERVICE_TABLE win32k;
/
/
win32k.sys 的服务函数(GDI32.dll
/
User32.dll 的内核支持)
KSYSTEM_SERVICE_TABLE notUsed1;
KSYSTEM_SERVICE_TABLE notUsed2;
}KSERVICE_TABLE_DESCRIPTOR,
*
PKSERVICE_TABLE_DESCRIPTOR;
/
/
定义KeServiceDescriptorTable, 需要导出
extern PKSERVICE_TABLE_DESCRIPTOR KeServiceDescriptorTable;
/
/
用于获取SSDT 中函数的地址
/
/
根据 ZwServiceFunction 获取 ZwServiceFunction 在 SSDT 中所对应的服务的索引号
/
/
根据 ZwServiceFunction 来获得服务在 SSDT 中的索引号,然后再通过该索引号来获取 ntServiceFunction的地址
/
/
用来保存SSDT 中所有的旧的服务函数的地址
ULONG oldSysServiceAddr[MAX_INDEX_NUM]
=
{
0
};
/
/
待HOOK 函数的函数指针
typedef NTSTATUS(
*
NTTERMINATEPROCESS)(__in_opt HANDLE ProcessHandle, __in NTSTATUS ExitStatus);
NTTERMINATEPROCESS pOldNtTerminateProcess;
typedef NTSTATUS(
*
NTOPENPROCESS)(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientId
);
NTOPENPROCESS pOldNtOpenProcess;
/
/
自定义函数
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
/
NTSTATUS MyNtTerminateProcess(__in_opt HANDLE ProcessHandle, __in NTSTATUS ExitStatus)
{
NTSTATUS status
=
STATUS_SUCCESS;
KdPrint((
"退出不了了吧,哈哈哈哈哈哈哈哈哈:%X"
, pOldNtTerminateProcess));
pOldNtTerminateProcess
=
(NTTERMINATEPROCESS)oldSysServiceAddr[SYSCALL_INDEX(ZwTerminateProcess)];
status
=
pOldNtTerminateProcess(ProcessHandle, ExitStatus);
return
status;
}
NTSTATUS MyNtOpenProcess(
_Out_ PHANDLE ProcessHandle,
_In_ ACCESS_MASK DesiredAccess,
_In_ POBJECT_ATTRIBUTES ObjectAttributes,
_In_opt_ PCLIENT_ID ClientId
){
NTSTATUS status
=
STATUS_SUCCESS;
KdPrint((
"打开进程"
));
pOldNtOpenProcess
=
(NTOPENPROCESS)oldSysServiceAddr[SYSCALL_INDEX(ZwOpenProcess)];
status
=
pOldNtOpenProcess(ProcessHandle, DesiredAccess, ObjectAttributes, ClientId);
return
status;
}
/
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
/
void BackupSysServiceTable()
{
ULONG i;
for
(i
=
0
; (i < KeServiceDescriptorTable
-
>ntoskrnl.NumberOfService) && (i < MAX_INDEX_NUM); i
+
+
)
{
/
/
备份原始函数表
oldSysServiceAddr[i]
=
KeServiceDescriptorTable
-
>ntoskrnl.ServiceTableBase[i];
KdPrint((
"\n备份的函数表{ Number: 0x%04X , Address: %08X}"
, i, oldSysServiceAddr[i]));
}
}
NTSTATUS installHook(ULONG oldService, ULONG newService)
{
NTSTATUS status
=
STATUS_SUCCESS;
__try
{
ULONG uOldAddr
=
0
;
/
/
去除页面保护
KdPrint((
"伪装的NtTerminateProcess 地址:%X\r\n"
, (
int
)newService));
KdPrint((
"真实的NtTerminateProcess 地址:%X\r\n"
, (
int
)oldService));
/
/
写入HOOK 的回调函数地址
SYSCALL_FUNCTION(oldService)
=
newService;
/
/
恢复页面包含
DisableWrite();
return
status;
}
__except (
1
)
{
KdPrint((
"安装Hook 失败"
));
}
return
status;
}
NTSTATUS unstallHook(ULONG oldService)
{
KdPrint((
"解除HOOK"
));
NTSTATUS status
=
STATUS_SUCCESS;
__try
{
EnableWrite();
/
/
去掉页面保护
/
/
做一个判断,判断指定位置的地址是否是原地址而不是自定义函数的地址
KdPrint((
"当前HOOK 位置的地址:%X\t备份的地址:%X"
, SYSCALL_FUNCTION(oldService), oldSysServiceAddr[SYSCALL_INDEX(oldService)]));
for
(UINT32 i
=
0
; TRUE; i
+
+
)
{
KdPrint((
"解除>>当前HOOK 位置的地址:%X\t备份的地址:%X"
, SYSCALL_FUNCTION(oldService), oldSysServiceAddr[SYSCALL_INDEX(oldService)]));
if
(SYSCALL_FUNCTION(oldService) !
=
oldSysServiceAddr[SYSCALL_INDEX(oldService)])
{
SYSCALL_FUNCTION(oldService)
=
oldSysServiceAddr[SYSCALL_INDEX(oldService)];
}
else
{
break
;
}
}
KdPrint((
"当前HOOK 位置的地址:%X\t备份的地址:%X"
, SYSCALL_FUNCTION(oldService), oldSysServiceAddr[SYSCALL_INDEX(oldService)]));
DisableWrite();
/
/
恢复页面保护
return
status;
}
__except (
1
)
{
KdPrint((
"卸载Hook 失败!"
));
}
return
status;
}
/
/
对页面保护属性的修改
/
/
设置为不可写
void DisableWrite()
{
__try
{
_asm
{
mov eax, cr0
or
eax,
10000h
mov cr0, eax
sti
}
}
__except (
1
)
{
DbgPrint(
"DisableWrite执行失败!"
);
}
}
/
/
设置为可写
void EnableWrite()
{
__try
{
_asm
{
cli
mov eax, cr0
and
eax,
not
10000h
/
/
and
eax,
0FFFEFFFFh
mov cr0, eax
}
}
__except (
1
)
{
DbgPrint(
"EnableWrite执行失败!"
);
}
}
/
/
创建符号链接
NTSTATUS CreateSymbolicLinkFunc()
{
NTSTATUS status
=
STATUS_SUCCESS;
/
/
定义驱动对象名称
UNICODE_STRING deviceName;
RtlInitUnicodeString(&deviceName, DEVICE_NAME);
/
/
定义符号链接对象名称
UNICODE_STRING symbolLinkName;
RtlInitUnicodeString(&symbolLinkName, SYMBOLLINK_NAME);
/
/
创建符号链接
status
=
IoCreateSymbolicLink(&symbolLinkName, &deviceName);
return
status;
}
/
/
创建设备
NTSTATUS CreateDeviceFunc(PDRIVER_OBJECT obj)
{
NTSTATUS status
=
STATUS_SUCCESS;
/
/
定义驱动对象名称
UNICODE_STRING deviceName;
RtlInitUnicodeString(&deviceName, DEVICE_NAME);
/
/
创建驱动对象
DEVICE_OBJECT deviceObj;
status
=
IoCreateDevice(obj,
0x4
, &deviceName, FILE_DEVICE_UNKNOWN, FILE_DEVICE_SECURE_OPEN, FALSE, &deviceObj);
return
status;
}
void DriverUnloadFunc(PDRIVER_OBJECT obj)
{
KdPrint((
"驱动卸载"
));
/
/
删除符号链接
UNICODE_STRING symbolLinkName;
RtlInitUnicodeString(&symbolLinkName, SYMBOLLINK_NAME);
IoDeleteSymbolicLink(&symbolLinkName);
/
/
删除设备
IoDeleteDevice(obj
-
>DeviceObject);
/
/
卸载HOOK
unstallHook(
/
*
新函数地址
*
/
(ULONG)ZwOpenProcess);
}
/
/
驱动派遣函数
NTSTATUS DriverIRPCtrl(PDRIVER_OBJECT obj, PIRP pIrp)
{
NTSTATUS status
=
STATUS_SUCCESS;
/
/
当前IO 栈,用于存放用户层调用时产生的IRP 事件
PIO_STACK_LOCATION pIoStackLocation
=
NULL;
/
/
获取用户层调用时产生的IRP 函数
pIoStackLocation
=
IoGetCurrentIrpStackLocation(pIrp);
/
/
判断IRP 事件类型
switch (pIoStackLocation
-
>MajorFunction)
{
case IRP_MJ_CREATE:
{
KdPrint((
"用户层调用CreateFile 开启对驱动的调用"
));
pIrp
-
>IoStatus.Status
=
STATUS_SUCCESS;
pIrp
-
>IoStatus.Information
=
4
;
};
break
;
case IRP_MJ_DEVICE_CONTROL:
{
/
/
获取控制码
ULONG funcCode
=
pIoStackLocation
-
>Parameters.DeviceIoControl.IoControlCode;
switch (funcCode)
{
case IO_TEST_CODE:
{
KdPrint((
"JJR:用户层调用了DeviceIoControl 函数"
));
/
/
取出传入的缓冲区数据和大小
char
*
inBuffer
=
(char
*
)pIrp
-
>AssociatedIrp.SystemBuffer;
KdPrint((
"JJR:用户层传入数据:%s"
, inBuffer));
/
/
inBuffer 既是传入数据的缓冲区,也是传出数据的缓冲区
strcpy(inBuffer,
"驱动层传出数据"
);
};
break
;
}
};
break
;
case IRP_MJ_CLOSE:
{
KdPrint((
"用户层调用CloseHandle 关闭对驱动的调用"
));
pIrp
-
>IoStatus.Status
=
STATUS_SUCCESS;
pIrp
-
>IoStatus.Information
=
4
;
};
break
;
}
KdPrint((
"JJR:退出派遣函数"
));
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return
status;
}
/
/
驱动入口函数
NTSTATUS DriverEntry(PDRIVER_OBJECT obj, PUNICODE_STRING path)
{
NTSTATUS status
=
STATUS_SUCCESS;
KdPrint((
"驱动入口"
));
if
(NT_SUCCESS(CreateDeviceFunc(obj)))
{
KdPrint((
"创建符号链接完成"
));
if
(NT_SUCCESS(CreateSymbolicLinkFunc()))
{
KdPrint((
"创建符号链接完成"
));
}
}
/
/
备份
BackupSysServiceTable();
/
/
安装HOOK
installHook(
/
*
原函数地址
*
/
(ULONG)ZwOpenProcess,
/
*
新函数地址
*
/
(ULONG)MyNtOpenProcess);
obj
-
>DriverUnload
=
DriverUnloadFunc;
return
status;
}