求助ssdt hook ZwClose得到句柄,获取文件名

VirtualRookit 2012-03-28 11:42:04
小弟想通过hook ZwClose获取句柄,通过句柄取得应用层调用CloseHandle的文件名怎么实现。
我把hookZwClose后得到句柄通过ObReferenceObjectByHandle(FileHandle, 0, *IoFileObjectType, KernelMode, &FileObject, NULL);后FileObject->FileName.Buffer是操作文件的进程名(如\windows\system\notepad.exe),而我想得到的是文件名(如*.txt)。怎么做呢。
...全文
306 16 打赏 收藏 转发到动态 举报
写回复
用AI写文章
16 条回复
切换为时间正序
请发表友善的回复…
发表回复
dengchaozhu 2012-04-27
  • 打赏
  • 举报
回复
我把hookZwClose后得到句柄通过ObReferenceObjectByHandle(FileHandle, 0, *IoFileObjectType, KernelMode, &FileObject, NULL);后FileObject->FileName.Buffer是操作文件的进程名 ????
楼主这句什么意思啊。。。
传入文件句柄 out出来的PFILE_OBJECT 怎么可能是操作文件的进程名 文件名字吧?
  • 打赏
  • 举报
回复
晕,坑爹的排版
  • 打赏
  • 举报
回复
ZwQueryInformationFile

NTSTATUS
ZwQueryInformationFile(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN FILE_INFORMATION_CLASS FileInformationClass
);

FileInformationClass

FileAccessInformation A FILE_ACCESS_INFORMATION structure. This structure contains an access mask. For more information about access masks, see ACCESS_MASK.
FileAlignmentInformation A FILE_ALIGNMENT_INFORMATION structure. The caller can query this information as long as the file is open, without any particular requirements for DesiredAccess. This information is useful if the file was opened with the FILE_NO_INTERMEDIATE_BUFFERING flag specified in the CreateOptions parameter.
FileAllInformation A FILE_ALL_INFORMATION structure. By combining several file-information structures into a single structure, FILE_ALL_INFORMATION reduces the number of queries required to obtain information about a file.
FileAttributeTagInformation A FILE_ATTRIBUTE_TAG_INFORMATION structure. The caller must have opened the file with the FILE_READ_ATTRIBUTES flag specified in the DesiredAccess parameter.
FileBasicInformation A FILE_BASIC_INFORMATION structure. The caller must have opened the file with the FILE_READ_ATTRIBUTES flag specified in the DesiredAccess parameter.
FileEaInformation A FILE_EA_INFORMATION structure. This structure specifies the size of the extended attributes block that is associated with the file.
FileInternalInformation A FILE_INTERNAL_INFORMATION structure. This structure specifies a 64-bit file ID that uniquely identifies a file in NTFS. On other file systems, this file ID is not guaranteed to be unique.
FileIoPriorityHintInformation A FILE_IO_PRIORITY_HINT_INFORMATION structure. The caller must have opened the file with the FILE_READ_DATA flag specified in the DesiredAccess parameter.
FileModeInformation A FILE_MODE_INFORMATION structure. This structure contains a set of flags that specify the mode in which the file can be accessed. These flags are a subset of the options that can be specified in the CreateOptions parameter of the IoCreateFile routine.
FileNameInformation A FILE_NAME_INFORMATION structure. The structure can contain the file's full path or only a portion of it. The caller can query this information as long as the file is open, without any particular requirements for DesiredAccess.
For more information about the file-name syntax, see the Comments section later in this topic.
FileNetworkOpenInformation A FILE_NETWORK_OPEN_INFORMATION structure. The caller must have opened the file with the FILE_READ_ATTRIBUTES flag specified in the DesiredAccess parameter.
FilePositionInformation A FILE_POSITION_INFORMATION structure. The caller must have opened the file with the DesiredAccess FILE_READ_DATA or FILE_WRITE_DATA flag specified in the DesiredAccess parameter, and with the FILE_SYNCHRONOUS_IO_ALERT or FILE_SYNCHRONOUS_IO_NONALERT flag specified in the CreateOptions parameter.
FileStandardInformation A FILE_STANDARD_INFORMATION structure. The caller can query this information as long as the file is open, without any particular requirements for DesiredAccess.

whispermyname 2012-03-29
  • 打赏
  • 举报
回复
根据句柄,去查HandleTable,找到Object,应该行吧
fishion 2012-03-29
  • 打赏
  • 举报
