x64内核中强删文件的实现

一丶简介

说道删除文件.有各种各样的方法. 有ring3 也有ring0. 而且也有许多对抗的方法. 如ring3想删除一个文件.被占用你就无法删除.此时可以通过解除句柄进行删除 ring0中想删除一个文件.有常规方法也有非常规方法.常规方法就是 设置文件属性为删除.然后进行设置. 还有就是直接调用ZwDeleteFile 进行删除. 暴力删除就是这里所讲的 IRP删除.给底层发送IRP即可进行删除文件.

1.步骤

步骤很简单.基本上说完就可以自己写代码做出

  • 1.打开文件.获取文件句柄 (IoCreateFile)
  • 2.根据文件句柄,获取文件对象.(有了句柄都应该第一时间想到获取它的对象) (ObReferenceObjectByHandle)
  • 3.获取文件对象的设备对象指针.这个发送IRP的时候需要使用(IoGetRelatedDeviceObject)
  • 4.申请IRP(IoAllocateIrp)
  • 5.初始化你申请的IRP
  • 6.获取IRP的下层堆栈,并且初始化信息.(IoGetNextIrpStackLocation)
  • 7.设置回调.系统完成IRP之后会调用你这个回调.所以你需要设置事件同步跟你自己同步,才知道IRP已经发送完了.(IoSetCompletionRoutine)
  • 8.获取文件对象的域指针.并且设置域指针的两个成员为0.系统以他来判断这个程序是否可以删除.如果不为0.那么则无法删除运行中的文件.
pSectionObjectPointer->ImageSectionObject = 0;
pSectionObjectPointer->DataSectionObject = 0;
  • 9.发送IRP(IoCallDriver)
  • 10.根据 事件 来等待是否IRP完成(KeWaitForSingleObject)
  • 11.做完收工.(ZwClose)

2.Nt驱动代码


