思路建议:

sys 驱动加载之前,要 CreateService ,试试拦截这个api?或者更底层?

不重启的话,Hook ZwLoadDriver,ZwSetSysteminformation基本就差不多了

createservice,zwloaddriver,zwsetsysteminformation

开发工具: C-C++

另类阻止驱动加载(转)

关于驱动的加载大概有几种方法
1 在WINDOWS下动态加载
2 在WINDOWS启动的时候加载
3 感染系统文件

对于 在WINDOWS启动的时候加载 和 感染系统文件 我们暂时不讨论,玩么只讨论动态加载

一般的加载流程,是这样的:打开服务管理器->创建服务->启动服务->(系统加载驱动)
这个过程系统最终会调用NtLoadDriver来加载驱动(也可以用Ntdll.dll里面的NtSetSystemInformation来加载)

而NtLoadDriver 会向系统插入一个作业,然后等待另外一个系统线程来加载驱动,并等待驱动的加载完成(NtSetSystemInformation也是一样的),然后返回
这样我们就可以HOOK NtLoadDriver和NtSetSystemInformation来阻止驱动加载,但是这个方法已经用烂了,这里我HOOK NtCreateSection来阻止驱动加载
为什么HOOK NtCreateSection呢???
因为在另外一个线程取得消息加载驱动的时候会调用NtCreateSection来映射驱动到内核内存空间

(流程:大概是这样 IoCreateFile(打开驱动文件,将它的第二个参数设置为FILE_EXECUTE | SYNCHRONIZE) -> NtCreateSection(为驱动在内核内存空间创建一个节) ->NtMapViewOfSection(映射驱动到内核内存空间) -> 寻找驱动的DriverEntry,并调用 -> ZwClose(关闭文件句柄) ->然后通知NtLoadDriver(或者NtSetSystemInformation)驱动加载完成->NtLoadDriver(或者NtSetSystemInformation)返回用户层,并通知用户驱动加载完成)

在驱动加载流程中,我们可以看到我们有很多机会劫持驱动的加载
我们可以HOOK NtCreateSection 或者 NtMapViewOfSection 来阻止驱动加载
这里我采用HOOK NtCreateSection的办法阻止驱动加载

以下为代码

#include <ntifs.h>

//声明用到的头文件和结构 宏等
#include "NtCreateSection.h"
#if DBG
#define DriversUnload(Address, p)                             \
 Address->DriverUnload=p;
#else
#define DriversUnload(Address, p)                             \
 Address->DriverUnload=NULL;
#endif
typedef int BOOL;
typedef unsigned int        UINT;
typedef unsigned long       DWORD;
typedef unsigned short      WORD;
typedef void *LPVOID;
typedef unsigned char       BYTE;
typedef DWORD          *PDWORD;
typedef BYTE *PBYTE;
typedef WORD            *PWORD;
#define PAGE_NOACCESS          0x01     
#define PAGE_READONLY          0x02     
#define PAGE_READWRITE         0x04     
#define PAGE_WRITECOPY         0x08     
#define PAGE_EXECUTE           0x10     
#define PAGE_EXECUTE_READ      0x20     
#define PAGE_EXECUTE_READWRITE 0x40     
#define PAGE_EXECUTE_WRITECOPY 0x80     
#define PAGE_GUARD            0x100     
#define PAGE_NOCACHE          0x200     
#define PAGE_WRITECOMBINE     0x400     
#define MEM_COMMIT           0x1000     
#define MEM_RESERVE          0x2000     
#define MEM_DECOMMIT         0x4000     
#define MEM_RELEASE          0x8000     
#define MEM_FREE            0x10000     
#define MEM_PRIVATE         0x20000     
#define MEM_MAPPED          0x40000     
#define MEM_RESET           0x80000     
#define MEM_TOP_DOWN       0x100000     
#define MEM_4MB_PAGES    0x80000000     
#define SEC_FILE           0x800000     
#define SEC_IMAGE         0x1000000     
#define SEC_VLM           0x2000000     
#define SEC_RESERVE       0x4000000     
#define SEC_COMMIT        0x8000000     
#define SEC_NOCACHE      0x10000000     
#define MEM_IMAGE         SEC_IMAGE  
PVOID WriteAddress=NULL;
PMDL pMdl=NULL; 
//声明所需要的函数
NTSYSAPI
NTSTATUS
NTAPI
ZwYieldExecution(
VOID
);
PVOID NTAPI GetJmpAddress(PVOID Fun,BOOL *Call_Code);
NTSTATUS
NTAPI
CallBack_NtCreateSection (
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN PLARGE_INTEGER MaximumSize OPTIONAL,
    IN ULONG SectionPageProtection,
    IN ULONG AllocationAttributes,
    IN HANDLE FileHandle OPTIONAL
    );