回复
ZwQueryInformationFile 呢
还有就是有可能他关闭操作有多个,一个是进程,还有一个是文件,你触发下看看会不会触发多次了
  • 打赏
  • 举报
回复

调用完,在调用这个函数,释放内存
SfGetFileNameCleanup( &nameControl );


VOID
SfGetFileNameCleanup(
IN OUT PGET_NAME_CONTROL NameControl
)
/*++

Routine Description:

This will see if a buffer was allocated and will free it if it was

Arguments:

NameControl - control structure used for retrieving the name. It keeps
track if a buffer was allocated or if we are using the internal
buffer.

Return Value:

None

--*/
{

if (NULL != NameControl->allocatedBuffer) {

ExFreePool( NameControl->allocatedBuffer);
NameControl->allocatedBuffer = NULL;
}
}


  • 打赏
  • 举报
回复
漏了一点

typedef struct _GET_NAME_CONTROL {

PCHAR allocatedBuffer;
CHAR smallBuffer[256];

} GET_NAME_CONTROL, *PGET_NAME_CONTROL;

调用时候
GET_NAME_CONTROL nameControl;
PUNICODE_STRING name = SfGetFileName(FileObject,
STATUS_SUCCESS,
&nameControl );

  • 打赏
  • 举报
回复
sfilter 代码

PUNICODE_STRING
SfGetFileName(
IN PFILE_OBJECT FileObject,
IN NTSTATUS CreateStatus,
IN OUT PGET_NAME_CONTROL NameControl
)
/*++

Routine Description:

This routine will try and get the name of the given file object. This
is guaranteed to always return a printable string (though it may be NULL).
This will allocate a buffer if it needs to.

Arguments:
FileObject - the file object we want the name for

CreateStatus - status of the create operation

NameControl - control structure used for retrieving the name. It keeps
track if a buffer was allocated or if we are using the internal
buffer.

Return Value:

Pointer to the unicode string with the name

--*/
{
POBJECT_NAME_INFORMATION nameInfo;
NTSTATUS status;
ULONG size;
ULONG bufferSize;

//
// Mark we have not allocated the buffer
//

NameControl->allocatedBuffer = NULL;

//
// Use the small buffer in the structure (that will handle most cases)
// for the name
//

nameInfo = (POBJECT_NAME_INFORMATION)NameControl->smallBuffer;
bufferSize = sizeof(NameControl->smallBuffer);

//
// If the open succeeded, get the name of the file, if it
// failed, get the name of the device.
//

status = ObQueryNameString(
(NT_SUCCESS( CreateStatus ) ?
(PVOID)FileObject :
(PVOID)FileObject->DeviceObject),
nameInfo,
bufferSize,
&size );

//
// See if the buffer was to small
//

if (status == STATUS_BUFFER_OVERFLOW) {

//
// The buffer was too small, allocate one big enough
//

bufferSize = size + sizeof(WCHAR);

NameControl->allocatedBuffer = ExAllocatePoolWithTag(
NonPagedPool,
bufferSize,
SFLT_POOL_TAG );

if (NULL == NameControl->allocatedBuffer) {

//
// Failed allocating a buffer, return an empty string for the name
//

RtlInitEmptyUnicodeString(
(PUNICODE_STRING)&NameControl->smallBuffer,
(PWCHAR)(NameControl->smallBuffer + sizeof(UNICODE_STRING)),
(USHORT)(sizeof(NameControl->smallBuffer) - sizeof(UNICODE_STRING)) );

return (PUNICODE_STRING)&NameControl->smallBuffer;
}

//
// Set the allocated buffer and get the name again
//

nameInfo = (POBJECT_NAME_INFORMATION)NameControl->allocatedBuffer;

status = ObQueryNameString(
FileObject,
nameInfo,
bufferSize,
&size );
}

//
// If we got a name and an error opening the file then we
// just received the device name. Grab the rest of the name
// from the FileObject (note that this can only be done if being called
// from Create). This only happens if we got an error back from the
// create.
//

if (NT_SUCCESS( status ) &&
!NT_SUCCESS( CreateStatus )) {

ULONG newSize;
PCHAR newBuffer;
POBJECT_NAME_INFORMATION newNameInfo;

//
// Calculate the size of the buffer we will need to hold
// the combined names
//

newSize = size + FileObject->FileName.Length;

//
// If there is a related file object add in the length
// of that plus space for a separator
//

if (NULL != FileObject->RelatedFileObject) {

newSize += FileObject->RelatedFileObject->FileName.Length +
sizeof(WCHAR);
}

//
// See if it will fit in the existing buffer
//

if (newSize > bufferSize) {

//
// It does not fit, allocate a bigger buffer
//

newBuffer = ExAllocatePoolWithTag(
NonPagedPool,
newSize,
SFLT_POOL_TAG );

if (NULL == newBuffer) {

//
// Failed allocating a buffer, return an empty string for the name
//

RtlInitEmptyUnicodeString(
(PUNICODE_STRING)&NameControl->smallBuffer,
(PWCHAR)(NameControl->smallBuffer + sizeof(UNICODE_STRING)),
(USHORT)(sizeof(NameControl->smallBuffer) - sizeof(UNICODE_STRING)) );

return (PUNICODE_STRING)&NameControl->smallBuffer;
}

//
// Now initialize the new buffer with the information
// from the old buffer.
//

newNameInfo = (POBJECT_NAME_INFORMATION)newBuffer;

RtlInitEmptyUnicodeString(
&newNameInfo->Name,
(PWCHAR)(newBuffer + sizeof(OBJECT_NAME_INFORMATION)),
(USHORT)(newSize - sizeof(OBJECT_NAME_INFORMATION)) );

RtlCopyUnicodeString( &newNameInfo->Name,
&nameInfo->Name );

//
// Free the old allocated buffer (if there is one)
// and save off the new allocated buffer address. It
// would be very rare that we should have to free the
// old buffer because device names should always fit
// inside it.
//

if (NULL != NameControl->allocatedBuffer) {

ExFreePool( NameControl->allocatedBuffer );
}

//
// Readjust our pointers
//

NameControl->allocatedBuffer = newBuffer;
bufferSize = newSize;
nameInfo = newNameInfo;

} else {

//
// The MaximumLength was set by ObQueryNameString to
// one char larger then the length. Set it to the
// true size of the buffer (so we can append the names)
//

nameInfo->Name.MaximumLength = (USHORT)(bufferSize -
sizeof(OBJECT_NAME_INFORMATION));
}

//
// If there is a related file object, append that name
// first onto the device object along with a separator
// character
//

if (NULL != FileObject->RelatedFileObject) {

RtlAppendUnicodeStringToString(
&nameInfo->Name,
&FileObject->RelatedFileObject->FileName );

RtlAppendUnicodeToString( &nameInfo->Name, L"\\" );
}

//
// Append the name from the file object
//

RtlAppendUnicodeStringToString(
&nameInfo->Name,
&FileObject->FileName );

ASSERT(nameInfo->Name.Length <= nameInfo->Name.MaximumLength);
}

//
// Return the name
//

return &nameInfo->Name;
}
sad 2012-03-29
  • 打赏
  • 举报
