/* * Copyleft (c) 2002, 2012 * The NSFOCUS INFORMATION TECHNOLOGY CO.,LTD. * ----------------------------------------------------------------------- * Author : NSFocus Security Team * : http://www.nsfocus.com * Maintain : scz * Version : 1.10 * Compile : For x86/EWindows XP SP1 & VC 7 * : cl enumservice.c /nologo /Os /G6 /Gs65536 /W3 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /link /RELEASE * : * Create : 2003-12-02 10:28 * Modify : 2003-12-03 22:51 * ----------------------------------------------------------------------- * The only thing they can't take from us are our minds. !H */ /* * 如果同时指定了target、username、password,就试着注销并重新建立SMB会话, * 最终注销SMB会话。否则本程序不影响SMB会话。 */ /************************************************************************ * * * Head File * * * ************************************************************************/ /* * #define _WIN32_WINNT 0x0501 */ #include #include #include #include #include /************************************************************************ * * * Macro * * * ************************************************************************/ #pragma comment( linker, "/INCREMENTAL:NO" ) #pragma comment( linker, "/subsystem:console" ) #pragma comment( lib, "kernel32.lib" ) #pragma comment( lib, "mpr.lib" ) #pragma comment( lib, "advapi32.lib" ) #define VERSION "1.10" /************************************************************************ * * * Function Prototype * * * ************************************************************************/ static void enumservice ( unsigned char *target ); static void PrintWin32ErrorCUI ( char *message, DWORD dwMessageId ); static BOOL SessionBegin ( unsigned char *username, unsigned char *password, unsigned char *resource ); static BOOL SessionEnd ( unsigned char *resource ); static void usage ( char *arg ); /************************************************************************ * * * Static Global Var * * * ************************************************************************/ /************************************************************************/ static void enumservice ( unsigned char *target ) { SC_HANDLE sc_handle = ( SC_HANDLE )NULL; DWORD BytesNeeded = 0, ServicesReturned = 0, ResumeHandle = 0, error = ERROR_SUCCESS, count, ServiceTypeIndex, CurrentStateIndex; LPENUM_SERVICE_STATUS enum_service_status = ( LPENUM_SERVICE_STATUS )NULL, p = ( LPENUM_SERVICE_STATUS )NULL; unsigned char * ServiceType[] = { "设备驱动程序", "文件系统驱动程序", "独立进程型服务", "共享进程型服务", "独立进程/桌面交互型服务", "共享进程/桌面交互型服务", "未知类型" }; unsigned char * CurrentState[] = { "停止", "正在启动", "正在停止", "运行", "正在恢复", "正在暂停", "暂停", "未知状态" }; sc_handle = OpenSCManager ( target, SERVICES_ACTIVE_DATABASE, SC_MANAGER_ENUMERATE_SERVICE | GENERIC_READ ); if ( NULL == sc_handle ) { PrintWin32ErrorCUI( "OpenSCManager() failed", GetLastError() ); goto enumservice_exit; } if ( FALSE == EnumServicesStatus ( sc_handle, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, NULL, 0, &BytesNeeded, &ServicesReturned, &ResumeHandle ) ) { error = GetLastError(); if ( ERROR_MORE_DATA != error ) { PrintWin32ErrorCUI( "EnumServicesStatus() failed [0]", error ); goto enumservice_exit; } } enum_service_status = ( LPENUM_SERVICE_STATUS )HeapAlloc ( GetProcessHeap(), HEAP_ZERO_MEMORY, BytesNeeded ); if ( NULL == enum_service_status ) { PrintWin32ErrorCUI( "HeapAlloc() failed [1]", ERROR_NOT_ENOUGH_MEMORY ); goto enumservice_exit; } if ( FALSE == EnumServicesStatus ( sc_handle, SERVICE_TYPE_ALL, SERVICE_STATE_ALL, enum_service_status, BytesNeeded, &BytesNeeded, &ServicesReturned, &ResumeHandle ) ) { PrintWin32ErrorCUI( "EnumServicesStatus() failed [1]", GetLastError() ); goto enumservice_exit; } p = enum_service_status; for ( count = 0; count < ServicesReturned; count++, p++ ) { if ( p->ServiceStatus.dwServiceType & SERVICE_KERNEL_DRIVER ) { ServiceTypeIndex = 0; } else if ( p->ServiceStatus.dwServiceType & SERVICE_FILE_SYSTEM_DRIVER ) { ServiceTypeIndex = 1; } else if ( p->ServiceStatus.dwServiceType & SERVICE_WIN32_OWN_PROCESS ) { ServiceTypeIndex = 2; if ( p->ServiceStatus.dwServiceType & SERVICE_INTERACTIVE_PROCESS ) { ServiceTypeIndex = 4; } } else if ( p->ServiceStatus.dwServiceType & SERVICE_WIN32_SHARE_PROCESS ) { ServiceTypeIndex = 3; if ( p->ServiceStatus.dwServiceType & SERVICE_INTERACTIVE_PROCESS ) { ServiceTypeIndex = 5; } } else { ServiceTypeIndex = 6; } switch ( p->ServiceStatus.dwCurrentState ) { case SERVICE_STOPPED: CurrentStateIndex = 0; break; case SERVICE_START_PENDING: CurrentStateIndex = 1; break; case SERVICE_STOP_PENDING: CurrentStateIndex = 2; break; case SERVICE_RUNNING: CurrentStateIndex = 3; break; case SERVICE_CONTINUE_PENDING: CurrentStateIndex = 4; break; case SERVICE_PAUSE_PENDING: CurrentStateIndex = 5; break; case SERVICE_PAUSED: CurrentStateIndex = 6; break; default: CurrentStateIndex = 7; break; } /* end of switch */ printf ( "%-23s %-8s %-30s %s\n", ServiceType[ServiceTypeIndex], CurrentState[CurrentStateIndex], p->lpServiceName, p->lpDisplayName ); } /* end of for */ printf ( "ServicesReturned = %u\n", ServicesReturned ); enumservice_exit: if ( NULL != enum_service_status ) { HeapFree( GetProcessHeap(), 0, enum_service_status ); enum_service_status = ( LPENUM_SERVICE_STATUS )NULL; }; if ( NULL != sc_handle ) { CloseServiceHandle( sc_handle ); sc_handle = ( SC_HANDLE )NULL; } return; } /* end of enumservice */ static void PrintWin32ErrorCUI ( char *message, DWORD dwMessageId ) { char *errMsg; FormatMessage ( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dwMessageId, MAKELANGID( LANG_NEUTRAL, SUBLANG_DEFAULT ), ( LPTSTR )&errMsg, 0, NULL ); fprintf( stderr, "%s: %s", message, errMsg ); LocalFree( errMsg ); return; } /* end of PrintWin32ErrorCUI */ static BOOL SessionBegin ( unsigned char *username, unsigned char *password, unsigned char *resource ) { BOOL ret = FALSE; DWORD error; NETRESOURCE netresource; SessionEnd( resource ); ZeroMemory( &netresource, sizeof( netresource ) ); netresource.dwType = RESOURCETYPE_ANY; netresource.lpLocalName = NULL; netresource.lpRemoteName = resource; netresource.lpProvider = NULL; error = WNetAddConnection2 ( &netresource, password, username, 0 ); if ( NO_ERROR != error ) { PrintWin32ErrorCUI( "WNetAddConnection2() failed", error ); goto SessionBegin_exit; } ret = TRUE; SessionBegin_exit: return( ret ); } /* end of SessionBegin */ static BOOL SessionEnd ( unsigned char *resource ) { BOOL ret = FALSE; DWORD error; error = WNetCancelConnection2 ( resource, CONNECT_UPDATE_PROFILE, TRUE ); if ( NO_ERROR != error ) { /* * PrintWin32ErrorCUI( "WNetCancelConnection2() failed", error ); */ goto SessionEnd_exit; } ret = TRUE; SessionEnd_exit: return( ret ); } /* end of SessionEnd */ static void usage ( char *arg ) { fprintf ( stderr, "Usage: %s [-h] [-v] [-t target] [-u username] [-p password]\n", arg ); exit( EXIT_FAILURE ); } /* end of usage */ int __cdecl main ( int argc, char * argv[] ) { int c, ret = EXIT_FAILURE; unsigned char *target = NULL, *username = NULL, *password = NULL, *resource = NULL; unsigned int resourcelen = 0; for ( c = 1; c < argc; c++ ) { if ( ( ( argv[c][0] != '-' ) && ( argv[c][0] != '/' ) ) || ( strlen( argv[c] ) < 2 ) ) { usage( argv[0] ); } else { switch ( tolower( argv[c][1] ) ) { case 't': if ( ( c + 1 ) >= argc ) { usage( argv[0] ); } target = argv[++c]; break; case 'u': if ( ( c + 1 ) >= argc ) { usage( argv[0] ); } username = argv[++c]; break; case 'p': if ( ( c + 1 ) >= argc ) { usage( argv[0] ); } password = argv[++c]; break; case 'v': fprintf( stderr, "%s ver "VERSION"\n", argv[0] ); return( EXIT_SUCCESS ); case 'h': case '?': default: usage( argv[0] ); break; } /* end of switch */ } } /* end of for */ if ( FALSE == SetConsoleCtrlHandler( NULL, FALSE ) ) { PrintWin32ErrorCUI( "SetConsoleCtrlHandler() failed", GetLastError() ); goto main_exit; } if ( NULL != target && NULL != username && NULL != password ) { resourcelen = 2 + strlen( target ) + 1 + 4 + 1; resource = ( unsigned char * )HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, resourcelen ); if ( NULL == resource ) { PrintWin32ErrorCUI( "HeapAlloc() failed", ERROR_NOT_ENOUGH_MEMORY ); goto main_exit; } sprintf( resource, "\\\\%s\\IPC$", target ); SessionBegin( username, password, resource ); } else { printf( "\n[Assuming one session already existed or target is null.]\n\n" ); } enumservice( target ); ret = EXIT_SUCCESS; main_exit: if ( NULL != resource ) { SessionEnd( resource ); HeapFree( GetProcessHeap(), 0, resource ); resource = NULL; } return( ret ); } /* end of main */ /************************************************************************/