Kernel下检测还原正确的SSDT

驱动编程-ssdt hook--系统服务表 整理下自己的驱动编程。 ssdt是系统服务表,每个window系统都会维护自己的系统服务表。我们可以使用kernel detective看下ssdt表。 以openProcess为例子: 开windbg kd> u nt!ZwOpenProcess nt!ZwOpenProcess: 804ff720 b87a000000      mov     eax,7Ah  //7A 8 阅读详情
 
步骤说明:
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;
}
 
深入解析KswordARK:Windows内核级Rootkit检测与系统可观测性实战 在操作系统安全领域,内核态与用户态的权限隔离是系统稳定性的基石,但也为Rootkit等高级威胁提供了藏身之所。Rootkit通过挂钩系统调用表或直接操作内核对象,能够欺骗用户态安全工具,实现进程、模块和网络连接的隐藏。为了对抗这种深度隐匿,Anti-Rootkit工具应运而生,其核心原理是直接以内核驱动形式运行,获取与恶意软件同等的Ring 0权限,从而绕过所有用户态钩子,从源头读取未被篡改的内核数据结构。这种技术不仅对恶意软件检测至关重要,也为内核开发、系统调试和高级威胁分析提供了终极可观测性。Kswor 阅读详情

相关推荐

pyautogui库详细教程,逐行注释(附项目实战:基于图像识别实现崩坏星穹铁道自动化测试)

本文包含了pyautogui的使用方法与常见问题指南,随文附带对游戏实现的自动化项目源码与说明文档

m0_53043024的博客 1万+

「 C++ 函数 」 “ZeroMemory()使用”讲解

一.前言 ZeroMemory() 常被称为清零函数。它也被定义为RtlZeroMemory宏,更多信息可以通过Winbase.h与 Winnt.h这两个头文件获得。 二.讲解 1.函数的功能 ZeroMemory()函数 用0来填充一块内存区域。 2.函数使用 ①.原型: void ZeroMemor...

Robot_Starscream的博客 1万+

claude使用教程

提供了三种模型:claude,codex, gemini,三种模型都共用同一个apikey, 有开发需求使用claude效果较好,知识问答等场景gemini效果会更好些,本文只提供了claude的安装方式,剩下两种按需按照以下参考链接安装下即可,安装有问题参考文档:https://www.aicodemirror.com/dashboard/official-installation/macos-linux (不需要挂梯子,自己手机号注册就好)

lichao19871216的博客 3493

[原创]反汇编分析 RtlZeroMemory (RtlZeroMemory)函数

刚学完汇编语言,就想试着去反汇编一个程序,后来就分析了RtlZeroMemory这个函数的工作原理了,并没有去仔细考究,只是分析了下流程,有分析不当或者遗漏的地方请慷慨指教 RtlZeroMemory作用是用0来填充一块内存区域 有两个参数,第一个参数指向一块准备用0来填充的内存区域的开始地址;第二个参数是准备用0来填充的内存区域的大小 下面开始调试分析这个函数的工作流程, ...

weixin_33785972的博客 705

Zemax非序列模式新手入门:从零搭建一个抛物面反射镜系统(含灯丝光源与探测器设置)

本文详细介绍了如何在Zemax非序列模式下从零搭建抛物面反射镜系统,包括灯丝光源配置、反射镜建模和探测器设置等关键步骤。通过实战指南,帮助光学设计新手快速掌握非序列模式的应用技巧,特别适合处理复杂光线传播场景如反射镜系统和杂散光分析。

weixin_28717431的博客 436

MODBUS通讯不求人:手把手教你用三菱FX2N控制士林变频器

本文详细介绍了如何使用三菱FX2N PLC通过MODBUS协议控制士林变频器,涵盖硬件连接、参数配置、程序设计及通讯优化等关键步骤。特别针对没有内置MODBUS函数块的老款PLC,提供了CRC校验和稳定数据交换的实用解决方案,帮助工程师快速实现工业自动化设备的高效通讯。

v4w5x6的博客 226

