Beispiel #1
0
int InstallAPIHook(const char *modname, const char *fnname,
				   const char *targetmod, int newfn) {
	int len, i, *blah, lookingfor;
	unsigned long oldprotect;

	HANDLE hModule = GetModuleHandle(targetmod);
	if (!hModule) {
		DispMsg("Failed to get base of %s!", targetmod);
		return 0;
	}

	blah = (int *)ImageDirectoryEntryToData((void *)hModule,
		1, IMAGE_DIRECTORY_ENTRY_IAT, (unsigned long *)&len);
	lookingfor = (int)GetProcAddress(GetModuleHandle(modname), fnname);

	for (i = 0; i != len; i++) {
		if (lookingfor == blah[i])
			goto success;
	}

	DispMsg("Failed to find %s in IAT of %s!", fnname, modname);
	return 0;

success:
	VirtualProtect(&blah[i], sizeof(int), PAGE_EXECUTE_READWRITE, &oldprotect);
	blah[i] = newfn;
	VirtualProtect(&blah[i], sizeof(int), oldprotect, &oldprotect);
	return 1;
}
Beispiel #2
0
/*
 * Chat, if the parameters are not NULL, a connection with the named
 * channel is made with the give username which will be forced to the
 * used nick name. This mode is used for forced sysop chat.
 * If the parameters are NULL, then it's up to the user what happens.
 */
