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.
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.