Kernel下检测还原正确的SSDT
来源:互联网 发布:mysql my.ini文件下载 编辑:程序博客网 时间:2024/05/16 08:08
步骤说明:
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 RetLen
);
typedef struct _NEED_INFO
{
ULONG ImageBase;
UCHAR UseLess1[204];
ULONG VOffset;
ULONG UseLess2;
ULONG ROffset;
} NEED_INFO, *PNEED_INFO;
typedef struct _SERVICE_DESCRIPTOR_TABLE
{
PVOID ServiceTableBase;
PULONG ServiceCounterTableBase;
ULONG NumberOfService;
ULONG ParamTableBase;
} SERVICE_DESCRIPTOR_TABLE, *PSERVICE_DESCRIPTOR_TABLE;
extern PSERVICE_DESCRIPTOR_TABLE KeServiceDescriptorTable;
VOID InterruptEnable()
{
__asm
{
MOV EAX, CR0
OR EAX, 10000H
MOV CR0, EAX
STI
}
}
VOID InterruptDisable()
{
__asm
{
CLI
MOV EAX, CR0
AND EAX, NOT 10000H
MOV CR0, EAX
}
}
NTSTATUS RestoreServiceDescriptorTable()
{
NTSTATUS rc;
ULONG NeededSize;
PMODULES pModules;
ULONG KernelBase;
ULONG ActualLength;
HANDLE LinkHandle;
WCHAR NameBuffer[128];
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING LinkString, NameString;
PFILE_OBJECT FileObject;
ANSI_STRING AnsiImageName;
UNICODE_STRING UniImageName, UniModuleName;
IO_STATUS_BLOCK IoStatusBlock;
LARGE_INTEGER CurrentOffset;
ULONG Elfnew, Index, *Address;
NEED_INFO NeedInfo;
PVOID Buffer;
pModules = (PMODULES)&pModules;
rc = NtQuerySystemInformation(SystemModuleInformation, pModules, 4, &NeededSize);
if(rc == STATUS_INFO_LENGTH_MISMATCH)
{
pModules = (PMODULES)ExAllocatePool(PagedPool, NeededSize);
if(!pModules)
return STATUS_INSUFFICIENT_RESOURCES;
rc = NtQuerySystemInformation(SystemModuleInformation, pModules, NeededSize, NULL);
if(!NT_SUCCESS(rc))
{
ExFreePool(pModules);
return rc;
}
}
if(!NT_SUCCESS(rc))
{
return rc;
}
KernelBase = (ULONG)pModules->smi.Base;
LinkString.Buffer = NameBuffer;
LinkString.MaximumLength = sizeof(NameBuffer);
RtlZeroMemory(NameBuffer, sizeof(NameBuffer));
RtlInitUnicodeString(&NameString, L"//KnownDlls//KnownDllPath");
InitializeObjectAttributes(&ObjectAttributes, &NameString, OBJ_KERNEL_HANDLE, NULL, NULL);
ZwOpenSymbolicLinkObject(&LinkHandle, SYMBOLIC_LINK_QUERY, &ObjectAttributes);
ZwQuerySymbolicLinkObject(LinkHandle, &LinkString, &ActualLength);
ZwClose(LinkHandle);
RtlInitAnsiString(&AnsiImageName, pModules->smi.ImageName + pModules->smi.ModuleNameOffset - 1);
RtlAnsiStringToUnicodeString(&UniModuleName, &AnsiImageName, TRUE);
wcscat(NameBuffer, UniModuleName.Buffer);
RtlInitUnicodeString(&UniImageName, NameBuffer);
RtlFreeUnicodeString(&UniModuleName);
ExFreePool(pModules);
rc = IrpCreateFile(&FileObject, FILE_READ_ATTRIBUTES|SYNCHRONIZE, &UniImageName,
&IoStatusBlock, 0, FILE_ATTRIBUTE_NORMAL, FILE_SHARE_READ|FILE_SHARE_WRITE,
FILE_OPEN, FILE_SYNCHRONOUS_IO_NONALERT, NULL, 0);
if(NT_SUCCESS(rc))
{
CurrentOffset.QuadPart = 60;
rc = IrpReadFile(FileObject, &IoStatusBlock, &Elfnew, sizeof(ULONG), &CurrentOffset);
if(NT_SUCCESS(rc))
{
CurrentOffset.QuadPart = Elfnew + 52;
rc = IrpReadFile(FileObject, &IoStatusBlock, &NeedInfo, sizeof(NEED_INFO), &CurrentOffset);
if(NT_SUCCESS(rc))
{
Buffer = ExAllocatePoolWithTag(NonPagedPool, KeServiceDescriptorTable->NumberOfService * 4, 'TDSS');
if (!Buffer)
rc = STATUS_INSUFFICIENT_RESOURCES;
else
{
CurrentOffset.QuadPart = *(PULONG)KeServiceDescriptorTable - KernelBase - (NeedInfo.VOffset - NeedInfo.ROffset);
rc = IrpReadFile(FileObject, &IoStatusBlock, Buffer, KeServiceDescriptorTable->NumberOfService * 4, &CurrentOffset);
if(NT_SUCCESS(rc))
{
for(Index = 0;Index < KeServiceDescriptorTable->NumberOfService;Index++)
{
Address = (PULONG)Buffer + Index;
*Address = *Address - NeedInfo.ImageBase + KernelBase;
}
InterruptDisable();
memcpy((unsigned char *)KeServiceDescriptorTable->ServiceTableBase, Buffer, KeServiceDescriptorTable->NumberOfService * 4);
InterruptEnable();
}
ExFreePoolWithTag(Buffer, 'TDSS');
}
}
}
IrpClose(FileObject);
}
return rc;
}
NTSTATUS DriverEntry( IN PDRIVER_OBJECT theDriverObject, IN PUNICODE_STRING theRegistryPath )
{
RestoreServiceDescriptorTable();
return STATUS_UNSUCCESSFUL;
}
- Kernel下检测还原正确的SSDT
- Kernel下检测还原正确的SSDT
- Kernel下检测还原正确的SSDT
- Kernel下检测还原正确的SSDT
- SSDT的检测与恢复
- 绕过安全软件挂钩SSDT的检测
- 绕过安全软件挂钩SSDT的检测
- 绕过安全软件挂钩SSDT的检测
- 正确还原子类化的窗体,子类化正确还原
- 编译kernel的正确顺序
- RING3下SSDT原始地址的获取
- RING3下SSDT原始地址的获取
- kernel内核栈的检测
- 对付kernel / fsd inline hook/ssdt hook
- Vista下的Shadow SSDT服务函数名表
- 转帖 SSDT HOOK拦截远线程的创建(下)
- SSDT HOOK拦截远线程的创建(下)
- 检测和恢复SSDT HOOK,INLINE SSDT HOOK
- 深入探索Symbian活动对象开发
- [Perl][Mail]关于邮件的几个模块
- velocity学习笔记
- 水一个:组合数学生成作业的程序,算法很垃圾,有兴趣的帮我改一下啊
- TextBox的扩展,支持文件夹和各类文件的拖入,同时可设置过滤文件格式!
- Kernel下检测还原正确的SSDT
- 關于在WIN32調用一些Zw系列的文件操作函數.
- 谷歌人肉搜索引擎
- Linux 2.6.19.x 内核编译配置选项简介
- ZwSetSystemInformation的使用
- Server.Htmlencode用于文本域显示带的html代码
- Linux 2.6.19.x 内核编译配置选项简介
- ORACLE的登陆NOLOG和没NOLOG有差别吗?
- Inline Hook IofCallDriver 截获所有IRP