S
also ich habs jetzt hinbekommen!
nur hab ich scheinbar bei der ganzen aktion einen windows bug gefunden. anders kann ich mir das nicht mehr erklären. kommentiert mal den aufruf von "NtQueryInformationFile" im GetHandleNameThreadProc aus, danach wird das programm unschließber. hilft meistens nur noch ein druck auf den resetknopf. ich will garnicht daran denken, wenn sowas ein trojaner oder virus ausnützt.
wie auch immer der code:
NTDDKFunctions.h
#ifndef __NT_DDK_FUNC_H__
#define __NT_DDK_FUNC_H__
#include <windows.h>
#pragma pack( push, 1 )
///////////////////////////////////////////////////////////////
typedef LONG NTSTATUS;
#define STATUS_SUCCESS ((NTSTATUS)0x00000000L)
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS)0xC0000004L)
///////////////////////////////////////////////////////////////
typedef struct _UNICODE_STRING {
USHORT Length;
USHORT MaximumLength;
PWSTR Buffer;
} UNICODE_STRING, *PUNICODE_STRING;
typedef enum _SYSTEM_INFORMATION_CLASS {
SystemInformationClassMin = 0,
SystemBasicInformation = 0,
SystemProcessorInformation = 1,
SystemPerformanceInformation = 2,
SystemTimeOfDayInformation = 3,
SystemPathInformation = 4,
SystemNotImplemented1 = 4,
SystemProcessInformation = 5,
SystemProcessesAndThreadsInformation = 5,
SystemCallCountInfoInformation = 6,
SystemCallCounts = 6,
SystemDeviceInformation = 7,
SystemConfigurationInformation = 7,
SystemProcessorPerformanceInformation = 8,
SystemProcessorTimes = 8,
SystemFlagsInformation = 9,
SystemGlobalFlag = 9,
SystemCallTimeInformation = 10,
SystemNotImplemented2 = 10,
SystemModuleInformation = 11,
SystemLocksInformation = 12,
SystemLockInformation = 12,
SystemStackTraceInformation = 13,
SystemNotImplemented3 = 13,
SystemPagedPoolInformation = 14,
SystemNotImplemented4 = 14,
SystemNonPagedPoolInformation = 15,
SystemNotImplemented5 = 15,
SystemHandleInformation = 16,
SystemObjectInformation = 17,
SystemPageFileInformation = 18,
SystemPagefileInformation = 18,
SystemVdmInstemulInformation = 19,
SystemInstructionEmulationCounts = 19,
SystemVdmBopInformation = 20,
SystemInvalidInfoClass1 = 20,
SystemFileCacheInformation = 21,
SystemCacheInformation = 21,
SystemPoolTagInformation = 22,
SystemInterruptInformation = 23,
SystemProcessorStatistics = 23,
SystemDpcBehaviourInformation = 24,
SystemDpcInformation = 24,
SystemFullMemoryInformation = 25,
SystemNotImplemented6 = 25,
SystemLoadImage = 26,
SystemUnloadImage = 27,
SystemTimeAdjustmentInformation = 28,
SystemTimeAdjustment = 28,
SystemSummaryMemoryInformation = 29,
SystemNotImplemented7 = 29,
SystemNextEventIdInformation = 30,
SystemNotImplemented8 = 30,
SystemEventIdsInformation = 31,
SystemNotImplemented9 = 31,
SystemCrashDumpInformation = 32,
SystemExceptionInformation = 33,
SystemCrashDumpStateInformation = 34,
SystemKernelDebuggerInformation = 35,
SystemContextSwitchInformation = 36,
SystemRegistryQuotaInformation = 37,
SystemLoadAndCallImage = 38,
SystemPrioritySeparation = 39,
SystemPlugPlayBusInformation = 40,
SystemNotImplemented10 = 40,
SystemDockInformation = 41,
SystemNotImplemented11 = 41,
/* SystemPowerInformation = 42, Conflicts with POWER_INFORMATION_LEVEL 1 */
SystemInvalidInfoClass2 = 42,
SystemProcessorSpeedInformation = 43,
SystemInvalidInfoClass3 = 43,
SystemCurrentTimeZoneInformation = 44,
SystemTimeZoneInformation = 44,
SystemLookasideInformation = 45,
SystemSetTimeSlipEvent = 46,
SystemCreateSession = 47,
SystemDeleteSession = 48,
SystemInvalidInfoClass4 = 49,
SystemRangeStartInformation = 50,
SystemVerifierInformation = 51,
SystemAddVerifier = 52,
SystemSessionProcessesInformation = 53,
SystemInformationClassMax
} SYSTEM_INFORMATION_CLASS;
///////////////////////////////////////////////////////////////
typedef struct _SYSTEM_HANDLE_TABLE_ENTRY_INFO {
ULONG ProcessId;
UCHAR ObjectTypeNumber;
UCHAR Flags;
USHORT Handle;
PVOID Object;
ACCESS_MASK GrantedAccess;
} SYSTEM_HANDLE_TABLE_ENTRY_INFO, *PSYSTEM_HANDLE_TABLE_ENTRY_INFO;
typedef struct _SYSTEM_HANDLE_INFORMATION {
ULONG NumberOfHandles;
SYSTEM_HANDLE_TABLE_ENTRY_INFO Handles[ 1 ];
} SYSTEM_HANDLE_INFORMATION, *PSYSTEM_HANDLE_INFORMATION;
typedef enum _OBJECT_INFORMATION_CLASS {
ObjectBasicInformation,
ObjectNameInformation,
ObjectTypeInformation,
ObjectAllTypesInformation,
ObjectHandleInformation
} OBJECT_INFORMATION_CLASS;
#define OB_TYPE_TYPE 1
#define OB_TYPE_DIRECTORY 2
#define OB_TYPE_SYMBOLIC_LINK 3
#define OB_TYPE_TOKEN 4
#define OB_TYPE_PROCESS 5
#define OB_TYPE_THREAD 6
#define OB_TYPE_EVENT 7
#define OB_TYPE_EVENT_PAIR 8
#define OB_TYPE_MUTANT 9
#define OB_TYPE_SEMAPHORE 10
#define OB_TYPE_TIMER 11
#define OB_TYPE_PROFILE 12
#define OB_TYPE_WINDOW_STATION 13
#define OB_TYPE_DESKTOP 14
#define OB_TYPE_SECTION 15
#define OB_TYPE_KEY 16
#define OB_TYPE_PORT 17
#define OB_TYPE_ADAPTER 18
#define OB_TYPE_CONTROLLER 19
#define OB_TYPE_DEVICE 20
#define OB_TYPE_DRIVER 21
#define OB_TYPE_IO_COMPLETION 22
#define OB_TYPE_FILE 23
typedef struct _OBJECT_NAME_INFORMATION {
UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION, *POBJECT_NAME_INFORMATION;
typedef struct _OBJECT_ATTRIBUTES {
ULONG Length;
HANDLE RootDirectory;
UNICODE_STRING *ObjectName;
ULONG Attributes;
PSECURITY_DESCRIPTOR SecurityDescriptor;
PSECURITY_QUALITY_OF_SERVICE SecurityQualityOfService;
} OBJECT_ATTRIBUTES,*POBJECT_ATTRIBUTES;
///////////////////////////////////////////////////////////////
typedef struct _IO_STATUS_BLOCK {
DWORD Status;
ULONG Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;
#define FILE_SUPERSEDE 0x00000000
#define FILE_OPEN 0x00000001
#define FILE_CREATE 0x00000002
#define FILE_OPEN_IF 0x00000003
#define FILE_OVERWRITE 0x00000004
#define FILE_OVERWRITE_IF 0x00000005
#define FILE_MAXIMUM_DISPOSITION 0x00000005
typedef enum _FILE_INFORMATION_CLASS {
FileDirectoryInformation = 1,
FileFullDirectoryInformation,
FileBothDirectoryInformation,
FileBasicInformation,
FileStandardInformation,
FileInternalInformation,
FileEaInformation,
FileAccessInformation,
FileNameInformation,
FileRenameInformation,
FileLinkInformation,
FileNamesInformation,
FileDispositionInformation,
FilePositionInformation,
FileFullEaInformation,
FileModeInformation,
FileAlignmentInformation,
FileAllInformation,
FileAllocationInformation,
FileEndOfFileInformation,
FileAlternateNameInformation,
FileStreamInformation,
FilePipeInformation,
FilePipeLocalInformation,
FilePipeRemoteInformation,
FileMailslotQueryInformation,
FileMailslotSetInformation,
FileCompressionInformation,
FileCopyOnWriteInformation,
FileCompletionInformation,
FileMoveClusterInformation,
FileOleClassIdInformation,
FileOleStateBitsInformation,
FileNetworkOpenInformation,
FileObjectIdInformation,
FileOleAllInformation,
FileOleDirectoryInformation,
FileContentIndexInformation,
FileInheritContentIndexInformation,
FileOleInformation,
FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;
///////////////////////////////////////////////////////////////
typedef LONG TDI_STATUS;
typedef PVOID CONNECTION_CONTEXT;
typedef struct _TDI_CONNECTION_INFORMATION {
LONG UserDataLength;
PVOID UserData;
LONG OptionsLength;
PVOID Options;
LONG RemoteAddressLength;
PVOID RemoteAddress;
} TDI_CONNECTION_INFORMATION, *PTDI_CONNECTION_INFORMATION;
typedef struct _TDI_REQUEST {
union {
HANDLE AddressHandle;
CONNECTION_CONTEXT ConnectionContext;
HANDLE ControlChannel;
} Handle;
PVOID RequestNotifyObject;
PVOID RequestContext;
TDI_STATUS TdiStatus;
} TDI_REQUEST, *PTDI_REQUEST;
typedef struct _TDI_REQUEST_QUERY_INFORMATION {
TDI_REQUEST Request;
ULONG QueryType;
PTDI_CONNECTION_INFORMATION RequestConnectionInformation;
} TDI_REQUEST_QUERY_INFORMATION, *PTDI_REQUEST_QUERY_INFORMATION;
#define TDI_QUERY_ADDRESS_INFO 0x00000003
#define TDI_QUERY_CONNECTION_INFO 0x00000004
typedef struct _TA_ADDRESS {
USHORT AddressLength;
USHORT AddressType;
UCHAR Address[ 1 ];
} TA_ADDRESS, *PTA_ADDRESS;
#define TDI_ADDRESS_TYPE_UNSPEC 0
#define TDI_ADDRESS_TYPE_UNIX 1
#define TDI_ADDRESS_TYPE_IP 2
#define TDI_ADDRESS_TYPE_IMPLINK 3
#define TDI_ADDRESS_TYPE_PUP 4
#define TDI_ADDRESS_TYPE_CHAOS 5
#define TDI_ADDRESS_TYPE_NS 6
#define TDI_ADDRESS_TYPE_IPX 6
#define TDI_ADDRESS_TYPE_NBS 7
#define TDI_ADDRESS_TYPE_ECMA 8
#define TDI_ADDRESS_TYPE_DATAKIT 9
#define TDI_ADDRESS_TYPE_CCITT 10
#define TDI_ADDRESS_TYPE_SNA 11
#define TDI_ADDRESS_TYPE_DECnet 12
#define TDI_ADDRESS_TYPE_DLI 13
#define TDI_ADDRESS_TYPE_LAT 14
#define TDI_ADDRESS_TYPE_HYLINK 15
#define TDI_ADDRESS_TYPE_APPLETALK 16
#define TDI_ADDRESS_TYPE_NETBIOS 17
#define TDI_ADDRESS_TYPE_8022 18
#define TDI_ADDRESS_TYPE_OSI_TSAP 19
#define TDI_ADDRESS_TYPE_NETONE 20
#define TDI_ADDRESS_TYPE_VNS 21
#define TDI_ADDRESS_TYPE_NETBIOS_EX 22
#define TDI_ADDRESS_TYPE_IP6 23
#define TDI_ADDRESS_TYPE_NETBIOS_UNICODE_EX 24
typedef struct _TRANSPORT_ADDRESS {
LONG TAAddressCount;
TA_ADDRESS Address[ 1 ];
} TRANSPORT_ADDRESS, *PTRANSPORT_ADDRESS;
typedef struct _TDI_ADDRESS_INFO {
ULONG ActivityCount;
TRANSPORT_ADDRESS Address;
} TDI_ADDRESS_INFO, *PTDI_ADDRESS_INFO;
typedef struct _TDI_ADDRESS_IP {
USHORT sin_port;
ULONG in_addr;
UCHAR sin_zero[ 8 ];
} TDI_ADDRESS_IP, *PTDI_ADDRESS_IP;
typedef struct _TA_ADDRESS_IP {
LONG TAAddressCount;
struct _AddrIp {
USHORT AddressLength;
USHORT AddressType;
TDI_ADDRESS_IP Address[ 1 ];
} Address[ 1 ];
} TA_ADDRESS_IP, *PTA_ADDRESS_IP;
///////////////////////////////////////////////////////////////
#pragma pack( pop )
#endif
Port.cpp
#include "NTDDKFunctions.h"
#include <stdio.h>
#include <vector>
typedef NTSTATUS (WINAPI* NtQuerySystemInformationProc)( SYSTEM_INFORMATION_CLASS SystemInformationClass, PVOID SystemInformation, ULONG SystemInformationLength, PULONG ReturnLength );
typedef NTSTATUS (WINAPI* NtQueryObjectProc)( HANDLE ObjectHandle, OBJECT_INFORMATION_CLASS ObjectInformationClass, PVOID ObjectInformation, ULONG Length, PULONG ResultLength );
typedef NTSTATUS (WINAPI* NtOpenFileProc)( OUT PHANDLE FileHandle, IN ACCESS_MASK DesiredAccess, IN POBJECT_ATTRIBUTES ObjectAttributes, OUT PIO_STATUS_BLOCK IoStatusBlock, IN ULONG ShareAccess, IN ULONG OpenOptions );
typedef NTSTATUS (WINAPI* NtQueryInformationFileProc)( IN HANDLE FileHandle, OUT PIO_STATUS_BLOCK IoStatusBlock, OUT PVOID FileInformation, IN ULONG Length, IN FILE_INFORMATION_CLASS FileInformationClass );
typedef VOID (WINAPI* RtlInitUnicodeStringProc)( IN OUT PUNICODE_STRING DestinationString, IN PCWSTR SourceString );
#define DEVICE_NAME_TCP L"\\Device\\Tcp"
#define DEVICE_NAME_UDP L"\\Device\\Udp"
#pragma warning( disable: 4786 )
typedef struct
{
unsigned long nPID;
unsigned long nIP;
unsigned long nPort;
} OpenPort;
typedef std::vector< OpenPort > OpenPortList;
bool GetPortHandleTypes( unsigned char* lpnObjectTypeTCP, unsigned char* lpnObjectTypeUDP );
void GetOpenPorts( unsigned char nObjectTypeTCP, unsigned char nObjectTypeUDP, OpenPortList* lpPortListTCP, OpenPortList* lpPortListUDP );
void UniqueAddList( OpenPortList* lpList, OpenPort* lpstrOpenPort );
bool IsRemoteDevice( HANDLE hDevice );
bool GetIPAddrTDI( HANDLE hDevice, unsigned long* lpnIP, unsigned short* lpnPort );
typedef struct
{
HANDLE hHandle;
UNICODE_STRING* lpstrBuffer;
unsigned long nBufferSize;
NtQueryObjectProc NtQueryObject;
NtQueryInformationFileProc NtQueryInformationFile;
} GetHandleNameThreadProcParam;
bool GetHandleName( HANDLE hHandle, UNICODE_STRING* lpstrBuffer, unsigned long nBufferSize );
unsigned long __stdcall GetHandleNameThreadProc( GetHandleNameThreadProcParam* lpParam );
#define printf printf
bool EnablePrivilege( const char* lpszPrivName )
{
HANDLE hToken;
// open token
if( OpenProcessToken( GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, &hToken ) )
{
bool bRet = false;
// get LUID
LUID LUIDDebugNameValue;
if( LookupPrivilegeValue( NULL, lpszPrivName, &LUIDDebugNameValue ) )
{
// enable
TOKEN_PRIVILEGES strTokenPriv;
strTokenPriv.PrivilegeCount = 1;
strTokenPriv.Privileges[ 0 ].Luid = LUIDDebugNameValue;
strTokenPriv.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
// do set
if( AdjustTokenPrivileges( hToken, false, &strTokenPriv, sizeof( strTokenPriv ), NULL, NULL ) )
bRet = true;
else
{
printf( "ERROR - couldn't set token privilege: %u\n", GetLastError() );
bRet = false;
}
}
else
{
printf( "ERROR - couldn't lookup privilege value: %u\n", GetLastError() );
bRet = false;
}
CloseHandle( hToken );
return bRet;
}
else
{
printf( "ERROR - couldn't open process token: %u\n", GetLastError() );
return false;
}
}
SYSTEM_HANDLE_INFORMATION* DumpHandles()
{
// load functions
HMODULE hNTDLL = LoadLibrary( "ntdll.dll" );
NtQuerySystemInformationProc NtQuerySystemInformation = (NtQuerySystemInformationProc)GetProcAddress( hNTDLL, "NtQuerySystemInformation" );
if( NtQuerySystemInformation )
{
// get handles
void* lpBuffer = NULL;
unsigned long nBufferLen = 0;
long nError;
do
{
// free old buffer
if( lpBuffer )
free( lpBuffer );
// allocte new buffer
nBufferLen += 65536;
lpBuffer = malloc( nBufferLen );
if( !lpBuffer )
{
printf( "ERROR - out of memory: %u\n", GetLastError() );
return NULL;
}
} while( ( nError = NtQuerySystemInformation( SystemHandleInformation, lpBuffer, nBufferLen, NULL ) ) == STATUS_INFO_LENGTH_MISMATCH );
if( nError == STATUS_SUCCESS )
return (SYSTEM_HANDLE_INFORMATION*)lpBuffer;
else
{
printf( "ERROR - NtQuerySystemInformation failed: %#08x\n", nError );
return NULL;
}
}
else
printf( "ERROR - couldn't load functions from dll: %u\n", GetLastError() );
return NULL;
}
void main()
{
// enable debug privilege
if( !EnablePrivilege( SE_DEBUG_NAME ) )
printf( "WARNING - couldn't enable debug privilege\n" );
// get handle types of \\Device\\Tcp and \\Device\\Udp - depends on the Windows version
unsigned char nHandleTypeTCP;
unsigned char nHandleTypeUDP;
if( GetPortHandleTypes( &nHandleTypeTCP, &nHandleTypeUDP ) )
{
printf( "[+] checking system handle list...\n" );
// get open port
OpenPortList PortListTCP;
OpenPortList PortListUDP;
GetOpenPorts( nHandleTypeTCP, nHandleTypeUDP, &PortListTCP, &PortListUDP );
// output
printf( "[+] all handles checked...\n" );
if( PortListTCP.size() || PortListUDP.size() )
{
printf( "\n%-*s %-*s %-*s\n", 3, "PID", 5, "Proto", 6, "Port" );
printf( "------------------------\n" );
for( int n = 0; n < PortListTCP.size(); n ++ )
printf( "%-*u %-*s %-*u\n", 3, PortListTCP[ n ].nPID, 5, "TCP", 6, (unsigned long)PortListTCP[ n ].nPort );
for( n = 0; n < PortListUDP.size(); n ++ )
printf( "%-*u %-*s %-*u\n", 3, PortListUDP[ n ].nPID, 5, "UDP", 6, (unsigned long)PortListUDP[ n ].nPort );
}
else
printf( "ERROR - couldn't get open ports\n" );
}
else
printf( "ERROR - couldn't get open device handle types\n" );
}
bool GetPortHandleTypes( unsigned char* lpnObjectTypeTCP, unsigned char* lpnObjectTypeUDP )
{
// load functions
HMODULE hNTDLL = LoadLibrary( "ntdll.dll" );
NtOpenFileProc NtOpenFile = (NtOpenFileProc)GetProcAddress( hNTDLL, "NtOpenFile" );
RtlInitUnicodeStringProc RtlInitUnicodeString = (RtlInitUnicodeStringProc)GetProcAddress( hNTDLL, "RtlInitUnicodeString" );
if( NtOpenFile && RtlInitUnicodeString )
{
// init unicode string
UNICODE_STRING strNameTCP, strNameUDP;
RtlInitUnicodeString( &strNameTCP, DEVICE_NAME_TCP );
RtlInitUnicodeString( &strNameUDP, DEVICE_NAME_UDP );
// object attributes
OBJECT_ATTRIBUTES strObjAttr = { 0 };
strObjAttr.Length = sizeof( strObjAttr );
long nError;
IO_STATUS_BLOCK strIOStat;
// open TCP handle
HANDLE hTCP;
strObjAttr.ObjectName = &strNameTCP;
nError = NtOpenFile( &hTCP, FILE_GENERIC_READ, &strObjAttr, &strIOStat, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN );
if( nError != STATUS_SUCCESS )
{
printf( "ERROR - couldn't open an TCP device handle: %#08x\n", nError );
return false;
}
// open UDP handle
HANDLE hUDP;
strObjAttr.ObjectName = &strNameUDP;
nError = NtOpenFile( &hUDP, FILE_GENERIC_READ, &strObjAttr, &strIOStat, FILE_SHARE_READ | FILE_SHARE_WRITE, FILE_OPEN );
if( nError != STATUS_SUCCESS )
{
CloseHandle( hTCP );
printf( "ERROR - couldn't open an UDP device handle: %#08x\n", nError );
return false;
}
// find handle types
bool bRet = false;
bool bFoundTCP = false;
bool bFoundUDP = false;
SYSTEM_HANDLE_INFORMATION* lpstrSysHandleInfo = DumpHandles();
if( lpstrSysHandleInfo )
{
for( unsigned long n = 0; n < lpstrSysHandleInfo->NumberOfHandles; n++ )
{
// only current process
if( lpstrSysHandleInfo->Handles[ n ].ProcessId != GetCurrentProcessId() )
continue;
// is TCP handle
if( !bFoundTCP && (HANDLE)lpstrSysHandleInfo->Handles[ n ].Handle == hTCP )
{
*lpnObjectTypeTCP = lpstrSysHandleInfo->Handles[ n ].ObjectTypeNumber;
bFoundTCP = true;
}
// is UDP handle
if( !bFoundUDP && (HANDLE)lpstrSysHandleInfo->Handles[ n ].Handle == hUDP )
{
*lpnObjectTypeUDP = lpstrSysHandleInfo->Handles[ n ].ObjectTypeNumber;
bFoundUDP = true;
}
// found all?
if( bFoundTCP && bFoundUDP )
break;
}
// found TCP and UDP?
bRet = ( bFoundTCP && bFoundUDP );
free( lpstrSysHandleInfo );
}
else
{
printf( "ERROR - failed to capture open handles\n" );
bRet = false;
}
// close handles
CloseHandle( hTCP );
CloseHandle( hUDP );
return bRet;
}
else
printf( "ERROR - couldn't load functions from dll: %u\n", GetLastError() );
return false;
}
void GetOpenPorts( unsigned char nObjectTypeTCP, unsigned char nObjectTypeUDP, OpenPortList* lpPortListTCP, OpenPortList* lpPortListUDP )
{
SYSTEM_HANDLE_INFORMATION* lpstrSysHandleInfo = DumpHandles();
if( lpstrSysHandleInfo )
{
for( unsigned long n = 0; n < lpstrSysHandleInfo->NumberOfHandles; n++ )
{
// skip PID 0 (System Idle Process)
if( !lpstrSysHandleInfo->Handles[ n ].ProcessId )
continue;
// skip non File/Device handles
if( lpstrSysHandleInfo->Handles[ n ].ObjectTypeNumber != nObjectTypeTCP && lpstrSysHandleInfo->Handles[ n ].ObjectTypeNumber != nObjectTypeUDP )
continue;
// skipp NT4 (SP6) BoD (Windows suckz)
if( lpstrSysHandleInfo->Handles[ n ].ProcessId == 2 && lpstrSysHandleInfo->Handles[ n ].Handle == 0x0100 )
continue;
// open process
HANDLE hProcess = NULL;
if( lpstrSysHandleInfo->Handles[ n ].ProcessId != GetCurrentProcessId() )
hProcess = OpenProcess( PROCESS_DUP_HANDLE, true, lpstrSysHandleInfo->Handles[ n ].ProcessId );
else
hProcess = GetCurrentProcess();
if( hProcess )
{
// get handle
HANDLE hHandle = NULL;
if( lpstrSysHandleInfo->Handles[ n ].ProcessId != GetCurrentProcessId() )
DuplicateHandle( hProcess, (HANDLE)lpstrSysHandleInfo->Handles[ n ].Handle, GetCurrentProcess(), &hHandle, 0, false, DUPLICATE_SAME_ACCESS );
else
hHandle = (HANDLE)lpstrSysHandleInfo->Handles[ n ].Handle;
if( hHandle )
{
// alloc name buffer
unsigned long nBufferSize = sizeof( UNICODE_STRING ) + ( sizeof( WCHAR ) * 32768 );
BYTE* lpBuffer = new BYTE[ nBufferSize ];
if( lpBuffer )
{
memset( lpBuffer, 0, nBufferSize );
// UNICODE_STRING struct
UNICODE_STRING* lpstrString = (UNICODE_STRING*)lpBuffer;
lpstrString->Length = 0;
lpstrString->MaximumLength = nBufferSize - sizeof( UNICODE_STRING );
lpstrString->Buffer = (WCHAR*)&lpBuffer[ sizeof( UNICODE_STRING ) ];
if( GetHandleName( hHandle, lpstrString, nBufferSize ) )
{
// sometimes this is reseted
lpstrString->Buffer = (WCHAR*)&lpBuffer[ sizeof( UNICODE_STRING ) ];
// check device type an get address
unsigned long nIP;
unsigned short nPort;
if( !wcscmp( lpstrString->Buffer, DEVICE_NAME_TCP ) )
{
// TCP DeviceFile
if( !IsRemoteDevice( hHandle ) ) // not implemented yet :|
{
if( GetIPAddrTDI( hHandle, &nIP, &nPort ) )
{
OpenPort strOpenPort;
strOpenPort.nPID = lpstrSysHandleInfo->Handles[ n ].ProcessId;
strOpenPort.nIP = nIP;
strOpenPort.nPort = nPort;
UniqueAddList( lpPortListTCP, &strOpenPort );
}
else
printf( "WARNING - couldn't get address info PID=%u Handle=%#08x\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, (unsigned long)lpstrSysHandleInfo->Handles[ n ].Handle );
}
}
else if( !wcscmp( lpstrString->Buffer, DEVICE_NAME_UDP ) )
{
// UDP DeviceFile
if( GetIPAddrTDI( hHandle, &nIP, &nPort ) )
{
OpenPort strOpenPort;
strOpenPort.nPID = lpstrSysHandleInfo->Handles[ n ].ProcessId;
strOpenPort.nIP = nIP;
strOpenPort.nPort = nPort;
UniqueAddList( lpPortListUDP, &strOpenPort );
}
else
printf( "WARNING - couldn't get address info PID=%u Handle=%#08x\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, (unsigned long)lpstrSysHandleInfo->Handles[ n ].Handle );
}
}
else
printf( "WARNING - couldn't get handle name PID=%u Handle=%#08x\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, (unsigned long)lpstrSysHandleInfo->Handles[ n ].Handle );
delete [] lpBuffer;
}
else
printf( "WARNING - out of memory on PID=%u Handle=%#08x: %u\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, (unsigned long)lpstrSysHandleInfo->Handles[ n ].Handle, GetLastError() );
CloseHandle( hHandle );
}
else
printf( "WARNING - couldn't duplicate handle PID=%u Handle=%#08x: %u\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, (unsigned long)lpstrSysHandleInfo->Handles[ n ].Handle, GetLastError() );
CloseHandle( hProcess );
}
else
printf( "WARNING - couldn't open process PID=%u: %u\n", lpstrSysHandleInfo->Handles[ n ].ProcessId, GetLastError() );
}
free( lpstrSysHandleInfo );
}
else
printf( "ERROR - failed to capture open handles\n" );
}
void UniqueAddList( OpenPortList* lpList, OpenPort* lpstrOpenPort )
{
// allready in list?
for( int n = 0; n < lpList->size(); n++ )
{
if( !memcmp( &( (*lpList)[ n ] ), lpstrOpenPort, sizeof( OpenPort ) ) )
return;
}
// not found -> add
lpList->push_back( *lpstrOpenPort );
}
bool IsRemoteDevice( HANDLE hDevice )
{
// async struct
OVERLAPPED strOverlapped = { 0 };
// request
TDI_REQUEST_QUERY_INFORMATION strQueryInfo = { 0 };
strQueryInfo.QueryType = TDI_QUERY_CONNECTION_INFO;
// query
unsigned long nBytesReturned;
BYTE buffer[ 65536 ] = { 0 };
if( !DeviceIoControl( hDevice, 0x210012, &strQueryInfo, sizeof( strQueryInfo ), buffer, sizeof( buffer ), &nBytesReturned, &strOverlapped ) )
return false;
return true;
}
bool GetIPAddrTDI( HANDLE hDevice, unsigned long* lpnIP, unsigned short* lpnPort )
{
// async struct
OVERLAPPED strOverlapped = { 0 };
// request
TDI_REQUEST_QUERY_INFORMATION strQueryInfo = { 0 };
strQueryInfo.QueryType = TDI_QUERY_ADDRESS_INFO;
// do query
unsigned long nBytesReturned;
BYTE buffer[ 65536 ] = { 0 };
if( !DeviceIoControl( hDevice, 0x210012, &strQueryInfo, sizeof( strQueryInfo ), buffer, sizeof( buffer ), &nBytesReturned, &strOverlapped ) )
return false;
// parse info
TDI_ADDRESS_INFO* lpstrAddrInfo = (TDI_ADDRESS_INFO*)buffer;
if( lpstrAddrInfo->Address.TAAddressCount == 1 ) // only one IP per socket
{
if( lpstrAddrInfo->Address.Address[ 0 ].AddressType == TDI_ADDRESS_TYPE_IP ) // parse only IP protocol
{
TDI_ADDRESS_IP* lpstrIPAddr = (TDI_ADDRESS_IP*)&lpstrAddrInfo->Address.Address[ 0 ].Address;
*lpnIP = ntohl( lpstrIPAddr->in_addr );
*lpnPort = ntohs( lpstrIPAddr->sin_port );
return true;
}
else
return false;
}
else
return false;
}
bool GetHandleName( HANDLE hHandle, UNICODE_STRING* lpstrBuffer, unsigned long nBufferSize )
{
// load functions
HMODULE hNTDLL = LoadLibrary( "ntdll.dll" );
NtQueryObjectProc NtQueryObject = (NtQueryObjectProc)GetProcAddress( hNTDLL, "NtQueryObject" );
NtQueryInformationFileProc NtQueryInformationFile = (NtQueryInformationFileProc)GetProcAddress( hNTDLL, "NtQueryInformationFile" );
if( NtQueryObject && NtQueryInformationFile )
{
// make thread parameter
GetHandleNameThreadProcParam strParam = { 0 };
strParam.hHandle = hHandle;
strParam.lpstrBuffer = lpstrBuffer;
strParam.nBufferSize = nBufferSize;
strParam.NtQueryObject = NtQueryObject;
strParam.NtQueryInformationFile = NtQueryInformationFile;
// create thread
unsigned long nThreadID;
HANDLE hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)GetHandleNameThreadProc, &strParam, 0, &nThreadID );
if( hThread )
{
// faster execution
SetThreadPriority( hThread, THREAD_PRIORITY_TIME_CRITICAL );
Sleep( 0 );
// wait for exit or timeout
bool bRet;
if( WaitForSingleObject( hThread, 150 ) == WAIT_OBJECT_0 )
{
// thread exited
// get exit code
unsigned long nExitCode;
if( GetExitCodeThread( hThread, &nExitCode ) )
bRet = ( nExitCode == STATUS_SUCCESS );
else
bRet = false;
}
else
{
// timeout
TerminateThread( hThread, 0 );
bRet = false;
}
CloseHandle( hThread );
return bRet;
}
else
return false;
}
else
return false;
}
unsigned long __stdcall GetHandleNameThreadProc( GetHandleNameThreadProcParam* lpParam )
{
// skip deadlock (without this the thread couldn't be closed/terminated) - Windows suckz!
// ---
char szBuffer[ 65536 ];
IO_STATUS_BLOCK strIOStat;
lpParam->NtQueryInformationFile( lpParam->hHandle, &strIOStat, szBuffer, sizeof( szBuffer ), FileNameInformation );
// ---
return lpParam->NtQueryObject( lpParam->hHandle, ObjectNameInformation, lpParam->lpstrBuffer, lpParam->nBufferSize, NULL );
}