首页 > 其他分享 >驱动基础

驱动基础

时间:2024-05-18 17:20:20浏览次数:28  
标签:STRING Unload OBJECT 基础 驱动 pDriver 加载

01Hello World

驱动基础知识

驱动不是进程,本质上和DLL一样是模块

NT驱动:如果绑定设备,不能卸载

WDM驱动:热拔插,可以更新卸载

WDF驱动:简化开发,相当于事件驱动机制,依赖环境

KWDF驱动:内核驱动框架

UWDF驱动:用户驱动框架(支持在用户下运行的)

学的主要是NF和WDM驱动

驱动内存不共享

驱动文件按照0x200对齐,内存按照0x1000对齐

驱动加载方法

  1. 服务加载(官方提供)
  2. 本地加载

服务加载

加载过程

OpenSrcManager->CreateService->StartService->StopService->DeleteService

服务加载是调用Windows所提供的服务,并不是本进程加载,能不能启动是Windows说的算,在R3就可以拦截

例如当用户设置什么策略的时候,就会导致驱动无法加载,可能让注册表都写不了

杀软在拦截模块加载的时候,使用服务加载可以让杀软获取不到启动进程

本地加载

加载过程

Zw/NtLoadDriver->Zw/NtUnloadDriver

需要自己实现创建服务也就是写注册表的过程

本地加载只能在R0拦截

杀软在拦截模块加载的时候,使用本地加载杀软拦截的时候可以直接获得对应的启动进程

代码

