参数KeyHandle 为SectionHandle。
解决了文件名因为缓冲机制导致的修改文件名,但获得的文件名是老名的问题。
有两种文件对象控制区域,DataSection 和 ImageSection
ImageSection :文件映像,进程退出时没被释放,而被放到空闲内存区域,以被重用
DataSection : 数据副本, 进程退出,被释放
在获得文件对象方法中,添加了
pFile = ((PFILE_OBJECT)pFile)->SectionObjectPointer->DataSectionObject;
pFile =(PVOID)*(ULONG *)((char *)pFile+36);
在2003上测试过,vista以上版本还没测试。
但还有一点疑问,在打开文件时,记录了文件FileObject,这里得到的FileObject还是和打开时不同,还有映像的FileObject也和打开对象不同,比较奇怪。
NTSTATUS GetFullName(HANDLE KeyHandle,char *fullname)
{
NTSTATUS ns;
PVOID pKey=NULL,pFile=NULL;
UNICODE_STRING fullUniName;
ANSI_STRING akeyname;
ULONG actualLen;
UNICODE_STRING dosName;
//char name_c[260] = {0};
// PVOID datafile;
UNREFERENCED_PARAMETER(actualLen);
fullUniName.Buffer=NULL;
fullUniName.Length=0;
fullname[0]=0x00;
ns= ObReferenceObjectByHandle( KeyHandle, 0, NULL, KernelMode, &pKey, NULL ) ;
if( !NT_SUCCESS(ns))
{
return ns;
}
fullUniName.Buffer = ExAllocatePool( PagedPool, MAX_PATH_LEN*2);//1024*2
fullUniName.MaximumLength = MAX_PATH_LEN*2;
__try
{
// KdPrint(("GetFullName 0\r\n"));
pFile=(PVOID)*(ULONG *)((char *)pKey+20);
pFile=(PVOID)*(ULONG *)((char *)pFile);
pFile=(PVOID)*(ULONG *)((char *)pFile+36);
//add------ not test for vista
//因为有缓存机制,需要重datasection中获得文件名
pFile = ((PFILE_OBJECT)pFile)->SectionObjectPointer->DataSectionObject;
pFile =(PVOID)*(ULONG *)((char *)pFile+36);
//added-------
ObReferenceObjectByPointer(pFile, 0, NULL, KernelMode);
//RtlVolumeDeviceToDosName(((PFILE_OBJECT)pFile)->DeviceObject,&dosName);
IoVolumeDeviceToDosName(((PFILE_OBJECT)pFile)->DeviceObject,&dosName);
//ns=ObQueryNameString( pFile, fullUniName, MAX_PATH_LEN, &actualLen );
RtlCopyUnicodeString(&fullUniName, &dosName);
RtlAppendUnicodeStringToString(&fullUniName,&((PFILE_OBJECT)pFile)->FileName);
ObDereferenceObject(pFile);
ObDereferenceObject(pKey );
RtlUnicodeStringToAnsiString( &akeyname, &fullUniName, TRUE );
if(akeyname.Length
{
memcpy(fullname,akeyname.Buffer,akeyname.Length);
fullname[akeyname.Length]=0x00;
}
else
{
memcpy(fullname,akeyname.Buffer,MAX_PATH_LEN);
fullname[MAX_PATH_LEN-1]=0x00;
}
RtlFreeAnsiString( &akeyname );
ExFreePool(dosName.Buffer);
ExFreePool( fullUniName.Buffer );
return STATUS_SUCCESS;
}
__except(1)
{
KdPrint(("GetFullName except\r\n"));
if(fullUniName.Buffer) ExFreePool( fullUniName.Buffer );
if(pKey) ObDereferenceObject(pKey );
return STATUS_SUCCESS;
}
}