您的位置:首页 > 其它

SSDT Hook

2016-04-10 18:01 573 查看
看看大概的调用情况

左边是2000有的,右边是xp后走的



Ntdll.dll 中的 API 是一个简单的包装函数。

当 Kernel32.dll 中的 API 通过 Ntdll.dll 时,会完成参数的检查再调用一个中断(int 2Eh 或者 SysEnter 指令),从而实现从 Ring3 进入 Ring0 层

并且将所要调用的服务号(也就是在 SSDT 数组中的索引值)存放到寄存器 EAX 中

再根据存放在 EAX 中的索引值来在 SSDT 数组中调用指定的服务即Nt*系列函数

SSDT表结构

结构:

#pragma pack(1)

typedef struct ServiceDescriptorEntry

{

unsigned int *ServiceTableBase;

unsigned int *ServiceCounterTableBase;

unsigned int NumberOfServices;

unsigned char *ParamTableBase;

} ServiceDescriptorTableEntry_t,

*PServiceDescriptorTableEntry_t;

#pragma pack()

导入:

__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;

我们要获得SSDT下某个函数的地址 我们只需要知道那个Zw函数的开头的2-6字节即可

就是获取那个Index 索引号

比如ZwReadFile 0B7就是Index



然后我们搞一个宏吧 给一个Zw的地址 返回它在SSDT对应函数的地址

引用:

#define SYSTEMSERVICE(_function)
KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]

#define SDT SYSTEMSERVICE

SSDT HOOK 思路:

找到函数地址---保存原地址--替换地址 当然代理函数要与原始函数一致

typedef NTSTATUS (*ZWCREATESECTION)(
OUT PHANDLE            		SectionHandle,
IN ULONG                		DesiredAccess,
IN POBJECT_ATTRIBUTES  	ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER     	 MaximumSize OPTIONAL,
IN ULONG                		PageAttributess,
IN ULONG                		SectionAttributes,
IN HANDLE              		FileHandle OPTIONAL );

static ZWCREATESECTION            OldZwCreateSection;

NTSTATUS NTAPI HOOK_NtCreateSection(PHANDLE SectionHandle,
ACCESS_MASK DesiredAccess,
POBJECT_ATTRIBUTES ObjectAttributes,
PLARGE_INTEGER SectionSize,
ULONG Protect,
ULONG Attributes,
HANDLE FileHandle)
{
return OldZwCreateSection(SectionHandle,
DesiredAccess,
ObjectAttributes,
SectionSize,
Protect,
Attributes,
FileHandle);
}


开始HOOK
void StartHook (void)
{
//获取未导出的服务函数索引号

__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}

OldZwCreateSection                =
(ZWCREATESECTION)InterlockedExchange((PLONG)
&SDT(ZwCreateSection),//必须是ZwCreateSection,而不能是NtCreateSection
(LONG)HOOK_NtCreateSection);

//关闭
__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
return ;
}


移除HOOK 这部很容易蓝屏 建议还是使用DeviceIControl进行卸载 (写一个恢复函数 然后通过下发请求调用)

void StartHook (void)
{
//获取未导出的服务函数索引号

__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}

OldZwCreateSection                =
(ZWCREATESECTION)InterlockedExchange((PLONG)
&SDT(ZwCreateSection),//必须是ZwCreateSection,而不能是NtCreateSection
(LONG)HOOK_NtCreateSection);

//关闭
__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
return ;
}


查看HOOK的SSDT
x nt!kes*des*table*
dd addr
dds addr L length


Base Hook 实现大量的HOOK 但没有实际拦截:

#include <ntddk.h>
#include <ntimage.h>

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define SDT     SYSTEMSERVICE
#define KSDT KeServiceDescriptorTable

//---------------------------------------------------------------------------
//
// Defines
//
//---------------------------------------------------------------------------

#define FILE_DEVICE_UNKNOWN            0x00000022
#define IOCTL_UNKNOWN_BASE              FILE_DEVICE_UNKNOWN
#define IOCTL_INIT                       CTL_CODE(IOCTL_UNKNOWN_BASE, 0x0800, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS)

/********************************************************************************

补充定义数据及结构

********************************************************************************/

typedef struct _INITIAL_TEB {
PVOID                StackBase;
PVOID                StackLimit;
PVOID                StackCommit;
PVOID                StackCommitMax;
PVOID                StackReserved;
} INITIAL_TEB, *PINITIAL_TEB;

typedef enum _SYSTEM_INFORMATION_CLASS
{
SystemBasicInformation,
SystemProcessorInformation,
SystemPerformanceInformation,
SystemTimeOfDayInformation,
SystemNotImplemented1,
SystemProcessesAndThreadsInformation,
SystemCallCounts,
SystemConfigurationInformation,
SystemProcessorTimes,
SystemGlobalFlag,
SystemNotImplemented2,
SystemModuleInformation,
SystemLockInformation,
SystemNotImplemented3,
SystemNotImplemented4,
SystemNotImplemented5,
SystemHandleInformation,
SystemObjectInformation,
SystemPagefileInformation,
SystemInstructionEmulationCounts,
SystemInvalidInfoClass1,
SystemCacheInformation,
SystemPoolTagInformation,
SystemProcessorStatistics,
SystemDpcInformation,
SystemNotImplemented6,
SystemLoadImage,
SystemUnloadImage,
SystemTimeAdjustment,
SystemNotImplemented7,
SystemNotImplemented8,
SystemNotImplemented9,
SystemCrashDumpInformation,
SystemExceptionInformation,
SystemCrashDumpStateInformation,
SystemKernelDebuggerInformation,
SystemContextSwitchInformation,
SystemRegistryQuotaInformation,
SystemLoadAndCallImage,
SystemPrioritySeparation,
SystemNotImplemented10,
SystemNotImplemented11,
SystemInvalidInfoClass2,
SystemInvalidInfoClass3,
SystemTimeZoneInformation,
SystemLookasideInformation,
SystemSetTimeSlipEvent,
SystemCreateSession,
SystemDeleteSession,
SystemInvalidInfoClass4,
SystemRangeStartInformation,
SystemVerifierInformation,
SystemAddVerifier,
SystemSessionProcessesInformation
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_HANDLE_INFORMATION
{
ULONG            ProcessId;
UCHAR            ObjectTypeNumber;
UCHAR            Flags;
USHORT          Handle;
PVOID            Object;
ACCESS_MASK      GrantedAccess;
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;

/*************************************************************************************************

私有变量

*************************************************************************************************/

typedef struct _DEVICE_EXTENSION
{
PDEVICE_OBJECT DeviceObject;
PKEVENT Event;

BOOLEAN bPCreate;
} DEVICE_EXTENSION, *PDEVICE_EXTENSION;

//    全局设备对象
PDEVICE_OBJECT g_pDeviceObject;

UNICODE_STRING g_RegPath;

/********************************************************************************

补充定义函数

********************************************************************************/

NTKERNELAPI NTSTATUS ObQueryNameString (
IN PVOID                        Object,
IN OUT PUNICODE_STRING            Name,
IN ULONG                        MaximumLength,
OUT PULONG                      ActualLength
);

NTKERNELAPI NTSTATUS ZwSetSecurityObject(
IN HANDLE Handle,
IN SECURITY_INFORMATION SecurityInformation,
IN PSECURITY_DESCRIPTOR SecurityDescriptor
);

NTKERNELAPI NTSTATUS ZwTerminateProcess(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );

NTKERNELAPI NTSTATUS ZwOpenProcess(
OUT PHANDLE            ProcessHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

NTKERNELAPI NTSTATUS ZwOpenThread(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

NTKERNELAPI NTSTATUS ZwLoadDriver(
IN PUNICODE_STRING DriverServiceName );

NTKERNELAPI NTSTATUS ZwSetSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID                SystemInformation,
IN ULONG                SystemInformationLength );

NTKERNELAPI NTSTATUS ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID              SystemInformation,
IN ULONG                SystemInformationLength,
OUT PULONG              ReturnLength OPTIONAL );

/***********************************************************************************

函数声明

***********************************************************************************/

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath);
void UnloadDriver(PDRIVER_OBJECT DriverObject);
NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);
NTSTATUS DispatchIoCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp);

