回忆.初学C语言时编写的第一个程序.TCP端口扫描器

//////////////////////////////////////////////////////////
//PortScan.cpp

#include < winsock2.h >
#include < windows.h >
#include < stdio.h >
#include < stdlib.h >
#include < string.h >

#pragma comment( lib, "WS2_32.lib" )

//-----------------by Chrython Chou 200532530012 ----------------------

//////////////////////////////////////////////////////////
//函数原型


//欢迎界面
void psTitle( char * );

//默认扫描方式
void ps1( char *, char * );

//自定义扫描方式
void ps2( char *, char *, char *, char * );

//获得主机信息
void GetLocalDate( void );

//线程函数
DWORD WINAPI psProc(
  LPVOID lpParameter   // thread data
);


//////////////////////////////////////////////////////////
//全局变量


//目标地址和目标端口
char g_szTargetIP[20];
int g_nTargetPort;

//默认常用探测端口
int g_nPorts[23] = {
  21,22,23,25,53,79,80,110,111,119,135,139,143,
  443,445,512,554,1080,1433,1521,2401,3306,3389
};

//端口开放数量
int g_nOpenPorts;

//////////////////////////////////////////////////////////
//类

//载入和释放Winsock2库的类
class CInitSock
{
public:

 CInitSock( BYTE minorVer = 2, BYTE majorVer = 2)
 {
  WORD wVersionRequested;
  WSADATA wsaData;
  int err;

  wVersionRequested = MAKEWORD( minorVer, majorVer );

  err = ::WSAStartup( wVersionRequested, &wsaData );
  if( err != 0 )
  {
   return;
  }
  if ( LOBYTE( wsaData.wVersion ) != minorVer || HIBYTE( wsaData.wVersion ) != majorVer )
  {
   ::WSACleanup();
   return;
  }
 }

 ~CInitSock()
 {
  ::WSACleanup();
 }
};

//参数输入错误类
class CGetError
{
public:

 void PortError( int nStartPort, int nEndPort )
 {
  if ( nStartPort < 0 || nStartPort > 65535 || nEndPort < 0 || nEndPort > 65535 )
  {
   printf("错误: 端口输入/n");
   exit(1);
  }
  if ( nStartPort >= nEndPort )
  {
   printf("错误: 端口输入/n");
   exit(1);
  }
 }
 
 void IPError( void )
 {
  DWORD IPmax = inet_addr( "255.255.255.255" );
  DWORD IPmin = inet_addr( "0.0.0.0" );
  DWORD nowIP = inet_addr( g_szTargetIP );

  if ( nowIP >= IPmax || nowIP <= IPmin )
  {
   printf("错误: IP地址输入/n");
   exit(1);
  }
 }

 void DelayTimeError( int nDelayTime )
 {
  if ( nDelayTime < 0 || nDelayTime > 65535 )
  {
   printf("错误: 等待时间输入/n");
   exit(1);
  }
 }

};


//////////////////////////////////////////////////////////
//主函数用于命令行参数输入

void main(int argc,char *argv[])
{
 if( argc == 1 )
 {
  psTitle( argv[0] );
  exit( 1 );
 }
 
 else if(argc == 3)
 {
  ps1( argv[1] , argv[2] );
 }
 else if( argc == 5 )
 {
  ps2( argv[1], argv[2], argv[3], argv[4] );
 }
 
 else
 {
  printf( "错误: 参数输入/n" );
  exit( 1 );
 }
}

//欢迎界面
void psTitle(char *help)
{
 printf ("--------------------------------------------------------------------/n");
 printf ("Portscan端口扫描器/n");
 printf ("------------------------------本机信息------------------------------/n");
 GetLocalDate();
 printf ("------------------------------功能说明------------------------------/n");
 printf ("常用端口扫描:/n");
 printf ("/tPortscan <目标IP> [等待时间(毫秒)]/n");
 printf ("自定义端口扫描:/n");
 printf ("/tPortscan <目标IP> [开始端口] [结束端口] [等待时间(毫秒)]/n");
 printf ("举例:/n");
 printf ("/tPortscan 127.0.0.1 1/n");
 printf ("/tPortscan 127.0.0.1 0 65535 1/n");
 printf ("--------------------------------------------------------------------/n");
}