回复
以前的一段代码
pDeviceObj = pFileObj->RelatedFileObject;
if ( pDeviceObj == NULL)
{
pDeviceObj = pFileObj->DeviceObject;
}
status = IoVolumeDeviceToDosName(pDeviceObj,&DevicePath);
DevicePath 就是文件所在分区的名字.
  • 打赏
  • 举报
回复
问列宁
VirtualRookit 2012-03-29
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 的回复:]

Hook NtCreateFile不行吗
[/Quote]因为只想在文件关闭时捕捉,所以就Hook ZwClose...
VirtualRookit 2012-03-29
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 的回复:]

应用层调用CloseHandle的文件名怎么实现


PsGetCurrentProcess()+0x174 =Process Name
[/Quote]你好,俺要的是操作目标的文件名(即是调用CloseHandle关闭哪个文件,而不是哪个进程调用CloseHandle),不是进程名。
Lactoferrin 2012-03-29
  • 打赏
  • 举报
回复
有现成的ZwQueryObject
VirtualRookit 2012-03-29
  • 打赏
  • 举报
回复
[Quote=引用 10 楼 的回复:]

ZwQueryInformationFile 呢
还有就是有可能他关闭操作有多个,一个是进程,还有一个是文件,你触发下看看会不会触发多次了
[/Quote]的确触发多次,不过都只触发到进程的,没有触发到文件的。
dengchaozhu 2012-03-28
  • 打赏
  • 举报
回复
应用层调用CloseHandle的文件名怎么实现


PsGetCurrentProcess()+0x174 =Process Name

whispermyname 2012-03-28
  • 打赏
  • 举报
回复
Hook NtCreateFile不行吗

69,382

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