void StartHook(void);
void RemoveHook(void);

NTSTATUS Hook_ZwWriteFile(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PVOID                Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL );

NTSTATUS Hook_ZwReadFile(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
OUT PVOID              Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL );

NTSTATUS Hook_ZwSetSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID                SystemInformation,
IN ULONG                SystemInformationLength );

NTSTATUS Hook_ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID              SystemInformation,
IN ULONG                SystemInformationLength,
OUT PULONG              ReturnLength OPTIONAL );

NTSTATUS Hook_ZwLoadDriver(
IN PUNICODE_STRING DriverServiceName );

NTSTATUS Hook_ZwSetSecurityObject(
IN HANDLE              ObjectHandle,
IN SECURITY_INFORMATION SecurityInformationClass,
IN PSECURITY_DESCRIPTOR DescriptorBuffer);

NTSTATUS Hook_ZwOpenKey(
OUT PHANDLE  KeyHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes);

NTSTATUS Hook_ZwCreateKey (
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions,
OUT PULONG Disposition OPTIONAL);

NTSTATUS Hook_ZwSetValueKey(
IN HANDLE  KeyHandle,
IN PUNICODE_STRING  ValueName,
IN ULONG  TitleIndex  OPTIONAL,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize);

NTSTATUS Hook_ZwDeleteKey(
IN HANDLE  KeyHandle);

NTSTATUS Hook_ZwDeleteValueKey(
IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName);

NTSTATUS Hook_ZwOpenSection(
OUT PHANDLE            SectionHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes );

NTSTATUS Hook_ZwCreateSection(
OUT PHANDLE            SectionHandle,
IN ULONG                DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER      MaximumSize OPTIONAL,
IN ULONG                PageAttributess,
IN ULONG                SectionAttributes,
IN HANDLE              FileHandle OPTIONAL );

NTSTATUS Hook_ZwCreateProcess(
OUT PHANDLE          ProcessHandle,
IN ACCESS_MASK        DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE            ParentProcess,
IN BOOLEAN            InheritObjectTable,
IN HANDLE            SectionHandle OPTIONAL,
IN HANDLE            DebugPort OPTIONAL,
IN HANDLE            ExceptionPort OPTIONAL );

NTSTATUS Hook_ZwCreateProcessEx(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN HANDLE UnknownHandle );