//默认扫描方式
void ps1( char *target, char *delay )
{
 //初始化CGetError
 CGetError psError;
 int nDelayTime = atoi( delay );

 

 //初始化Winsock库
 CInitSock initSock;

 HANDLE hThread1;

 strcpy( g_szTargetIP , target );

 //输入错误处理
 psError.IPError();
 psError.DelayTimeError( nDelayTime );
 
 printf ("/n--------------------------------------------------------------------/n");
 printf( "目标地址: ");
 puts( target );
 printf( "目标端口: 默认常用端口" );
 printf("/n------------------------------扫描报告------------------------------");

 for ( int i = 0; i < 23; i++ )
 { 
  g_nTargetPort = g_nPorts[i];

  //NULL 使用缺省的安全性
  //0 采用调用线程一样的大小
  //psProc 指定线程入口函数的地址
  //NULL 传递给线程的一个参数
  //0 创建的标记为0 一旦创建立即运行
  //NULL 线程的ID 不需要使用
  hThread1 = CreateThread( NULL, 0, psProc, NULL, NULL, NULL );
 
  CloseHandle( hThread1 );

  Sleep( nDelayTime );
 }
 printf( "/n/n共扫描到%d个端口开放" , g_nOpenPorts );
 printf ("/n--------------------------------------------------------------------/n");
 printf( "/n/n端口扫描完毕/n" );
}

//自定义扫描方式
void ps2( char *target, char *start, char *end, char *delay )

 //初始化CGetError
 CGetError psError;

 int nStartPort = atoi( start );
 int nEndPort = atoi( end );
 int nDelayTime = atol( delay );

 //初始化Winsock库
 CInitSock initSock;

 HANDLE hThread2;

 strcpy( g_szTargetIP , target );
 
 
 //输入错误处理
 psError.PortError( nStartPort, nEndPort );
 psError.IPError();
 psError.DelayTimeError( nDelayTime );

 printf ("/n--------------------------------------------------------------------/n");
 printf( "目标地址: ");
 puts( target );
 printf( "目标端口: %d -- %d:", nStartPort, nEndPort );
 printf ("/n------------------------------扫描报告------------------------------");

 for ( int port = nStartPort; port <= nEndPort; port++ )
 { 
  g_nTargetPort = port;

  //NULL 使用缺省的安全性
  //0 采用调用线程一样的大小
  //psProc 指定线程入口函数的地址
  //NULL 传递给线程的一个参数
  //0 创建的标记为0 一旦创建立即运行
  //NULL 线程的ID 不需要使用
  hThread2 = CreateThread( NULL, 0, psProc, NULL, NULL, NULL );
 
  CloseHandle( hThread2 );

  Sleep( nDelayTime );
 }
 printf( "/n/n共扫描到%d个端口开放" , g_nOpenPorts );
 printf ("/n--------------------------------------------------------------------/n");
 printf( "/n/n端口扫描完毕/n" );
}

//获得主机信息
void GetLocalDate( void )
{
 //初始化Winsock库
 CInitSock initSock;

 char szHost[256];
//获取本地主机名
 ::gethostname( szHost, 256 );
//通过主机名获取主机信息
 hostent *pHost = ::gethostbyname( szHost );
//打印出所有IP
 in_addr addr;

 for( int i = 0;; i++ )
 {
  char *p;
  char *szlp;

  p = pHost->h_addr_list[i];
  
  if ( p == NULL )
   break;
  memcpy( &addr.S_un.S_addr, p, pHost->h_length );

  szlp = ::inet_ntoa( addr );

  printf("本地主机名: %s /n", szHost);
  printf("本地主机IP: %s /n", szlp);
 }
}

//调用辅线程来循环扫描每个端口
DWORD WINAPI psProc(
 LPVOID lpParameter   // thread data
)
{
 //创建套接字
 SOCKET psSock = ::socket ( AF_INET, SOCK_STREAM, 0 );
 
 //sockaddr_in结构
 struct sockaddr_in psAddr;

 if( psSock == INVALID_SOCKET )
 {
  printf( "Error: socket /n" );
  exit(1);
 }

 //将psAddr中的前sizeof( psAddr )个字符都替换成0
 memset( &psAddr, 0, sizeof( psAddr ) );

 //填充sockaddr结构
 psAddr.sin_family = AF_INET;
 psAddr.sin_addr.S_un.S_addr = inet_addr( g_szTargetIP );
 psAddr.sin_port = htons( g_nTargetPort );

 if( ::connect( psSock, ( sockaddr* )&psAddr, sizeof( psAddr ) ) != SOCKET_ERROR )
 {
  printf( "/n端口 %d 开放", ntohs( psAddr.sin_port) );
  g_nOpenPorts++;
  
 }

 //关闭监听套接字
 ::closesocket( psSock );

 return 0;
}

展开阅读全文

没有更多推荐了,返回首页