Kernel下检测还原正确的SSDT

驱动编程-ssdt hook--系统服务表 整理下自己的驱动编程。 ssdt是系统服务表,每个window系统都会维护自己的系统服务表。我们可以使用kernel detective看下ssdt表。 以openProcess为例子: 开windbg kd> u nt!ZwOpenProcess nt!ZwOpenProcess: 804ff720 b87a000000      mov     eax,7Ah  //7A 8 阅读详情

Kernel下检测还原正确的SSDT 

首先声明这个是菜鸟我的学习日记,不是什么高深文章,高手们慎看.

都好久没写自己的博客了,玩游戏玩到好闷,突然想写一些东西.以前我见到www.rootkit.com上面有人写了怎么在ntkrnlpa.exentoskrnl.exe搜索出正确的SSDT,不过他写的是在User Mode下进行的,那么我就想做到怎么在驱动中也能直接实现搜索正确SSDT.(已经有非常多人写出来了,不过我之前不会,现在逐渐明白,写出来是为了分享,我在网上找不到,可能我笨).

u       还原会造成卡巴等杀软主动防御失效,慎用!病毒除外!哈哈!

 

步骤说明:

1)        NtQuerySystemInformation取得内核模块ntkrnlpa.exentoskrnl.exe的基址KernelBase,获取内核模块的文件名称,到底是ntkrnlpa.exe还是ntoskrnl.exe.

2)        读取ntkrnlpa.exentoskrnl.exe的映象基址ImageBase,.Text节中虚拟偏移Virtual Offset,实际偏移Real Offset.

3)        ntkrnlpa.exentoskrnl.exe读出正确的SSDT: 正确SSDTntkrnlpa.exentoskrnl.exe文件中偏移 = *(PULONG)KeServiceDescriptorTable - KernelBase Virtual Offset + Real Offset.读取长度 = KeServiceDescriptorTable->NumberOfService * 4.

4)        这里读出的内容每4字节就是一个调用的地址,但这样读出的内容还不是SSDT. 计算出正确的SSDT: 4个字节 - ImageBase + KernelBase.

5)        禁用中断 -> memcpySSDT -> 启用中断.

以下是代码了,需要用到我前篇文章写的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;

}

 

PnP 单目相机位姿估计(二):solvePnP利用二维码求解相机世界坐标 前言 原理简介 输入参数准备 1 objectPoints特征点世界坐标 2 imagePoints特征点在摄像头下的像素点坐标 3cameraMatrixdistCoeffs内参矩阵和畸变矩阵 相机世界坐标的求解 1求世界坐标中的点在相机坐标系下的坐标 2求相机在世界坐标中的坐标 3效果求解相机在世界坐标系下的坐标点 4求解代码1.前言  很多时候,当我们利用单目相机获取图像时,往往只能获取图像中 阅读详情

相关推荐

汇川AM系列ethercat控制伺服的使用说明(含转矩模式)

本文以一个实际例子,介绍ethercat伺服驱动器的工作原理,以及在汇川AM系列PLC中,如何点动、定位、速度、转矩控制ethercat伺服。

qq_34047402的博客 5047

获取ntoskrnl的基址

使用NtQuerySystemInformation来检索加载的模块,从加载模块里面搜索出ntoskrnl.exe模块 NTSTATUS Status; PUCHAR BaseAddress = NULL; NTSTATUS ntStatus; PMODULES pModules; ULONG NeededSize; pModules = (PMODULES)&pModules;

十年磨一剑,霜刃未曾试! 1356

钢材性能参数查询软件

钢材性能参数查询软件

Do All In One EXE File Under Win32

文章提交:icelord (icelord_at_sohu.com)希望题目没有语法错误。    Exe可执行,可以使用系统提供的各种服务,do all in one exe看起来是句废话。仅作技术研究,各位不要为几个文字争论。很早就看过高手写过的文章,>、>,今天我也来班门弄斧一把。做后门、木马,现在的技术不知道是什么样的,但是个人认为将他们做到内核之中,将更有威力。当然,这也是把双刃剑。见过一

1319

驱动编程,通过驱动名获取驱动模块地址

//功能:模块名称,地址 ULONG64 GetDirverBase(char* drivername) { NTSTATUS status; ULONG size; char* pDrvName; PSYSTEM_MODULE_INFORMATION moduleinfo; PSYSTEM_MODULE_INFORMATION_ENTRY moduleinfoentry; status = NtQuerySystemInformation(11, &size, NULL, &amp..

追逐光芒,追随内心 635

ZwSystemDebugControl函数

使用ZwSystemDebugControl,可以在ring3下读写内核空间虚拟内存 //读取 MEMORY_CHUNKS QueryBuff; DWORD *address2=new DWORD[dwServices]; QueryBuff.Address = dwKernelBase+dwKiServiceTable; QueryBuff.Data = address2;

mergerly的专栏 3677

Kernel Hooks 1 SSDT by webxeyes

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

240

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 ﹏ 601

SSDT HOOK

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

zqf_office的专栏 765

城里城外看SSDT

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

278

MS11-046

/* * 触发MS11-046 * 来源:azy,http://hi.baidu.com/azy0922/blog/item/053065d197cebfca572c8492.html * 改编:KiDebug,Google@pku.edu.cn * 编译:VC6.0 * 测试环境:原版Windows XP SP3,Windows 2003 SP2,普通用户 */ #include

Yatere的天平秤 1201

[科普]SSDT/SSSDT那些事

哇,看到很多人找SSDT/SSSDT名称很蛋疼,读ntdll啊什么的,最后index还很乱,github上也有相关的工具,关键字是syscall,也是用ntdll的方式.. 这里科普下吧 以win10为例 x86下 找到ssdt表很简单,ida打开找到后交叉下 会找到KiInitSystem INIT:00998E8E A3 48 93 64 00

zhuhuibeishadiao 4039

绕过安全软件挂钩SSDT检测

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

1469

恢复在WIN64上的SSDT钩子

原始位置链接:http://www.weixianmanbu.com/article/57.html  在上一篇文章里我描述了如何在Win64系统上实现SSDTHOOK,有SSDTHOOK,自然也有UNHOOKSSDT的方法,现在我就来讲一下如何实现UNHOOKSSDT。 要恢复SSDT,首先要获得SSDT各个函数的原始地址,而SSDT各个函数的原始地址,自然是存储在内核文件里的。于是,有

qq_36453052的博客 1922
上一篇: 使用IRP进行文件操作
下一篇: Inline Hook NtQueryDirectoryFile
cooblily
博客等级 码龄19年 24粉丝 9原创
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值