用HOOK来修改API函数的功能 @之禁止删除文件
2012-02-10 15:56
375 查看
转载自:http://www.cnblogs.com/bcxx_qin/archive/2009/02/21/1395502.html
下面是全文
原blog地址:http://fxh7622.blog.51cto.com/63841/32290
在"未文档化函数中"有个函数叫做ZwSetInformationFile。这个函数对应的WIN32的函数有"SetFileAttributes、SetEndOfFile、SetFilePointer、SetFileTime、DeleteFile"。也就是说,以上的函数均是和这个ZwSetInformationFile函数有关。如果我们截获到这个函数那么我们就可以做到禁止删除文件。
下面是我的代码。我首先对用户操作的文件名和我们要保护的文件名进行比较,如果文件名相同,则继续判断路径是否相同。如果相同,那么这个文件就是我们保护的文件。否则继续用户的原有操作。
#include "ntddk.h"
#include "bugcodes.h"
#include "ntstatus.h"
#include <ntddkbd.h>
#include <stdio.h>
#include "stdarg.h"
#include "ntiologc.h"
#define MAXPATHLEN 1024
#define MaxBuf 1024
#define MIN(x,y) ((x) < (y) ? (x) : (y))
.....
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
...
//反删除文件需要的函数
//(1).声明原有函数
typedef NTSTATUS (*ZWSETINFORMATIONFILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
ZWSETINFORMATIONFILE RealZwSetInformationFile;
//(2).定义HOOK反删除文件的函数
NTSTATUS HookZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
...
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
......
RealZwSetInformationFile=(ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")]);
(ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")])=HookZwSetInformationFile;
//上面两行的代码含义请参照我上面的文章。
}
NTSTATUS HookZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
)
{
PVOID *pFileObject;
NTSTATUS rc;
ULONG ActualLength;
int DelInt;
PUNICODE_STRING puniFileName_Del;
ANSI_STRING ansiFileName_Del,
m_ansiFileName_Del,
ansiGetFileName_Del,
m_ansiGetFileName_Del;
IO_STATUS_BLOCK MyIoStatusBlock;
PFILE_NAMES_INFORMATION pFileInfo;
char DeleteFileDir[MaxBuf]={'\0'};
char TempDel[2]={'\0'};
char TempInstallDir[256]={'\0'};//定义临时使用的安装路径数组
UNICODE_STRING pHideFileDir; //定义反删除读取文件的文件名
UNICODE_STRING *pFullPath=NULL;
int Judge=0;
int CompareJudge=0;
int i;
pFileInfo = (PFILE_NAME_INFORMATION)ExAllocatePool( NonPagedPool, sizeof(FILE_NAME_INFORMATION)*255);
//调用ZwQueryInformationFile函数将操作文件的信息放如pFileInfo。
rc = ZwQueryInformationFile( FileHandle,&MyIoStatusBlock,pFileInfo,sizeof(FILE_NAME_INFORMATION)*255,FileNameInformation );
if(NT_SUCCESS(rc))
{
//定义变量
PWSTR pTemp = (PWSTR)ExAllocatePool( NonPagedPool, sizeof(PWSTR)*pFileInfo->FileNameLength);
puniFileName_Del = (PUNICODE_STRING)ExAllocatePool( NonPagedPool, sizeof( UNICODE_STRING));
puniFileName_Del->Buffer = pTemp;
//将文件名成拷贝到puniFileName_Del变量中
RtlCopyMemory( puniFileName_Del->Buffer, pFileInfo->FileName, pFileInfo->FileNameLength);
puniFileName_Del->Length = (USHORT)pFileInfo->FileNameLength;
puniFileName_Del->MaximumLength = (USHORT)pFileInfo->FileNameLength;
//对文件名称转换大小写
RtlUnicodeStringToAnsiString( &ansiFileName_Del, puniFileName_Del, TRUE);
RtlUnicodeStringToAnsiString( &m_ansiFileName_Del, puniFileName_Del, TRUE);
RtlUpperString(&ansiFileName_Del,&m_ansiFileName_Del);
//将文件名称保存在变量ansiFileName_Del中
RtlFreeAnsiString(&m_ansiFileName_Del);
//比较我们要保护的文件名称是否和正在操作的文件名称相同
if (RtlCompareMemory(ansiFileName_Del.Buffer,"Test1.txt",strlen("Test1.txt") ) == strlen("Test1.txt"))
{
rc = ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,(PVOID*)&pFileObject,NULL);
if(NT_SUCCESS(rc))
{
pFullPath = (UNICODE_STRING *)ExAllocatePool(NonPagedPool,MaxBuf);
RtlZeroMemory(pFullPath,MaxBuf);
pFullPath->MaximumLength = MaxBuf ;
//得到文件的全路径
rc = ObQueryNameString(pFileObject,pFullPath,MaxBuf,&ActualLength);
if(rc != STATUS_SUCCESS)
{
//如果失败 则调用正常处理
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
ExFreePool(pFullPath);
ObDereferenceObject(pFileObject);
return rc;
}
ObDereferenceObject(pFileObject);
//将文件的全路径转换成大写
RtlUnicodeStringToAnsiString(&ansiGetFileName_Del,pFullPath,TRUE);
RtlUnicodeStringToAnsiString(&m_ansiGetFileName_Del,pFullPath,TRUE);
RtlUpperString(&ansiGetFileName_Del,&m_ansiGetFileName_Del);
RtlFreeAnsiString(&m_ansiGetFileName_Del);
memset(DeleteFileDir,0,MaxBuf);
memcpy(DeleteFileDir,ansiGetFileName_Del.Buffer,ansiGetFileName_Del.Length);
RtlFreeAnsiString(&ansiGetFileName_Del);
ExFreePool(pFullPath);
//判断文件的全路径是否和我们需要保护的文件全路径匹配
if(RtlCompareMemory(DeleteFileDir,"http://www.cnblogs.com/bcxx_qin/admin/file://??/C://Test1.txt")
) == strlen("http://www.cnblogs.com/bcxx_qin/admin/file://??/C://Test1.txt"))
{
//如果匹配,直接返回,不调用删除功能
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
return(rc);
}
}
else
{
//如果调用ObReferenceObjectByHandle函数不正常,则调用原来的操作
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
return rc;
}
}
}
//如果文件名称不匹配,则调用原来的操作
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
}
ExFreePool(pFileInfo);
return(rc);
}
下面是全文
用HOOK来修改API函数的功能
@之禁止删除文件
原blog地址:http://fxh7622.blog.51cto.com/63841/32290在"未文档化函数中"有个函数叫做ZwSetInformationFile。这个函数对应的WIN32的函数有"SetFileAttributes、SetEndOfFile、SetFilePointer、SetFileTime、DeleteFile"。也就是说,以上的函数均是和这个ZwSetInformationFile函数有关。如果我们截获到这个函数那么我们就可以做到禁止删除文件。
下面是我的代码。我首先对用户操作的文件名和我们要保护的文件名进行比较,如果文件名相同,则继续判断路径是否相同。如果相同,那么这个文件就是我们保护的文件。否则继续用户的原有操作。
#include "ntddk.h"
#include "bugcodes.h"
#include "ntstatus.h"
#include <ntddkbd.h>
#include <stdio.h>
#include "stdarg.h"
#include "ntiologc.h"
#define MAXPATHLEN 1024
#define MaxBuf 1024
#define MIN(x,y) ((x) < (y) ? (x) : (y))
.....
typedef struct _FILE_NAMES_INFORMATION {
ULONG NextEntryOffset;
ULONG FileIndex;
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;
...
//反删除文件需要的函数
//(1).声明原有函数
typedef NTSTATUS (*ZWSETINFORMATIONFILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
ZWSETINFORMATIONFILE RealZwSetInformationFile;
//(2).定义HOOK反删除文件的函数
NTSTATUS HookZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);
...
NTSTATUS DriverEntry(IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath)
{
......
RealZwSetInformationFile=(ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")]);
(ZWSETINFORMATIONFILE)(KeServiceDescriptorTable->ServiceTableBase[SYSTEMSERVICE("ZwSetInformationFile")])=HookZwSetInformationFile;
//上面两行的代码含义请参照我上面的文章。
}
NTSTATUS HookZwSetInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
IN PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
)
{
PVOID *pFileObject;
NTSTATUS rc;
ULONG ActualLength;
int DelInt;
PUNICODE_STRING puniFileName_Del;
ANSI_STRING ansiFileName_Del,
m_ansiFileName_Del,
ansiGetFileName_Del,
m_ansiGetFileName_Del;
IO_STATUS_BLOCK MyIoStatusBlock;
PFILE_NAMES_INFORMATION pFileInfo;
char DeleteFileDir[MaxBuf]={'\0'};
char TempDel[2]={'\0'};
char TempInstallDir[256]={'\0'};//定义临时使用的安装路径数组
UNICODE_STRING pHideFileDir; //定义反删除读取文件的文件名
UNICODE_STRING *pFullPath=NULL;
int Judge=0;
int CompareJudge=0;
int i;
pFileInfo = (PFILE_NAME_INFORMATION)ExAllocatePool( NonPagedPool, sizeof(FILE_NAME_INFORMATION)*255);
//调用ZwQueryInformationFile函数将操作文件的信息放如pFileInfo。
rc = ZwQueryInformationFile( FileHandle,&MyIoStatusBlock,pFileInfo,sizeof(FILE_NAME_INFORMATION)*255,FileNameInformation );
if(NT_SUCCESS(rc))
{
//定义变量
PWSTR pTemp = (PWSTR)ExAllocatePool( NonPagedPool, sizeof(PWSTR)*pFileInfo->FileNameLength);
puniFileName_Del = (PUNICODE_STRING)ExAllocatePool( NonPagedPool, sizeof( UNICODE_STRING));
puniFileName_Del->Buffer = pTemp;
//将文件名成拷贝到puniFileName_Del变量中
RtlCopyMemory( puniFileName_Del->Buffer, pFileInfo->FileName, pFileInfo->FileNameLength);
puniFileName_Del->Length = (USHORT)pFileInfo->FileNameLength;
puniFileName_Del->MaximumLength = (USHORT)pFileInfo->FileNameLength;
//对文件名称转换大小写
RtlUnicodeStringToAnsiString( &ansiFileName_Del, puniFileName_Del, TRUE);
RtlUnicodeStringToAnsiString( &m_ansiFileName_Del, puniFileName_Del, TRUE);
RtlUpperString(&ansiFileName_Del,&m_ansiFileName_Del);
//将文件名称保存在变量ansiFileName_Del中
RtlFreeAnsiString(&m_ansiFileName_Del);
//比较我们要保护的文件名称是否和正在操作的文件名称相同
if (RtlCompareMemory(ansiFileName_Del.Buffer,"Test1.txt",strlen("Test1.txt") ) == strlen("Test1.txt"))
{
rc = ObReferenceObjectByHandle(FileHandle,0,NULL,KernelMode,(PVOID*)&pFileObject,NULL);
if(NT_SUCCESS(rc))
{
pFullPath = (UNICODE_STRING *)ExAllocatePool(NonPagedPool,MaxBuf);
RtlZeroMemory(pFullPath,MaxBuf);
pFullPath->MaximumLength = MaxBuf ;
//得到文件的全路径
rc = ObQueryNameString(pFileObject,pFullPath,MaxBuf,&ActualLength);
if(rc != STATUS_SUCCESS)
{
//如果失败 则调用正常处理
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
ExFreePool(pFullPath);
ObDereferenceObject(pFileObject);
return rc;
}
ObDereferenceObject(pFileObject);
//将文件的全路径转换成大写
RtlUnicodeStringToAnsiString(&ansiGetFileName_Del,pFullPath,TRUE);
RtlUnicodeStringToAnsiString(&m_ansiGetFileName_Del,pFullPath,TRUE);
RtlUpperString(&ansiGetFileName_Del,&m_ansiGetFileName_Del);
RtlFreeAnsiString(&m_ansiGetFileName_Del);
memset(DeleteFileDir,0,MaxBuf);
memcpy(DeleteFileDir,ansiGetFileName_Del.Buffer,ansiGetFileName_Del.Length);
RtlFreeAnsiString(&ansiGetFileName_Del);
ExFreePool(pFullPath);
//判断文件的全路径是否和我们需要保护的文件全路径匹配
if(RtlCompareMemory(DeleteFileDir,"http://www.cnblogs.com/bcxx_qin/admin/file://??/C://Test1.txt")
) == strlen("http://www.cnblogs.com/bcxx_qin/admin/file://??/C://Test1.txt"))
{
//如果匹配,直接返回,不调用删除功能
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
return(rc);
}
}
else
{
//如果调用ObReferenceObjectByHandle函数不正常,则调用原来的操作
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
ExFreePool(pFileInfo);
return rc;
}
}
}
//如果文件名称不匹配,则调用原来的操作
rc=RealZwSetInformationFile(FileHandle,IoStatusBlock,FileInformation,Length,FileInformationClass);
RtlFreeAnsiString(&ansiFileName_Del);
ExFreePool(puniFileName_Del);
ExFreePool(pTemp);
}
ExFreePool(pFileInfo);
return(rc);
}
相关文章推荐
- 用HOOK来修改API函数的功能(3)-禁止删除文件(转)
- 用HOOK来修改API函数的功能(3)-禁止删除文件
- 用HOOK来修改API函数的功能 @之禁止删除文件
- 用HOOK来修改API函数的功能(3)-禁止删除文件 推荐
- 用HOOK来修改API函数的功能(2)-创建文件
- 用HOOK来修改API函数的功能(2)-创建文件 推荐
- 用HOOK来修改API函数的功能(2)-创建文件(转)
- 禁止修改注册表,设置文件不被删除,隐藏“添加/删除
- 用HOOK来修改API函数的功能(1)-注册表
- 用VC6.0做了一个文件监视器,简单监视新建、删除和修改文件功能
- 用HOOK来修改API函数的功能(4)-环境搭建(转)
- 用HOOK来修改API函数的功能(4)-环境搭建 推荐
- 用HOOK来修改API函数的功能(5)-EXE和WDM驱动通信(转)
- 用HOOK来修改API函数的功能(4)-环境搭建
- 用HOOK来修改API函数的功能(5)-EXE和WDM驱动通信
- 禁止删除、修改共享文件,防止局域网用户私自复制共享文件到本地的方法
- 用HOOK来修改API函数的功能(5)-EXE和WDM驱动通信 推荐
- Qt 定制QFileDialog 实现文件新建 删除 修改 保存等功能
- 牛客网Java刷题知识点之File对象常用功能:获取文件名称、获取文件路径、获取文件大小、获取文件修改时间、创建与删除、判断、重命名、查看系统根目录、容量获取、获取某个目录下内容、过滤器
- 学生信息管理系统V0.3(优化文件存取、增加修改删除功能)