关于SSDT钩子

nibian   2008-1-22 14:05 楼主
说明: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)])





回复评论 (1)

  1. typedef NTSTATUS (NTAPI *ZWQUERYINFORMATIONFILE)(
  2.         IN HANDLE  FileHandle,
  3.         OUT PIO_STATUS_BLOCK  IoStatusBlock,
  4.         OUT PVOID  FileInformation,
  5.         IN ULONG  Length,
  6.         IN FILE_INFORMATION_CLASS  FileInformationClass
  7.         );
你的ZWQUERYINFORMATIONFILE类型是这样定义的吗?
点赞  2008-1-22 16:06
电子工程世界版权所有 京B2-20211791 京ICP备10001474号-1 京公网安备 11010802033920号
    写回复