[第一部分]取全路径
以下是获取全路径的所有函数【string操作参见字符串操作的一个库unicode.lib】
PVOID
SpyGetFullPath(
PFILE_OBJECT fileobject
)
//----------------------------------------------------------------------
//
// SpyGetFullPath
//
// Takes a fileobject and filename and returns a canonical path,
// nicely formatted, in fullpathname.
//
//----------------------------------------------------------------------
{
NTSTATUS status= STATUS_SUCCESS;
UNICODE_STRING filename;
WCHAR namebuf[MAX_PATH];
UNICODE_STRING volname;
WCHAR volbuf[8];
PVOID path = NULL;
RtlInitEmptyUnicodeString(&filename, namebuf, MAX_NAME_SPACE);
RtlInitEmptyUnicodeString(&volname, volbuf, 8 * sizeof(WCHAR));
if( !SpyGetFileName(fileobject, &filename) )// 07-09-25修改
{
return NULL;
}
status = SpyGetVolumeName(fileobject, &volname);
if( !NT_SUCCESS(status) )
{
return NULL;
}
path = AllocStrWithUniStr(&volname);
if(path)
{
if(filename.Buffer[0] != L'//')
{
AppendStrWithWideStr(path, L"//");
}
AppendStrWithUniStr(path, &filename);
}
return path;
}
//
// Record: Add by lwf :07-07-25
// Purpose: get symbolic target unicode string
//
PVOID
SpyGetSymbolicUniStr(
PUNICODE_STRING symbolic
)
{
OBJECT_ATTRIBUTES attrib;
NTSTATUS status;
WCHAR buf[8];
WCHAR *dbuf = NULL;
UNICODE_STRING target;
PVOID targetret = NULL;
ULONG length;
HANDLE linkhandle;
InitializeObjectAttributes(
&attrib,
symbolic,
OBJ_KERNEL_HANDLE | OBJ_CASE_INSENSITIVE,
NULL,NULL);
status = ZwOpenSymbolicLinkObject(
&linkhandle,
GENERIC_READ,
&attrib);
if( !NT_SUCCESS(status))
{
return NULL;
}
RtlInitEmptyUnicodeString(&target, buf, 8 * sizeof(WCHAR));
status = ZwQuerySymbolicLinkObject(
linkhandle,
&target,
&length);
if( status == STATUS_BUFFER_TOO_SMALL)
{
dbuf = ExAllocatePool(NonPagedPool, length + 2);
if( NULL == dbuf )
{
ZwClose(linkhandle);
return NULL;
}
RtlInitEmptyUnicodeString( &target, dbuf, length + 2);
status = ZwQuerySymbolicLinkObject(
linkhandle,
&target,
&length);
}
if(NT_SUCCESS(status))
{
targetret = AllocStrWithUniStr(&target);
}
if(NULL != dbuf)
{
FreeStr(dbuf);
}
ZwClose(linkhandle);
return targetret;
}
//
// Record: Add by lwf :07-07-25
// Purpose: get dos name
//
PVOID
SpyGetSymbolicTarget(
WCHAR* symbolic
)
{
PVOID sym;
PVOID ret;
if( NULL == symbolic )
{
return NULL;
}
sym = AllocStrWithWideStr(symbolic);
if( NULL == sym )
{
return NULL;
}
ret = SpyGetSymbolicUniStr(GetStrUniStr(sym));
FreeStr(sym);
return ret;
}
//
// Record: Add by lwf :07-07-24
// Purpose: get dos name
//
PVOID
SpyVolumeNameToDosName(
WCHAR* name
)
{
WCHAR volsyb[] = {L"//DosDevices//X:"};
UNICODE_STRING volname;
WCHAR c;
if(NULL == name)
{
return NULL;
}
RtlInitUnicodeString(&volname, name);
for( c = L'A' ; c < ('Z'+1); ++c )
{
PVOID mytarget = NULL;
volsyb[12] = c;
mytarget = SpyGetSymbolicTarget(volsyb);
if(mytarget != NULL &&
RtlCompareUnicodeString(GetStrUniStr(mytarget), &volname,TRUE) == 0)
{
FreeStr(mytarget);
break;
}
if(mytarget != NULL)
{
FreeStr(mytarget);
}
}
if(c == 'Z'+1)
{
return NULL;
}
else
{
return AllocStrWithWideStr(&volsyb[12]);
}
}
//
// Record: Add by lwf :07-07-24
// Purpose: get dos name
//
PVOID
SpyQueryObjName(
PVOID obj
)
{
NTSTATUS status;
UCHAR nibuf[512];
int len = MAX_PATH;
ULONG ret;
OBJECT_NAME_INFORMATION *name_infor =
(OBJECT_NAME_INFORMATION *)nibuf;
status = ObQueryNameString(obj, name_infor, 512, &ret);
if(NT_SUCCESS(status))
{
return AllocStrWithUniStr(&name_infor->Name);
}
else
{
return NULL;
}
}
//
// Record: Add by lwf :07-07-24
// Purpose: get dos name
//
PVOID
SpyGetDosName(
PDEVICE_OBJECT dev
)
{
PVOID volname = SpyQueryObjName(dev);
PVOID ret = NULL;
if( NULL == volname)
{
return NULL;
}
ret = SpyVolumeNameToDosName(GetStrBuf(volname));
FreeStr(volname);
return ret;
}
//
// Record: Add by lwf :07-07-24
// Purpose: get volume name
//
NTSTATUS
SpyGetVolumeName(
PFILE_OBJECT fileobject,
PUNICODE_STRING volname
)
{
NTSTATUS status = STATUS_SUCCESS;
PVOID pdosname = NULL;
pdosname = SpyGetDosName(fileobject->DeviceObject);
if(NULL == pdosname)
{
return STATUS_UNSUCCESSFUL;
}
RtlCopyUnicodeString(volname,GetStrUniStr(pdosname) );
FreeStr(pdosname);
return status;
}
//
// Record: Add by lwf :07-07-23
// Purpose: get object name
//
VOID
SpyGetObjectName(
PVOID obj,
PUNICODE_STRING name
)
{
NTSTATUS status;
char nibuf[512];
OBJECT_NAME_INFORMATION *name_infor = (OBJECT_NAME_INFORMATION*)nibuf;
ULONG ret;
status = ObQueryNameString(obj, name_infor, 512, &ret);
if(NT_SUCCESS(status))
{
RtlCopyUnicodeString(name, &name_infor->Name);
}
else
{
name->Length = 0;
}
}
//
// Record: add by lwf : 07-07-23
// Purpose: get file name
//
NTSTATUS
SpyGetFileName(
IN PFILE_OBJECT fileobject,
PUNICODE_STRING name
)
{
WCHAR *p = NULL;
WCHAR buf[MAX_PATH];
UNICODE_STRING temp;
int len;
RtlInitEmptyUnicodeString(&temp, buf, MAX_NAME_SPACE);
SpyGetObjectName((PVOID)fileobject, &temp);
KdPrint(("QueryFileName: [%wZ]/r/n", &temp));
if(temp.Length == 0)
{
return FALSE;
}
len = temp.Length / sizeof(WCHAR);
p = temp.Buffer;
p = wcschr( (const WCHAR*)(((UNICODE_STRING*)(&temp))->Buffer), L'//');
if( p == NULL || ++p >= ((UNICODE_STRING*)(&temp))->Buffer + len)
{
return FALSE;
}
p = wcschr( p, L'//');
if( p == NULL || ++p >= ((UNICODE_STRING*)(&temp))->Buffer + len)
{
return FALSE;
}
p = wcschr( p, L'//');
if( p == NULL || (p+1) >= ((UNICODE_STRING*)(&temp))->Buffer + len)
{
return FALSE;
}
if(name->MaximumLength <= wcslen( p )*sizeof(WCHAR))
{
return FALSE;
}
name->Length = wcslen( p ) * sizeof(WCHAR);
wcscpy( name->Buffer , p);
return TRUE;
}
[第二部分]在何处取
由于在CREATE IRP时,收到的请求是最真实的(没有被篡改过),因此我们在SpyCreate完成时调用取全路径函数,达到获取全路径的目的
NTSTATUS
SpyCreate (
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
NTSTATUS status;
KIRQL oldIrql;
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PFILE_OBJECT FileObject;
PVOID block;
KEVENT waitEvent;
PCHAR pDbgStr = NULL;
if (DeviceObject == gControlDeviceObject) {
KeAcquireSpinLock( &gControlDeviceStateLock, &oldIrql );
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = FILE_OPENED;
gControlDeviceState = OPENED;
KeReleaseSpinLock( &gControlDeviceStateLock, oldIrql );
g_hProcessId=PsGetCurrentProcessId();
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
ASSERT( IS_FILESPY_DEVICE_OBJECT( DeviceObject ) );
KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
IoCopyCurrentIrpStackLocationToNext( Irp );
IoSetCompletionRoutine(
Irp,
SpyCreateCompletion,
&waitEvent,
TRUE,
TRUE,
TRUE );
status = IoCallDriver(((PFILESPY_DEVICE_EXTENSION)DeviceObject->DeviceExtension)->NLExtHeader.AttachedToDeviceObject,
Irp );
if (STATUS_PENDING == status)
{
NTSTATUS localStatus = KeWaitForSingleObject( &waitEvent,
Executive,
KernelMode,
FALSE,
NULL );
ASSERT(STATUS_SUCCESS == localStatus);
}
ASSERT(KeReadStateEvent(&waitEvent) ||
!NT_SUCCESS(Irp->IoStatus.Status));
FileObject = irpSp->FileObject;
block = SpyGetFullPath(FileObject);
pDbgStr =UnicodeToANSI(GetStrUniStr(block));
dprintf("[FileSpy.sys]MajorFunction:SpyCreate: [%s]", pDbgStr);
FreeStr(block);
status = Irp->IoStatus.Status;
IoCompleteRequest( Irp, IO_NO_INCREMENT );
return status;
}
[第三部分]中文打印
写个支持中文的打印函数
由于DbgPrint遇到中文字符的UNICODE_STRING时会截断,因此我们转成ANSI_STRING里打印
PCHAR UnicodeToANSI (
IN PUNICODE_STRING pUnicodeString
)
{
//UNICODE_STRING不为空
if(pUnicodeString == NULL)
{
return NULL;
}
//STRING的BUFFER不为空
if(pUnicodeString->Buffer == NULL)
{
return NULL;
}
DbgStr.Length = 0;
DbgStr.MaximumLength = MAX_LENGTH;
RtlZeroMemory(DbgStr.Buffer, MAX_LENGTH);
//转BUFFER
RtlUnicodeStringToAnsiString(&DbgStr, pUnicodeString, FALSE);
return DbgStr.Buffer;
}