NTSTATUS
NTAPI
OldNtCreateSection (
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN PLARGE_INTEGER MaximumSize OPTIONAL,
    IN ULONG SectionPageProtection,
    IN ULONG AllocationAttributes,
    IN HANDLE FileHandle OPTIONAL
    );
void makejmp(LPVOID Fun1,LPVOID Fun2,LPVOID jmp);
#pragma alloc_text(PAGE,makejmp)
#pragma alloc_text(PAGE,OldNtCreateSection)
#pragma alloc_text(PAGE,CallBack_NtCreateSection)
#pragma alloc_text(PAGE,GetJmpAddress)

//所有声明结束

//驱动入口

NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
  )
{
  NTSTATUS Status = 0;
  PDEVICE_OBJECT pDeviceObject = NULL;
//创建设备,这个就不讲解了,大家明白就好,我重点讲解HOOK过程
  Status = IoCreateDevice(
          DriverObject,
          0,
          NULL,
          FILE_DEVICE_UNKNOWN,
          0,
          FALSE,
          &pDeviceObject
          );

if ( NT_SUCCESS(Status) ) {
    KIRQL oldIrql;
    PVOID HookAddress = NULL;

BOOL Hook=0;
    PVOID JmpData=ExAllocatePool(NonPagedPool,5);//申请内存,用来保存内容为Jmp CallBack_NtCreateSection的代码
    DriversUnload(DriverObject,Unload);//设置DriverObject->DriverUnload = Unload;这个宏只有在调试版本的时候才会设置
//DriverObject->DriverUnload = Unload;如果不是调试版本,就会设置DriverObject->DriverUnload = NULL;
    if(JmpData==NULL)
    {
      DbgPrint("HOOK NtCreateSection失败! 内存申请失败\n");
      return Status; 
    }
    memset(JmpData,0x90,5);//初始化JmpData内容为NOP
//将NtCreateSection的头7个字节复制到OldNtCreateSection中来
      pMdl=IoCreateWriteMdlForAddress(OldNtCreateSection,&WriteAddress,7);
    if(pMdl==NULL)
    {
      DbgPrint("HOOK NtCreateSection失败! OldNtCreateSection 写入失败\n");
      ExFreePool(JmpData);
      JmpData=NULL;
                        WriteAddress=NULL;
                        pMdl=NULL;
      return Status;  
    }
    memcpy(WriteAddress,NtCreateSection,7);
    IoFreeMdlForAddress(WriteAddress,pMdl);
    WriteAddress=NULL;
//将NtCreateSection的头5字节变成可写
    pMdl=IoCreateWriteMdlForAddress(NtCreateSection,&WriteAddress,7);
    if(pMdl==NULL)
    {
      DbgPrint("HOOK NtCreateSection失败! NtCreateSection 写入失败\n");
      ExFreePool(JmpData);
      JmpData=NULL;
                        WriteAddress=NULL;
                        pMdl=NULL;
      return Status; 
    }
//检查是否已经被别人HOOK,如果已经被别人HOOK则我们退出HOOK,这里是可以改进的,但是我没有时间写,只能退出HOOK
    HookAddress=GetJmpAddress(NtCreateSection,&Hook);
    if(HookAddress!=NULL)
    {
      DbgPrint("HOOK NtCreateSection失败! 发现NtCreateSection已经被别人HOOK 所以本HOOK退出\n");
      ExFreePool(JmpData);
      JmpData=NULL;
      IoFreeMdlForAddress(WriteAddress,pMdl);
                        WriteAddress=NULL;
                        pMdl=NULL;
      return Status; 
    }
//HOOK NtCreateSection
    if(NT_SUCCESS(ZwYieldExecution()))//先向系统申请CPU时间
    {
    _asm cli//关闭中断
    oldIrql = KeRaiseIrqlToDpcLevel();//提升到DPC级别
    memset(WriteAddress,0x90,7);//修改NtCreateSection的前7个字节为NOP指令
    makejmp(NtCreateSection,CallBack_NtCreateSection,JmpData);//取得 Jmp CallBack_NtCreateSection的代码,代码保存在JmpData中
    memcpy(WriteAddress,JmpData,5);//修改NtCreateSection前5个字节为 Jmp CallBack_NtCreateSection
    KeLowerIrql(oldIrql);//还原到原来的IRQL级别
    _asm sti//开中断

}else
    {
      DbgPrint("申请CPU时间失败,HOOK退出\n");
    }
      ExFreePool(JmpData);
      JmpData=NULL;
      
  }

return Status;
}