NTSTATUS Hook_ZwTerminateProcess(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );
NTSTATUS Hook_ZwOpenProcess(
OUT PHANDLE            ProcessHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

NTSTATUS Hook_ZwCreateThread(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
IN HANDLE              ProcessHandle,
OUT PCLIENT_ID          ClientId,
IN PCONTEXT            ThreadContext,
IN PINITIAL_TEB        InitialTeb,
IN BOOLEAN              CreateSuspended );

NTSTATUS Hook_ZwTerminateThread(
IN HANDLE              ThreadHandle,
IN NTSTATUS            ExitStatus );

NTSTATUS Hook_ZwOpenThread(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

NTSTATUS Hook_ZwCreateFile(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PLARGE_INTEGER      AllocationSize OPTIONAL,
IN ULONG                FileAttributes,
IN ULONG                ShareAccess,
IN ULONG                CreateDisposition,
IN ULONG                CreateOptions,
IN PVOID                EaBuffer OPTIONAL,
IN ULONG                EaLength );

NTSTATUS Hook_ZwOpenFile(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN ULONG                ShareAccess,
IN ULONG                OpenOptions );

NTSTATUS Hook_ZwClose(
IN HANDLE ObjectHandle );

#ifdef ALLOC_PRAGMA

#pragma alloc_text(INIT, DriverEntry)
#pragma alloc_text(INIT, StartHook)

#pragma alloc_text(PAGE, DispatchCreate)
#pragma alloc_text(PAGE, DispatchClose)
#pragma alloc_text(PAGE, DispatchIoCtrl)
#pragma alloc_text(PAGE, RemoveHook)

#pragma alloc_text(PAGE, UnloadDriver)

#pragma alloc_text(PAGE, Hook_ZwOpenKey)
#pragma alloc_text(PAGE, Hook_ZwSetSecurityObject)
#pragma alloc_text(PAGE, Hook_ZwCreateKey)
#pragma alloc_text(PAGE, Hook_ZwSetValueKey)
#pragma alloc_text(PAGE, Hook_ZwDeleteKey)
#pragma alloc_text(PAGE, Hook_ZwDeleteValueKey)

#pragma alloc_text(PAGE, Hook_ZwOpenSection)
#pragma alloc_text(PAGE, Hook_ZwCreateSection)

#pragma alloc_text(PAGE, Hook_ZwOpenProcess)
#pragma alloc_text(PAGE, Hook_ZwTerminateProcess)

#pragma alloc_text(PAGE, Hook_ZwOpenThread)

#pragma alloc_text(PAGE, Hook_ZwCreateFile)
#pragma alloc_text(PAGE, Hook_ZwOpenFile)
#pragma alloc_text(PAGE, Hook_ZwClose)

#pragma alloc_text(PAGE, Hook_ZwLoadDriver)

#pragma alloc_text(PAGE, Hook_ZwSetSystemInformation)
#pragma alloc_text(PAGE, Hook_ZwQuerySystemInformation)

#pragma alloc_text(PAGE, Hook_ZwReadFile)
#pragma alloc_text(PAGE, Hook_ZwWriteFile)

#endif

/*******************************************************************************

函数原型定义

********************************************************************************/

typedef NTSTATUS (*ZWLOADDRIVER)(
IN PUNICODE_STRING DriverServiceName );

typedef NTSTATUS (*ZWCREATEFILE)(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PLARGE_INTEGER      AllocationSize OPTIONAL,
IN ULONG                FileAttributes,
IN ULONG                ShareAccess,
IN ULONG                CreateDisposition,
IN ULONG                CreateOptions,
IN PVOID                EaBuffer OPTIONAL,
IN ULONG                EaLength );

typedef NTSTATUS (*ZWOPENFILE)(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN ULONG                ShareAccess,
IN ULONG                OpenOptions );

typedef NTSTATUS (*ZWCLOSE)(
IN HANDLE              ObjectHandle );

typedef NTSTATUS (*ZWWRITEFILE)(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PVOID                Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL );

typedef NTSTATUS (*ZWREADFILE)(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
OUT PVOID              Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL );

typedef NTSTATUS (*ZWCREATEPROCESS)(
OUT PHANDLE          ProcessHandle,
IN ACCESS_MASK        DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE            ParentProcess,
IN BOOLEAN            InheritObjectTable,
IN HANDLE            SectionHandle OPTIONAL,
IN HANDLE            DebugPort OPTIONAL,
IN HANDLE            ExceptionPort OPTIONAL);

typedef NTSTATUS (*ZWCREATEPROCESSEX)(
OUT PHANDLE ProcessHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
IN HANDLE ParentProcess,
IN BOOLEAN InheritObjectTable,
IN HANDLE SectionHandle OPTIONAL,
IN HANDLE DebugPort OPTIONAL,
IN HANDLE ExceptionPort OPTIONAL,
IN HANDLE Unknown );

typedef NTSTATUS (*ZWOPENPROCESS)(
OUT PHANDLE            ProcessHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

typedef NTSTATUS (*ZWTERMINATEPROCESS)(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );

typedef NTSTATUS (*ZWCREATETHREAD)(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
IN HANDLE              ProcessHandle,
OUT PCLIENT_ID          ClientId,
IN PCONTEXT            ThreadContext,
IN PINITIAL_TEB        InitialTeb,
IN BOOLEAN              CreateSuspended );

typedef NTSTATUS (*ZWTERMINATETHREAD)(
IN HANDLE              ThreadHandle,
IN NTSTATUS            ExitStatus );

typedef NTSTATUS (*ZWOPENTHREAD)(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId );

typedef NTSTATUS (*ZWCREATESECTION)(
OUT PHANDLE            SectionHandle,
IN ULONG                DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER      MaximumSize OPTIONAL,
IN ULONG                PageAttributess,
IN ULONG                SectionAttributes,
IN HANDLE              FileHandle OPTIONAL );

typedef NTSTATUS (*ZWOPENSECTION)(
OUT PHANDLE            SectionHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes );

//注册表

typedef NTSTATUS (*ZWCREATEKEY) (
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions,
OUT PULONG Disposition OPTIONAL
);

typedef NTSTATUS (*ZWOPENKEY) (
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes
);

typedef NTSTATUS (*ZWSETVALUEKEY)(
IN HANDLE  KeyHandle,
IN PUNICODE_STRING  ValueName,
IN ULONG  TitleIndex  OPTIONAL,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize
);

typedef NTSTATUS (*ZWSETSECURITYOBJECT)(
IN HANDLE              ObjectHandle,
IN SECURITY_INFORMATION SecurityInformationClass,
IN PSECURITY_DESCRIPTOR DescriptorBuffer);

typedef NTSTATUS (*ZWDELETEKEY)(
IN HANDLE  KeyHandle);
typedef NTSTATUS (*ZWDELETEVALUEKEY)(
IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName);

typedef NTSTATUS (*ZWSETSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID                SystemInformation,
IN ULONG                SystemInformationLength );

typedef NTSTATUS (*ZWQUERYSYSTEMINFORMATION)(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID              SystemInformation,
IN ULONG                SystemInformationLength,
OUT PULONG              ReturnLength OPTIONAL );

/***********************************************************

//       SDT 原函数地址

***********************************************************/

static ZWCREATEFILE                OldZwCreateFile;
static ZWOPENFILE                OldZwOpenFile;
static ZWCLOSE                    OldZwClose;
static ZWWRITEFILE                OldZwWriteFile;
static ZWREADFILE                OldZwReadFile;

static ZWTERMINATEPROCESS        OldZwTerminateProcess;
static ZWOPENPROCESS            OldZwOpenProcess;

static ZWOPENTHREAD                OldZwOpenThread;
static ZWCREATESECTION            OldZwCreateSection;
static ZWOPENSECTION            OldZwOpenSection;

static ZWCREATEKEY                OldZwCreateKey;
static ZWSETVALUEKEY            OldZwSetValueKey;
static ZWDELETEKEY                OldZwDeleteKey;
static ZWDELETEVALUEKEY            OldZwDeleteValueKey;
static ZWSETSECURITYOBJECT        OldZwSetSecurityObject;
static ZWOPENKEY                OldZwOpenKey;

static ZWLOADDRIVER                OldZwLoadDriver;

static ZWSETSYSTEMINFORMATION    OldZwSetSystemInformation;
static ZWQUERYSYSTEMINFORMATION    OldZwQuerySystemInformation;

/***********************************************************************************

挂接函数执行体

***********************************************************************************/

/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwWriteFile(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PVOID                Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL )
{
NTSTATUS rc;
rc = OldZwWriteFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
return rc;
}

/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwReadFile(
IN HANDLE              FileHandle,
IN HANDLE              Event OPTIONAL,
IN PIO_APC_ROUTINE      ApcRoutine OPTIONAL,
IN PVOID                ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
OUT PVOID              Buffer,
IN ULONG                Length,
IN PLARGE_INTEGER      ByteOffset OPTIONAL,
IN PULONG              Key OPTIONAL )
{
NTSTATUS rc;
rc = OldZwReadFile(FileHandle,Event,ApcRoutine,ApcContext,IoStatusBlock,Buffer,Length,ByteOffset,Key);
return rc;
}

/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwSetSystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
IN PVOID                SystemInformation,
IN ULONG                SystemInformationLength )
{
NTSTATUS rc;
rc = OldZwSetSystemInformation(SystemInformationClass,SystemInformation,SystemInformationLength);
return rc;
}

/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwQuerySystemInformation(
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID              SystemInformation,
IN ULONG                SystemInformationLength,
OUT PULONG              ReturnLength OPTIONAL )
{
NTSTATUS rc;
rc = OldZwQuerySystemInformation(SystemInformationClass,SystemInformation,SystemInformationLength,ReturnLength);
return rc;
}

/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwLoadDriver(
IN PUNICODE_STRING DriverServiceName )
{
NTSTATUS rc;

rc = OldZwLoadDriver(DriverServiceName);
return rc;
}
/************************************************************************************************

************************************************************************************************/

NTSTATUS Hook_ZwSetSecurityObject(
IN HANDLE              ObjectHandle,
IN SECURITY_INFORMATION SecurityInformationClass,
IN PSECURITY_DESCRIPTOR DescriptorBuffer)
{

NTSTATUS rc;

rc = OldZwSetSecurityObject(ObjectHandle,SecurityInformationClass,DescriptorBuffer);

return rc;
}

/************************************************************************************************

ZwOpenKey

************************************************************************************************/

NTSTATUS Hook_ZwOpenKey(
OUT PHANDLE  KeyHandle,
IN ACCESS_MASK  DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes)
{
NTSTATUS rc;

rc = OldZwOpenKey(KeyHandle,DesiredAccess,ObjectAttributes);

return rc;
}

/*************************************************************************************************

挂接函数 ZwCreateKey

***************************************************************************************************/

NTSTATUS Hook_ZwCreateKey (
OUT PHANDLE KeyHandle,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes,
IN ULONG TitleIndex,
IN PUNICODE_STRING Class OPTIONAL,
IN ULONG CreateOptions,
OUT PULONG Disposition OPTIONAL
)
{
NTSTATUS rc;

rc = OldZwCreateKey(KeyHandle, DesiredAccess, ObjectAttributes,
TitleIndex, Class, CreateOptions, Disposition);

return rc;
}

/***************************************************************************************************

****************************************************************************************************/

NTSTATUS Hook_ZwSetValueKey(
IN HANDLE  KeyHandle,
IN PUNICODE_STRING  ValueName,
IN ULONG  TitleIndex  OPTIONAL,
IN ULONG  Type,
IN PVOID  Data,
IN ULONG  DataSize
)
{
NTSTATUS rc;

rc = OldZwSetValueKey(KeyHandle,ValueName,TitleIndex,Type,Data,DataSize);

return rc;
}

/********************************************************************************************************

********************************************************************************************************/

NTSTATUS Hook_ZwDeleteKey(IN HANDLE  KeyHandle)
{
NTSTATUS rc;

rc = OldZwDeleteKey(KeyHandle);

return rc;
}

/*********************************************************************************************************

*********************************************************************************************************/

NTSTATUS Hook_ZwDeleteValueKey( IN HANDLE KeyHandle, IN PUNICODE_STRING ValueName)
{
NTSTATUS rc;

rc = OldZwDeleteValueKey(KeyHandle,ValueName);

return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwOpenSection(
OUT PHANDLE            SectionHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes )
{
NTSTATUS rc;
//    DbgPrint("Hook_ZwOpenSection\n");
rc = OldZwOpenSection(SectionHandle,DesiredAccess,ObjectAttributes);
return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwCreateSection(
OUT PHANDLE            SectionHandle,
IN ULONG                DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes OPTIONAL,
IN PLARGE_INTEGER      MaximumSize OPTIONAL,
IN ULONG                PageAttributess,
IN ULONG                SectionAttributes,
IN HANDLE              FileHandle OPTIONAL )
{
NTSTATUS rc;
DbgPrint("Hook_ZwCreateSection");
return OldZwCreateSection(SectionHandle,DesiredAccess,ObjectAttributes,
MaximumSize,PageAttributess,SectionAttributes,FileHandle);
return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwTerminateProcess(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus )
{
NTSTATUS rc;

rc = OldZwTerminateProcess(ProcessHandle,ExitStatus);
return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwOpenProcess(
OUT PHANDLE            ProcessHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId )

{
NTSTATUS rc;

rc = OldZwOpenProcess(ProcessHandle,AccessMask,ObjectAttributes,ClientId);
return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwOpenThread(
OUT PHANDLE            ThreadHandle,
IN ACCESS_MASK          AccessMask,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
IN PCLIENT_ID          ClientId )
{
NTSTATUS rc;

rc =  OldZwOpenThread(ThreadHandle,AccessMask,ObjectAttributes,ClientId);

return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwCreateFile(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN PLARGE_INTEGER      AllocationSize OPTIONAL,
IN ULONG                FileAttributes,
IN ULONG                ShareAccess,
IN ULONG                CreateDisposition,
IN ULONG                CreateOptions,
IN PVOID                EaBuffer OPTIONAL,
IN ULONG                EaLength )
{
NTSTATUS rc;

rc = OldZwCreateFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,
AllocationSize,FileAttributes,ShareAccess,CreateDisposition,
CreateOptions,EaBuffer,EaLength);

return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwOpenFile(
OUT PHANDLE            FileHandle,
IN ACCESS_MASK          DesiredAccess,
IN POBJECT_ATTRIBUTES  ObjectAttributes,
OUT PIO_STATUS_BLOCK    IoStatusBlock,
IN ULONG                ShareAccess,
IN ULONG                OpenOptions )
{
NTSTATUS rc;

rc =  OldZwOpenFile(FileHandle,DesiredAccess,ObjectAttributes,IoStatusBlock,ShareAccess,
OpenOptions);

return rc;
}

/*************************************************************************************************

**************************************************************************************************/

NTSTATUS Hook_ZwClose(
IN HANDLE              ObjectHandle )
{
NTSTATUS rc;

//在这里执行扫描必须十分注意,否则容易蓝屏

rc = OldZwClose(ObjectHandle);
return rc;
}

/*************************************************************************************************

驱动函数入口

**************************************************************************************************/

NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS        ntStatus;
UNICODE_STRING  uszDriverString;
UNICODE_STRING  uszDeviceString;
UNICODE_STRING  uszEventString;

PDEVICE_OBJECT    pDeviceObject;
PDEVICE_EXTENSION extension;
// 初始化设备对象名
RtlInitUnicodeString(&uszDriverString, L"\\Device\\ITSys");
// 创建并初始化对象
ntStatus = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&uszDriverString,
FILE_DEVICE_UNKNOWN,
0,
FALSE,
&pDeviceObject
);
if(ntStatus != STATUS_SUCCESS)
return ntStatus;
extension = pDeviceObject->DeviceExtension;
RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\ITSys");
// 创建用户可见连接名称
ntStatus = IoCreateSymbolicLink(&uszDeviceString, &uszDriverString);
if(ntStatus != STATUS_SUCCESS)
{
// 创建失败,删除对象并返回错误值
IoDeleteDevice(pDeviceObject);
return ntStatus;
}
// 赋值全局设备对象指针

// Assign global pointer to the device object for use by the callback functions
g_pDeviceObject = pDeviceObject;
// 设置所有可用的DeviceIoControl的处理IRP的函数

DriverObject->DriverUnload                            = UnloadDriver;
DriverObject->MajorFunction[IRP_MJ_CREATE]            = DispatchCreate;
DriverObject->MajorFunction[IRP_MJ_CLOSE]            = DispatchClose;
DriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]    = DispatchIoCtrl;

#if DBG
KdPrint(("RegistryPath : %ws\n",RegistryPath->Buffer));
#endif

//SDT挂接
StartHook();

return ntStatus;
}

/*************************************************************************************************

启用系统服务挂接

**************************************************************************************************/

void StartHook (void)
{
//获取未导出的服务函数索引号
HANDLE    hFile;
PCHAR    pDllFile;
ULONG  ulSize;
ULONG  ulByteReaded;

__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
//挂接SDT函数
OldZwCreateFile                    = (ZWCREATEFILE)    InterlockedExchange((PLONG)
&SDT(ZwCreateFile),
(LONG)Hook_ZwCreateFile);
OldZwOpenFile                    = (ZWOPENFILE)        InterlockedExchange((PLONG)
&SDT(ZwOpenFile),
(LONG)Hook_ZwOpenFile);
OldZwClose                        = (ZWCLOSE)            InterlockedExchange((PLONG)
&SDT(ZwClose),
(LONG)Hook_ZwClose);
OldZwReadFile                    = (ZWREADFILE)        InterlockedExchange((PLONG)
&SDT(ZwReadFile),
(LONG)Hook_ZwReadFile);
OldZwWriteFile                    = (ZWWRITEFILE)        InterlockedExchange((PLONG)
&SDT(ZwWriteFile),
(LONG)Hook_ZwWriteFile);

OldZwTerminateProcess            = (ZWTERMINATEPROCESS)InterlockedExchange((PLONG)
&SDT(ZwTerminateProcess),
(LONG)Hook_ZwTerminateProcess);

OldZwOpenProcess                = (ZWOPENPROCESS)InterlockedExchange((PLONG)
&SDT(ZwOpenProcess),
(LONG)Hook_ZwOpenProcess);

OldZwOpenThread                    = (ZWOPENTHREAD)InterlockedExchange((PLONG)
&SDT(ZwOpenThread),
(LONG)Hook_ZwOpenThread);
OldZwCreateSection                = (ZWCREATESECTION)InterlockedExchange((PLONG)
&SDT(ZwCreateSection),
(LONG)Hook_ZwCreateSection);
OldZwOpenSection                = (ZWOPENSECTION)InterlockedExchange((PLONG)
&SDT(ZwOpenSection),
(LONG)Hook_ZwOpenSection);

OldZwOpenKey                    = (ZWOPENKEY) InterlockedExchange((PLONG)
&SDT(ZwOpenKey),
(LONG)Hook_ZwOpenKey);
OldZwCreateKey                    = (ZWCREATEKEY) InterlockedExchange((PLONG)
&SDT(ZwCreateKey),
(LONG)Hook_ZwCreateKey);
OldZwSetValueKey                = (ZWSETVALUEKEY) InterlockedExchange((PLONG)
&SDT(ZwSetValueKey),
(LONG)Hook_ZwSetValueKey);
OldZwDeleteKey                    = (ZWDELETEKEY) InterlockedExchange((PLONG)
&SDT(ZwDeleteKey),
(LONG)Hook_ZwDeleteKey);
OldZwDeleteValueKey                = (ZWDELETEVALUEKEY) InterlockedExchange((PLONG)
&SDT(ZwDeleteValueKey),
(LONG)Hook_ZwDeleteValueKey);
OldZwSetSecurityObject            = (ZWSETSECURITYOBJECT)InterlockedExchange((PLONG)
&SDT(ZwSetSecurityObject),
(LONG)Hook_ZwSetSecurityObject);

OldZwLoadDriver                    = (ZWLOADDRIVER)InterlockedExchange((PLONG)
&SDT(ZwLoadDriver),
(LONG)Hook_ZwLoadDriver);

OldZwSetSystemInformation        = (ZWSETSYSTEMINFORMATION)InterlockedExchange((PLONG)
&SDT(ZwSetSystemInformation),
(LONG)Hook_ZwSetSystemInformation);

OldZwQuerySystemInformation        = (ZWQUERYSYSTEMINFORMATION)InterlockedExchange((PLONG)
&SDT(ZwQuerySystemInformation),
(LONG)Hook_ZwQuerySystemInformation);

//关闭
__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
return ;
}

/*************************************************************************************************

移除系统服务挂接

**************************************************************************************************/

void RemoveHook (void)
{
__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}

InterlockedExchange( (PLONG) &SDT(ZwCreateFile)                ,  (LONG) OldZwCreateFile                );
InterlockedExchange( (PLONG) &SDT(ZwOpenFile)                ,  (LONG) OldZwOpenFile                    );
InterlockedExchange( (PLONG) &SDT(ZwClose)                    ,  (LONG) OldZwClose                    );
InterlockedExchange( (PLONG) &SDT(ZwReadFile)                ,  (LONG) OldZwReadFile                    );
InterlockedExchange( (PLONG) &SDT(ZwWriteFile)                ,  (LONG) OldZwWriteFile                );

InterlockedExchange( (PLONG) &SDT(ZwTerminateProcess)        ,  (LONG) OldZwTerminateProcess            );
InterlockedExchange( (PLONG) &SDT(ZwOpenProcess)            ,  (LONG) OldZwOpenProcess                );
InterlockedExchange( (PLONG) &SDT(ZwOpenThread)                ,  (LONG) OldZwOpenThread                );
InterlockedExchange( (PLONG) &SDT(ZwCreateSection)            ,  (LONG) OldZwCreateSection            );
InterlockedExchange( (PLONG) &SDT(ZwOpenSection)            ,  (LONG) OldZwOpenSection                );

InterlockedExchange( (PLONG) &SDT(ZwOpenKey)                ,  (LONG) OldZwOpenKey                    );
InterlockedExchange( (PLONG) &SDT(ZwCreateKey)                ,  (LONG) OldZwCreateKey                );
InterlockedExchange( (PLONG) &SDT(ZwSetValueKey)            ,  (LONG) OldZwSetValueKey                );
InterlockedExchange( (PLONG) &SDT(ZwDeleteKey)                ,  (LONG) OldZwDeleteKey                );
InterlockedExchange( (PLONG) &SDT(ZwDeleteValueKey)            ,  (LONG) OldZwDeleteValueKey            );
InterlockedExchange( (PLONG) &SDT(ZwSetSecurityObject)        ,  (LONG) OldZwSetSecurityObject        );

InterlockedExchange( (PLONG) &SDT(ZwLoadDriver)                ,  (LONG) OldZwLoadDriver                );

InterlockedExchange( (PLONG) &SDT(ZwSetSystemInformation)    ,  (LONG) OldZwSetSystemInformation        );
InterlockedExchange( (PLONG) &SDT(ZwQuerySystemInformation)    ,  (LONG) OldZwQuerySystemInformation    );

__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
}

void UnloadDriver(IN PDRIVER_OBJECT DriverObject)
{
UNICODE_STRING  uszDeviceString;
NTSTATUS        ntStatus;

//移除挂接
RemoveHook();

IoDeleteDevice(DriverObject->DeviceObject);

RtlInitUnicodeString(&uszDeviceString, L"\\DosDevices\\ITSys");
IoDeleteSymbolicLink(&uszDeviceString);

}

/*************************************************************************************************
//
// 创建与关闭驱动处理历程
//
**************************************************************************************************/

NTSTATUS DispatchCreate(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information=0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
NTSTATUS rc;

Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information=0;

rc = Irp->IoStatus.Status;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return rc;
}

/**************************************************************************************************

Win32 使用 DeviceIoControl 获取当前创建进程的信息的响应函数

***************************************************************************************************/

NTSTATUS DispatchIoCtrl(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{

NTSTATUS              ntStatus = STATUS_UNSUCCESSFUL;
PIO_STACK_LOCATION    irpStack  = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION    extension = DeviceObject->DeviceExtension;

switch(irpStack->Parameters.DeviceIoControl.IoControlCode)
{
default:
break;
}

Irp->IoStatus.Status = ntStatus;

// 设置返回给用户层程序的数据的字节数
if(ntStatus == STATUS_SUCCESS)
Irp->IoStatus.Information = irpStack->Parameters.DeviceIoControl.OutputBufferLength;
else
Irp->IoStatus.Information = 0;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return ntStatus;

}


Hook ZwTerminateProcess

R3关键代码:

void CLstProcDlg::OnProtectProc()
{
DWORD ret	= -1;
DWORD read	= 0;

if(m_dwPID==-1)
{
MessageBox("请选择进程");
return;
}
if(MessageBox(_T("确认要进行保护吗?"),_T("保护进程"),MB_YESNO)==IDYES)
{
DeviceIoControl(gh_Device,
IOCTL_PROC_PROTECT,
&m_dwPID,
sizeof(m_dwPID),
&ret,
sizeof(ret),
&read,
NULL);
//UnloadDeviceDriver(ac_driverName);
if(ret==0)
MessageBox(_T("保护成功执行"));
else
MessageBox(_T("保护执行失败"));
//ShellExecute(NULL, "open", "sc","stop LstProc", NULL, SW_HIDE);

}
}


R0关键代码:

#include "precomp.h"

#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()

__declspec(dllimport)  ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
#define SYSTEMSERVICE(_function) KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)_function+1)]
#define SDT     SYSTEMSERVICE
#define KSDT KeServiceDescriptorTable

void StartHook(void);
void RemoveHook(void);
NTKERNELAPI NTSTATUS ZwTerminateProcess(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );

NTSTATUS Hook_ZwTerminateProcess(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );

typedef NTSTATUS (*ZWTERMINATEPROCESS)(
IN HANDLE              ProcessHandle OPTIONAL,
IN NTSTATUS            ExitStatus );

static ZWTERMINATEPROCESS        OldZwTerminateProcess;

NTSTATUS Hook_ZwTerminateProcess(
__in_opt HANDLE ProcessHandle,
__in NTSTATUS ExitStatus
)
{
ULONG 			uPID = 0;
NTSTATUS 		ntStatus = 0;
PEPROCESS 		pEProcess = NULL;

ntStatus = ObReferenceObjectByHandle(ProcessHandle, FILE_READ_DATA, NULL, KernelMode, &pEProcess, NULL);
if(!NT_SUCCESS(ntStatus))
{
return ntStatus;
}

uPID = (ULONG)PsGetProcessId(pEProcess);

if(ValidateProcessNeedProtect(uPID) != -1)//这里遍历一个数组 数组里面放着要保护的PID 这个数组由分发函数赋值
{
if(uPID != (ULONG)PsGetProcessId(PsGetCurrentProcess()))//看看是不是自己 自己结束自己就结束呗
{
return STATUS_ACCESS_DENIED;
}
}
ntStatus = OldZwTerminateProcess(ProcessHandle, ExitStatus);

return ntStatus;
}

void StartHook (void)
{
//获取未导出的服务函数索引号
HANDLE    hFile;
PCHAR    pDllFile;
ULONG  ulSize;
ULONG  ulByteReaded;

__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}

OldZwTerminateProcess  = (ZWTERMINATEPROCESS)InterlockedExchange((PLONG)
&SDT(ZwTerminateProcess),
(LONG)Hook_ZwTerminateProcess);

//关闭
__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
return ;
}

void RemoveHook (void)
{
__asm
{
push    eax
mov        eax, CR0
and        eax, 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
InterlockedExchange( (PLONG) &SDT(ZwTerminateProcess),  (LONG) OldZwTerminateProcess);

__asm
{
push    eax
mov        eax, CR0
or        eax, NOT 0FFFEFFFFh
mov        CR0, eax
pop        eax
}
}


下面是梦老大教程总结的:

第10课 实现hook ssdt

typedef struct _SERVICE_DESCRIPTOR_TABLE {
PULONG   ServiceTableBase;
PULONG  ServiceCounterTableBase;
ULONG   NumberOfServices;
PUCHAR  ParamTableBase;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
//ssdt表已经导出了,这里例行公事下
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;


ServiceTableBase就是内核API所在的一个数组,这个数组里面包含了很多很多API,那些API呢都是为上层应用提供服务的.

这个数据结构呢,就是描述这些服务的,

这个typedef struct实际上就是指明这个结构呢怎么对齐方式,是以几个字节对齐的

现在指定是(#pragma pack(1)) 1个字节对齐的,这样有一个好处就是,避免浪费内存,如果不写这个的话,那么就是按照4个字节对齐的了.

__declspec(dllimport)这个呢是导出别的模块的一个东西,导出别的模块的一些函数,或者是变量,类之类的.

__declspec(dllimport)-----导出的是一个结构

extern ------------------导出的是一个指针

这节课我们做一个让别人打开不了我们进程的小程序,别人用OpenProcess打开这个进程的时候,我们让他打开不了,那么怎么实现呢.

我们看一下OpenProcess在od中

752D7F2A >  8BFF            mov edi,edi
752D7F2C    55              push ebp
752D7F2D    8BEC            mov ebp,esp
752D7F2F    83EC 20         sub esp,0x20
752D7F32    8B45 10         mov eax,dword ptr ss:[ebp+0x10]
752D7F35    8945 F8         mov dword ptr ss:[ebp-0x8],eax
752D7F38    8B45 0C         mov eax,dword ptr ss:[ebp+0xC]
752D7F3B    56              push esi
752D7F3C    33F6            xor esi,esi
752D7F3E    F7D8            neg eax
752D7F40    1BC0            sbb eax,eax
752D7F42    83E0 02         and eax,0x2
752D7F45    8945 EC         mov dword ptr ss:[ebp-0x14],eax
752D7F48    8D45 F8         lea eax,dword ptr ss:[ebp-0x8]
752D7F4B    50              push eax
752D7F4C    8D45 E0         lea eax,dword ptr ss:[ebp-0x20]
752D7F4F    50              push eax
752D7F50    FF75 08         push dword ptr ss:[ebp+0x8]
752D7F53    8D45 10         lea eax,dword ptr ss:[ebp+0x10]
752D7F56    50              push eax
752D7F57    8975 FC         mov dword ptr ss:[ebp-0x4],esi
752D7F5A    C745 E0 1800000>mov dword ptr ss:[ebp-0x20],0x18
752D7F61    8975 E4         mov dword ptr ss:[ebp-0x1C],esi
752D7F64    8975 E8         mov dword ptr ss:[ebp-0x18],esi
752D7F67    8975 F0         mov dword ptr ss:[ebp-0x10],esi
752D7F6A    8975 F4         mov dword ptr ss:[ebp-0xC],esi
752D7F6D    FF15 D4112D75   call dword ptr ds:[<&ntdll.NtOpenProcess>]    ; ntdll.ZwOpenProcess


最后一条代码跳到以下代码

77245DC8 >  B8 BE000000     mov eax,0xBE
77245DCD    BA 0003FE7F     mov edx,0x7FFE0300
77245DD2    FF12            call dword ptr ds:[edx]
77245DD4    C2 1000         retn 0x10


其中mov eax,0xBE就是在ssdt中的数组下标值,转换成10进制就是190

以上代码是在od反编译出来的,查看所有模块的OpenProcess

我们hook一个函数呢,我们必须定义一个新的函数,定义一个新的函数是有要求的,不是你胡乱定义的,

比如说你随便定义一个

VOID XXX
{

}


这样是不行的,因为你这样的话会导致应用层传过来的参数,然后会造成不对齐,不对齐的话内核栈就会被破坏掉了,破坏掉的话绝对会发生的事情就是他会蓝屏.

所以我们定义的时候要注意,你定义的这个函数一定要和我们替换的那个函数他的类型,他的返回类型,他的参数是要保持一样的才可以,就是他有几个参数,你新定义的那个函数就要有几个参数,他的返回值类型是什么,你的返回值类型就是什么.

那么这个定义呢,有很多方法可以去得到他的那些参数表,有很多方法可以得到他的参数是什么,有几个参数,你都可以得到,其中,以前用的一种蠢办法就是自己慢慢逆向,我们跟这个OpenProcess的流程在应用层通过od软件跟一下他的流程,然后因为他的应用层,OpenProcess的参数都是确定的,所以我们自己把那个他的汇编代码逆向下来然后跟到

77245DC8 >  B8 BE000000     mov eax,0xBE
77245DCD    BA 0003FE7F     mov edx,0x7FFE0300
77245DD2    FF12            call dword ptr ds:[edx]
77245DD4    C2 1000         retn 0x10


就知道传入到内核里面去,有几个参数,类型是什么了,这种方法是比较蠢的,但是呢,可以锻炼你的汇编能力.

现在有一种比较好的方法就是,你直接可以通过微软在2006年公布的一个开源的内核的源码,公布了一个win2003的内核源码,这个内核源码呢里面就有我们所有的那些常用的系统服务,函数的定义已经实现代码,所以呢,你可以根据这个然后你去找,因为他winXP,win2003,还是vista,还是win7他的那些系统服务都是保持一样的,所以呢他这些基本上你不用考虑他的兼容性问题,所以呢你一般你在这个wrk去找基本上就没有错了,

NTSTATUS NtOpenProcess(
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
)
//改成我们要用的
NTSTATUS MyNtOpenProcess (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);


在Hook我们的ssdt之前呢,一定要先去除内存保护

//去掉内存保护
void WPOFF()
{
__asm{
cli//关闭中断,我们修改的时候,防止他切换到另外一个线程去了,如果线程切换的话,就造成哪些怎么说呢,可能会发生访问冲突,可能在你修改一半的时候,你复制一个东西,比如说你修改的时候,还没修改完成,修改到一半的时候呢,然后别的东西马上就访问这个东西的话,那么这个东西他只修改了一半,不正确,所以呢,他会造成哪些蓝屏了,这里就把中断关闭掉,在恢复的时候,把中断开启sti
mov  eax,cr0//这个cr0呢是一个寄存器,可以参考一本书,有一本书是对内核这些寄存器是描述的是比较好的,IA-32 Intel架构软件开发人员手册 卷3:系统编程指南(中文 ),这本书感觉是非常不错的,因为是Intel的,里面涉及很多很多操作系统相关的东西,
and  eax,not 10000h//cr0其中某一位的内存是代表这个内存页开启还是关闭内存保护,他的某一位就是影响了你是开启还是关闭.对某一位进行操作的话就可以去除或者恢复内存保护的目的了.
mov  cr0,eax
}
}
//恢复内存保护
void WPON()
{
__asm{
mov  eax,cr0
or   eax,10000h
mov  cr0,eax
sti//把中断开启,别的线程才可以进行线程切换,
}
}


WPOFF();//去掉内存保护

WPON();//恢复内存保护

记住这两个函数是成对出现的,如果不恢复内存保护的话,那就永远都关闭了,意思就是只有你这个线程永远都在执行,其他线程都不能执行了,这样的话整个windows等于是死机了,一定要记住成对出现.

ULONG g_OldNtOpenProcess;


你直接调用这个g_OldNtOpenProcess()这个的话他应该是实现不了的,因为他是个变量,不是一个函数,所以呢,在这里的话,g_OldNtOpenProcess(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);是会出现问题的,因为g_OldNtOpenProcess不是函数.

那么我们要想办法把OldNtOpenProcess变成一个函数,我们可以定义一下

把上面的

NTSTATUS NtOpenProcess


定义成一个函数指针

typedef NTSTATUS (*NTOPENPROCESS) (
__out PHANDLE ProcessHandle,
__in ACCESS_MASK DesiredAccess,
__in POBJECT_ATTRIBUTES ObjectAttributes,
__in_opt PCLIENT_ID ClientId
);


把变量g_OldNtOpenProcess强制转换成

(NTOPENPROCESS)函数指针的形式((NTOPENPROCESS)g_OldNtOpenProcess)

((NTOPENPROCESS)g_OldNtOpenProcess)(ProcessHandle,DesiredAccess,ObjectAttributes,ClientId);

调用进程名字,内核有一个函数,PsGetCurrentProcess(),这个函数呢就是得到进程对象,就是进程关联的一个数据结构,这个进程关联的数据结构呢,他有一个偏移量,

在windbg里面,dt _eprocess

lkd> dt _eprocess
nt!_EPROCESS
+0x000 Pcb              : _KPROCESS
+0x098 ProcessLock      : _EX_PUSH_LOCK
+0x0a0 CreateTime       : _LARGE_INTEGER
.......
.....
+0x16c ImageFileName    : [15] UChar


这个数据结构是进程执行底层的一个数据结构,这个数据结构里面有很多关于进程方面的信息,比如说,进程的进程ID,进程名字,或者是进程路径,或者是进程模块,已经进程的那些安全信息,和进程的线程之类的那些信息都在这个数据结构里面,譬如创建时间,退出时间之类的,等等,很多很多信息,还有句柄表啊,一般你得到这个结构的话对这个进程你可以获取一个进程的很多很多信息,但是这个结构是和操作系统相关的,比如说winXP 和win2003,或者是vista和win7,它里面关于对这个结构的描述他都是不太一样的,很多部分不一样,至少他的偏移量,想这些成员的偏移量他是绝对不会相同的,所以在这里的时候呢,我们只能写硬编码,我们要根据不同的操作系统,如果你要写一个比较兼容的软件,一个驱动的话你必须要获取每一个NT操作系统的硬编码,然后把这些硬编码根据你对应的那些操作系统然后进行编写对应的函数,这样的话,实际你这样开发驱动的话,兼容性太难考虑了,我们看一下进程名字是在那,+0x16c
这个位置就是进程名字,+0x16c ImageFileName : [15] UChar

ImageFileName映像文件名字,然后只占了15个字节,我们就用这个+0x16c,因为他得到的是一个+0x16c,记住是16进制的,不是10进制的.

现在功能还是太简单了,我们只是打印一下谁在调用这个函数,感觉还是不满足我们的需求,我们现在做一件什么事呢,我们现在可以试一下我们,比如说我们让他得到某一个函数的时候,让他得不到某个进程句柄,比如说,我们现在可以通过ssdt hook保护一个进程,比如说保护那个进程呢,我们保护ReadWriteProcess.exe试试,假如某个进程要调用OpenProcess打开我们的ReadWriteProcess.exe进程,打开我们的进程的话,我们让他打开不了,那么就可以通过这个函数(MyNtOpenProcess)进行操作就可以了.

那么在这里有个问题,我们怎么知道被打开的是我们要保护的这一个进程呢,那我们可以通过ClientId,ClientId里面有个进程ID号,然后我们通过那个进程ID号,获取到这个进程的一些信息ClientId->UniqueProcess,来判断是不是我们保护的进程,那么,我们写一个函数用于判断,

//通过一个进程ID保护进程,我们要输入一个进程ID(ULONG ProcessId),

void ProtectProcess(ULONG ProcessId)
{
//这里要调用一个函数,我们通过一个进程ID然后再获取这个进程的信息,这里通过一个内核的API,这个API的名字是PsLookupProcessByProcessId,这个函数有个功能,通过进程ID获取进程对象,这个进程对象和刚才说的那个PsGetCurrentProcess他那个函数获得对象是一样的,他都是一样的对象,只是这里不是获得当前的对象,而是获取只要你填写一个进程ID,获取这个对应的ID的进程对象,因为在wdk中这个函数是没有声明的,所以我们在这里要声明一下.
NTSTATUS PsLookupProcessByProcessId(//有2个参数---->通过进程ID获取进程对象
_In_   HANDLE ProcessId,//1.进程ID,
_Out_  PEPROCESS *Process//2.进程对象
);
}


PsLookupProcessByProcessId直接填写进去一个进程ID呢,会输出一个进程对象指针,

因为PsLookupProcessByProcessId这个函数的调用会引起对这个进程对象的引用计数加1,这个引用计数以前也说过,如果当这个对象引用计数为0的时候,这个对象才会被释放,如果这个计数不为0的话,这个对象内存是不会被释放的,这样的话就会引起内存泄漏,而我们调用这个PsLookupProcessByProcessId就会增加一次对这个进程对象的引用计数,把这个引用计数加1

strstr((UCHAR*)PsGetCurrentProcess()+0x16c,"ReadWrite")在第一个参数中搜索第二个参数存在不,如果存在的话,直接返回第二个字符串在第一个字符串中位置,意思就是如果搜索到的话,他的值肯定不为0的,如果搜素不到的话那值就是0.

(教程时间 51:00)
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: