求助ssdt hook ZwClose得到句柄,获取文件名
小弟想通过hook ZwClose获取句柄,通过句柄取得应用层调用CloseHandle的文件名怎么实现。
我把hookZwClose后得到句柄通过ObReferenceObjectByHandle(FileHandle, 0, *IoFileObjectType, KernelMode, &FileObject, NULL);后FileObject->FileName.Buffer是操作文件的进程名(如\windows\system\notepad.exe),而我想得到的是文件名(如*.txt)。怎么做呢。
[解决办法]
Hook NtCreateFile不行吗
[解决办法]
应用层调用CloseHandle的文件名怎么实现
PsGetCurrentProcess()+0x174 =Process Name
[解决办法]
问列宁
[解决办法]
以前的一段代码
pDeviceObj = pFileObj->RelatedFileObject;
if ( pDeviceObj == NULL)
{
pDeviceObj = pFileObj->DeviceObject;
}
status = IoVolumeDeviceToDosName(pDeviceObj,&DevicePath);
DevicePath 就是文件所在分区的名字.
[解决办法]
sfilter 代码
PUNICODE_STRINGSfGetFileName( 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;}
[解决办法]
漏了一点
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 );
[解决办法]
调用完,在调用这个函数,释放内存SfGetFileNameCleanup( &nameControl );VOIDSfGetFileNameCleanup( IN OUT PGET_NAME_CONTROL NameControl )/*++Routine Description: This will see if a buffer was allocated and will free it if it wasArguments: 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; }}
[解决办法]
ZwQueryInformationFile 呢
还有就是有可能他关闭操作有多个,一个是进程,还有一个是文件,你触发下看看会不会触发多次了
[解决办法]
根据句柄,去查HandleTable,找到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.
[解决办法]
晕,坑爹的排版
[解决办法]
有现成的ZwQueryObject