
Windows 驱动开发
Windows 驱动开发
(-: LYSM :-)
这个作者很懒,什么都没留下…
展开
-
[VT 虚拟化] 资料整合
请转到以下链接食用 (* ̄(oo) ̄)intel:x86架构VT虚拟化(一):基本概念和流程简介intel:x86架构VT虚拟化(二):核心代码入门介绍intel:x86架构VT虚拟化(三):x64多核代码介绍intel:x86架构VT虚拟化(四):x64 无痕hook/shadow walker/页面读写分离...原创 2021-06-10 14:57:25 · 744 阅读 · 0 评论 -
[驱动开发] 驱动隐藏 - driveEntry返回失败
常见隐藏驱动的方式:驱动模块断链调用MiProcessLoadEntry删除驱动对象(据说不会触发PG)清理MmUnloadDriver List 和 PiDDBCacheTable两处driveEntry返回失败驱动模块加载后立即卸载今天介绍一种driveEntry返回失败隐藏驱动的方法 —— DriverEntry返回失败原理windows会根据DriverEntry的返回值判断驱动是否加载成功。如果返回成功,会在注册表详细记录,并将sys文件复制到System32/drivers转载 2021-06-10 11:30:13 · 1816 阅读 · 1 评论 -
[Windows 驱动开发] 获取时间
开机时间void MyGetTickCount(PULONG msec) //进行传出{ LARGE_INTEGER la; ULONG MyInc; MyInc = KeQueryTimeIncrement(); //返回滴答数 //下方 KeQueryTickCount 的宏的原型. KeQueryTickCount(&la); la.QuadPart *= MyInc; la.QuadPart /= 10000;转载 2021-04-15 20:00:57 · 747 阅读 · 0 评论 -
[Windows 驱动开发] 清内存强杀进程
原理Attach 到进程进行内存清零.这里提供了两种方法.原理是一样KeAttachProcess方法 与 KeStackAttachProcess方法. 其中第一种属于旧方法了.根据MSDN所说API已经升级为了KeStackAttachProcess#include <ntifs.h>NTKERNELAPI UCHAR* PsGetProcessImageFileName(IN PEPROCESS Process); //未公开的进行导出即可NTKERNELAPI VOID转载 2021-04-15 11:54:35 · 1336 阅读 · 1 评论 -
[Windows 驱动开发] 获取驱动详细信息
驱动对象在内核中. 每一个驱动模块都是一个驱动对象. 都有一个 DRIVER_OBJECT结构体代表。驱动对象结构如下:typedef struct _DRIVER_OBJECT { CSHORT Type; CSHORT Size; // // The following links all of the devices created by a single driver // together on a list, and the Flags word转载 2021-04-15 11:43:45 · 768 阅读 · 0 评论 -
[Windows 驱动开发] 使用 verifier 测试驱动 bug
同时按win + R调出窗口,在窗口中输入cmd,打开cmd命令窗口,并输入verifier,敲击回车。在进入了verifier界面后,我们选择第二个单选框,并点击下一步。勾选除了除“随机低资源模拟”其他全部的测试类型。点击下一步。我们选择最后一个单选框,点击下一步。因为微软自己的驱动程序很少出现问题,所以为了节省时间,大家可以只勾选由<未知>提供程序的驱动程序来进行验证。当然全选也是没有问题的。在点击完成后,会提示必须重新启动电脑后,才能生效,这是自己手动重新启动就可以了。在转载 2021-04-15 11:32:35 · 725 阅读 · 0 评论 -
[Windows 驱动开发] 驱动中获取函数地址
跟ring3 GetProcAddress相似.PVOID MmGetSystemRoutineAddress( PUNICODE_STRING SystemRoutineName);驱动程序可以使用这个例程来确定一个例程在特定版本的Windows上是否可用。它只能用于内核或HAL导出的例程,不能用于任何驱动程序定义的例程。...原创 2021-04-15 11:18:09 · 914 阅读 · 0 评论 -
[Windows 驱动开发] 驱动判断地址是否有效
R0 层BOOLEAN MmIsAddressValid( PVOID VirtualAddress);即使 MmIsAddressValid 返回 TRUE,访问地址也可能导致页错误,除非内存已锁定或地址是有效的非分页池地址。原创 2021-04-15 10:23:44 · 965 阅读 · 0 评论 -
[windows 驱动开发] 不触发 PG 的 Object Protect
首先,最高效的应该是这种办法,但是最不稳定的也是这种办法。 虽然不会触发 PG ,但是由于调用方太多了,所以动不动炸进程或者蓝屏。进程对象(EPORCESS)->PsProcessType线程对象(PETHREAD)->PsThreadType文件对象(FileObject)->IoFileObjectType…具体流程不分析大概是这样,创建对象->Ob插入对象->系统访问(对象,这些对象是分配出来的不归PG管理)->根据对象Index->寻找对应Ob回调转载 2021-04-13 09:55:13 · 1146 阅读 · 0 评论 -
[windows 驱动开发] r0 枚举进程
#include "ntddk.h"typedef enum _SYSTEM_INFORMATION_CLASS { SystemBasicInformation, // 0 SystemProcessorInformation, // 1 SystemPerformanceInformation, // 2 SystemTimeOfDayInformation,转载 2021-04-12 20:27:26 · 599 阅读 · 0 评论 -
[Windows驱动开发] 驱动中的字符串操作
初始化UNICODE_STRING u_src;RtlInitUnicodeString(&src,"hello");原创 2021-04-07 14:50:30 · 784 阅读 · 0 评论 -
[windows 驱动] 获取当前进程名
PEPROCESS ep = NULL;if (STATUS_SUCCESS == PsLookupProcessByProcessId(PsGetCurrentProcessId(), &ep)){ char* name = PsGetProcessImageFileName(ep); if (strcmp(name, "notepad.exe") == 0) { // do something ... }}原创 2021-03-25 20:07:40 · 2033 阅读 · 0 评论 -
[驱动开发] wcsstr 蓝屏
原因wcsstr是根据最后一个字符是否为NULL判断字符串是否完成的 ,而 UNICODE_STRING,并不是应用层开发意义上的字符串,也不一定是以NULL结束。解决方案RtlStringCbCopyNW 复制 buffer 到 wchar* 中,在进行比较WCHAR pszDest[MAX_PATH] = { 0 };if (STATUS_SUCCESS != RtlStringCbCopyW(pszDest, MAX_PATH, FltObjects->FileObject->F原创 2021-03-02 16:59:01 · 536 阅读 · 0 评论 -
[驱动开发] 手写 r0 hook(NtOpenProcess 为例)
inlineHook的原理:为了方便好理解,一些变量名和函数名在这里使用中文命名,有些编译器不支持中文命名,在这里要注意(我的是VS2019)hook.h:#pragma once#include<ntifs.h>#include<ntddk.h>#pragma intrinsic(__readmsr) //SSDT的结构typedef struct _SYSTEM_SERVICE_TABLE { PLONG ServiceTableBase; PVOI转载 2020-11-09 16:23:55 · 1727 阅读 · 0 评论 -
[Windows 驱动开发] MDL 绕过内核写保护
背景通常,我们在内核中修改内存的时候,都是通过修改 CR0 寄存器,关闭内存写保护属性,然后再写入内存的方式来修改内存。我个人不喜欢这种方式,因为总感觉我们使用没有线程接口函数的方法,总感觉不太稳定。实现过程内存描述符列表 (MDL) 是一个系统定义的结构,通过一系列物理地址描述缓冲区。MDL的全称是 Memory Descriptor List,即内存描述符表。可以通过MDL描述一块内存区域,在MDL中包含了该内存区域的起始地址、拥有者进程、字节数量、标记等信息。MDL 是用来建立一块虚拟地址空间转载 2020-08-31 23:47:07 · 1377 阅读 · 0 评论 -
[Windows 驱动开发] MDL 共享内存,实现 r0 和 r3 通信
背景默认情况下,进程内存有一半为内核所有,一半为进程本身所有。但是因为 r3 的进程在不断的切换,所以不能在 r0 直接分配一个低位的内存(你不知道现在正在哪个进程的高位中)。当然,使用 KeStackAttachProcess 附加到指定的进程上操作内存(读/写),最后再使用 KeUnstackDetachProcess 脱离进程,这样也可以实现 r0 和 r3 通信,但更推荐使用 MDL 的方式对将同一块物理内存同时映射到 r0 和 r3,这样我们只需要使用 DeviceIoControl 向驱动发原创 2020-08-31 23:39:39 · 2299 阅读 · 1 评论 -
[Windows 驱动开发] object hook
内核对象种类名称类型Job、Directory对象目录中的路径SymbolLink符号链接Section内存映射文件PortLPC端口IoCompletionIo完成端口File文件(并非专指磁盘文件)Mutex、Event、Semaphore、Timer同步对象Key注册表中的键Token用户/组令牌Process、Thread进程线程Pipe管道Mailslot邮件槽Debug调试端口原创 2020-08-30 22:36:05 · 672 阅读 · 0 评论 -
[x64驱动] - WFP网络监控驱动
背景WFP 是微软推出来替代 TDI HOOK、NDIS HOOK 等拦截网络通信的方案,WFP 的框架非常庞大,在 RING3 和 RING0 各有一套类似的函数,令人兴奋的是,即使在 R3 使用 WFP,也可以做到全局拦截访问网络。本文介绍利用 WFP 拦截指定进程访问网络,或拦截对指定 IP 地址/端口的访问。原理一个标准的 WFP 程序大体是这样子的使用 FwpmEngineOpen 开启 WFP 引擎用 FwpmTransactionBegin 设置对网络通信内容的过滤权限用转载 2020-08-20 16:15:00 · 3103 阅读 · 1 评论 -
x64驱动操作注册表
创建注册表目录HANDLE create_regedit_dir(UNICODE_STRING registryPath) { // 初始化 OBJECT_ATTRIBUTES objectAttributes = { 0 }; InitializeObjectAttributes( &objectAttributes, // 返回 OBJECT_ATTRIBUTES 结构体指针 ®istryPath, // 注册表路径 OBJ_CAS原创 2020-08-04 17:21:55 · 539 阅读 · 0 评论 -
WinDbg 与被调试机的通信过程
原文摘自百度百科,讲实话这是我在百科里看到的最良心的文,可惜百科也是抄的别人的 ????。WinDBG和用户调试器一点很大不同是内核调试器在一台机器上启动,通过串口调试另一个相联系的以Debug方式启动的系统,这个系统可以是虚拟机上的系统,也可以是另一台机器上的系统(当然也可以是本地内核调试,不需要第二台机器)。windbg 提供的调试功能并不是都集成在了程序本身,很多功能被 windows集成进了内核,WinDBG 只是用来作为 “通讯工具” ,来让被调试机器和本机保持联系。当异常发生于内核态下,会调转载 2020-07-17 18:46:40 · 427 阅读 · 0 评论 -
x64驱动 关闭&开启 写时保护
背景在内核里想要写入“别人的”内存(一般指 NTOS 等系统模块的内存空间),需要遵守一个规则 : IRQL和内存保护。IRQL称为中断请求级别,从0~31 共32个级别内存保护可以打开和关闭,如果在内存处于保护状态时写入,会导致蓝屏一般来说,要写入“别人的”内核内存,必须关闭内存写保护,并把 IRQL提升到 2 才行(绝大多数候时候 IRQL 都为 0 ,当IRQL=2时,会阻断大部分线程执行,防止执行出错)。内存是否处于写保护的状态记录在 CR0 寄存器上,因此直接修改CR0寄存器的值即可原创 2020-07-06 18:17:50 · 1808 阅读 · 0 评论 -
x64 驱动 创建 dpc 定时器
初始化KTIMER my_timer;KDPC KiTimerExpireDpc;KTIMER:typedef struct _KTIMER { DISPATCHER_HEADER Header; ULARGE_INTEGER DueTime; LIST_ENTRY TimerListEntry; struct _KDPC *Dpc;#if !defined(KENCODED_TIMER_PROCESSOR) ULONG Processor;#en原创 2020-07-06 17:51:51 · 453 阅读 · 0 评论 -
x64驱动 遍历驱动模块
_LDR_DATA_TABLE_ENTRY(未导出)以下是win10 1803(x64) 上的 _LDR_DATA_TABLE_ENTRY:lkd> dt _LDR_DATA_TABLE_ENTRY nt!_LDR_DATA_TABLE_ENTRY +0x000 InLoadOrderLinks : _LIST_ENTRY // 指向下一个 _LDR_DATA_TABLE_ENTRY 的 InLoadOrderLinks 成员 +0x010 InMemoryOrderL原创 2020-07-02 10:34:20 · 2399 阅读 · 0 评论 -
驱动使用 MDL 方式读写内存
背景通常,我们在内核中修改内存的时候,都是通过修改 CR0 寄存器,关闭内存写保护属性,然后再写入内存的方式来修改内存。我个人不喜欢这种方式,因为总感觉我们使用没有线程接口函数的方法,总感觉不太稳定,而且,在 64 位程序下,CR0 方式不再适用了。所以,我强烈推荐在内核下使用 MDL 方式来修改内存,在 32 位内核和 64 位内核下同样有效。实现过程内存描述符列表 (MDL) 是一个系统定义的结构,通过一系列物理地址描述缓冲区。MDL的全称是 Memory Descriptor List,即内存转载 2020-06-24 16:18:16 · 7148 阅读 · 0 评论 -
驱动程序使用 EVENT 主动和应用程序通信
背景用户层程序使用 DeviceIoControl 将 IOCTL 控制码、输入缓冲区、输出缓冲区传入到内核;内核响应 IRP_MJ_DEVICE_CONTRL 消息,并从 IRP 中获取传入的 IOCTL 控制码、输入缓冲区、输出缓冲区,以此实现数据的交互。但是,当内核层想主动传递数据到用户层,用户层又怎样才能知道呢?因为只有用户层知道内核层有数据输出的时候,它才会调用 DeviceIoControl 函数去获取数据。所以,本文要介绍的就是基于事件 EVENT 实现的同步框架,可以解决这个的问题。函转载 2020-06-24 14:20:47 · 2505 阅读 · 0 评论 -
创建系统回调实现行为监控
请转到以下链接食用 ???????? :基于ExRegisterCallback实现监控系统时间的修改???? :基于ObRegisterCallbacks实现的线程和进程监控及其保护???? :基于CmRegisterCallback实现监控监控注册表并拒绝注册表操作???? :基于PsSetLoadImageNotifyRoutine实现监控模块加载并卸载已加载模块???? :基于PsSetCreateProcessNotifyRoutineEx实现监控进程创建并阻止创建...原创 2020-06-24 11:43:34 · 533 阅读 · 0 评论 -
基于进程 EPROCESS - ActiveProcessLists 枚举进程,并通过摘链隐藏进程
实现原理进程 EPROCESS 结构存储着进程一切信息,所以这个结构体很庞大,而且,不同系统, EPROCESS 结构定义也不相同,它里面的一些成员的偏移也不是固定一成不变的。可使用函数 PsGetCurrentProcess 获取当前进程结构 EPROCESS; PsGetProcessId 从 EPROCESS 结构中获取进程的 PID 信息;使用 PsGetProcessImageFileName 函数,从 ERPROCESS 结构中获取进程的名称信息。其中,EPROCESS 结构中的成员 Ac转载 2020-06-24 11:12:17 · 978 阅读 · 0 评论 -
使用 PspTerminateThreadByPointer 强制结束进程
实现过程我们知道,线程是进程中执行运算的最小单位,是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。也就是说,当一个进程中的所有线程都被结束的时候,这个进程也就没有了存在的意义,也随之结束了。这,便是我们本文介绍的这种强制杀进程的实现原理,即把进程中的线程都杀掉,从而让进程消亡,实现间接杀进程的效果。Windows转载 2020-06-24 10:58:41 · 2104 阅读 · 1 评论 -
HOOK SSDT,获取 SSDT 函数地址
背景我们要开始向大家演示 SSDT HOOK 的使用方式,帮助我们的程序实现隐藏或是监控等工作。我们之前也一直提到过,在 32 位系统上,要想实现隐藏或是监控的操作,大多数操作就是对 SSDT 函数各种 HOOK,可以是 SSDT HOOK,也可以是 Inline HOOK。但,这些通过对 SSDT 表内存修改而实现的操作,在 64 位系统上不再适用,因为 64 位系统的 Patch Guard 保护机制,把 SSDT 的内存作为重点保护对象,只要对 SSDT 的内存进行修改,都会触发 Patch Gua原创 2020-06-24 09:17:10 · 601 阅读 · 0 评论 -
通过暴力搜索PID遍历进程并获取进程信息
背景通常我们在内核中使用 ZwQuerySystemInformation 函数来遍历进程模块并获取进程信息,这种是通过正常的进程遍历方式,所以,有很多 Rootkit 程序会 HOOK 这个 ZwQuerySystemInformation 函数,过滤指定进程,从而实现进程的隐藏。本文实现的进程遍历和获取进程信息并不打算使用 ZwQuerySystemInformation 这种方式,而是直接暴力搜索进程的 PID,根据有效的 PID 获取相应进程的信息,从而实现进程的遍历。现在,我就来讲解具体的实现转载 2020-06-23 18:36:09 · 3258 阅读 · 1 评论 -
枚举系统中的各种回调
请转到以下链接食用 ???????? :进程/线程对象回调????:注册表回调????:模块加载回调????:进程创建回调???? :线程创建回调原创 2020-06-23 18:22:59 · 718 阅读 · 0 评论 -
ring0解锁文件
背景当我们要删除一个文件的的时候,有时候会出现“文件被占用”或是“无法删除”的提示框,这往往是由于该文件句柄已经在其它进程中打开未关闭的缘故。本文要介绍的是关闭在其它进程中的文件句柄,对文件进行解锁。现在,我把实现过程和原理,整理成文档,分享给大家。实现原理要实现对指定文件进行解锁,我们首先要做的就是获取这个文件所有被打开的文件句柄,然后在关闭这些句柄即可。那么接下来,我就对指定文件句柄的遍历以及结束文件句柄的实现原理分别进行解析。遍历指定文件句柄首先,我们使用 16 号功能调用 ZwQuery转载 2020-06-23 18:05:19 · 579 阅读 · 0 评论 -
ring0层下实现的文件强制删除
文件强删在日常生活使用电脑的过程中,遇到删不掉的文件的时候,我们总会通过一些软件提供的强制删除文件功能来删除顽固的文件。文件强删技术对于杀软来说是清楚病毒木马的武器,在扫描器检测出恶意文件的时候,就需要强删功能来清除恶意文件。而对于病毒木马来说,反过来可以用强删技术来强制删除系统保护文件或是受杀软保护的文件。本文将会介绍文件强删技术,即使文件正在运行,也能强制删除本地文件。实现过程当文件是PE文件而且已经被加载到内存中的时候,正常情况下是无法通过资源管理器explorer.exe来删除本地文件的,因转载 2020-06-23 17:59:17 · 1498 阅读 · 1 评论 -
x64驱动 使用 InfinityHook
准备首先,下载 InfinityHook 项目:git clone https://github.com/everdox/InfinityHook打开 sln ,编译一下:得到我们需要的 lib 文件(以 x64 为例):再找到 这个 .h 头文件,需要的就这么多 ????新建项目新建一个驱动项目,将刚才的 .lib 和 .h 文件拷贝到工程目录中:项目中添加现有项:注意,这里的 lib 文件必须添加到工程目录中,如果只单纯的设置附加依赖项和附加库目录,会报 “无法解析的外部符号原创 2020-06-18 14:35:12 · 5321 阅读 · 5 评论 -
x64驱动 遍历 PspCidTable 枚举隐进程和线程
介绍PspCidTable 是一个内核句柄表,存放进程和线程的内核对象(EPROCESS 和 ETHREAD),并通过 PID 和 TID 进行索引(所以进程ID和线程ID不可能相同),ID 号以 4 递增。获取 PspCidTable 地址win7:PsLookupProcessByProcessId(被导出) -> PspCidTablewin10:PsLookupProcessByProcessId(被导出) -> PspReferenceCidTableEntry -&g原创 2020-06-05 17:26:11 · 3200 阅读 · 3 评论 -
驱动 获取系统版本
// 判断操作系统版本RTL_OSVERSIONINFOEXW OSVersion = { 0 };OSVersion.dwOSVersionInfoSize = sizeof(RTL_OSVERSIONINFOEXW);RtlGetVersion((PRTL_OSVERSIONINFOW)&OSVersion);// OSVersion.dwMajorVersion (主版本) , OSVersion.dwMinorVersion (次版本)...原创 2020-06-01 17:06:05 · 958 阅读 · 0 评论 -
x64驱动遍历 DPC 定时器
目的拿到类似于 PChunter 中的信息:过程首先,要拿到系统的 _KPRCB ,也就是 KiProcessorBlock 的地址:我这里显示了 4 地址,这是因为我的 CPU 是 4 核 ——(垃圾电脑勿喷)对于 KiProcessorBlock 这个 API , Windows 没有导出:但是可以通过另一种办法获取到这个地址:// 获取特殊寄存器中的值,拿 _KPRCBULONG64 PrcbAddress = (ULONG64)__readmsr(0xC0000101)原创 2020-05-22 09:02:41 · 854 阅读 · 0 评论 -
c++ 驱动【加载,启动,停止,卸载】
驱动代码参考:https://blog.youkuaiyun.com/Simon798/article/details/103308039exe 代码:#include <iostream>#include <Windows.h>using namespace std;// 安装驱动BOOL installDvr(CONST WCHAR drvPath[50], CONST WCHAR serviceName[20]) { // 打开服务控制管理器数据库原创 2020-05-16 13:51:22 · 5511 阅读 · 2 评论 -
C++ 遍历 MiniFilter
目的实现一个类似 PCHunter 中的一个功能:代码功能参考:https://write-bug.com/article/2503.html其余参考:https://blog.youkuaiyun.com/Simon798/article/details/103308039// 获取 Operations 偏移LONG GetOperationsOffset(){ // 初始化 RTL_OSVERSIONINFOW osInfo = { 0 }; LONG lOperationsOffset =原创 2020-05-09 18:10:23 · 554 阅读 · 0 评论 -
C++ 第一个驱动程序
驱动入口// NTSTATUS : (LONG) 0~0X7FFFFFFF 正确状态,0X80000000~0XFFFFFFFF 错误状态。参考:https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-erref/596a1078-e883-4972-9bbc-49e60bebca55/* PDRIVER_OBJECT...原创 2019-11-29 18:23:47 · 4936 阅读 · 1 评论