Click to See Complete Forum and Search --> : About list the opened file handles.


TimiXu
June 29th, 2007, 04:55 AM
I write a programe to list the opened file handles. There is source code.
It can be compiled by vc6.0 as console project.

#include <windows.h>

#define NTAPI __stdcall
typedef LONG NTSTATUS;
#define IN
#define OUT
#define OPTIONAL

#define SystemHandleInformation 16

typedef struct _HANDLE_ENTRY
{
DWORD ProcessID;
WORD HandleType;
WORD HandleNumber;
DWORD KernelAddress;
DWORD Flags;
} HANDLE_ENTRY;

typedef struct _HANDLE_INFORMATION
{
DWORD Count;
HANDLE_ENTRY Handles[1];
} HANDLE_INFORMATION;


#define SYSTEM_INFORMATION_CLASS ULONG
#define OBJECT_INFORMATION_CLASS ULONG

typedef struct _IO_STATUS_BLOCK
{
LONG Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

#define FileNameInformation 9

typedef struct _FILE_NAME_INFORMATION
{
ULONG FileNameLength;
WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;


typedef
NTSTATUS
(NTAPI *NT_QUERY_SYSTEM_INFORMATION ) (
IN SYSTEM_INFORMATION_CLASS SystemInformationClass,
OUT PVOID SystemInformation,
IN ULONG SystemInformationLength,
OUT PULONG ReturnLength OPTIONAL
);


typedef
NTSTATUS
(NTAPI *NT_QUERY_OBJECT) (
IN HANDLE Handle,
IN OBJECT_INFORMATION_CLASS ObjectInformationClass,
IN PVOID ObjectInformation,
IN ULONG ObjectInformationLength,
OUT PULONG ReturnLength
);

typedef
NTSTATUS
(NTAPI *NT_QUERY_INFORMATION_FILE)(
IN HANDLE FileHandle,
OUT PIO_STATUS_BLOCK IoStatusBlock,
OUT PVOID FileInformation,
IN ULONG Length,
IN ULONG FileInformationClass
);


NT_QUERY_SYSTEM_INFORMATION pNtQuerySystemInformation;
NT_QUERY_OBJECT pNtQueryObject;
NT_QUERY_INFORMATION_FILE pNtQueryInformationFile;


#include <stdio.h>
void Trace(const char* szFormat, ...)
{
va_list args;
int nBuf;
TCHAR szBuffer[512];

va_start(args, szFormat);

nBuf = _vsnprintf(szBuffer, sizeof(szBuffer)/sizeof(TCHAR), szFormat, args);

OutputDebugString(szBuffer);

va_end(args);
}

void EnableDebugPriv( void )
{
HANDLE hToken;
LUID sedebugnameValue;
TOKEN_PRIVILEGES tkp;

if ( ! OpenProcessToken( GetCurrentProcess(),
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
return;

if ( ! LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
{
CloseHandle( hToken );
return;
}

tkp.PrivilegeCount = 1;
tkp.Privileges[0].Luid = sedebugnameValue;
tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof tkp, NULL, NULL );

CloseHandle( hToken );
}

VOID LoadFunctionPointer( )
{
PVOID ProcAddr;
HANDLE hNtDll;

hNtDll = GetModuleHandleW(L"ntdll.dll");

ProcAddr = GetProcAddress( hNtDll,
"NtQuerySystemInformation"
);
pNtQuerySystemInformation =(NT_QUERY_SYSTEM_INFORMATION) ProcAddr;

ProcAddr = GetProcAddress( hNtDll,
"NtQueryObject"
);
pNtQueryObject = (NT_QUERY_OBJECT) ProcAddr;

ProcAddr = GetProcAddress( hNtDll,
"NtQueryInformationFile"
);
pNtQueryInformationFile = (NT_QUERY_INFORMATION_FILE) ProcAddr;
}

void
CloneHandle(
ULONG ProcessId,
HANDLE hRemoteObject,
HANDLE* hLocalObject
)
{
BOOL IsSelfProcess;
HANDLE hRemoteProcess;

IsSelfProcess = ( ProcessId == GetCurrentProcessId( ) ) ? TRUE: FALSE;
if( IsSelfProcess )
*hLocalObject = NULL;
else
{
hRemoteProcess = OpenProcess( PROCESS_DUP_HANDLE,
TRUE,
ProcessId
);
DuplicateHandle( hRemoteProcess,
hRemoteObject,
GetCurrentProcess(),
hLocalObject,
0,
1,
DUPLICATE_SAME_ACCESS
);
CloseHandle( hRemoteProcess );
}
}

DWORD __stdcall GetFileNameThread(
PVOID para
)
{
ULONG status;
HANDLE hFileObject ;
IO_STATUS_BLOCK IoStatus;
PFILE_NAME_INFORMATION FileNameInfo = malloc(1024);

hFileObject=para;
status = pNtQueryInformationFile( hFileObject,
&IoStatus,
FileNameInfo,
1024,
9
);
if( status == 0 )
{
Trace("FileName:%ws\n", FileNameInfo->FileName );
printf("FileName:%ws\n", FileNameInfo->FileName );
}

free( FileNameInfo );
return 1;
}

void main( )
{
ULONG i;
ULONG DefaultLength = 4096;
ULONG RequiredLength;
HANDLE_INFORMATION* HandleInformation;

LoadFunctionPointer( );
EnableDebugPriv( );

HandleInformation = (HANDLE_INFORMATION*)malloc( DefaultLength );

pNtQuerySystemInformation( SystemHandleInformation,
HandleInformation,
DefaultLength,
&RequiredLength
);
free( HandleInformation );

HandleInformation = (HANDLE_INFORMATION*)malloc(RequiredLength);

pNtQuerySystemInformation( SystemHandleInformation,
HandleInformation,
RequiredLength,
&RequiredLength
);

for( i=0; i<HandleInformation->Count; i++ )
{
ULONG size;
PCHAR TypeName;
HANDLE hLocalObject;
HANDLE hCloneObject;

CloneHandle( HandleInformation->Handles[i].ProcessID,
(HANDLE)HandleInformation->Handles[i].HandleNumber,
&hLocalObject
);
if( hLocalObject == NULL )
hCloneObject = (HANDLE)HandleInformation->Handles[i].HandleNumber;
else
hCloneObject = hLocalObject;

//query object type
pNtQueryObject( hCloneObject, 2, NULL, 0, &size );
TypeName = malloc( size );

if ( pNtQueryObject( hCloneObject, 2, TypeName, size, NULL ) == 0 )
{
if( !_wcsicmp(L"File", (WCHAR*) (TypeName+0x60) ) )
{
//query file name
HANDLE hThread;
DWORD dwThreadId;

hThread = CreateThread( NULL,
0,
GetFileNameThread,
hLocalObject,
0,
&dwThreadId
);
if ( hThread == NULL )
return;

if ( WaitForSingleObject( hThread, 10 ) == WAIT_TIMEOUT )
TerminateThread( hThread, 0 );
}
}
if( hLocalObject == NULL )
CloseHandle( hCloneObject );
free( TypeName );
}
free(HandleInformation);
}

It can work, the output like this :

FileName:\Documents and Settings\LocalService\Local Settings\Application Data\Microsoft\Windows\UsrClass.dat
FileName:\pagefile.sys
FileName:\Documents and Settings\NetworkService\Local Settings\Application

the file name do not include "\Devcie\hardiskvolume0" characters, so I can not know which volume the file is store on. How to make the output include
the "\Devcie\hardiskvolume0" characters.
thank you very much.

Krishnaa
June 29th, 2007, 05:23 AM
Are you not getting the drive letter in file path ?

TimiXu
June 29th, 2007, 05:43 AM
From the source code, I using NtQueryInformationFile to get fullpath name.
but the function do not return the drive letter. I do not know why.
the PROCESS EXPLORER can get drive letter.

ashukasama
June 29th, 2007, 05:51 AM
Dear

in your

function

DWORD __stdcall GetFileNameThread(
PVOID para
)
{
ULONG status;
HANDLE hFileObject ;
IO_STATUS_BLOCK IoStatus;
PFILE_NAME_INFORMATION FileNameInfo = malloc(1024);

hFileObject=para;
status = pNtQueryInformationFile( hFileObject,
&IoStatus,
FileNameInfo,
1024,
9 // it should be some thing different
// FILE_INFORMATION_CLASS
// 9 is for FileNameInformation (http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/FILE_INFORMATION_CLASS.html#FileNameInformation) );
if( status == 0 )
{
Trace("FileName:%ws\n", FileNameInfo->FileName );
printf("FileName:%ws\n", FileNameInfo->FileName );
}

free( FileNameInfo );
return 1;
}

got thru this link will give you complete details

http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/NtQueryInformationFile.html

http://undocumented.ntinternals.net/UserMode/Undocumented%20Functions/NT%20Objects/File/FILE_INFORMATION_CLASS.html

may be it will be fuitful for you