#include <ntifs.h>
VOID Unload(PDRIVER_OBJECT pDriver)
{
	DbgPrint("unload\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	pDriver->DriverUnload = Unload;
	DbgBreakPoint();//断点进去windbg
	DbgPrint("TEST_Entry\r\n");
	return STATUS_SUCCESS;
}

介绍

入口点在这,在这里JMP到我们的DriverEntry函数里面

可以看到程序在DbgBreakPoint()的地方自动断下

使用dt pDriver命令查看pDriver结构体

kd> dt pDriver
Local var @ 0x807ee9d8 Type _DRIVER_OBJECT*
0x872925c8 
   +0x000 Type             : 0n4//格式
   +0x002 Size             : 0n168
   +0x004 DeviceObject     : (null) 
   +0x008 Flags            : 2
   +0x00c DriverStart      : 0xac600000 Void//PE头
   +0x010 DriverSize       : 0x6000//驱动的大小(被拉伸后)
   +0x014 DriverSection    : 0x88b567f0 Void
   +0x018 DriverExtension  : 0x87292670 _DRIVER_EXTENSION//驱动拓展
   +0x01c DriverName       : _UNICODE_STRING "\Driver\MyDriver8"//驱动名
   +0x024 HardwareDatabase : 0x843c7270 _UNICODE_STRING "\REGISTRY\MACHINE\HARDWARE\DESCRIPTION\SYSTEM"//注册表路径(和pReg不一样)
   +0x028 FastIoDispatch   : (null) 
   +0x02c DriverInit       : 0xac604000     long  MyDriver8!GsDriverEntry+0//驱动入口点
   +0x030 DriverStartIo    : (null) 
   +0x034 DriverUnload     : 0xac601030     void  MyDriver8!Unload+0
   +0x038 MajorFunction    : [28] 0x84101c0d     long  nt!IopInvalidDeviceRequest+0

查看一下驱动的PE头

   +0x00c DriverStart      : 0xac600000 Void//PE头

查看驱动拓展

   +0x018 DriverExtension  : 0x87292670 _DRIVER_EXTENSION//驱动拓展
kd> dt _DRIVER_EXTENSION 0x87292670
ntdll!_DRIVER_EXTENSION
   +0x000 DriverObject     : 0x872925c8 _DRIVER_OBJECT//指向一个驱动对象
   +0x004 AddDevice        : (null) 
   +0x008 Count            : 0
   +0x00c ServiceKeyName   : _UNICODE_STRING "MyDriver8"//服务名字
   +0x014 ClientDriverExtension : (null) 
   +0x018 FsFilterCallbacks : (null) 

DriverObject

可以发现我们的驱动对象(DriverObject)和我们的驱动的pDriver指向的是一致的

是一个链式结构(A->B->A)

ServiceKeyName

根据驱动的ServiceKeyName可以找到驱动在注册表的路径

services中的MyDriver8

DisplayName:显示名字

ErrorControl:错误控制,当驱动加载失败的时候会有个错误描述

ImagePath:驱动路径

Start:驱动启动类型

Start的值设置为0,则驱动由启动引导器加载,应该跟“随着开机,最先启动”是同一回事;
Start的值设置为1,则驱动由操作系统的I/O子系统加载,即在系统内核初始化时加载;
Start的值设置为2,则驱动/服务在启动后自动加载;
Start的值设置为3,则驱动/服务就是按需手动加载;
Start的值设置为4,驱动/服务就是被禁用的状态

Type:驱动必为1

PUNICODE_STRING

PUNICODE_STRING是一个结构体

typedef struct _UNICODE_STRING {
    USHORT Length;//当前字符串长度
    USHORT MaximumLength;//申请出来的大小,最大长度
#ifdef MIDL_PASS
    [size_is(MaximumLength / 2), length_is((Length) / 2) ] USHORT * Buffer;
#else // MIDL_PASS
    _Field_size_bytes_part_opt_(MaximumLength, Length) PWCH   Buffer;
#endif // MIDL_PASS
} UNICODE_STRING;
typedef UNICODE_STRING *PUNICODE_STRING;
typedef const UNICODE_STRING *PCUNICODE_STRING;

打印PUNICODE_STRING类型的字符串的时候要使用%wZ来打印

小技巧

当驱动注册后可以通过cmd命令行运行

net start 驱动服务名

停止时使用net stop 驱动服务名停止

驱动卸载的时候可以使用sc delete 驱动服务名将驱动卸载

课后题

火哥要证明驱动内存不共享,要求是用A驱动读B驱动的值,看看能否成功

B驱动代码,打印出了x的地址

#include <ntifs.h>

int x = 100;
VOID Unload(PDRIVER_OBJECT pDriver)
{
	DbgPrint("unload\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	pDriver->DriverUnload = Unload;
	DbgBreakPoint();
	DbgPrint("----%x------\r\n",&x);
	return STATUS_SUCCESS;
}

A驱动代码,读出了B驱动内的x的值

#include <ntifs.h>

int *x = 0xb42cb000;
VOID Unload(PDRIVER_OBJECT pDriver)
{
	DbgPrint("unload\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	pDriver->DriverUnload = Unload;
	DbgBreakPoint();
	DbgPrint("----%i------\r\n", *x);
	return STATUS_SUCCESS;
}

VS-工具-代码片段

<?xml version="1.0" encoding="utf-8"?>
<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
	<CodeSnippet Format="1.0.0">
		<Header>
			<Title>DriverMain</Title>
			<Shortcut>DriverMain</Shortcut>
			<Description>DriverMain</Description>
			<Author>MuRKuo</Author>
			<SnippetTypes>
				<SnippetType>Expansion</SnippetType>
				<SnippetType>SurroundsWith</SnippetType>
			</SnippetTypes>
		</Header>
		<Snippet>
			<Declarations>
				<Literal>
					<ID>expression</ID>
					<ToolTip>要计算的表达式</ToolTip>
					<Default>true</Default>
				</Literal>
			</Declarations>
			<Code Language="cpp"><![CDATA[#include <ntifs.h>
VOID Unload(PDRIVER_OBJECT pDriver)
{
	DbgPrint("unload\r\n");
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriver, PUNICODE_STRING pReg)
{
	pDriver->DriverUnload = Unload;
	//DbgBreakPoint();
	DbgPrint("TEST_Entry\r\n");
	return STATUS_SUCCESS;
}]]>

			</Code>
		</Snippet>
	</CodeSnippet>
</CodeSnippets>

C:\Users\MuRKuo\Documents\Visual Studio 2019\Code Snippets\Visual C++\My Code Snippets\DriverMain.snippet

标签:STRING,Unload,OBJECT,基础,驱动,pDriver,加载
From: https://www.cnblogs.com/murkuo/p/18199512

相关文章

  • 驱动基础2
    02驱动基础基础类型基础数据类型在驱动中用基础数据类型需要用大写R3R0intINTshortSHORTcharCHARlongLONGunsightedcharUCHAR指针是在前面加PNTSTATUSNTSTATUS本质上是LONGNTSTATUS>=0成功NTSTATUS<0失败判断NTSTATUS是否成......
  • 驱动断链
    03驱动断链获取驱动信息的途径是从Driver和FileSystem两个目录下获得的正常情况下我们自己做驱动遍历只能便利Driver下的所有驱动,也就是驱动链表里的驱动分析这里我们F12进去找一下DRIVER_OBJECT的结构typedefstruct_DRIVER_OBJECT*PDRIVER_OBJECT;WinDbg里dt一下kd......
  • Angular-测试驱动开发-全-
    Angular测试驱动开发(全)原文:zh.annas-archive.org/md5/60F96C36D64CD0F22F8885CC69A834D2译者:飞龙协议:CCBY-NC-SA4.0前言本书将为读者提供一个关于JavaScript测试驱动开发(TDD)的完整指南,然后深入探讨Angular的方法。它将提供清晰的、逐步的示例,不断强调TDD的最佳实......
  • [Java基础复习]注解
    一、什么是注解注解是JDK1.5才引入的,Java增加了对元数据(描述数据的数据)的支持,也就是注解。注解可以标注在类,成员变量,方法、形参上等。注解可以做到在不改变代码逻辑的前提下在代码中嵌入补充信息。这些信息被保存在注解的“name=value”键值对中。框架=反射+注解+设计模式......
  • MongoDB基础知识梳理笔记
    1、mongodb是什么?MongoDB是由C++语言编写的,是一个基于分布式文件存储的开源数据库系统。在高负载的情况下,添加更多的节点,可以保证服务器性能。MongoDB旨在给WEB应用提供可扩展的高性能数据存储解决方案。MongoDB将数据存储给一个文档,数据结构由键值(key=>value)对组成......
  • 基础知识学习
    基础知识学习1.打开cmd的方式:#图形化:菜单—命令提示符。#win+r:输入cmd,打开控制台。#shift+文件夹右键选项中选择打开。#资源管理器地址栏:输入cmd。2.常用的DOS命令:#盘符切换:盘符+:#查看当前目录下的所有文件:dir#切换目录:cd(changedirectory)#清理屏幕:cls(clearscr......
  • 汇编语言基础及编译原理(网安)
    汇编语言基础及编译原理二进制基础程序的编译汇编与链接从c语言到可执行程序源代码.c编译汇编代码.s汇编目标文件.o链接(静态库直接拷贝,动态库运行时通过动态链接方式加载)可执行文件(p)x86机器指令入门栈一种先进后出的数据结构被用于保存函数的局部(保存局部变量和......
  • java基础 韩顺平老师的 异常 自己记的部分笔记
    443,异常处理入门 packagecom.hspedu.exception_;publicclassException{publicstaticvoidmain(String[]args){intnum1=10;intnum2=0;//老韩解读//1,num1/num2=10/0//2,当执行到num1/num2,因为num2......
  • python基础环境
    刚开始接触并学习一门开发语言,带着不求甚解的想法,其实也挺有好处的:我并不是所有的东西都知道,但是代码跑起来了。但是时间久了,还是带着这种想法,可能就会遇到一些棘手的问题。比如电脑上不知不觉已经安装了多个python版本,python3.8/3.10/3.11,甚至一些软件中也集成有python解释器;那......
  • 内网渗透 Metasploit(MSF)基础使用
    免责申明以下内容仅供学习使用,非法使用造成的问题由使用人承担攻击思路漏洞探测(信息收集)<-fsacn,namp|漏洞利用<-工具(msf等)|获取服务器权限MSF使用Metasploit就是一个安全漏洞检测工具。它的全称叫做TheMetasploitFramework,简称MSF。MSF主要用于攻击非web端口1......