void Chat(char *username, char *channel)
{
    int		    width, curpos = 0, stop = FALSE, data, rc;
    unsigned char   ch;
    char	    sbuf[81], resp[128], *name, *mname;
    static char	    buf[200];
    time_t	    c_start, c_end;


    WhosDoingWhat(SYSOPCHAT, NULL);
    clear();

    rsize = rows - 5;
    rpointer = 0;

    if (SYSOP == TRUE) {
	/*
	 * Forbid the sysop to chat, the sysop MUST use mbmon.
	 */
	Syslog('+', "The Sysop attempted to chat");
	pout(LIGHTRED, BLACK, (char *) Language(29));
	Enter(1);
	Pause();
	return;
    }
   
    if (username && channel) {
	colour(LIGHTGREEN, BLACK);
	PUTCHAR('\007');
	/* *** Sysop is starting chat *** */
	pout(LIGHTGREEN, BLACK, (char *) Language(59));
	Enter(1);
	sleep(1);
	PUTCHAR('\007');
	sleep(1);
	PUTCHAR('\007');
	Syslog('+', "Sysop chat started");
	chat_with_sysop = TRUE;
    } else {
	Syslog('+', "User started chatting");
    }
    
    /*
     * Setup the screen, this is only possible in ANSI mode.
     */
    clear();
    locate(1, 1);
    colour(WHITE, BLUE);
    snprintf(buf, 200, "%-*s", cols, " MBSE BBS Chat Server");
    mvprintw(1, 1, buf);

    mname = xstrcpy(clencode(exitinfo.sUserName));
    name  = xstrcpy(clencode(exitinfo.Name));
    width = cols - (strlen(name) + 3);
    snprintf(buf, 200, "CCON,4,%d,%s,%s,0;", mypid, mname, name);
    free(mname);
    free(name);
    if (socket_send(buf) == 0) {
	strncpy(buf, socket_receive(), sizeof(buf)-1);
	if (strncmp(buf, "200:1,", 6) == 0) {
	    Syslog('!', "Chat server is not available");
	    colour(LIGHTRED, BLACK);
	    mvprintw(4, 1, (char *) Language(30));
	    Enter(2);
	    Pause();
	    chat_with_sysop = FALSE;
	    return;
	}
    }

    locate(rows - 2, 1);
    colour(WHITE, BLUE);
    snprintf(buf, 200, "%-*s", cols, " Type \"/EXIT\" to exit or \"/HELP\" for help.");
    mvprintw(rows - 2, 1, buf);

    colour(WHITE, BLACK);
    mvprintw(rows - 1, 1, ">");
    mvprintw(rows - 1, width + 2, "<");
    memset(&sbuf, 0, sizeof(sbuf));
    memset(&rbuf, 0, sizeof(rbuf));
    colour(LIGHTGRAY, BLACK);

    /*
     * If username and channelname are given, send the /nick and /join
     * commands to the chatserver.
     */
    if (username && channel) {
	snprintf(buf, 200, "CPUT:2,%d,/nick %s;", mypid, clencode(username));
	if (socket_send(buf) == 0)
	    strcpy(buf, socket_receive());
	snprintf(buf, 200, "CPUT:2,%d,/join %s;", mypid, clencode(channel));
	if (socket_send(buf) == 0)
	    strcpy(buf, socket_receive());
    }

    chatting = TRUE;
    c_start = time(NULL);

    while (stop == FALSE) {

	/*
	 * Check for new message, loop fast until no more data available.
	 */
	data = TRUE;
	while (data) {
	    snprintf(buf, 200, "CGET:1,%d;", mypid);
	    if (socket_send(buf) == 0) {
		strncpy(buf, socket_receive(), sizeof(buf)-1);
		if (strncmp(buf, "100:2,", 6) == 0) {
		    strncpy(resp, strtok(buf, ":"), 10);    /* Should be 100        */
		    strncpy(resp, strtok(NULL, ","), 5);    /* Should be 2          */
		    strncpy(resp, strtok(NULL, ","), 5);    /* 1= fatal, chat ended */
		    rc = atoi(resp);
		    memset(&resp, 0, sizeof(resp));
		    strncpy(resp, cldecode(strtok(NULL, ";")), 80);  /* The message          */
		    DispMsg(resp);
		    if (rc == 1) {
			Syslog('+', "Chat server error: %s", resp);
			stop = TRUE;
			data = FALSE;
		    }
		} else {
		    data = FALSE;
		}
	    }
	}

	if (stop)
	    break;

        /*
	 * Check for a pressed key, if so then process it.
	 * Allow hi-ascii for multi-language.
	 */
	ch = testkey(rows -1, curpos + 2);
	if ((ch == KEY_BACKSPACE) || (ch == KEY_RUBOUT) || (ch == KEY_DEL)) {
	    alarm_on();
	    if (curpos) {
		curpos--;
		sbuf[curpos] = '\0';
		BackErase();
	    } else {
		PUTCHAR(7);
	    }
	/* if KEY_DEL isprint, do no output again */
	} else if (isprint(ch) || traduce((char *)&ch)) {
	    alarm_on();
	    if (curpos < width) {
		PUTCHAR(ch);
		sbuf[curpos] = ch;
		curpos++;
	    } else {
		PUTCHAR(7);
	    }
	} else if ((ch == '\r') && curpos) {
	    alarm_on();
	    snprintf(buf, 200, "CPUT:2,%d,%s;", mypid, clencode(sbuf));
	    if (socket_send(buf) == 0) {
		strcpy(buf, socket_receive());
		if (strncmp(buf, "100:2,", 6) == 0) {
		    strncpy(resp, strtok(buf, ":"), 10);    /* Should be 100            */
		    strncpy(resp, strtok(NULL, ","), 5);    /* Should be 2              */
		    strncpy(resp, strtok(NULL, ","), 5);    /* 1= fatal, chat ended	*/
		    rc = atoi(resp);
		    strncpy(resp, cldecode(strtok(NULL, ";")), 80);  /* The message              */
		    DispMsg(resp);
		    if (rc == 1) {
			Syslog('+', "Chat server error: %s", resp);
			stop = TRUE;
		    }
		}
	    }
	    curpos = 0;
	    memset(&sbuf, 0, sizeof(sbuf));
	    locate(rows - 1, 2);
	    clrtoeol();
	    colour(WHITE, BLACK);
	    mvprintw(rows - 1, 1, ">");
	    mvprintw(rows - 1, width + 2, "<");
	    colour(LIGHTGRAY, BLACK);
	}
    }
    chatting = FALSE;
    c_end = time(NULL);
    mib_chats++;
    mib_chatminutes += (unsigned int) ((c_end - c_start) / 60);


    /* 
     * Before sending the close command, purge all outstanding messages.
     */
    data = TRUE;
    while (data) {
	snprintf(buf, 200, "CGET:1,%d;", mypid);
	if (socket_send(buf) == 0) {
	    strncpy(buf, socket_receive(), sizeof(buf)-1);
	    if (strncmp(buf, "100:2,", 6) == 0) {
		strncpy(resp, strtok(buf, ":"), 10);    /* Should be 100        */
		strncpy(resp, strtok(NULL, ","), 5);    /* Should be 2          */
		strncpy(resp, strtok(NULL, ","), 5);	/* 1= fatal error	*/
		rc = atoi(resp);
		memset(&resp, 0, sizeof(resp));
		strncpy(resp, cldecode(strtok(NULL, ";")), 80);  /* The message          */
		DispMsg(resp);
		if (rc == 1) {
		    Syslog('+', "Chat server error: %s", resp);
		    data = FALSE;   /* Even if there is more, prevent a loop */
		}
	    } else {
		data = FALSE;
	    }
	}
    }

    if (username && channel) {
	/*
	 * Disjoin sysop channel
	 */

	/* *** Sysop has terminated chat *** */
	snprintf(buf, 200, "%s", (char *) Language(60));
	DispMsg(buf);
	Syslog('+', "Sysop chat ended");
	chat_with_sysop = FALSE;
    } else {
	Syslog('+', "User chat ended");
    }

    /*
     * Close server connection
     */
    snprintf(buf, 200, "CCLO,1,%d;", mypid);
    if (socket_send(buf) == 0) {
	strcpy(buf, socket_receive());
    }
    sleep(2);
    clear();
}
int CTcpServ::ReadSock(int sock)
{
    int len = -1;
    int evlen = 14; // Length of API message head.

    char buf[TCP_MAXMSG];

    int idx = m_opSockTable->Search(sock);

    if (idx>=TCP_MAX_CONNECT)
    {
        Print("No such socket=%d.", sock);
        return 0;
    }

     len = read(sock, buf, TCP_MAXMSG); // Read in 1024 bytes data.

// Begin JOYIT tcp mode.
    if (len == 0)
    { // Connection be closed.
        int index;
        index = m_opSockTable->Search(sock);
        STcpLinkAttribute tla;
        tla.tcpLinkId = m_opSockTable->m_sSockTable[index].iLinkID; // m_opSockTable->Sock2Link(sock);
        strcpy(tla.ipAddr, m_opSockTable->m_sSockTable[index].IPAddr);

        WEvent ev;
#ifdef __PSG_REDUANT
        ev.dmid = (m_iRealMID & 0xFFFF0000) | (LMI_SYSMGR<<4);
#else // __PSG_REDUNANT
        ev.dmid = LMI_SYSMGR << 4;
#endif // __PSG_REDUANT
        ev.smid = m_iRealMID;
        // ev.what=evOAM;
        ev.what = evBroadcast; // Modify 2004-12-27, by Wujianjin.
        ev.PtlId=PTL_SYSMGR;
        ev.PtlVer=VER_SYSMGR;
        ev.Priority=0;
        ev.evCode=SYSMGR_IPC_TCPDOWN;
        ev.Reserved=m_opSockTable->Sock2Link(sock);
        ev.bcEvent.src = m_iRealMID;

        ev.msgLen = sizeof(STcpLinkAttribute);
        ev.msgPtr = new char[ev.msgLen];
        memcpy(ev.msgPtr,&tla,ev.msgLen);

        //ev.msgPtr = (char *)&tla;
        
        m_opClnt->SendMsg(ev);
        Print("TCP link=%d sock=%d tear down: sock read EOF.", tla.tcpLinkId, sock);

        // Print("Socket=%d shutdown.",sock);
        m_opSockTable->DelSock(sock);
#ifdef __TCP_DEBUG
        // Print("Send to %d what=%d len=%d.",
        //     (int)ev.dmid,(int)ev.what,(int)ev.msgLen);
        // Print("TCP connection shutdown. linkid=%d, sock=%d.", ev.Reserved, sock);
#endif // __TCP_DEBUG
        ev.del();

        return -1;
    }

    if (len<0)
    {
        if ((errno == EWOULDBLOCK)
            || (errno == EINTR)
            || (errno == EAGAIN)) // Resource temporarily unavailable
            // EAGIN: It is very common to get this error when your application
            // is doing non-blocking operations on files or network sockets. For
            // example, you can open a file/socket/fifo for reading with the
            // O_NONBLOCK flag. If you subsequently do a read(2) call and there
            // is no data waiting, instead of blocking and waiting until there is
            // data ready and returning that data, the read() call will return an
            // error (EAGAIN) to let your application know that there is no data
            // ready and to try again later.
            // Another example is if a system call failed due to insufficient
            // resources (such as virtual memory), but it might succeed if called
            // again. (eg fork(2) does this). 
        {
            return 0;
        }
        else
        { // Socket read error.
            int index;
            index = m_opSockTable->Search(sock);
            STcpLinkAttribute tla;
            tla.tcpLinkId = m_opSockTable->m_sSockTable[index].iLinkID; // m_opSockTable->Sock2Link(sock);
            strcpy(tla.ipAddr, m_opSockTable->m_sSockTable[index].IPAddr);

            WEvent ev;
#ifdef __PSG_REDUANT
            ev.dmid = (m_iRealMID & 0xFFFF0000) | (LMI_SYSMGR<<4);
#else // __PSG_REDUNANT
            ev.dmid = LMI_SYSMGR << 4;
#endif // __PSG_REDUANT
            ev.smid = m_iRealMID;
            // ev.what=evOAM;
            ev.what = evBroadcast;
            ev.PtlId=PTL_SYSMGR;
            ev.PtlVer=VER_SYSMGR;
            ev.Priority=0;
            ev.evCode=SYSMGR_IPC_TCPDOWN;
            ev.Reserved=m_opSockTable->Sock2Link(sock);
            ev.bcEvent.src = m_iRealMID;

            ev.msgLen = sizeof(STcpLinkAttribute);
            ev.msgPtr = new char[ev.msgLen];
            memcpy(ev.msgPtr,&tla,ev.msgLen);

            //ev.msgPtr = (char *)&tla;

            m_opClnt->SendMsg(ev);
            Print("TCP link=%d sock=%d tear down: sock read error.", tla.tcpLinkId, sock);

            // Print("Socket=%d read error.",sock);
            m_opSockTable->DelSock(sock);
#ifdef __TCP_DEBUG
            // Print("Send to %d what=%d len=%d.",
            //     (int)ev.dmid,(int)ev.what,(int)ev.msgLen);
            // Print("TCP connection shutdown. linkid=%d, sock=%d.", ev.Reserved, sock);
#endif // __TCP_DEBUG
            ev.del();

            return -1;
        }
    }

    if (idx>=TCP_MAX_CONNECT)
    {
        Print("LinkID-Socket error (sock=%d).",sock);
        m_opSockTable->DelSock(sock);
        return 0;
    }

    int pos = m_opSockTable->m_sSockTable[idx].iReadBufPos; // bytes left
    memcpy(m_opSockTable->m_sSockTable[idx].caReadBuf+pos, buf, len);

    WEvent event;

    pos = 0; // The position of data has been deal.
    while (1)
    {
        //Not enogh bytes left
        if ((len+m_opSockTable->m_sSockTable[idx].iReadBufPos-pos) < evlen)
        {
            //Print("cnt=%d pos=%d rest len=%d.",tt,pos,len+m_opSockTable->m_sSockTable[idx].iReadBufPos-pos);
            //m_opSockTable->DelSock(sock);
            break;
        }

        //copy message header
        memcpy(&event, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, evlen); // ?????
        
        if (event.PktLength >= (TCP_MAXMSG-evlen)) // ignor the rest
        {
            Print("The message which from link=%d sock=%d content invalid msgLen=%d.",
                m_opSockTable->m_sSockTable[idx].iLinkID, // Modify 2005-03-25, by Wujianjin.
                m_opSockTable->m_sSockTable[idx].iSockfd,
                event.PktLength);
            m_opSockTable->m_sSockTable[idx].iReadBufPos = 0;
            return 0;
        }

        pos += evlen;
        // Copy extra information
        if ((event.PktLength-evlen) > 0)
        { // Modify 2005-05-13, by Wujianjin.
            event.msgPtr = new char[event.PktLength-evlen];
            
            if (NULL == event.msgPtr)
            { // Discard all data.
                Print("Memory allocate error.");
                m_opSockTable->m_sSockTable[idx].iReadBufPos = 0;
                return 0;
            }
            event.msgLen = event.PktLength-evlen;
            memcpy(event.msgPtr, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, event.msgLen);
        }
        else if ((event.PktLength-evlen) < 0)
        {
            // Add 2005-05-13, by Wujianjin.
            // print all data in buffer for debug popose.
            DispMsg((char *)m_opSockTable->m_sSockTable[idx].caReadBuf, len + m_opSockTable->m_sSockTable[idx].iReadBufPos, 1);

            Print("link=%d sock=%d, PktLength=%d  error.",
                m_opSockTable->m_sSockTable[idx].iLinkID, // Modify 2005-03-25, by Wujianjin.
                m_opSockTable->m_sSockTable[idx].iSockfd,
                event.PktLength);
            m_opSockTable->m_sSockTable[idx].iReadBufPos = 0; // Discard all data.
            return 0;
        }

        pos += (event.PktLength-evlen); // Move to next packet's head.

        if (pos > (len + m_opSockTable->m_sSockTable[idx].iReadBufPos))
        { // Data not enough.
            //Print("Not enough bytes.");
            pos -= (event.PktLength);
            event.del( ); // Add 2005-12-23, by Wu jianjin.
            break;
        }


        // UINT8  Ptl=event.PtlId;
        UINT16 evCode=*(UINT16 *)event.msgPtr;
        //printf("evCode:%d\n", evCode);
#ifdef __TCP_HEARTBEAT
        // if (Ptl == 0x01 && evCode == 0x59)
        if ((PTL_TCP == event.PtlId)  &&
            (SYSMGR_IPC_HEARTBEAT_ACK == evCode))
        { // Heartbeat acknowledgement.
            // m_iHeartBeat[idx] = 1; // Delete 2005-01-27, by Wujianjin.
            m_iCheckLife[idx] = 0; // Clear the CHECK LIFE counter.
            // return 0; // HeartBeat handle, return here.
            event.del( ); // Add 2005-12-23, by Wu jianjin.
        }
        else if ((PTL_TCP == event.PtlId)  &&
            (SYSMGR_IPC_HEARTBEAT == evCode))
        { // Heartbeat message, response ACK.
            // Add 2005-01-28, by Wujianjin.
            SJoyitApiHead hback;
            hback.PtlId = PTL_TCP;
            hback.PtlVer = VER_TCP;
            hback.PktLength = sizeof(SJoyitApiHead);
            hback.dmid = event.smid;
            hback.smid = m_iRealMID;
            hback.Reserved = m_opSockTable->m_sSockTable[idx].iLinkID;
            hback.Priority = 0;
            hback.msgType = SYSMGR_IPC_HEARTBEAT_ACK;
            hback.noie = 0;

            WEvent sev;
            memcpy(&sev, &hback, evlen);
            sev.PktLength =sizeof(WEvent)+hback.PktLength;
            sev.msgLen = hback.PktLength;
            sev.msgPtr = (char *)&hback;
            WriteToSock(sev);            

            // return 0; // HeartBeat handle, return here. // Add 2005-03-25, by Wujianjin.
            event.del( ); // Add 2005-12-23, by Wu jianjin.
        }
        else
#endif // __TCP_HEARTBEAT
//#endif // ifdef __SRD_TCP
        {
             //printf("Recv from sock:\n");
            // DispMsg(buf,len);
            /*如果能够收到正常数据包,则认为心跳正常*/
#ifdef __TCP_HEARTBEAT
            m_iCheckLife[idx] = 0;
#endif
            
            WEvent ev;

            ev.msgLen = event.PktLength;
            ev.msgPtr = new char[ev.msgLen];
            if (ev.msgPtr==NULL)
            {
                Print("Memory allocate error.");
                event.del( ); // Add 2005-12-23, by Wu jianjin.
                return 0;
            }

            memcpy(ev.msgPtr, &event, evlen);
            if ((event.msgPtr != NULL)  &&
                (event.msgLen > 0))
            {
                memcpy(ev.msgPtr+evlen, event.msgPtr, event.msgLen);
            }

            ev.smid = m_iRealMID; // Add 2005-01-18, by Wujianjin.
            ev.dmid = event.dmid;
            ev.what=evNetwork;
            ev.PtlId=PTL_TCP;
            ev.PtlVer=VER_TCP;
            ev.Priority=0;
            ev.Reserved=m_opSockTable->Sock2Link(sock);

            m_opClnt->SendMsg(ev);
        
#ifdef __TCP_DEBUG
            Print("TCP Rcv: TCP packet from linkid=%d sock=%d.", ev.Reserved, sock);
            // Print("Tx: Send to %d what=%d len=%d.",ev.dmid, ev.what, ev.msgLen);
            if (ev.msgPtr!=NULL)
            {
                DispMsg(ev.msgPtr,ev.msgLen, 1);
            }
#endif // __TCP_DEBUG

            event.del();
            ev.del();
        }

    }

    char tmp[2*TCP_MAXMSG];
    int tlen;

    // Move the left data to head.
    tlen = m_opSockTable->m_sSockTable[idx].iReadBufPos+len-pos;
        //Print("cnt=%d idx=%d bufpos=%d pos=%d len=%d tlen=%d.",
        //tt,idx,m_opSockTable->m_sSockTable[idx].iReadBufPos,pos,len,tlen);
    memcpy(tmp, m_opSockTable->m_sSockTable[idx].caReadBuf+pos, tlen);
    memcpy(m_opSockTable->m_sSockTable[idx].caReadBuf, tmp, tlen);
    m_opSockTable->m_sSockTable[idx].iReadBufPos = tlen;
    //Print("cnt=%d last pos=%d.",tt,tlen);

    return pos;
#endif  // __TCP_RAW_CONNECT
}