步骤说明:
1) 用NtQuerySystemInformation取得内核模块ntkrnlpa.exe或ntoskrnl.exe的基址KernelBase,获取内核模块的文件名称,到底是ntkrnlpa.exe还是ntoskrnl.exe.
2) 读取ntkrnlpa.exe或ntoskrnl.exe的映象基址ImageBase,和.Text节中虚拟偏移Virtual Offset,实际偏移Real Offset.
3) 从ntkrnlpa.exe或ntoskrnl.exe读出正确的SSDT: 正确SSDT在ntkrnlpa.exe或ntoskrnl.exe文件中偏移 = *(PULONG)KeServiceDescriptorTable - KernelBase –Virtual Offset + Real Offset.读取长度 = KeServiceDescriptorTable->NumberOfService * 4.
4) 这里读出的内容每4字节就是一个调用的地址,但这样读出的内容还不是SSDT. 计算出正确的SSDT: 每4个字节 - ImageBase + KernelBase.
5) 禁用中断 -> memcpy写SSDT -> 启用中断.
以下是代码了,需要用到我前篇文章写的IrpFile.h,去复制就OK啦.
//RestoreSSDT_Kernel.c/
#include "IrpFile.h"
#define SystemModuleInformation 11
typedef struct _SYSTEM_MODULE_INFORMATION
{
ULONG Reserved[2];
PVOID Base;
ULONG Size;
ULONG Flags;
USHORT Index;
USHORT Unknown;
USHORT LoadCount;
USHORT ModuleNameOffset;
CHAR ImageName[256];
} SYSTEM_MODULE_INFORMATION, *PSYSTEM_MODULE_INFORMATION;
typedef struct
{
ULONG NumberOfModules;
SYSTEM_MODULE_INFORMATION smi;
} MODULES, *PMODULES;
NTSYSAPI
NTSTATUS
NTAPI
NtQuerySystemInformation(
IN ULONG SysInfoClass,
IN OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG Re
Kernel下检测还原正确的SSDT
最新推荐文章于 2022-05-09 01:41:33 发布