08-05-2010, 10:31 AM
<snip>
Not Malware
Code:
/*****************************************************\
a small and simple IRC bot for learning purposes
by skorikov 2007
-- I was originally planning on putting detailed comments
but i got a bit lazy half way through, sorry :x
\*****************************************************/
#define WIN32
/*#define LINUX*/
#ifdef WIN32
#include <windows.h>
#include <winsock.h>
#define BUILD_TYPE "WIN32"
#endif
#ifdef LINUX
#include <sys/socket.h>
#include <sys/types.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <netdb.h>
#define BUILD_TYPE "LINUX"
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include <stdarg.h>
#define IRC_BUFFER_SIZE 512
#define MAX_ARGS 256
#ifdef WIN32
#define vsnprintf _vsnprintf
#define snprintf _snprintf
#endif
/********************************************************************\
IRC_CLIENT CONFIGURATION
\********************************************************************/
const char *IRC_SERVER = "irc.bluehell.org";
const short IRC_PORT = 6667;
const char *IRC_CHAN = "#testchan";
const char *IRC_CHANKEY = "key";
const char *IRC_NICK = "SmallBot";
const char *IRC_REALNAME = "Small IRC Bot";
const char IRC_CMD_TRIGGER = '.';
/********************************************************************\
COMMAND PROTOTYPES
\********************************************************************/
void cmd_quit(int sock, char *from_p, char **arg_p, int arg_count),
cmd_test(int sock, char *from_p, char **arg_p, int arg_count),
cmd_help(int sock, char *from_p, char **arg_p, int arg_count);
/********************************************************************\
FUNCTION PROTOTYPES
\********************************************************************/
int irc_connect(int sock, const char *remote_host_p, unsigned short remote_port),
irc_send_line(int sock, const char *format_p, ...),
irc_recv_line(int sock, char *line_p, unsigned int line_size);
/* this is pretty much just a table of
command names and pointers to their according functions */
struct irc_command
{
const char *command_name_p,
*description_p;
void (*exec_command)(int sock, char *from_p, char **arg_p, int arg_count);
}
/********************************************************************\
COMMAND TABLE
\********************************************************************/
COMMAND[] =
{
{"quit", "Make the bot quit", &cmd_quit},
{"test", "A test command", &cmd_test},
{"help", "Print this menu", &cmd_help}
};
/********************************************************************\
BOT MAIN
\********************************************************************/
int main(int argc, char **argv)
{
#ifdef WIN32
WSADATA wsa_data; /* a structure to store output from the WSAStartup call,
we dont do anything with this so just ignore it */
#endif
int sock, /* our socket handle */
connect_attempts = 0,
argument_count,
i;
char buffer[512] = {0}, /* buffer to recv lines from IRC */
from[56] = {0},
nick[56] = {0},
*argument[MAX_ARGS],
*token_p;
#ifdef WIN32
/* WSAStartup() initializes the WinSock DLL, version 2.2,
MAKEWORD(2, 2) just takes 2 bytes each with a value of 2 (00000010)
and puts them together like so (0000001000000010),
^^ this isn't really important so you can ignore this */
if (WSAStartup(MAKEWORD(2, 2), &wsa_data))
{
printf("- fatal error: failed to initialize winsock\r\n");
return (0);
}
#endif
/* create a socket using the INET protocol family (IPv4),
and make it a streaming TCP socket */
if ((sock = socket(PF_INET,
SOCK_STREAM,
IPPROTO_TCP)) == -1)
{
printf("- fatal error: socket() failed.\r\n");
return (0);
}
printf("- Created socket\r\n");
if (!irc_connect(sock, IRC_SERVER, IRC_PORT))
{
printf("- Failed to connect to %s:%i\r\n", IRC_SERVER, IRC_PORT);
return (0);
}
printf("- Connected to %s:%i\r\n", IRC_SERVER, IRC_PORT);
snprintf(nick, sizeof(nick), "%s", IRC_NICK);
irc_send_line(sock, "USER %s 127.0.0.1 localhost :%s", IRC_NICK, IRC_REALNAME);
irc_send_line(sock, "NICK %s", nick);
while (1)
{
memset(buffer, 0, sizeof(buffer));
if (irc_recv_line(sock, buffer, sizeof(buffer)) == 0)
break;
token_p = strtok(buffer, " ");
argument_count = 0;
while (token_p != NULL)
{
argument[argument_count] = token_p;
token_p = strtok(NULL, " ");
argument_count++;
}
if (argument_count > 2)
{
if (strcmp(argument[1], "001") == 0)
{
irc_send_line(sock, "JOIN %s :%s", IRC_CHAN, IRC_CHANKEY);
continue;
}
else if (strcmp(argument[1], "433") == 0)
{
strncat(nick, "_", 1);
irc_send_line(sock, "NICK %s", nick);
continue;
}
}
if (argument_count == 2)
{
if (strcmp(argument[0], "PING") == 0)
{
irc_send_line(sock, "PONG %s", argument[1]);
continue;
}
}
if (argument_count >= 4)
{
if (strcmp(argument[1], "PRIVMSG") == 0)
{
snprintf(from, sizeof(from), "%s", argument[2]);
/* this just shifts the argument variable the
numbers of bytes there are before the PRIVMSG text
so ":user@host PRIVMSG #channel :message here"
becomes just "message here" */
if (argument[3][1] == IRC_CMD_TRIGGER)
{
*argument += (strlen(argument[0]) + 1) +
(strlen(argument[1]) + 1) +
(strlen(argument[2]) + 3);
for (i = 0; i < sizeof(COMMAND) / sizeof(struct irc_command); ++i)
{
if (strcmp(argument[0], COMMAND[i].command_name_p) == 0)
{
COMMAND[i].exec_command(sock, from, argument, argument_count - 3);
break;
}
}
}
continue;
}
}
}
printf("- Disconnected\r\n");
#ifdef WIN32
/* clean up after ourselves */
WSACleanup();
#endif
return (0);
}
/********************************************************************\
IRC CONNECT FUNCTION
\********************************************************************/
int irc_connect(int sock, const char *remote_host_p, unsigned short remote_port)
{
struct sockaddr_in sin; /* a structure which tells our socket where it's connecting to */
struct hostent *hostent_p; /* a structure which will store results from the DNS query we do
for remote_host_p */
/* perform a DNS query to find the IP address of remote_host_p */
if (!(hostent_p = gethostbyname(remote_host_p)))
return (0);
memset(&sin, 0, sizeof(sin));
sin.sin_family = PF_INET; /* IPv4 */
sin.sin_addr.s_addr = *(long *) hostent_p->h_addr; /* take the IP address returned */
sin.sin_port = htons(remote_port); /* convert remote_port to a network order byte */
printf("- Resolved %s to %s\r\n", remote_host_p, inet_ntoa(sin.sin_addr));
/* tell the socket to connect */
if (connect(sock, (struct sockaddr *) &sin, sizeof(sin)) == -1)
return (0);
return (1);
}
/********************************************************************\
IRC SEND LINE FUNCTION
\********************************************************************/
int irc_send_line(int sock, const char *format_p, ...)
{
va_list args;
char buffer[512] = {0};
va_start(args, format_p);
vsnprintf(buffer, sizeof(buffer), format_p, args);
va_end(args);
strncat(buffer, "\r\n", (sizeof(buffer) - strlen(buffer)));
printf(">> %s", buffer);
return (send(sock, buffer, strlen(buffer), 0));
}
/********************************************************************\
IRC RECIEVE LINE FUNCTION
\********************************************************************/
int irc_recv_line(int sock, char *line_p, unsigned int line_size)
{
char byte = 0;
/* recv one byte at a time from the socket
untill you reach a newline (\n) character */
while (byte != '\n' && strlen(line_p) < line_size)
{
if (!recv(sock, (char *) &byte, 1, 0))
return (0);
if (byte != '\r' && byte != '\n' && byte != '\0')
{
strncat(line_p, (char *) &byte, 1);
}
}
printf("<< %s\r\n", line_p);
return (1);
}
/********************************************************************\
QUIT COMMAND FUNCTION
\********************************************************************/
void cmd_quit(int sock, char *from_p, char **arg_p, int arg_count)
{
irc_send_line(sock, "QUIT");
}
/********************************************************************\
TEST COMMAND FUNCTION
\********************************************************************/
void cmd_test(int sock, char *from_p, char **arg_p, int arg_count)
{
irc_send_line(sock, "PRIVMSG %s :This is a test. Did it work?", from_p);
}
/********************************************************************\
HELP COMMAND FUNCTION
\********************************************************************/
void cmd_help(int sock, char *from_p, char **arg_p, int arg_count)
{
unsigned int i;
irc_send_line(sock, "PRIVMSG %s :(Help): Build type: %s (%s, %s)", from_p, BUILD_TYPE, __DATE__, __TIME__);
irc_send_line(sock, "PRIVMSG %s :(Help): COMMAND DESCRIPTION", from_p);
for (i = 0; i < sizeof(COMMAND) / sizeof(struct irc_command); ++i)
{
irc_send_line(sock, "PRIVMSG %s :(Help): %s %s", from_p, COMMAND[i].command_name_p,
COMMAND[i].description_p);
Not Malware