说明:SSDT (system service discriptor table)钩子, 钩挂文件系统ZwXxxFile服务,ring0级。
环境:xp sp2(microsoft virtual pc), XP Checked Build Environment,drivermonitor监视dbgprint
错误处:
为了从句柄得到文件名GetFileNameFromHandle()中应该调用OldZwQueryInformationFile,可是OldZwQueryInformationFile却几乎全部返回 失败(没仔细看ntstatus值)但直接用ZwQueryInformationFile却OK(这样显然在NewZwQueryInformationFile中不能用,会造成循环)
为什么这样?
////////////hook.c/////////////////////////////
////// ///
// //
/////////////////////////////////////////////////
#if 0
200801132207 MicroMath
servicetable hook
200801211945
BOOL GetFileNameFromHandle(HANDLE hFile,PCHAR pszName);
debug(must use zwquery ,old不行???)
#endif
#ifdef __cplusplus
extern "C"
{
#endif
#include "ntddk.h"
#include "stdio.h"
#include"windef.h"
#include "hook.h"
#ifdef __cplusplus
}
#endif
////////////////////////////////////////
ZWCREATEFILE OldZwCreateFile;
ZWWRITEFILE OldZwWriteFile;
ZWREADFILE OldZwReadFile;
ZWQUERYINFORMATIONFILE OldZwQueryInformationFile;
ZWSETINFORMATIONFILE OldZwSetInformationFile;
ZWOPENFILE OldZwOpenFile;
/////////////////////////////////////////////////////
ULONG ProcessNameOffset;
//////////////////////////////////////////////////
NTSTATUS
DriverEntry(IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath)
{
DbgPrint("[hook] This is DriverEntry!\n");
DriverObject->MajorFunction[IRP_MJ_CREATE] =
DriverObject->MajorFunction[IRP_MJ_CLOSE] = DriverDispatch;
DriverObject->DriverUnload = DriverUnload;
// save old system call 地址
//OldZwCreateFile = (ZWCREATEFILE)SERVICE(ZwCreateFile);
OldZwReadFile = (ZWREADFILE)SERVICE(ZwReadFile);
OldZwWriteFile = (ZWWRITEFILE)SERVICE(ZwWriteFile);
//OldZwOpenFile = (ZWOPENFILE)SERVICE(ZwOpenFile);
OldZwQueryInformationFile = (ZWQUERYINFORMATIONFILE)SERVICE(ZwQueryInformationFile);
OldZwSetInformationFile = (ZWSETINFORMATIONFILE)SERVICE(ZwSetInformationFile);
EnableInterrupt(0);
//SERVICE(ZwCreateFile)= (ULONG)NewZwCreateFile;
SERVICE(ZwReadFile)= (ULONG)NewZwReadFile;
SERVICE(ZwWriteFile)= (ULONG)NewZwWriteFile;
//SERVICE(ZwOpenFile)= (ULONG)NewZwOpenFile;
SERVICE(ZwQueryInformationFile)=(ULONG)NewZwQueryInformationFile;
SERVICE(ZwSetInformationFile)= (ULONG)NewZwSetInformationFile;
EnableInterrupt(1);
return STATUS_SUCCESS;
}
NTSTATUS
DriverDispatch(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest (Irp,IO_NO_INCREMENT);
return Irp->IoStatus.Status;
}
void DriverUnload(IN PDRIVER_OBJECT DriverObject)
{
DbgPrint("[hook] This is DriverUnload!\n");
EnableInterrupt(0);
//SERVICE(ZwCreateFile)= (ULONG)OldZwCreateFile;
SERVICE(ZwReadFile)= (ULONG)OldZwReadFile;
SERVICE(ZwWriteFile)= (ULONG)OldZwWriteFile;
//SERVICE(ZwOpenFile)= (ULONG)OldZwOpenFile;
SERVICE(ZwQueryInformationFile)=(ULONG)OldZwQueryInformationFile;
SERVICE(ZwSetInformationFile)= (ULONG)OldZwSetInformationFile;
EnableInterrupt(1);
}
void EnableInterrupt(int bEnable){
if(bEnable){
_asm
{
MOV EAX, CR0 //move CR0 register into EAX
OR EAX, 10000H //enable WP bit
MOV CR0, EAX //write register back
STI //enable interrupt
}
}
else{
_asm
{
CLI //dissable interrupt
MOV EAX, CR0 //move CR0 register into EAX
AND EAX, NOT 10000H //disable WP bit
MOV CR0, EAX //write register back
}
}
}
////////////////////////////////////////////////////////////////
NTSTATUS NewZwQueryInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
)
{
NTSTATUS rc;
CHAR chFileName[512];
/*if(GetFileNameFromHandle(FileHandle,chFileName)){
DbgPrint("[QueryInfo]%s\n",chFileName);
}*/
rc=OldZwQueryInformationFile(
IN FileHandle,
OUT IoStatusBlock,
OUT FileInformation,
IN Length,
IN FileInformationClass
);
return rc;
}
//.....
NTSTATUS NewZwReadFile(
IN HANDLE FileHandle,
IN HANDLE Event OPTIONAL,
IN PIO_APC_ROUTINE ApcRoutine OPTIONAL,
IN PVOID ApcContext OPTIONAL,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID Buffer,
IN ULONG Length,
IN PLARGE_INTEGER ByteOffset OPTIONAL,
IN PULONG Key OPTIONAL
)
{
NTSTATUS rc;
CHAR chFileName[512];
if(GetFileNameFromHandle(FileHandle,chFileName)){
DbgPrint("[Read]%s\n",chFileName);
}
rc=OldZwReadFile(
IN FileHandle,
IN Event OPTIONAL,
IN ApcRoutine OPTIONAL,
IN ApcContext OPTIONAL,
OUT IoStatusBlock,
OUT Buffer,
IN Length,
IN ByteOffset OPTIONAL,
IN Key OPTIONAL
);
return rc;
}
//////////////////////////////////////////
BOOL GetFileNameFromHandle(HANDLE hFile,PCHAR pszName){
FILE_NAME_INFORMATION* pFileInfo;
IO_STATUS_BLOCK IoStatusBlock;
ANSI_STRING asName;
UNICODE_STRING usName;
if(!pszName)
return 0;
//DbgPrint("pszName\n");
if(!hFile)
return 0;
//DbgPrint("hFile\n");
if(!(char*)(pFileInfo=(FILE_NAME_INFORMATION*)ExAllocatePool(NonPagedPool,1024))){
return 0;
}
//DbgPrint("pFileInfo\n");
if(!NT_SUCCESS(OldZwQueryInformationFile(hFile,&IoStatusBlock,pFileInfo,1024,FileNameInformation))){
ExFreePool(pFileInfo);
return 0;
}
//DbgPrint("query\n");
usName.Length=(USHORT)pFileInfo->FileNameLength;
usName.Buffer=pFileInfo->FileName;
if(!NT_SUCCESS(RtlUnicodeStringToAnsiString(&asName,&usName,1))){
ExFreePool(pFileInfo);
RtlFreeAnsiString(&asName);
return 0;
}
//DbgPrint("uni2ans\n");
memcpy(pszName,asName.Buffer,asName.Length);
pszName[asName.Length]=0;
ExFreePool(pFileInfo);
RtlFreeAnsiString(&asName);
return 1;
}
///////////hook.h///////////////////
// //
// //
////////////////////////////////////////////
#if 0
200801132207 MicroMath
servicetable hook
#endif
#pragma pack(1)
typedef struct ServiceDescriptorEntry {
unsigned int *ServiceTableBase;
unsigned int *ServiceCounterTableBase; //Used only in checked build
unsigned int NumberOfServices;
unsigned char *ParamTableBase;
} ServiceDescriptorTableEntry_t, *PServiceDescriptorTableEntry_t;
#pragma pack()
__declspec(dllimport) ServiceDescriptorTableEntry_t KeServiceDescriptorTable;
void EnableInterrupt(int bEnable);
///
//........
///
//////////////////////////////////////////////////////////////
BOOL GetFileNameFromHandle(HANDLE hFile,PCHAR pszName);
///////////////////////////////////
#define SERVICE(FunctionAddress) (KeServiceDescriptorTable.ServiceTableBase[ *(PULONG)((PUCHAR)FunctionAddress+1)])
- typedef NTSTATUS (NTAPI *ZWQUERYINFORMATIONFILE)(
- IN HANDLE FileHandle,
- OUT PIO_STATUS_BLOCK IoStatusBlock,
- OUT PVOID FileInformation,
- IN ULONG Length,
- IN FILE_INFORMATION_CLASS FileInformationClass
- );
你的ZWQUERYINFORMATIONFILE类型是这样定义的吗?