#include "Driver.h" //删除文件函数的入口
NTSTATUS RetOpenFileHandle(UNICODE_STRING uDelFileName, PHANDLE pFileHandle)
{ NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
IO_STATUS_BLOCK iostu;
HANDLE hFileHandle = 0;
if (pFileHandle == NULL)
return STATUS_UNSUCCESSFUL;
if (KeGetCurrentIrql() > PASSIVE_LEVEL)
return 0; if (uDelFileName.Length < 0 || uDelFileName.MaximumLength < 0)
{
return 0;
} OBJECT_ATTRIBUTES ObjAttribute;
ObjAttribute.ObjectName = &uDelFileName;
ObjAttribute.SecurityDescriptor = NULL;
ObjAttribute.SecurityQualityOfService = NULL;
ObjAttribute.Attributes = OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE;
ObjAttribute.Length = sizeof(OBJECT_ATTRIBUTES); /* InitializeObjectAttributes(
&ObjAttribute,
&uDelFileName,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL, NULL);*/ ntStatus = IoCreateFile(&hFileHandle,
FILE_READ_ATTRIBUTES,
&ObjAttribute,
&iostu,
0,
FILE_ATTRIBUTE_NORMAL,
FILE_SHARE_DELETE,
FILE_OPEN,
0,
NULL,
0,
CreateFileTypeNone,
NULL,
IO_NO_PARAMETER_CHECKING); *pFileHandle = hFileHandle;
return ntStatus;
} //去掉文件属性 //CallBack回调
NTSTATUS
CallBackIrpCompleteionProc(
PDEVICE_OBJECT DeviceObject,
PIRP Irp,
PVOID Context
)
{ //操作系统会设置这个回调
Irp->UserIosb->Status = Irp->IoStatus.Status;
Irp->UserIosb->Information = Irp->IoStatus.Information;
KeSetEvent(Irp->UserEvent, IO_NO_INCREMENT, FALSE); IoFreeIrp(Irp);
return STATUS_MORE_PROCESSING_REQUIRED;
}
NTSTATUS PassFileattribute(PFILE_OBJECT pFileObj)
{
/*
1.申请IRP,初始化IRP
2.初始化同步事件,以及设置回调.
3.设置文件属性为默认
4.发送IRP
*/
PDEVICE_OBJECT pNextDeviceObj = NULL;
PIRP pAllocIrp = NULL;
KEVENT IrpSynEvent = {0}; //Irp同步需要的事件同步
FILE_BASIC_INFORMATION fileBasciInfo = { 0 };
IO_STATUS_BLOCK iostu;
PIO_STACK_LOCATION IrpStack;
//通过文件对象.获取其设备对象指针
pNextDeviceObj = IoGetRelatedDeviceObject(pFileObj);
if (pNextDeviceObj == NULL)
return STATUS_UNSUCCESSFUL; //通过设备对象指针.确定申请的IRP的大小,注意在完成设置里面进行释放.
pAllocIrp = IoAllocateIrp(pNextDeviceObj->StackSize,TRUE);
if (pAllocIrp == NULL)
return STATUS_UNSUCCESSFUL; //初始化Irp //设置为自动,设置为无信号.
KeInitializeEvent(&IrpSynEvent, SynchronizationEvent, FALSE); fileBasciInfo.FileAttributes = FILE_ATTRIBUTE_NORMAL;
pAllocIrp->AssociatedIrp.SystemBuffer = &fileBasciInfo;
pAllocIrp->UserIosb = &iostu;
pAllocIrp->UserEvent = &IrpSynEvent;
pAllocIrp->Tail.Overlay.OriginalFileObject = pFileObj;
pAllocIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); //获取下层堆栈.进行设置. //IrpStack =
IrpStack = IoGetNextIrpStackLocation(pAllocIrp);
IrpStack->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpStack->DeviceObject = pNextDeviceObj;
IrpStack->FileObject = pFileObj;
IrpStack->Parameters.SetFile.Length = sizeof(FILE_BASIC_INFORMATION);
IrpStack->Parameters.SetFile.FileObject = pFileObj;
IrpStack->Parameters.SetFile.FileInformationClass = FileBasicInformation; //设置完成例程
IoSetCompletionRoutine(pAllocIrp, CallBackIrpCompleteionProc, &IrpSynEvent, TRUE, TRUE, TRUE); //发送IRP
IoCallDriver(pNextDeviceObj, pAllocIrp);
//等待完成. KeWaitForSingleObject(&IrpSynEvent, Executive, KernelMode, TRUE, NULL); return STATUS_SUCCESS;
} NTSTATUS FsDeleteFile(PFILE_OBJECT pFileObj)
{
/*
1.申请IRP,初始化IRP
2.初始化同步事件,以及设置回调.
3.设置文件属性为默认
4.发送IRP 核心:
核心是设置 FileObject中的域.进而删除正在运行中的文件 */
PDEVICE_OBJECT pNextDeviceObj = NULL;
PIRP pAllocIrp = NULL;
KEVENT IrpSynEvent = { 0 }; //Irp同步需要的事件同步
FILE_DISPOSITION_INFORMATION fileBasciInfo = { 0 }; //注意此位置.已经变化为 FILE_DISPOSITION_INFORMATION
IO_STATUS_BLOCK iostu;
PIO_STACK_LOCATION IrpStack; PSECTION_OBJECT_POINTERS pFileExe; //注意此属性要设置为0.欺骗系统进行删除
//通过文件对象.获取其设备对象指针
pNextDeviceObj = IoGetRelatedDeviceObject(pFileObj);
if (pNextDeviceObj == NULL)
return STATUS_UNSUCCESSFUL; //通过设备对象指针.确定申请的IRP的大小,注意在完成设置里面进行释放.
pAllocIrp = IoAllocateIrp(pNextDeviceObj->StackSize, TRUE);
if (pAllocIrp == NULL)
return STATUS_UNSUCCESSFUL; //初始化Irp //设置为自动,设置为无信号.
KeInitializeEvent(&IrpSynEvent, SynchronizationEvent, FALSE); fileBasciInfo.DeleteFile = TRUE; //设置标记为删除
pAllocIrp->AssociatedIrp.SystemBuffer = &fileBasciInfo;
pAllocIrp->UserIosb = &iostu;
pAllocIrp->UserEvent = &IrpSynEvent;
pAllocIrp->Tail.Overlay.OriginalFileObject = pFileObj;
pAllocIrp->Tail.Overlay.Thread = (PETHREAD)KeGetCurrentThread(); //获取下层堆栈.进行设置. //IrpStack =
IrpStack = IoGetNextIrpStackLocation(pAllocIrp);
IrpStack->MajorFunction = IRP_MJ_SET_INFORMATION;
IrpStack->DeviceObject = pNextDeviceObj;
IrpStack->FileObject = pFileObj;
IrpStack->Parameters.SetFile.Length = sizeof(FILE_DISPOSITION_INFORMATION);
IrpStack->Parameters.SetFile.FileObject = pFileObj;
IrpStack->Parameters.SetFile.FileInformationClass = FileDispositionInformation; //设置完成例程
IoSetCompletionRoutine(pAllocIrp, CallBackIrpCompleteionProc, &IrpSynEvent, TRUE, TRUE, TRUE); //删除正在运行中的文件. pFileExe = pFileObj->SectionObjectPointer;
pFileExe->DataSectionObject = 0;
pFileExe->ImageSectionObject = 0;
//发送IRP
IoCallDriver(pNextDeviceObj, pAllocIrp);
//等待完成. KeWaitForSingleObject(&IrpSynEvent, Executive, KernelMode, TRUE, NULL); return STATUS_SUCCESS;
}
NTSTATUS IrpDeleteFileRun(UNICODE_STRING uDelFileName)
{
KdBreakPoint();
NTSTATUS ntStatus = STATUS_UNSUCCESSFUL;
/*
1.首先通过发送IRP去掉文件的属性
2.设置文件属性为删除.进行发送IRP强删文件.
*/
HANDLE hFileHandle = { 0 };
PFILE_OBJECT pFileObject = NULL;
//sep1 : OpenFile Get File Handle
ntStatus = RetOpenFileHandle(uDelFileName,&hFileHandle); if (!NT_SUCCESS(ntStatus))
{
goto ExitAnRelease;
}
//sep2: Chang File Handle to FileObject ntStatus = ObReferenceObjectByHandle(
hFileHandle,
GENERIC_ALL,
*IoFileObjectType,
KernelMode,
&pFileObject,
NULL);
if (!NT_SUCCESS(ntStatus))
{ goto ExitAnRelease;
} //setp 3: Pass File Atribute
KdBreakPoint();
ntStatus = PassFileattribute(pFileObject);
if (!NT_SUCCESS(ntStatus))
{
goto ExitAnRelease;
} //setp 4: Send Irp DeleteFile
KdBreakPoint();
ntStatus = FsDeleteFile(pFileObject);
if (!NT_SUCCESS(ntStatus))
{
goto ExitAnRelease;
}
ExitAnRelease: if (pFileObject != NULL)
ObDereferenceObject(pFileObject);
if (hFileHandle != NULL)
ZwClose(hFileHandle); return ntStatus;
}
NTSTATUS DriverEntry(PDRIVER_OBJECT pDriverObj, PUNICODE_STRING pRegPath)
{
ULONG iCount = 0;
NTSTATUS ntStatus;
UNICODE_STRING uDelFileName = { 0 };
pDriverObj->DriverUnload = DriverUnLoad;
/*ntStatus = InitDeviceAnSybolicLinkName(pDriverObj);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
} ntStatus = InitDisPatchFunction(pDriverObj);
if (!NT_SUCCESS(ntStatus))
{
return ntStatus;
}*/ //也可写成: \\??\\c:\\xxx.txt RtlInitUnicodeString(&uDelFileName, L"//DosDevices//C://123.txt");
IrpDeleteFileRun(uDelFileName);
return STATUS_SUCCESS;
}