//我们的NtCreateSection过滤函数
NTSTATUS
NTAPI
CallBack_NtCreateSection (
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN PLARGE_INTEGER MaximumSize OPTIONAL,
    IN ULONG SectionPageProtection,
    IN ULONG AllocationAttributes,
    IN HANDLE FileHandle OPTIONAL
    )
{
  NTSTATUS Status = 0;
  Status = OldNtCreateSection(
      SectionHandle,
      DesiredAccess,
      ObjectAttributes ,
      MaximumSize ,
      SectionPageProtection,
      AllocationAttributes,
      FileHandle);
    if ( NT_SUCCESS(Status) )
  {
//进行行为判断,如果是要加载驱动,我们就直接返回错误,并关闭句柄,如果不是就返回原来的结果
  if(((DWORD)PsGetCurrentProcessId()==(DWORD)4)|((DWORD)PsGetCurrentProcessId()==(DWORD)8)|((DWORD)PsGetCurrentProcessId()==(DWORD)0))
  {

if((FlagOn(DesiredAccess,SECTION_MAP_EXECUTE))||(FlagOn(DesiredAccess,PAGE_EXECUTE_READ)))
    if((PAGE_EXECUTE==SectionPageProtection)|(AllocationAttributes==SEC_IMAGE))
    {
      ZwClose(*SectionHandle);
      *SectionHandle=NULL;
      return STATUS_ACCESS_DENIED;
    }
  }
  }
  return Status;
}
//用来跳转到原函数的一个裸函数
__declspec(naked)NTSTATUS
NTAPI
OldNtCreateSection (
    OUT PHANDLE SectionHandle,
    IN ACCESS_MASK DesiredAccess,
    IN POBJECT_ATTRIBUTES ObjectAttributes OPTIONAL,
    IN PLARGE_INTEGER MaximumSize OPTIONAL,
    IN ULONG SectionPageProtection,
    IN ULONG AllocationAttributes,
    IN HANDLE FileHandle OPTIONAL
    )
{
  _asm
  {
    nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      nop
      mov eax,NtCreateSection //将原函数地址送入eax
      add eax,7 //eax加7,用来跳过我们的HOOK
      push eax //将eax压入
      ret //跳回原函数
  }
}

//用来生成跳转代码的函数
   void makejmp(LPVOID Fun1,LPVOID Fun2,LPVOID jmp)
{
  BYTE *data=(BYTE *)jmp;
    long dFun1=(long)Fun1;
  long dFun2=(long)Fun2;
  DWORD H;
  data[0]=0xe9;

_asm
  {
  
      mov eax,dFun1
      mov edx,dFun2
      sub edx,eax
      sub edx,5
    mov H,edx
  }

memcpy(&data[1],(void *)&H,4);

}
VOID Unload(
  IN PDRIVER_OBJECT DriverObject 
  )
{
  KIRQL oldIrql;
  while(!NT_SUCCESS(ZwYieldExecution()))//取得CPU时间,如果取得失败,就一直获取,直到成功
  {
  }
  if(pMdl!=NULL)//检查我们是否已经进行过HOOK,//如果我们进行过HOOK 就还原
  {
  oldIrql = KeRaiseIrqlToDpcLevel();
  memcpy(WriteAddress,OldNtCreateSection,7);
  KeLowerIrql(oldIrql);
  IoFreeMdlForAddress(WriteAddress,pMdl);
  }
IoDeleteDevice(DriverObject->DeviceObject);//删除设备

pMdl=NULL;
WriteAddress=NULL;
}
PVOID NTAPI GetJmpAddress(PVOID Fun,BOOL *Call_Code)
{
    PVOID Return=NULL;
  BYTE *data=(BYTE *)Fun;
  DWORD Old=0;
  if(data[0]==0xe9)
  {
    *Call_Code=0;
  }else if (data[0]==0xe8)
  {
    *Call_Code=1;
  }else
  {
    *Call_Code=2;
    return NULL;
  }

memcpy((void *)&Old,&data[1],4);
    _asm
  {
    mov eax,Old
    mov edx,Fun
    add eax,edx
    add eax,5
    mov Return,eax
  }
    return Return; 
}

这个驱动只支持单核心CPU 多核心CPU请自行修改(将所有CPU都提升到DPC级别 以后再进行HOOK)驱动加载流程是看了WIN2K的代码来讲的,WIN2K的代码很长,所以就简单的讲了一下

