#include "ntddk.h"
//804ff720 b87a000000 mov eax,7Ah NtOpenProcess 的索引为7Ah
//804ff725 8d542404 lea edx,[esp+4]
typedef struct _SystemServiceDescriptorTable
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
}SystemServiceDescriptorTable,*PSystemServiceDescriptorTable;
extern PSystemServiceDescriptorTable KeServiceDescriptorTable;
//定义NtOpenProcess原型
typedef NTSTATUS (__stdcall *NTOPENPROCESS)(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);
NTOPENPROCESS RealNtOpenProcess;
//原函数地址
ULONG RealServiceAddress;
//要保护的进程id
HANDLE pid;
//函数声明
VOID hook();
VOID unhook();
VOID OnUnload(IN PDRIVER_OBJECT DriverObject);
NTSTATUS __stdcall MyNtOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId);
#include "hook.h"
//EntryPoint
#ifdef __cplusplus
extern "C" {
#endif
NTSTATUS DriverEntry(
IN OUT PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
//保护进程
hook();
DriverObject->DriverUnload = OnUnload;
return STATUS_SUCCESS; //函数一但离开Entry 就蓝屏了 WinDebug 上显示Access violation - code c0000005 (!!! second chance !!!)
00000000 ??
}
#ifdef __cplusplus
}
#endif
//保护进程
VOID hook()
{
ULONG address;
address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x74 * 4;
//保存原函数地址,供还原使用
RealServiceAddress = *(ULONG *)address;
//去除cr0保护
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
//ssdt中7A位置的函数的地址为我们自己的函数,并过滤相关操作
*((ULONG *)address) = (ULONG)MyNtOpenProcess;
//cr0保护
__asm
{
mov eax,cr0
or eax,1000h
mov cr0,eax
sti
}
DbgPrint("yes,hook sucess!");
}
//取出保护
VOID unhook()
{
ULONG address;
address = (ULONG)KeServiceDescriptorTable->ServiceTableBase + 0x7A * 4;
//去除cr0保护
__asm
{
cli
mov eax,cr0
and eax,not 10000h
mov cr0,eax
}
//用保存好的NtOpenProcess地址还原7A 位置的函数地址
*((ULONG *)address) = (ULONG)RealServiceAddress;
//cr0保护
__asm
{
mov eax,cr0
or eax,1000h
mov cr0,eax
sti
}
DbgPrint("yes,unhook sucess!");
}
//新的NtOpenProcess
NTSTATUS __stdcall MyNtOpenProcess(OUT PHANDLE ProcessHandle,
IN ACCESS_MASK AccessMask,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN PCLIENT_ID ClientId)
{
NTSTATUS status;
ULONG notepadId;
//首先调用原始函数获取信息做比对
status = (NTSTATUS)(NTOPENPROCESS)RealNtOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId);
if(ClientId != NULL)
{
notepadId = (ULONG)ClientId->UniqueProcess;
if(notepadId == 304)
{
//1234 为要保护的进程的id 这里是记事本为例
ProcessHandle = NULL;
status = STATUS_ACCESS_DENIED;
}
}
return status;
}
//卸载
VOID OnUnload(IN PDRIVER_OBJECT DriverObject)
{
unhook();
}
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)