代码测试可以进行强删.

x64内核强删文件.的更多相关文章

  1. x64内核HOOK技术之拦截进程.拦截线程.拦截模块

    x64内核HOOK技术之拦截进程.拦截线程.拦截模块 一丶为什么讲解HOOK技术. 在32系统下, 例如我们要HOOK SSDT表,那么直接讲CR0的内存保护属性去掉. 直接讲表的地址修改即可. 但是 ...

  2. Win64 驱动内核编程-5.内核里操作文件

    内核里操作文件 RING0 操作文件和 RING3 操作文件在流程上没什么大的区别,也是"获得文件句柄->读/写/删/改->关闭文件句柄"的模式.当然了,只能用内核 A ...

  3. x64内核内存空间结构

    0x00 前言 本文主要是讨论Windows 7 x64下的内核虚拟地址空间的结构,可以利用WiinDBG调试的扩展命令"!CMKD.kvas"来显示x64下的内核虚拟地址空间的整 ...

  4. [经验] Win7减肥攻略(删文件不删功能、简化优化系统不简优化性能)

    [经验] Win7减肥攻略(删文件不删功能.简化优化系统不简优化性能) ☆心梦无痕☆ 发表于 2014-1-24 11:15:04 https://www.itsk.com/thread-316471 ...

  5. android内核读取file文件

    内核读取file文件的方法: char* file_read(const char * file_path) { struct file *file = NULL; //保存打开文件的文件指针变量 s ...

  6. 【转】 Linux内核中读写文件数据的方法--不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8193954 Linux内核中读写文件数据的方法  有时候需要在Linuxkernel--大 ...

  7. 【转】在linux内核中读写文件 -- 不错

    原文网址:http://blog.csdn.net/tommy_wxie/article/details/8194276 1. 序曲 在用户态,读写文件可以通过read和write这两个系统调用来完成 ...

  8. hadoop 提高hdfs删文件效率----hadoop删除文件流程解析

    前言 这段时间在用hdfs,由于要处理的文件比较多,要及时产出旧文件,但是发现hdfs的blocks数一直在上涨,经分析是hdfs写入的速度较快,而block回收较慢,所以分心了一下hadoop删文件 ...

  9. myEclipse勿删文件怎么恢复

    今天码代码的时候项目里有一个jsp文件不小心被删了,又懒得重写,然后发现myEclipse竟然可以恢复被勿删的文件,当然,也仅仅限于最近被删的文件. 具体怎么恢复呢?-------右键点击被删文件所在 ...

随机推荐

  1. ssm动态sql语句

    1.将上面的元素分为四组来演示,分别为:[if,where,trim],[if,set,trim],[choose,when,otherwise],[foreach] ________________ ...

  2. java之mybatis之helloworld

    1. MyBatis 是一款一流的支持自定义SQL.存储过程和高级映射的持久化框架. MyBatis几乎消除了所有的 JDBC 代码,也基本不需要手工去设置参数和获取检索结果. MyBatis几乎能够 ...

  3. AWS成本估算的相关小工具

    1.AWS-partner :云势数据做的在线小工具,有微信版本可以使用,但是涉及的服务很少,更新慢,型号缺,界面不友好.不是很理想,连接如下:     https://www.goclouds.cn ...

  4. StopWatch方法详解

    namespace System.Diagnostics { // // 摘要: // 提供一组方法和属性,可用于准确地测量运行时间. public class Stopwatch { // // 摘 ...

  5. spring 中的 bean 是线程安全的吗?

    spring 中的 bean 是线程安全的吗? Spring 不保证 bean 的线程安全. 默认 spring 容器中的 bean 是单例的.当单例中存在竞态条件,即有线程安全问题.如下面的例子 计 ...

  6. RSA算法一:数学原理

  7. docker实战 (3) 常规配置

    本节会持续更新,在项目实战中遇到的docker配置都会更新进来 docker常用命令: docker 介绍: what: 是什么 why: 为什么用 how: 怎么用 docker 特点: 轻量级,可 ...

  8. React: JSX生成真实DOM结点

    在上一篇文章中,我们介绍了 Babel 是如何将 JSX 代码编译成可执行代码的,随后也实现了一个自己的解析器,模拟了 Babel 编译的过程. 现在我们再来回顾一下,假定有如下业务代码: const ...

  9. manjaro中微信不能输入中文及微信窗口出现透明轮廓的问题

    一.在安装deepin-wine-wechat后,无法切换成中文输入法.网上查找资料,在配置中添加 export 等 均未成功. 后来在官方(https://aur.archlinux.org/pac ...

  10. Docker基础用法篇

    Docker基础用法篇 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.安装docker 1>.依赖的基础环境 64 bits CPU Linux Kerner 3.10+ ...