阻止反外挂GPK/sys加载思路相关推荐

  1. 反沙箱CobaltStrike木马加载器分析

    总结 1.计算Sleep类函数延时时间与实际流逝时间是否匹配可判断环境是否为正常.对沙箱来说,跳过Sleep节约时间成本是有必要的不可省去,但可适当处理GetTickCount类函数,使其与延时时间匹 ...

  2. vfatfs.sys加载

    在DriverEntry中,创建了一个device,并调用IoRegisterFileSystem,将它注册到文件系统类型中. 每个分区类型驱动加载时候,都会调用IoRegisterFileSyste ...

  3. ios App启动加载广告页面思路

    需求 很多app(如淘宝.美团等)在启动图加载完毕后,还会显示几秒的广告,一般都有个跳过按钮可以跳过这个广告,有的app在点击广告页之后还会进入一个广告页面,点击返回进入首页.虽然说这个广告页面对用户 ...

  4. 关于App启动加载广告页面思路

    需求 很多app(如淘宝.美团等)在启动图加载完毕后,还会显示几秒的广告,一般都有个跳过按钮可以跳过这个广告,有的app在点击广告页之后还会进入一个广告页面,点击返回进入首页.虽然说这个广告页面对用户 ...

  5. 懒加载原理以及实现思路

    懒加载的优点 提高前端性能,按需加载图片减轻服务器负担,提高页面加载速度. 懒加载的原理 图片的加载是依赖于src路径,我们可以设置一个暂存器,把图片路劲放到暂存器中,当我们需要这个图片加载显示时,再 ...

  6. Android动态加载黑科技 动态创建Activity模式

    基本信息 Author:kaedea GitHub:android-dynamical-loading 代理Activity模式的限制 还记得我们在代理Activity模式里谈到启动插件APK里的Ac ...

  7. 晨枫U盘维护工具的ISOLINUX模式可加载磁盘映像的探索及USB-ROM引导后安装系统的相关问题

    哎呀,标题似乎写的好乱,以后心情静下来在整理吧.乱七八糟的.~~~ --大头爸爸2010-12-9注 怎么说呢,为了突出这篇文章目的,废话少说,直接将今天一天的调试情况记录一下. 我的目的就是在&qu ...

  8. webpack 异步加载配置文件_Webpack 是怎样运行的?

    在平时开发中我们经常会用到Webpack这个时下最流行的前端打包工具.它打包开发代码,输出能在各种浏览器运行的代码,提升了开发至发布过程的效率. 我们知道一份Webpack配置文件主要包含入口(ent ...

  9. Android Fragment懒加载

    懒加载思路 在Fragment布局创建的时候调用懒加载方法,创建之后将isViewPrepared设置为true. /**标记Fragment视图是否已经初始化完毕*/private boolean ...

最新文章

  1. mysql 不同连接的事务 会嵌套_MySQL——事务
  2. malloc 就是返回开辟内存空间的首地址
  3. OpenCV Laplace point/edge detection拉普拉斯点/边缘检测的实例(附完整代码)
  4. dns服务器漏洞修复,KB4569509:DNS 服务器漏洞 CVE-2020-1350 指南
  5. 如何免费注册Coursera课程
  6. 饥荒进地洞服务器无响应,饥荒联机洞穴设置及常见问题的解决方法
  7. [Unity3D]无缝场景切换解决方案(1) - 简单场景切换
  8. matplotlib plot 分组_Python数据分析模块二:Matplotlib
  9. 第128篇 智能合约改进(ERC721)
  10. 浏览器内置打开方正CEB是文件进行阅读
  11. Java开发微信支付实践
  12. 设计专用黑苹果台式机9代intel平台I59500+微星b360m mortar+蓝宝石rx560
  13. 有限元编程示例matlab + C++
  14. home为什么是地点副词_home为什么可以做副词
  15. 【小月电子】ALTERA FPGA开发板系统学习教程-LESSON8 LCD1602液晶显示
  16. select 获取选择的值
  17. skynet框架应用 (十四) 登录服务
  18. O2优化后,程序freez了(变量的读取过程被优化,使用volatile可解决)
  19. HDU - 6555 The Fool(思维)
  20. 300G,某小屁孩乐疯了

热门文章

  1. Neuron Newsletter 2022-07|新增非 A11 驱动、即将支持 OPC DA
  2. 马克·吐温:十月炒股最危险
  3. .NetWeb前端-大三-零食系统-零食管理
  4. 网游实名制将实施 家长叫好
  5. 数据库连接池(Druid(德鲁伊))
  6. 解决Easywechat授权登录出现重定向页面(Redirecting to https://open.wein.qq.com/...) 直接出现代码 用户体验不好
  7. EXCEL表格中单元格的左上角的绿颜色小三角形怎么添加?怎么消除?
  8. 210322,鑫铂股份,中电电机,中信重工成交量检测
  9. python环绕文字_Java 设置 Word 文档中图片文字环绕方式
  10. 什么是负载均衡(SLB)