您的位置:首页 > 其它

用HOOK来修改API函数的功能 @之禁止删除文件

2012-02-10 15:56 375 查看
转载自:http://www.cnblogs.com/bcxx_qin/archive/2009/02/21/1395502.html
下面是全文


用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);

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