从ntoskrnl文件中直接查找ssdt各个参数

 bool LoadNtosFile(PWCHAR szNtosFullPath, PVOID *FileBase, ULONG *FileSize){    NTSTATUS st;    /************************************************************************/    /* 读取文件镜像                 

1291

【QNX Hypervisor 2.2 用户手册】2.6 处理qvm终止

你可以注册通知,以在qvm进程实例退出时得到通知。这样你就可以采取相应的措施来响应这种终止事件。

从0到1,突破自己 1106

绕过安全软件挂钩SSDT的检测

很多安全软件都靠挂钩SSDT中的函数来检测恶意代码,就拿卡巴举例吧,他挂了NtCreateKey来检测注册表的创建,NtCreateThread和NtResumeThread/NtWriteVirtualMemory来检测远程注入, 等等,这些钩子让我们后期的动作很可能暴露,怎么样才能为所欲为呢?我这里提一种方案:1. 首先在用户态读取NTOSKRNL.EXE,找出原始的SSDT的位置,提交到内核

1470

c语言实现求一个矩阵特征值和特征向量

前言 求矩阵的特征值,主要是用的QR分解,在我的有一次博客里,我已经详细地给出了计算的过程,大家有兴趣可以去看下,经过几天的钻研,终于完成了整个的eig算法。下面我将把我的整个代码附上,有不懂的可以问我,欢迎一起讨论学习! 这是对上一次的修改版,上一次写的程序是在C++编译环境下编译的,所以放在c里面编译有些会出错。 最后,如果有不对的地方希望大...

qq_36417014的博客 2万+

Allegro技巧----相同模块复用实现快速布局

使用Allegro软件进行PCB Layout设计时,当电路图中有很多路相同的模块,使用模块复用的的操作方法,可以显著提高工作效率,同时也可以使PCB布局在整体上显得美观。 如图,有8个相同的ADC采样电路模块,它们在原理图中的电路也是一样的,对于这多个相同的电路模块,如果一个个元器件布局很明显做了很多重复机械的劳动,效率低下;但是强大的Allegro软件早就考虑到了这点,只需要在PCB中做好其中的一个,则其余相同的模块通过复用的方式,可以快速完成,方便省事还美观。 具体步骤: 1.首先完成一个模块的PC

sinat_15677011的博客 5655

Kernel Hooks 1 SSDT by webxeyes

 用户态的钩子比较容易被发现,比较优雅的解决办法就是使用内核态钩子内核态是一个高虚拟地址区域,在x86中地址从0x80000000开始,如果/3GB开关打开的话,起始地址为0xC000000通常情况下,进程不能读写内核空间内存的,不过一些进程可以通过调试权限或者一些gates进入内核态对于我们来说,将通过驱动程序来操作内核态数据 SSDT HOOKINGwindows执行体

242

2ED2410-EM:12v / 24v智能模拟高侧MOSFET栅极驱动器

12v / 24v智能模拟高侧MOSFET栅极驱动器。2ED2410-EM具有输入CPP和CPN的电压比较器。该比较器可用于基于任何模拟电压触发SAFESTATE模式,甚至是外部电压2ED2410-EM。CPP为比较器的正输入,CPN为负输入。VcPREF可以通过微控制器进行调节,也可以通过板载电源芯片(如英飞凌SBC)或简单的分压器在限制VcP(REF)内进行固定,以保持稳定性。使用此比较器允许2ED2410-EM进入SAFESTATE并独立于微控制器关闭MOSFET。

让学习成为一种习惯 2190

SSDT HOOK

打造自己的HOOK引擎 之一 --- SSDT HOOK引擎 SSDT HOOK已经是老生常谈的话题了,这里我就不对其进行介绍了,其实HOOK技术已经被大牛们分析的淋漓尽致,无以复加了,我也只是个初学者,失误之处,还望大牛们多多指教 读者可以通过后面的参考连接得到更多的关于SSDT HOOK的信息 我就相当于在这里对论坛的关于SSDT的精华贴做个总结了 呵呵 【原创】扫盲贴,H

zqf_office的专栏 766

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

ring3 恢复SSDT

<br />// IATHOOK.cpp : Defines the entry point for the console application. // #include "stdafx.h" #include <windows.h> #include <stdio.h> #include <iostream> #include <stdio.h> #include <stdlib.h> #include <aclapi.h> using names

Rootkit ﹏ 605

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

城里城外看SSDT

 From 李马,Ring 0下恢复SSDT Hook 真的很强大。引子2006年,中国互联网上的斗争硝烟弥漫。这时的战场上,先前颇为流行的窗口挂钩、API挂钩、进程注入等技术已然成为昨日黄花,大有逐渐淡出之势;取而代之的,则是更狠毒、更为赤裸裸的词汇:驱动、隐藏进程、Rootkit……前不久,我不经意翻出自己2005年9月写下的一篇文章《DLL的远程注入技术》,在下面看到了一

279

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

从内核任意读写到SYSTEM权限:BYOVD Astra64 Shadow SSDT劫持10步详解,竟能绕过HVCI/VBS

BYOVD(Bring Your Own Vulnerable Driver,"自带漏洞驱动")攻击的核心,是利用系统中残留的**有漏洞的已签名内核驱动**获得**内核任意读写**能力,再将其升级为 SYSTEM 权限。BYOVD 仓库中的 [Astra64-RW](https://link.gitcode.com/i/66418aa71fad5122880ce9894ac265cf) 模块就是一

gitblog_00478的博客 493

KswordARK:最强开源内核工具实战,从编译到Rootkit检测

在系统安全领域,内核态与用户态的权限差异是理解高级威胁对抗的基础。内核作为操作系统的核心,拥有最高权限(Ring 0),而Rootkit等恶意软件常驻于此,通过挂钩系统服务描述符表(SSDT)、操纵内核对象等方式实现深度隐藏,使得传统用户态工具失效。反Rootkit(ARK)工具的价值正在于以内核驱动形式加载,获得同等权限,直接遍历和检测被隐藏的进程、模块及钩子,从而揭示系统真实状态。这类技术对于恶意软件分析、系统调试和安全研究至关重要。本文聚焦于实战应用,以开源工具KswordARK为例,详细解析其针对S

weixin_34337381的博客 361

Anthropic Cybersecurity Skills 实战:用 Volatility 内存取证与交叉视图检测揪出隐藏的 Rootkit

本指南基于 Anthropic Cybersecurity Skills 仓库中的 `detecting-rootkit-activity` 技能([skills/detecting-rootkit-activity/SKILL.md](https://link.gitcode.com/i/744f9f87e93e6949ff5054a6f9ccd793))展开,面向"标准工具(任务管理器、net

gitblog_00171的博客 398

YJX_Driver_011_驱动保护原理实战__IDA

1、 【00:28】认识Win32子系统   【02:02】WinAPI 一般分为3类:USER函数、GDI函数、Kernel函数     【02:38】GDI --> 物理设备上执行绘图操作 --> win32k.sys     【02:55】win32k.sys 一般我们很少用到,常用的是 ntkrnlpa.exe 和 ntkrnlpa.lib (kernel32.dll)...

weixin_30651273的博客 382
上一篇: 下载指定代理文件调用IE使用代理访问指定网站的代码
下一篇: 關于在WIN32調用一些Zw系列的文件操作函數.
iiprogram
博客等级 码龄25年 1068粉丝 1515原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值