Connect with us

Controllo Remoto in C

Programmazione

Controllo Remoto in C

Un programma di controllo remoto è essenzialmente un’utlity che permette a un utente remoto di controllare il proprio Computer a distanza,tramite l’utilizzo della rete. Si intuisce quindi che è composto da un server in attesa su di una porta che gira sulla macchina remota da controllare, e da un client in mano all’utente. Il lato client prevede di solito una serie di menu tramite i quali inviare iComandi remoti più disparati che vengono seguiti sul server, il quale a sua Volta fornirà i risultati ottenuti (come la lettura di un file); il client ad hoc comunque non è indispensabile al 100%, un po’ come non è indispensabile un client di posta elettronica per accedere a un POP3. Per stabilire una connessione può bastare una connessione Telnet all’IP della macchina server (programmato per ricevere comandi testuali), inserendo La porta su cui esso è in ascolto (che dipende dallo stesso). È il caso del nostro programma, ovvero una singola applicazione server che si mette in ascolto sulla porta 2003 attendendouna connessione, mentre tutto quello che dovremo fare noi sarà utilizzare un normalissimo client telnet.

Come è fatto il server
La struttura del server è semplice: prima saluta il client con una stringa di
benvenuto (utile per far capire che il server è in esecuzione sul computer remoto)E poi si mette in attesa della password. Dopodiché, se questa è
giusta, provvede a spedire al client il codice prodotto (quello che viene richiesto in fase di installazione e che si può leggere in impostazioni->pannello di controllo->sistema) del Windows su cui sta girando (tanto per fare qualcosa, giusto a titolo dimostrativo); poi interrompe la connessione e si riporta in attesa. Altrimenti, se la password è sbagliata, si limita a chiudere la connessione. Non che sia molto complesso, però è pur sempre un esempio. Programmi più maliziosi (tipo Netbus o simili) si basano sullo stesso principio (almeno a grandi linee) ma possiedono una serie di accorgimenti per nasconderre all’utente il fatto di essere Un esecuzione, con la possibilità di caricarsi automaticamente all’avvio del sistema per esempio aggiungendo voci nel registro di Windows, o modificando file di configurazione.

 I dettagli
Dato che il server è per Windows, dovremo utilizzare le particolarissime API messe a disposizione dal sistema (WSA, winsock e via dicendo); Il server
chiama la funzione connettiti(), dove sono inserite tutte le istruzioni necessarie allo scopo; si inizializza la WSA (Windows Socket API) tramite la chiamata WSAStartup() passandogli la versione della libreria (wsock32.dll) e un puntatore a una struttura dati di tipo WSADATA, che verrà quindi riempita di informazioni che comunque non tratteremo successivamente per mantenere leggero il codice. Subito dopo si provvede ad aprire il socket locale (s1) specificando la famiglia di protocolli da usare (PF_INET) e il protocollo specifico, ovvero il TCP/IP (SOCK_STREAM). Si passa quindi a impostare in1 con i parametri di protocollo e porta (in1.sin_port=htons(2003)) e si inizializza la socket associando (bind) tale struttura di tipo sockaddr_in con la socket s1. Ci si pone quindi in attesa di connessione con la listen(). Ad avvenutaconnessione, si crea la seconda socket (s2) tramite la accept(); da adesso in poi tale puntatore verrà utilizzato per tutte le operazioni di comunicazione con il client (send/recv), un po’ come avviene per l’handle dei file per leggere, scrivere o agire su di essi. Preso nota dell’IP, ci si connette all’host inserendo i parametri come in Figura 1. Se il server gira sulla stessa macchina del client si inserisce 127.0.0.1 (localhost) specificando la porta. Fatto questo il programma esce da connettiti(), invia tramite la funzione send() la stringa “\rtoc toc neo…\r\inserisci password:” (vedi Figura 2) e torna in ricevi() in attesa della password. Tale funzione è un ciclo for di una coppia recv/send per cui si prende un carattere, lo si registra in memoria e si invia una copia al client remoto, giusto per avere un echo locale sul terminale(e sapere se si sta scrivendo senza errori). La funzione prende come parametri un puntatore a carattere (il buffer) e un ntero che indica il numero di caratteri da acquisire, nel nostro caso 8. Va comunque detto che la password non è necessaria ma può impedire (ai più) di accedere al programma. Inserita la stringa la si compara con “01234567” (la password inserita nel codice, da modificare prima di compilarlo) e in caso di esito positivo si entra in prendi_productID() dove si genera una chiamata al sistema operativo per accedere al registro (Reg- CreateKeyEx()) passando il percorso della chiave e i vari permessi, si copia la chiave “ProductId” nel buffer con RegQueryValueEx() e poi si chiude la “sessione” di registro invocando RegCloseKey(). A questo punto si invia il codice prodotto, dopodiché il server chiude la connessione e torna in ascolto. Il ciclo è infinito come si nota dal while(1) { … } del main(). funzione che permetta al client di impartire comandi arbitrari.

Sorgente:

#include
#include
#include
#include
#include
SOCKET s1,s2;
WSADATA WSAdata;
struct sockaddr_in in1,in2;
HKEY hKey;
void connettiti(void)
{
int lenght;
WSAStartup(0x0202,&WSAdata);
s1=socket(PF_INET,SOCK_STREAM,0);
in1.sin_family=PF_INET;
in1.sin_port=htons(2003); // porta da usare
in1.sin_addr.s_addr=INADDR_ANY;
bind(s1,(struct sockaddr*)&in1,sizeof(struct sockaddr_in));
lenght=sizeof(struct sockaddr);
listen(s1,1);
printf(“\nIN ATTESA…”); // info locali di debug
s2=accept(s1,(struct sockaddr*)&in2,(LPINT)&lenght);
printf(“OK…\n”); // info locali di debug
}
char* ricevi(char* buff,int lenght) // riceve un comando
{
int i;
for(i=0;i {
recv(s2,buff+i,1,0); // riceve il carattere
send(s2,buff+i,1,0); // echo
}
return buff;
}
char* prendi_ProductID(char* buff)
{
unsigned long d=0xFF;
RegCreateKeyEx(HKEY_LOCAL_MACHINE,
“Software\\Microsoft\\Windows\\CurrentVersion”
,0,NULL,REG_OPTION_NON_VOLATILE,KEY_ALL_ACCESS,NULL,&hKey,NULL);
RegQueryValueEx(hKey,”ProductId”,NULL,NULL,(LPBYTE)buff,&d);
RegCloseKey(hKey);
return buff;
}
int main(void)
{
char buffer[100]; // buffer dati
while(1)
{
connettiti(); // inizializza il server
strcpy(buffer,”\rtoc toc neo… \r\ninserisci password:”);
send(s2,buffer,strlen(buffer),0);
if (strncmp(ricevi(buffer,8),”01234567”,8)==0)
{
strcpy(buffer,”\r\nlogin OK\r\nProductID:”);
send(s2,buffer,strlen(buffer),0);
send(s2,prendi_ProductID(buffer),strlen(buffer),0); // invia il ProductID
}
shutdown(s1,2);
closesocket(s1);
shutdown(s2,2);
closesocket(s2);
WSACleanup();
}
return(0);
}

Continue Reading

More in Programmazione



News


Top News

To Top