• // Code source : crack en C++ \\

    //---------------------------------------- Licence ------------------------------------------
    //
    //Auteur : Pifoman
    //Email : pifoman@yahoo.com
    //Adresse site : http://crackinfrance.free.fr
    //Url redirection : www.geocities.com/mitonnes
    //Première source : version 1.0 du 13/10/2004
    //Dernière source : version 1.1 du 06/01/2004
    //Langage : C++
    //Compilateur : dev C++ 4 build 10/09/2000 (gratuit)
    //Adresse téléchargement : http://www.telecharger.com ou http://www.bloodshed.net/devcpp.html
    //Compilation : Windows XP édition familiale
    //Tests : Windows XP édition familiale / Windows 98
    //Type licence : libre. Vous pouvez copier et distribuer cette source
    // si vous laissez les lignes concernant la licence.
    // //------------------------------------------------------------------------------------------- //------------------------------ Instructions de compilation -------------------------------- // // Avant compilation du code // // 1/ Ouvrez STARTCLN.EXE dans Resource Hacker (version 3.4) // Faites action->Enregistrer toutes les ressources pour récupérer l'icône du programme Start clean // // 2/ Définissez un nouveau projet vide dans dev c++ // File->New Project->Empty Project // // 3/ Définissez un répertoire de travail au lancement de DevCpp.exe (dev c++) // Par exemple C:/Documents and Settings/inconnu/Bureau/Start Clean/ // // 4/ Copiez cette page (CTRL A CTRL C) dans Untitled1 (le fichier ouvert qui est vide) // // 5/ Définissez le fichier de resources // Vous devez définir un fichier de ressources dans lequel vous spécifiez l'icône à utiliser et le chemin du fichier info.htm // Ce fichier s'appelle par défaut Rsrc.rc et vous y accéder dans le menu Project->Edit Resource File de dev c++. // Copiez le contenu suivant en adaptant le chemin (supprimez les // devant 500 et texte pas devant BINAIRE1) // // 500 ICON "C:/Documents and Settings/inconnu/Bureau/Start Clean/icon.ico" // TEXTE BINARY "C:/Documents and Settings/inconnu/Bureau/Start Clean/infos_original.htm" // //BINAIRE1 BINARY "C:/Documents and Settings/inconnu/Bureau/Start Clean/ressource/ressource.exe" // // Faites ensuite une compilation de la ressource en cliquant sur le bouton "Build resource" accessible depuis le menu Projetc->Edit resource file // // 6/ Cocher l'option "Do not create a console" dans Project->Project option // // 7/ Compilez et lancez par CTRL F10 // //------------------------------------------------------------------------------------------- //---------------------------- Compression de l'exécutable compilé -------------------------- // // 1/ Après compilation avec dev c++ vous obtenez Project 1.exe // 2/ Téléchargez UPX (j'utilise la version 0.72) sur http://www.exetools.com/compressors.htm // 3/ Mettez upx.exe dans votre répertoire de travail // 4/ Créez un fichier compress.bat dans votre répertoire de travail (enlevez les //) // // @echo off // del Crack.exe // upx -9 -oCrack.exe "Project 1.exe" // echo Crack pour Start Clean v1.2>file_id.diz // pause // // 5/ Double-cliquez sur compress.bat // 6/ Votre crack est maintenant de taille réduite (vous divisez la taille du crack par 4) // 7/ Vous pouvez le zipper et le diffuser sur internet :) // //------------------------------------------------------------------------------------------- //------------------------------------- Rendu graphique -------------------------------------

    <script type="text/javascript">document.write("")</script>

    //-------------------------------------------------------------------------------------------- //--------------------------------- Commentaires sur le code ---------------------------------- // // C'est le code de ce crack que j'utilise pour mes cracks depuis cloneCD 5.0.2.2 fr. // Il n'y a que la disposition graphique des composants qui change sinon tout le reste est identique // Le code de ce crack est efficace en terme de résultat et de rapidité mais fût assez long à programmer.Ses particularités // // ->Il possède une fonction d'installation de fichiers à partir de ressources (fichiers de la version complète du programme que l'on stocke au préalable dans le crack) // Cette fonction d'installation effectue une opération de création/copie de fichiers et porte sur l'intégralité du fichier. // Cette fonction peut se combiner avec la procédure classique de craquage qui ne porte elle que sur quelques octets // // ->Il possède un contrôle d'erreur assez poussé qui rétabli l'ensemble des fichiers originaux dans le répertoire // en cas d'erreur rencontré pendant le processus de craquage. // // ->L'interface du crack comporte plus de commandes que l'ancienne version (un lien vers le téléchargement du programme // et un bouton caché pour lancer le programme inntallé sur le PC ont été ajoutés). // // // Fonctionnement de la procédure de craquage. // // Quand on appuie sur le bouton crack la fonction ecrire_en_boucle() est invoquée et on va // // -> Effectuer une copie temporaire sous forme de fichier .exe.temp et .bak.temp des fichiers .exe et .bak existant dans le répertoire. C'est la fonction sauver_fichiers() // // -> Appeler la fonction booléenne ecrire(int numero_fichier_a_craquer,int numero_boucle) sur chaque fichier à modifier et identifié par son numéro dans le tableau liste_identifiants_fichiers. // x Cette fonction crée d'abord les chemins d'accès (au fichier à craquer ainsi qu'à sa sauvegarde éventuelle) // x Cette fontion examine ensuite si le mode restauration est activé (checkbox3 à true) // Si C'est le cas la fonction écrase le fichier .exe par le fichier correspondant d'extension .bak // x Sinon on passe en mode craquage // On vérifie si le fichier existe => si le fichier n'existe pas => erreur déclenchée et fin de la focntion ecrire() qui renvoie un message et faux // On vérifie la taille du fichier à partir du tableau taille_somme => si pas bonne => erreur déclenchée et fin de la fonction ecrire() qui renvoie un message et faux // On vérifie l'intégrité du fichier à craquer à partir du tableau taille_somme si la case checkbox2 est cochée => si somme pas bonne => erreur déclenchée et fin de la fonction ecrire() qui renvoie un message et faux // On fait la copie de sauvegarde si la case checkbox1 activée => si erreur de copie => erreur déclenchée et fin de la fonction ecrire() qui renvoie un message et faux // On regarde si le fichier à modifier est une ressource à copier ou bien un craquage classique (test sur le 4ième paramètre du tableau d'information du fichier dans liste_fichiers) // On effectue la copie ou le craquage => si erreur => erreur déclenchée et fin de la fonction ecrire() qui renvoie un message et faux // On renvoie true si aucune erreur apparue sinon false à la fonction appelante ecrire_en_boucle() // // -> Si resultat des différentes écritures pendant le craquage a donné true tout le temps (valeur de la variable etat_ecriture) // x On coche la case nommée restaure // x On remplace le texte du bouton "Crack" par "Restaurer" // x On efface tous les fichiers temporaires crées (fichiers d'extension .temp) // x On affiche dans une boîte à message le message de réussite // // -> Si resultat des différentes écritures pendant le craquage a donné au moins un résultat faux (valeur de la variable etat_ecriture) // x On renomme les fichiers d'extension .exe.temp en .exe et les .bak.temp en .bak // x on efface les fichiers d'extension *.bak crées (il n'ont pas de .bak.temp puisque c'est nous qui l'avons crée sur demande) // x On affiche dans une boîte à message le message d'erreur // // //-------------------------------------------------------------------------------------------- //----------------------------------- Mise à jour du code ------------------------------------ // // // 06/01/2005 Version 1.1 : correction d'un bug dans la fonction calculer_taille_sous_matrice // Le processus de craquage sur les octets définis dans le tableau nommé matrice // s'arrêtait prématurément si un octet à patcher recevait la valeur hexadécimale 00. // // //-------------------------------------------------------------------------------------------- //--------------------------------------- Code source ---------------------------------------- //Inclusion des bibliothèques #include <windows.h> // Accès aux API windows #include <stdio.h> // Pour avoir sprintf : la fonction de traitement sur les chaînes // Déclaration des fonctions (autres que winmain) // Ici c'est inutile car winmain est à la fin du fichier // Quand on entre dedans il connaît les fonctions définies avant puisque le fichier est lu de haut en bas // Variables globales char * nom_application = "Start Clean v 1.2"; char * titre_application = "Start Clean v 1.2"; char cle_registre[] = "Start Clean"; char * date_crack = "12/10/2004"; char adresse_site_editeur[] = "http://www.adresse_editeur_fictive.com"; char adresse_site_telechargement[] = "http://membres.lycos.fr/pifoman/cours_cracking/cours_telechargements.htm"; char adresse_site_cracker[] = "http://www.geocities.com/mitonnes/"; char adresse_mail[] = "pifoman@yahoo.com"; char titre_mail[] = "Remarques sur votre crack "; char corps_mail[] = "Bonjour"; char * fichier_infos = "infos.htm"; char * titre_boite_dialogue = "Sélectionnez le fichier"; char message_reussite[] = "Le programme est maintenant cracké.\nVous pouvez saisir n'importe quel code d'enregistrement."; // Dimensions long largeur_fenetre = 350; long hauteur_fenetre = 245; long ordonnee_checkbox = 120; long ordonnee_edit = 156; long ordonnee_bouton = 180; long hauteur_bouton = 23 ; long largeur_bouton = 100; long abscisse_text = 16 ; long abscisse_static = 85 ; long ordonnee_static1 = 15 ; long ordonnee_static2 = 37 ; long ordonnee_static3 = 59 ; long ordonnee_static4 = 81 ; long hauteur_groupe = 210; long hauteur_static = 17 ; long largeur_static = 245; long hauteur_static4 = 73 ; long largeur_icone = 32 ; long hauteur_icone = 32 ; // Définition de zone rectangulaires RECT cracker = {largeur_fenetre * 4 / 100 ,38,largeur_fenetre * 4 / 100 + 38,50}; //left,top,right,bottom de la zone rectangulaire RECT auteur = {largeur_fenetre * 52 / 100 ,38,largeur_fenetre * 52 / 100 + 38,50}; //left,top,right,bottom de la zone rectangulaire RECT message_date = {largeur_fenetre * 48 / 100 ,62,largeur_fenetre * 48 / 100 + 60,70}; //left,top,right,bottom de la zone rectangulaire RECT icone = {largeur_fenetre * 4 / 100 ,hauteur_fenetre * 28 / 100,largeur_fenetre * 4 / 100+largeur_icone ,hauteur_fenetre * 28 / 100+hauteur_icone}; RECT lancement = {largeur_fenetre * 95 /100 ,ordonnee_edit, largeur_fenetre * 99 /100,ordonnee_edit+18}; //left,top,right,bottom de la zone rectangulaire // Position de la fenêtre affichant le crack long point_gauche_fenetre = (GetSystemMetrics(SM_CXFULLSCREEN)-largeur_fenetre)/2; long point_haut_fenetre = (GetSystemMetrics(SM_CYFULLSCREEN)-hauteur_fenetre)/2; // Etat initial des boutons checkbox bool checkbox1 = true; // Etat coché du bouton checkbox1 (sauve) bool checkbox2 = true; // Etat coché du bouton checkbox2 (Vérifie) bool checkbox3 = false; // Etat décoché du bouton checkbox3 (restaure) //Paramétrages de l'application // Tableau représentatif des fichiers à craquer // et des ressources à copier stockées dans le crack. // Mettre les fichier à craquer avant les ressources à cause de la matrice // 1 ière variable = nom affiché dans le crack // 2 ième variable = nom de l'exécutable à craquer correspondant au nom donné dans la 1 ière variable // 3 ième variable = chemin d'accès relatif du fichier à craquer sans / initial mais un / final depuis le chemin calculé dans la zone edit ; "" => chemin calculé dans la zone edit = chemin de l'exe donnée en 2 ième variable // 4 ième variable = type du fichier : "" = pas une ressource; "r"=ressource // 5 ième variable = filtre utilisé dans la boîte de sélection de fichiers char * liste_fichiers[][5] = { {"Start Clean v1.2","StartCln.exe","","","Start Clean v1.2 (StartCln.exe)\0STARTCLN.EXE\0\0"}, //{"BINAIRE1","Ressource.exe","","r",""}, }; //Liste des modifications offset / valeur pour chaque fichier qui n'est pas une ressource //Chaque sous-liste délimitée par des {} de la liste principale correspond aux modifications à apporter à un seul fichier //Le fichier à modifier est celui indiqué dans liste_fichiers dont le numéro d'ordre correspond à celui de la sous-liste //Attention : si 5 offsets et 5 octets soient 10 valeurs il faudra mettre au moins 11 pour la dimension long matrice[][11] = { { 0x5DE,0x50, 0x5DF,0x90, 0x5E0,0x90, 0x5E1,0x90, 0x5E2,0x90, }, }; //Tableau des tailles et des sommes des fichiers et des resssources //1 ier élément de chaque sous-liste : taille attendue du fichier à craquer ou de la ressource nommé dans liste_fichiers //2 ième élément de chaque sous-liste : somme des octets du fichier à craquer ou taille de la ressource à écrire //3 ième élément de chaque sous-liste : taille de la ressource si le fichier est une ressource long taille_somme[][3] = { {31744,2151373,0}, //{0,0,6144}, }; //Numéro du fichier à craquer int numero_fichier_a_craquer = 0; //Liste des identifiants de fichiers //Taille du tableau = nb identifiants +1 long liste_identifiants_fichiers[2] = {0}; //Liste des états des fichiers bool etat_craquage[]={false}; //Pour le debug bool afficher_somme = 0; // Fin des paramétrages de l'application // Déclarations nécessaires pour le choix de la police HDC hdc; LOGFONT lf; HFONT hfont; HFONT hfontOld; // Type de police choisie char f[32]={"ARIAL"}; // Déclarations des composants pour pouvoir les utiliser dans tout le programme HWND hwnd; /* Pointeur vers notre fenêtre */ HWND hwndEdit1; /* La zone de texte */ HWND hwndButton1; /* 1 ier bouton */ HWND hwndButton2; /* 2 ieme bouton */ HWND hwndButton3; /* 3 ieme bouton */ HWND hwndCheckBox1; /* 1 iere boite à cocher */ HWND hwndCheckBox2; /* 2 ieme boite à cocher */ HWND hwndCheckBox3; /* 3 ieme boite à cocher */ char chemin_registre[100]; char chemin_registre_edit[100]; char chaine[100]; char res[100],res2[100],res3[100]; char premier_fichier[100]; char chemin_nom_fichier [100] =""; char chemin_nom_fichier2[100] =""; char chemin_nom_fichier3[100] =""; char chemin_nom_fichier4[100] =""; char derniere_erreur[200]; // chaine contenant la dernière erreur rencontrée pour l'écriture char * fichier_courant; static HINSTANCE hGlobInstance = NULL; // Pour le traitement des ressources static HGLOBAL hresource; // Pour le traitement des ressources HINSTANCE hThisInstance; /***********************************************************
    * *
    * Les fonctions *
    * *
    ***********************************************************/
    // Fonction qui ouvre le site web donné dans la variable adresse // Retour : aucun void site(char adresse[], bool mon_site) { // Si l'adresse à charger dans le navigateur web est celle de mon site // j'ajoute un paramètre supplémentaire pour signifier à mon site qu'on y vient // suite à un clic sur une zone de mon crack. if (mon_site) {sprintf(adresse,"%s?Crack pour %s",adresse,nom_application);} // J'ouvre l'adresse du site web demandée dans le navigateur web ShellExecute(NULL,"open",adresse,NULL,NULL,SW_SHOWNORMAL); } // Fonction qui envoie un mail au destinataire désigné par adresse_mail // Retour : aucun void mail() { // On ré-initialise la variable chaine en mettant un caractère de fin de chaine // en première position chaine[0]='\0'; // On crée la chaine de connexion pour le logiciel de messagerie // sprintf permet de formater des expressions suivant des commutateurs %s,%ld ... sprintf(chaine, "mailto:%s?subject=%s%s&body=%s",adresse_mail,titre_mail,nom_application,corps_mail); // On lance le logiciel de messagerie ShellExecute(NULL,"open",chaine,NULL,NULL,SW_SHOWNORMAL); } // Fonction qui lance le programme de la zone EDIT // Retour : aucun void lancer_programme() { GetWindowText(hwndEdit1,chaine,100); ShellExecute(NULL,"open",chaine,NULL,NULL,SW_SHOWNORMAL); } // Fonction qui affiche les informations // Retour : aucun void infos() { // On crée et on ouvre le fichier nommé fichier_infos en mode write (écriture) FILE * pFile = fopen(fichier_infos,"w"); if (pFile!=NULL) { // On copie la ressource correspondant au fichier d'informations // dans un fichier d'infos static char *ptexte; // On charge la ressource nommé TEXTE de type BINARY dans la variable pTexte hresource=LoadResource(hGlobInstance,FindResource(hGlobInstance,"TEXTE","BINARY")); ptexte=(char*) LockResource(hresource); // On écrit le contenu de la variable ptexte dans le fichier // représenté par le pointeur pFile fputs(ptexte,pFile); // On ferme le fichier fclose(pFile); // On lance le fichier d'infos dans le navigateur web ShellExecute(NULL,"open",fichier_infos,NULL,NULL,SW_SHOWNORMAL); } else { // Si on n'a pas réussi à créer et ouvrir le fichier d'infos // On affiche le message d'erreur suivant sprintf(chaine, "Impossible de créer le fichier %s dans le répertoire courant.",fichier_infos); MessageBox(hwnd, chaine, nom_application, MB_OK|MB_ICONERROR); } } // Fonction d'extraction du chemin de désinstallation de l'éxécutable à partir de la clé trouvée dans le registre // Retour : chemin de l'éxécutable formaté char * formater_chemin_registre(char * ch) { int k=0; int debut=0,fin=0,guillemet_suivant=1; for (int i=0 ;ch[i] ;i++) { //if (ch[i]==' ') {debut=i+1;} //if ((ch[i]=='"' || ch[i]=='\'') && guillemet_suivant) {debut=i+1;guillemet_suivant=0;} //if (ch[i]=='\\') {fin=i;} //if (ch[i]=='\\' || ch[i]=='/') {fin=i;} fin=i; } for (int i=debut ;i<=fin ;i++) { res[k]=ch[i]; k++; } // On ajoute ce caractère terminal pour pouvoir // ensuite ajouté derrière le nom de l'executable res[k]='\\'; return res; } // Fonction d'extraction du chemin d'accès dans une chaîne // Retour : chemin de l'éxécutable char * extraire(char* ch2) { int i=0,k=0,fin=0; // Boucle qui lit la chaine ch2 pour trouver le caractère \ ou / du chemin d'accès for(i;ch2[i]!='\0' ;i++) { if (ch2[i]=='\\' || ch2[i]=='/') {fin=i;} } // Boucle qui construit le chemin extrait for(i=0;i<=fin ;i++) { res2[k]=ch2[i]; k++; } // On termine la chaine res2 par le caractère de fin de chaine // Cela evite une erreur dans l'extraction du chemin dans la fonction ecrire // si on extrait successivement 2 chemins de longueur différents (le premier plus // long que le deuxième). res2[k]='\0'; return res2; } // Fonction d'extraction du nom de fichier dans une chaîne // Retour : chemin de l'éxécutable char * extraire_nom_fichier(char* ch3) { int i=0,k=0; for(i=strlen(ch3)-2;ch3[i]!='\\' && ch3[i]!='/' ;i--) {;} for(i=i+1;i<=strlen(ch3)-1;i++) { res3[k]=ch3[i]; k++; } // On termine la chaine res2 par le caractère de fin de chaine // Cela evite une erreur dans l'extraction du chemin dans la fonction ecrire // si on extrait successivement 2 chemins de longueur différents (le premier plus // long que le deuxième). res3[k]='\0'; return res3; } // Fonction qui lit le chemin d'accès de l'application exécutable depuis la clé uninstall du registre // Retour : valeur du chemin char * lire_registre() { HKEY hKey; DWORD dwLen = 255; char dwKeyEn[255]={'\0'}; sprintf(chaine,"SOFTWARE\\Microsoft\\windows\\CurrentVersion\\Uninstall\\%s",cle_registre); // On ouvre la clé uninstall du registre RegOpenKey(HKEY_LOCAL_MACHINE,chaine,&hKey); // On récupère dans dwKeyEn la valeur associée au nom InstallLocation RegQueryValueEx(hKey,"InstallLocation", NULL, NULL, (LPBYTE)&dwKeyEn, &dwLen); RegCloseKey(hKey); // On met le chemin trouvé dans chemin_registre sprintf(chemin_registre,"%s", formater_chemin_registre(dwKeyEn)); return chemin_registre; } // Fonction qui dessine des objets sur la fenêtre principale // Retour : aucun void dessiner() { PAINTSTRUCT ps; // Début du dessin hdc = BeginPaint (hwnd, &ps); // Initialisation de la structure LOGFONT ZeroMemory(&lf, sizeof(LOGFONT)); // On met le nom de la police dans la propriété lfFaceName de lf strcpy(lf.lfFaceName,f); lf.lfHeight = 14; // hauteur des caractères lf.lfWeight = 0; // épaisseur des caractères lf.lfItalic = 0; // caractères en italique ou non lf.lfUnderline = 0; // caractères soulignés ou non // Création de la police hfont = CreateFontIndirect(&lf); hfontOld = (HFONT)SelectObject(hdc, hfont); // Arrière plan du dessin où l'on va écrire le texte // de la même couleur que le fond de la fenêtre SetBkMode(hdc,TRANSPARENT); // On écrit en bleu navy SetTextColor(hdc, RGB(0,0,128)); //DrawText(hdc, date_crack, -1, &message_date, DT_SINGLELINE); // On écrit le texte à partir des coordonnées d'un point // strlen calcule la taille d'une chaine TextOut (hdc, abscisse_text,15,"Programme",strlen("Programme")); TextOut (hdc, abscisse_text,38,"Cracker" ,strlen("Cracker")); TextOut (hdc, largeur_fenetre * 10 / 100,ordonnee_checkbox ,"Sauve",strlen("Sauve")); TextOut (hdc, largeur_fenetre * 10 / 100,ordonnee_checkbox+20,"Vérifie",strlen("Vérifie")); TextOut (hdc, largeur_fenetre * 10 / 100,ordonnee_checkbox+40,"Restaure",strlen("Restaure")); // Charger une icône située dans les ressource sous le numéro 500 // Remplacer le mot ICON par BITMAP pour charger une image de type bitmap HICON hBmp = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(500), IMAGE_ICON, largeur_icone, hauteur_icone, 0); DrawState(hdc,NULL,NULL,(LPARAM)hBmp,(WPARAM)NULL,icone.left,icone.top,0,0,DST_ICON); // Fin du dessin EndPaint (hwnd, &ps); } // Fonction qui calcule la somme tous les octets du fichiers // Retour : booléen qui dit si la somme est égale à celle attendue bool verification_integrite_fichier(char * f,int numero_fichier_a_craquer) { // On ouvre le fichier f en mode read binary (lecture binaire) FILE * pFile=fopen(f,"rb"); // On initilaise les variables long i=0; long somme=0; bool resultat=false; long taille = taille_somme[numero_fichier_a_craquer][0]; //On fait la somme des octets du fichier f while(i<taille) { somme+=fgetc(pFile); i++; } fclose(pFile); // Si on a demandé l'affichage de la somme. // On ne l'utilise une seule fois que pour le debugging if(afficher_somme) { chaine[0]='\0'; sprintf(chaine, "Somme octets de %s = %ld.", liste_fichiers[numero_fichier_a_craquer][1] , somme); MessageBox(hwnd, chaine , nom_application ,MB_OK|MB_ICONINFORMATION); } return (somme==taille_somme[numero_fichier_a_craquer][1]); } // Fonction qui calcule la taille d'une sous-matrice du tableau matrice // Retour : nombre d'octets à craquer pour le fichier considéré long calculer_taille_sous_matrice(long sous_matrice[]) { long i=0; //On evite avec i%2==1 l'arrêt prématuré sur un offset recevant la valeur 0x00 //La boucle while parcourt en effet toutes les valeurs du tableau offset/valeur //nommé sous_matrice mais elle peut s'arrêter avant le fin du tableau si un 0 est //trouvé dans les valeurs du tableau. while(sous_matrice[i] || i%2==1) i++; return i; } // Fonction qui écrit dans les fichiers listés dans liste_fichiers. // Retour : booléen. Vrai si aucune erreur rencontrée faux sinon. bool ecrire(int numero_fichier_a_craquer,int numero_boucle) { FILE * pFile; int nb_erreurs=0; GetWindowText(hwndEdit1,chemin_nom_fichier,100); // Si c'est la première boucle on vérifie le nom du fichier donné par la zone EDIT // Sinon on prend sans vérifier le nom du fichier à craquer dans la liste_fichiers if(numero_boucle==1) { fichier_courant = extraire_nom_fichier(chemin_nom_fichier); // On concatène le chemin de la zone edit et le nom de l'exécutable à craquer sprintf(chemin_nom_fichier, "%s%s", extraire(chemin_nom_fichier),fichier_courant); // On sauvegarde le nom du premier fichier ouvert pour le nom à afficher en // cas de restauration sprintf(premier_fichier,"%s",fichier_courant); } else { fichier_courant = liste_fichiers[numero_fichier_a_craquer][1]; // On concatène le chemin de la zone edit,le chemin relatif du fichier et // le nom de l'exécutable à craquer sprintf(chemin_nom_fichier, "%s%s%s", extraire(chemin_nom_fichier),liste_fichiers[numero_fichier_a_craquer][2],fichier_courant); } // Le nom donné au fichier de sauvegarde est d'extension .bak sprintf(chemin_nom_fichier2, "%s.bak", chemin_nom_fichier); // Le nom donné au fichier temporaire .exe est d'extension .temp sprintf(chemin_nom_fichier3, "%s.temp", chemin_nom_fichier); // Si le fichier existe et est en lecture seule // on enlève la protection en écriture if (GetFileAttributes(chemin_nom_fichier) | FILE_ATTRIBUTE_READONLY) { SetFileAttributes(chemin_nom_fichier, FILE_ATTRIBUTE_NORMAL); } // Si la case checkbox 3 est cochée on restaure if (checkbox3) { // On ouvre les fichiers en lecture pour voir s'ils existent FILE * pFile2=fopen(chemin_nom_fichier2,"r"); //Si le fichier .bak existe on effectue la restauration if(pFile2!=NULL) { // On remplace le fichier modifié par sa copie if(!CopyFile(chemin_nom_fichier2,chemin_nom_fichier,0)) { // Si une erreur est constatée sprintf(derniere_erreur,"Impossible de restaurer le fichier %s depuis %s.bak",fichier_courant); nb_erreurs++; } // On ferme le fichier ouvert avec succès fclose(pFile2); } else { // On lève une exception nb_erreurs++; // On empile l'erreur rencontrée sprintf(derniere_erreur, "Le fichier %s.bak à restaurer est introuvable !",fichier_courant); } } else { // Sinon on craque le fichier ou on copie la ressource pFile = fopen(chemin_nom_fichier,"rb+"); // Si l'ouverture en mode lecture binaire a réussi if (pFile!=NULL) { // Obtenir la taille du fichier. fseek (pFile , 0 , SEEK_END); long Taille_reelle_fichier = ftell (pFile); rewind (pFile); if (Taille_reelle_fichier==taille_somme[numero_fichier_a_craquer][0]) { bool erreur_somme=false; // Si la case est cochée on vérifie l'intégrité des fichiers if(checkbox2) { if (!verification_integrite_fichier(chemin_nom_fichier,numero_fichier_a_craquer)) { nb_erreurs++; // Si le fichier a déja été modifié ou cracké on arrête le craquage. sprintf(derniere_erreur, "Le fichier %s est déja cracké ou a été modifié !",fichier_courant); erreur_somme=true; } } // On écrit dans le fichier // -> si on ne demande pas de vérification d'intégité du fichier // -> s'il n'y a pas d'erreurs une fois la vérification de la somme du fichier effectuée // -> si c'est une ressource du crack if(!checkbox2 || (checkbox2 && erreur_somme==0) || liste_fichiers[numero_fichier_a_craquer][3]=="r") { // On fait une copie de sauvegarde du fichier // si le bouton checkbox1 est coché if(checkbox1) { if(!CopyFile(chemin_nom_fichier,chemin_nom_fichier2,0)) { sprintf(derniere_erreur, "Impossible de créer une copie de sauvegarde du fichier %s.",fichier_courant); nb_erreurs++; } } if(nb_erreurs==0) { //si c'est un fichier à craquer if(liste_fichiers[numero_fichier_a_craquer][3]=="") { for(int j=0;j<calculer_taille_sous_matrice(matrice[numero_fichier_a_craquer]);j=j+2) { //on se positionne sur l'offset à modifier du fichier à craquer fseek(pFile,matrice[numero_fichier_a_craquer][j],SEEK_SET); // On écrit le nouvel octet à l'offset fputc(matrice[numero_fichier_a_craquer][j+1],pFile); } // On ferme le fichier ouvert avec succès en mode écriture fclose(pFile); // Si aucune erreur d'écriture if(nb_erreurs==0) { etat_craquage[numero_fichier_a_craquer]=true; } } else { // Alors c'est une ressource à copier // On ferme le fichier ouvert avec succès en mode lecture fclose(pFile); if(nb_erreurs==0) { // On ouvre en mode écriture un nouveau fichier // dans lequel on va mettre tout le contenu de la ressource pFile = fopen(chemin_nom_fichier,"wb"); // Si l'ouverture en mode lecture binaire a réussi if (pFile!=NULL) { // On charge la ressource type binaire à partir de la liste des fichiers hresource=LoadResource(hGlobInstance,FindResource(hGlobInstance,liste_fichiers[numero_fichier_a_craquer][0],"BINARY")); char * contenu_ressource =(char*) LockResource(hresource); // On copie le contenu de la ressource dans le fichier crée fwrite(contenu_ressource,1,taille_somme[numero_fichier_a_craquer][2],pFile); // On ferme le fichier ouvert avec succès en mode écriture fclose(pFile); } else { // Si l'ouverture en écriture a échoué on lève une exception nb_erreurs++; // On empile l'erreur dans la pile nommée derniere_erreur sprintf(derniere_erreur, "Impossible d'écrire dans la ressource %s.",fichier_courant); } } //Fin du nb_erreurs=0 } //Fin des ressources à copier } //Fin du nb_erreurs=0 } //Fin du test sur checkbox2 //On ferme le fichier ouvert avec succès car il n'est pas fermé fclose(pFile); } // Fin du test sur les tailles else { //Si la taille n'est pas bonne nb_erreurs++; // On empile l'erreur dans la pile nommée derniere_erreur sprintf(derniere_erreur, "La taille du fichier est incorrecte.\n%s aurait dû faire %ld octets.\nCe n'est probablement pas la bonne version.",fichier_courant,taille_somme[numero_fichier_a_craquer][0]); //On ferme le fichier ouvert avec succès car il n'est pas fermé fclose(pFile); } } //Fin du test sur l'ouverture de fichier else { // Si une erreur apparaît à l'ouverture du fichier nb_erreurs++; if(GetFileAttributes(extraire(chemin_nom_fichier)) != FILE_ATTRIBUTE_DIRECTORY) { // Si le chemin d'accès du fichier est introuvable on renvoie une erreur sprintf(derniere_erreur, "Le chemin d'accès spécifié est introuvable.");} else { FILE * pFile = fopen(chemin_nom_fichier,"r"); // On teste l'existence du fichier chemin_nom_fichier if(pFile==NULL) { // Le chemin existe mais pas le répertoire sprintf(derniere_erreur, "Le fichier %s n'existe pas dans le répertoire spécifié.",fichier_courant); } else { // Sinon le fichier est déja utilisé auquel cas il est inaccessible. On renvoie à ce moment une erreur sprintf(derniere_erreur, "Le fichier %s est inaccessible\nIl est déja ouvert par un autre processus.",fichier_courant); // On ferme le fichier ouvert avec succes en mode lecture fclose(pFile); } } } } // Fin du test sur la restauration // On retourne l'état de l'écriture if(nb_erreurs==0) {return true;} else {return false;} } void effacer(long identifiants[],long nombre_id,bool erreurs) { GetWindowText(hwndEdit1,chemin_nom_fichier,100); for(int i=0;i<nombre_id;i++) { fichier_courant = liste_fichiers[identifiants[i]][1]; // On concatène le chemin de la zone edit,le chemin relatif du fichier et // le nom de l'exécutable à craquer sprintf(chemin_nom_fichier, "%s%s%s", extraire(chemin_nom_fichier),liste_fichiers[liste_identifiants_fichiers[i]][2],fichier_courant); // Le nom donné au fichier de sauvegarde est d'extension .bak sprintf(chemin_nom_fichier2, "%s.bak", chemin_nom_fichier); // Le nom donné au fichier temporaire est d'extension .temp sprintf(chemin_nom_fichier3, "%s.temp", chemin_nom_fichier); // Le nom donné au fichier temporaire .bak est d'extension .temp sprintf(chemin_nom_fichier4, "%s.temp", chemin_nom_fichier2); if(erreurs) { // On restitue le fichiers .exe original CopyFile(chemin_nom_fichier3,chemin_nom_fichier,0); // On restitue le fichiers .bak original CopyFile(chemin_nom_fichier4,chemin_nom_fichier2,0); //Si un fichier .bak existait avant la sauvegarde un .bak.temp a été crée //Donc on n'efface pas la sauvegarde qui existait avant FILE * pFile = fopen(chemin_nom_fichier4,"r"); if(pFile!=NULL) {fclose(pFile);} else {DeleteFile(chemin_nom_fichier2);} } //Si restauration activée // ->pas d'erreur on efface le .bak // ->erreur on ne touche pas au .bak if(checkbox3 && !erreurs) DeleteFile(chemin_nom_fichier2); DeleteFile(chemin_nom_fichier3); DeleteFile(chemin_nom_fichier4); } } // Effectue une copie préventive des fichiers .exe et .bak éventuels sous forme de fichiers // exe.temp et .bak.temp indiqués dans la liste des identifiants de fichiers liste_identifiants_fichiers. // Cela permet de rétablir facilement tous les fichiers originaux en cas d'erreur. // Retour rien (void = rien) void sauver_fichiers() { int i=0; GetWindowText(hwndEdit1,chemin_nom_fichier,100); // On sauve les fichiers identifiés dans liste_identifiants_fichiers // avec leur .bak éventuel. // En C tout ce qui différent de 0 est true => pb si indentifiant i vaut 0 => test du while lourd à écrire while(liste_identifiants_fichiers[i] || (liste_identifiants_fichiers[i]==0 && i==0)) { fichier_courant = liste_fichiers[liste_identifiants_fichiers[i]][1]; // On concatène le chemin de la zone edit,le chemin relatif du fichier et // le nom de l'exécutable à craquer sprintf(chemin_nom_fichier, "%s%s%s", extraire(chemin_nom_fichier),liste_fichiers[liste_identifiants_fichiers[i]][2],fichier_courant); // On enlève l'attribut en lecture seule sur le fichiers // car au moment de l'effacement le fichier .temp correspondant // qui aura été crée ne pourra être effacé if (GetFileAttributes(chemin_nom_fichier) | FILE_ATTRIBUTE_READONLY) { SetFileAttributes(chemin_nom_fichier, FILE_ATTRIBUTE_NORMAL); } // Le nom donné au fichier de sauvegarde est d'extension .bak sprintf(chemin_nom_fichier2, "%s.bak", chemin_nom_fichier); // Le nom donné au fichier temporaire est d'extension .temp sprintf(chemin_nom_fichier3, "%s.temp", chemin_nom_fichier); // Le nom donné au fichier temporaire .bak déja existant sera d'extension .temp sprintf(chemin_nom_fichier4, "%s.temp", chemin_nom_fichier2); // On fait une copie temporaire du fichiers .exe. // 0 dans CopyFile pour l'overwrite si le fichier .temp existe déja (normalement il n'y en a pas => mais prudence oblige) CopyFile(chemin_nom_fichier,chemin_nom_fichier3,0); // On fait une copie temporaire du fichiers .bak CopyFile(chemin_nom_fichier2,chemin_nom_fichier4,0); i++; } } // On écrit tous les fichiers et les ressources inscrits sous forme de numéro dans // liste_identifiants_fichiers en appelant la fonction ecrire pour chaque fichier à traiter // Retour : rien void ecrire_en_boucle() { bool etat_ecriture=true; int numero_boucle=1; int k=0; bool etat_checkbox3=checkbox3; //On sauve tous les fichiers avant d'effectuer les opérations d'écriture ou d'effacement sauver_fichiers(); //On balaie la liste des identifiants de fichiers //Attention : si un identifiant vaut 0 on sort de la boucle => il faut éviter ce pb par ce test dans le while. while(liste_identifiants_fichiers[k] || (liste_identifiants_fichiers[k]==0 && k==0)) { etat_ecriture = etat_ecriture & ecrire(liste_identifiants_fichiers[k],numero_boucle); numero_boucle++; k++; } // Si aucune erreur constatée sur tous les fichiers écrits if(etat_ecriture) { if(!checkbox3) { // Si on n'est pas en mode restauration // on affiche le message correspondant sprintf(chaine,message_reussite); //Si une copie de sauvegarde a été demandée on active la case checkbox3 //pour la restauration if(checkbox1) { SetWindowText(hwndButton1,"Restaurer"); } } else { // Si on était dans l'état restauration on affiche le message correspondant // et on repasse dans l'état initial if(k>1) { sprintf(chaine, "Tous les fichiers ont été restaurés. "); } else { sprintf(chaine, "Le fichier %s a été restauré. ",premier_fichier); } // On change le nom du bouton et on coche ou non la case checkbox3 SetWindowText(hwndButton1,"Crack"); } //On efface tous les fichiers temporaires crées effacer(liste_identifiants_fichiers,numero_boucle-1,false); //On modifie l'état coché ou non de checkbox3 si la sauvegarde a été demandée //Ne pas permuter avec ligne du dessus sinon pb sur état checkbox3 dans effacer if(checkbox1) { if(!checkbox3) {checkbox3=true;} else {checkbox3=false;} SendMessage(hwndCheckBox3, BM_SETCHECK, checkbox3, 0); } MessageBox(hwnd,chaine,nom_application,MB_OK|MB_ICONINFORMATION); } else { //On renomme tous les fichiers .temp crées en .exe //On efface tous les fichiers .bak crées effacer(liste_identifiants_fichiers,numero_boucle-1,true); //On renvoie la dernière erreur MessageBox(hwnd,derniere_erreur,nom_application,MB_OK|MB_ICONERROR); } } // Fonction qui ouvre la boite de dialogue de sélection de fichiers // Retour : rien char * selection_fichier(long numero_fichier) { OPENFILENAME ofn; char szFileName[MAX_PATH]; ZeroMemory(&ofn, sizeof(ofn)); szFileName[0] = '\0'; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFilter = liste_fichiers[numero_fichier][4]; ofn.lpstrTitle = titre_boite_dialogue; // szFileName = le fichier avec son chemin qui a été sélectionné // dans la boite de dialogue ofn.lpstrFile = szFileName; // Si on n'a pas trouvé le chemin d'insatllation dans le registre // On positionne la boîte de sélection de fichiers sur C:\Program Files if(chemin_registre[0]=='\0') {ofn.lpstrInitialDir = "C:\\Program Files";} else {ofn.lpstrInitialDir = chemin_registre;} ofn.nMaxFile = MAX_PATH; ofn.lpstrDefExt = "exe"; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; //Ouverture de la boîte de dialogue avec les paramètres précédents GetOpenFileName(&ofn); //Chemin + nom du fichier sélectionné sprintf(chaine, "%s", szFileName); // Si aucun fichier n'a été sélectionné on restitue la chaîne qui est dans le edit if (chaine[0]=='\0') GetWindowText(hwndEdit1,chaine,200); return chaine; } // Fonction qui désactive hwndButton1 quand la zone de texte hwndEdit1 est vide // ou qui le réactive sinon // Retour : aucun void controler_contenu_edit() { //Si le contenu de la zone edit est vide on désactive hwndButton3 GetWindowText(hwndEdit1,chaine,100); bool bouton_actif; if (chaine[0]=='\0') {bouton_actif=false;} else {bouton_actif=true;} EnableWindow(hwndButton1,bouton_actif); } // Fonction qui retourne le contenu de la zone edit // Retour : contenu de la zone edit char * contenu_edit() { GetWindowText(hwndEdit1,chaine,100); return chaine; } // Fonction qui change le chemin et de l'exe dans la zone edit quand on clique sur un bouton radio // Retour : aucun void changer_edit(char * chaine_chemin,char * nom_de_l_exe) { //On met le chemin suivi du nom de l'exe dans la zone edit sprintf(chaine,"%s\%s", chaine_chemin,nom_de_l_exe); SetWindowText(hwndEdit1,chaine); } /***********************************************************
    * *
    * Composants minimum de l'application graphique *
    * *
    ***********************************************************/
    // Cette fonction est appelée par la fonction windows DispatchMessage( ) LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { HDC hdcStatic = (HDC)wParam; HDC hdc = (HDC)wParam; HBRUSH g_hbrBackground; switch (message) /* pointeur des messages */ { // Evénement déclenché lors du coloriage des composants statics du groupe case WM_CTLCOLORSTATIC: { // On fixe la couleur de fond des composants de type static g_hbrBackground = CreateSolidBrush(RGB(0xEC,0xE9,0xD8)); // On fixe la couleur du texte du premier composant static if (GetWindowLong((HWND)lParam, GWL_ID) == 11) { // On écrit en marron SetTextColor(hdcStatic, RGB(128,00,00)); } else { // On fixe la couleur du texte du deuxième composant static
    if (GetWindowLong((HWND)lParam, GWL_ID) == 12) { // On met la police en gras lf.lfWeight = FW_BOLD; // Création de la police hfont = CreateFontIndirect(&lf); hfontOld = (HFONT)SelectObject(hdc, hfont); // On écrit en vert SetTextColor(hdcStatic, RGB(0,128,128)); } else { // Sinon les autres composants static seront de couleur navy
    SetTextColor(hdcStatic, RGB(0,0,128)); } } SetBkMode(hdcStatic, TRANSPARENT); return (LONG)g_hbrBackground; } break; // Evénement déclenché lors du coloriage de la zone edit case WM_CTLCOLOREDIT: // On fixe la couleur de fond du composant EDIT g_hbrBackground = CreateSolidBrush(RGB(0xEE,0xEE,0xEE)); // On écrit en violet
    SetTextColor(hdc, RGB(128,0,128)); // L'arrière plan du rectangle dans lequel on écrit sera de la même // couleur que le fond SetBkMode(hdc, TRANSPARENT); return (LONG)g_hbrBackground; break; // Evénement déclenché quand la fenêtre doit être redessinée case WM_PAINT: dessiner(); break; // Evénement déclenché lorsque la souris bouge sur le fenêtre case WM_MOUSEMOVE: // Déclaration d'un point static POINT MousePos; // Récupération de la position du pointeur de la souris GetCursorPos(&MousePos); // Transformation des coordonnées absolues de la souris en coordonnées relatives à la fenêtre ScreenToClient(hwnd,&MousePos); // Si l'utilisateur passe au dessus d'une des zones "icone","cracker","auteur","message_date" on change le curseur par une main if( MousePos.x>=icone.left && MousePos.x<=icone.right && MousePos.y<=icone.bottom && MousePos.y>=icone.top || MousePos.x>=cracker.left && MousePos.x<=cracker.right && MousePos.y<=cracker.bottom && MousePos.y>=cracker.top || MousePos.x>=auteur.left && MousePos.x<=auteur.right && MousePos.y<=auteur.bottom && MousePos.y>=auteur.top || MousePos.x>=message_date.left && MousePos.x<=message_date.right && MousePos.y<=message_date.bottom && MousePos.y>=message_date.top || MousePos.x>=lancement.left && MousePos.x<=lancement.right && MousePos.y<=lancement.bottom && MousePos.y>=lancement.top ) { // Le curseur en forme de main est identifié par windows comme ayant le numéro 32649 const long HandCursor = 32649; // On charge le curseur HCURSOR hCursor = SetCursor(LoadCursor(hThisInstance,MAKEINTRESOURCE(HandCursor))); // On affiche le curseur en forme de main ShowCursor(TRUE); } break; // Evénement déclenché lorsque le bouton gauche de la souris est pressé case WM_LBUTTONDOWN: // Si l'utilisateur clique sur l'icône if(MousePos.x>=icone.left && MousePos.x<=icone.right && MousePos.y<=icone.bottom && MousePos.y>=icone.top) {site(adresse_site_editeur,false);} // Si l'utilisateur clique sur le nom du cracker qui correspond au rectangle "auteur" if(MousePos.x>=auteur.left && MousePos.x<=auteur.right && MousePos.y<=auteur.bottom && MousePos.y>=auteur.top) {site(adresse_site_cracker,true);} // Si l'utilisateur clique sur l'auteur du crack qui correspond à la zone nommée cracker if(MousePos.x>=cracker.left && MousePos.x<=cracker.right && MousePos.y<=cracker.bottom && MousePos.y>=cracker.top) {mail();} // Si l'utilisateur clique sur la zone message_date if(MousePos.x>=message_date.left && MousePos.x<=message_date.right && MousePos.y<=message_date.bottom && MousePos.y>=message_date.top) {site(adresse_site_telechargement,false);} // Si l'utilisateur clique sur la zone de lancement if(MousePos.x>=lancement.left && MousePos.x<=lancement.right && MousePos.y<=lancement.bottom && MousePos.y>=lancement.top) {lancer_programme();} break; // Evénement déclenché lorsque l'on ferme la fenêtre case WM_DESTROY: // Fermeture de la fenêtre DeleteFile(fichier_infos); // On efface le fichier d'infos PostQuitMessage(0); // On envoie un message WM_QUIT à la pile break; // Evénement déclenché lorsqu'une commande est envoyée case WM_COMMAND: // si l'utilisateur fait un clic sur le bouton checkbox1 on transforme en coché on non l'état du bouton. if ((LOWORD(wParam) == 31)) { if(SendMessage(hwndCheckBox1,BM_GETCHECK,checkbox1,0)==BST_CHECKED) {checkbox1=true;} else {checkbox1=false;} } // si l'utilisateur fait un clic sur le bouton checkbox2 on transforme en coché on non l'état du bouton. if ((LOWORD(wParam) == 32)) { if(SendMessage(hwndCheckBox2,BM_GETCHECK,checkbox2,0)==BST_CHECKED) {checkbox2=true;} else {checkbox2=false;} } // si l'utilisateur fait un clic sur le bouton checkbox3 on transforme en coché on non l'état du bouton. if ((LOWORD(wParam) == 33)) { if(SendMessage(hwndCheckBox3,BM_GETCHECK,checkbox3,0)==BST_CHECKED) {checkbox3=true;} else {checkbox3=false;} } // Clic sur le edit if (LOWORD(wParam) == 15) {controler_contenu_edit();} //Clic sur le bouton crack if ((LOWORD(wParam) == 21) && (HIWORD(wParam) == BN_CLICKED)) {ecrire_en_boucle();} //Clic sur le bouton infos if ((LOWORD(wParam) == 22) && (HIWORD(wParam) == BN_CLICKED)) {infos();} //Clic sur le bouton chercher if ((LOWORD(wParam) == 23) && (HIWORD(wParam) == BN_CLICKED)) {SetWindowText(hwndEdit1,selection_fichier(numero_fichier_a_craquer));controler_contenu_edit();} //Clic sur le bouton checkbox3 if ((LOWORD(wParam) == 33) && (HIWORD(wParam) == BN_CLICKED)&& checkbox3) {SetWindowText(hwndButton1,"Restaurer");} if ((LOWORD(wParam) == 33) && (HIWORD(wParam) == BN_CLICKED)&& !checkbox3) {SetWindowText(hwndButton1,"Crack");} break; // Evénement déclenché lorsqu'une touche du clavier est pressée case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: // Si la touche échappe est pressée DeleteFile(fichier_infos); // On efface le fichier d'infos PostQuitMessage(0); // On ferme le programme } break; // Pour les messages qu'on ne traite pas default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } //Point d'entrée du programme (équivaut à la procédure main en C) int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { MSG messages; /* Variable contenant les messages de l'application */ WNDCLASSEX wincl; /* Structure de données pour windowclass */ /* Structure de la fenêtre */ wincl.hInstance = hThisInstance; wincl.lpszClassName = "WindowsApp"; wincl.lpfnWndProc = WindowProcedure; /* Cette fonction est appelée par windows */ wincl.style = CS_HREDRAW|CS_VREDRAW; /* Réagir au demande de redessinage */ wincl.cbSize = sizeof(WNDCLASSEX); /* Utilisons l'icône par défaut et la flèche de la souris */ wincl.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(500)); wincl.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(500), IMAGE_ICON, 16, 16, 0); wincl.hCursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszMenuName = NULL; /* Pas de menu */ wincl.cbClsExtra = 0; /* Pas d'octets supplémentaires après la classe window */ wincl.cbWndExtra = 0; /* structure or the window instance */ // Fixons la couleur de fond de la fenêtre wincl.hbrBackground = CreateSolidBrush(RGB(0xCC, 0xCC, 0xCC)); // 0xEC,0xE9,0xD8 par défaut // Enregistrons la classe window, si échec quitons le programme if(!RegisterClassEx(&wincl)) return 0; // Initialisation de la structure LOGFONT ZeroMemory(&lf, sizeof(LOGFONT)); strcpy(lf.lfFaceName,f); lf.lfHeight = 14; // Taille des caractères dans la police choisie lf.lfWeight = 0; // Epaisseur de la police (Gras ou non) lf.lfItalic = 0; // Police en italic lf.lfEscapement = 0; // Espacement des caractères dans la police
    lf.lfQuality = PROOF_QUALITY; // Qualité de la police // Création de la fonte hfont = CreateFontIndirect(&lf); hfontOld = (HFONT)SelectObject(hdc, hfont); // La classe est enregistrée , créons le programme // Créons la fenêtre principale hwnd = CreateWindowEx( 0, /* Extended possibilites for variation */ "WindowsApp", /* Nom de la classe */ nom_application, /* Titre de la fenêtre */ WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, /* Style de la fenêtre */ point_gauche_fenetre, // coordonnée gauche du coin supérieur gauche de la fenêtre point_haut_fenetre, // coordonnée du haut du coin supérieur gauche de la fenêtre //CW_USEDEFAULT, /* Ou bien Windows decide automatiquement du coin supérieur gauche de la fenêtre */ //CW_USEDEFAULT, /* Ou bien Windows decide automatiquement du coin supérieur haut de la fenêtre */ largeur_fenetre, /* Largeur de la fenêtre en pixels */ hauteur_fenetre, /* hautre de la fenêtre en pixels */ HWND_DESKTOP, /* La fenêtre est fille du bureau */ NULL, /* Pas de menu */ hThisInstance, /* Pointeur de l'instance du programme */ NULL /* Pas de données pour la création de la fenêtre */ ); // Définition du cadre qui enveloppe toutes les zone de la fenêtre // C'est en fait un bouton transparent dont on ne voit que le contour (propriété BS_GROUPBOX) HWND hwndCadre1 = CreateWindow( "BUTTON", //Type BUTTON du composant à créer "", //Texte écrit sur le bouton (dans le cas des GROUPBOX c'est juste au dessus du cadre à gauche sinon c'est sur le bouton directement) WS_CHILD|WS_VISIBLE|BS_GROUPBOX, //Styles associés au bouton largeur_fenetre* 2 / 100 , 0,largeur_fenetre * 95 / 100,hauteur_groupe, //Coordonnées du point supérieur gauche et du point inférieur droit qui délimitent le bouton (abscisse,ordonnée,abscisse,ordonnée) hwnd, //Le bouton fait partie de la fenêtre repérée par le pointeur hwnd (WiNDow Handle) (HMENU)10, //10 est l'identifiant que nous allons donner à ce composant hThisInstance, /* Pointeur de l'instance du programme */ NULL); /* Pas de données pour la création de la fenêtre */ // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant
    SendMessage(hwndCadre1,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée une zone static d'identifiant 11 HWND hwndStatic1 = CreateWindow ( "STATIC", titre_application, WS_CHILD | WS_VISIBLE | SS_CENTER | SS_SUNKEN, // SS_SUNKEN pour avoir un static de forme enfoncée dans la fenêtre abscisse_static , ordonnee_static1 , largeur_static, hauteur_static, hwnd, (HMENU) 11, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndStatic1,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée une zone static d'identifiant 12 HWND hwndStatic2 = CreateWindow ( "STATIC", "Pifoman", WS_CHILD | WS_VISIBLE | SS_CENTER | SS_SUNKEN, abscisse_static , ordonnee_static2 , largeur_static, hauteur_static, hwnd, (HMENU) 12, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndStatic2,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée une zone static d'identifiant 13 qui contient la date du crack HWND hwndStatic3 = CreateWindow ( "STATIC", date_crack, WS_CHILD | WS_VISIBLE | SS_CENTER | SS_SUNKEN, abscisse_static , ordonnee_static3 , largeur_static, hauteur_static, hwnd, (HMENU) 13, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndStatic3,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée une zone static d'identifiant 14 qui contiendra les commentaires HWND hwndStatic4 = CreateWindow ( "STATIC", /* Type de composant à créer */ "\r\nCommentaires", WS_CHILD | WS_VISIBLE | SS_CENTER | SS_SUNKEN, abscisse_static , ordonnee_static4, largeur_static, hauteur_static4, /* Dimensions du composant */ hwnd, /* Le parent de ce composant est cette fenêtre */ (HMENU) 14, /* Identifiant de contrôle = 14 */ hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndStatic4,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On cherche le chemin d'accès par défaut de l'application dans le registre avec lire_registre(). // Et on l'écrit dans la zone d'édition le rséultat de cette interrogation. // On lit la valeur de la clé uninstall du registre sprintf(chemin_registre,"%s",lire_registre()); // Si on a trouvé le chemin dans le registre (ie chaine non nulle) on ajoute le nom de l'exe au chemin trouvé dans le registre avec la fonction sprintf if(chemin_registre[0]!='\0') sprintf(chemin_registre_edit,"%s%s",chemin_registre,liste_fichiers[numero_fichier_a_craquer][1]); // On crée une zone d'édition de texte d'identifiant 15 qui contiendra le chemin d'accès de l'exécutable à craquer hwndEdit1 = CreateWindow ( "EDIT", chemin_registre_edit, WS_CHILD | WS_VISIBLE | ES_LEFT | ES_AUTOHSCROLL, abscisse_static+1 , ordonnee_edit, largeur_static-1, hauteur_static, hwnd, (HMENU) 15, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndEdit1,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // Limiter le texte tapé à 100 caractères dans la zone edit SendMessage(hwndEdit1, EM_LIMITTEXT,100, true) ; // On crée le bouton Crack avec l'identifiant 21 hwndButton1 = CreateWindow ( "button", "Crack", WS_CHILD | WS_VISIBLE | BS_FLAT, largeur_fenetre* 5 / 100 , ordonnee_bouton , largeur_bouton , hauteur_bouton, hwnd, (HMENU) 21, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndButton1,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée le bouton infos avec l'identifiant 22 hwndButton2 = CreateWindow ( "button", "Infos", WS_CHILD | WS_VISIBLE | BS_FLAT, 124, ordonnee_bouton, largeur_bouton, hauteur_bouton, hwnd, (HMENU) 22, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndButton2,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée le bouton chercher avec l'identifiant 23 hwndButton3 = CreateWindow ( "Button", "Chercher", WS_CHILD | WS_VISIBLE | BS_FLAT, largeur_fenetre* 66 / 100 , ordonnee_bouton, largeur_bouton, hauteur_bouton, hwnd, (HMENU) 23, hThisInstance, NULL ); // On envoie un message au dispatcher : la fonction DispatchMessage() pour spécifier la police d'écriture qu'on va utiliser dans le composant SendMessage(hwndButton3,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // On crée une case à cocher avec l'identifiant 31 hwndCheckBox1 = CreateWindow ( "button", "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, largeur_fenetre* 5 / 100 , 120, 13, 13, hwnd, (HMENU) 31, hThisInstance, NULL ); // On envoie un message pour spécifier l'état coché ou non du bouton
    SendMessage(hwndCheckBox1, BM_SETCHECK, checkbox1, 0); // On crée une case à cocher avec l'identifiant 32 hwndCheckBox2 = CreateWindow ( "button", "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, largeur_fenetre* 5 / 100 , 140, 13, 13, hwnd, (HMENU) 32, hThisInstance, NULL ); // On envoie un message pour spécifier l'état coché ou non du bouton SendMessage(hwndCheckBox2, BM_SETCHECK, checkbox2, 0); // On crée une case à cocher avec l'identifiant 33 hwndCheckBox3 = CreateWindow ( "button", "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, largeur_fenetre* 5 / 100 , 160, 13, 13, hwnd, (HMENU) 33, hThisInstance, NULL ); // On envoie un message pour spécifier l'état coché ou non du bouton SendMessage(hwndCheckBox3, BM_SETCHECK, checkbox3, 0); //Si la zone edit est vide on désactive le bouton crack controler_contenu_edit(); // Rendre la fenêtre visible à l'écran ShowWindow(hwnd, nFunsterStil); // Démarrer la boucle de messages // Elle fonctionnera jusqu'à ce que GetMessage( ) retourne 0 while(GetMessage(&messages, NULL, 0, 0)) { // Traduire les messages clé virtuel en messages avec caractères TranslateMessage(&messages); // Envoyer les messages à la fonction WindowProcedure DispatchMessage(&messages); } // Le programme retourne la valeur 0 // C'est la valeur donnée par la fonction PostQuitMessage( ) return messages.wParam; } //--------------------------------------------------------------------------------------------


    <script language="JavaScript" type="text/javascript"> document.write(""); </script>


    votre commentaire
  • // Code source : crack en C++ \\

    //---------------------------------------- Licence ------------------------------------------
    //
    //Auteur : Pifoman
    //Email : pifoman@yahoo.com
    //Adresse site : http://crackinfrance.free.fr
    //Url redirection : www.geocities.com/mitonnes
    //Date source : 28/09/2004
    //Version source : 1.1
    //Langage : C++
    //Compilateur : dev C++ 4 build 10/09/2000 (gratuit)
    //Adresse téléchargement : http://www.telecharger.com ou http://www.bloodshed.net/devcpp.html
    //Compilation : Windows XP édition familiale
    //Tests : Windows XP édition familiale / Windows 98
    //Type licence : libre. Vous pouvez copier et distribuer cette source
    // si vous laissez les lignes concernant la licence.
    // //------------------------------------------------------------------------------------------- //------------------------------ Instructions de compilation -------------------------------- // // Avant compilation du code // // 1/ Ouvrez STARTCLN.EXE dans Resource Hacker (version 3.4) // Faites action->Enregistrer toutes les ressources pour récupérer l'icône du programme Start clean // // 2/ Définissez un nouveau projet vide dans dev c++ // File->New Project->Empty Project // // 3/ Définissez un répertoire de travail au lancement de DevCpp.exe (dev c++) // Par exemple C:/Documents and Settings/inconnu/Bureau/Start Clean/ // // 4/ Copiez cette page (CTRL A CTRL C) dans Untitled1 (le fichier ouvert qui est vide) // // 5/ Définissez le fichier de resources // Vous devez définir un fichier de ressources dans lequel vous spécifiez l'icône à utiliser et le chemin du fichier info.htm // Ce fichier s'appelle par défaut Rsrc.rc et vous y accéder dans le menu Project->Edit Resource File de dev c++. // Copiez le contenu suivant en adaptant le chemin (supprimez les // devant 500 et texte) // // 500 ICON "C:/Documents and Settings/inconnu/Bureau/Start Clean/icon.ico" // TEXTE BINARY "C:/Documents and Settings/inconnu/Bureau/Start Clean/infos_original.htm" // // 6/ Cocher l'option "Do not create a console" dans Project->Project option // // 7/ Compilez et lancez par CTRL F10 // //------------------------------------------------------------------------------------------- //---------------------------- Compression de l'exécutable compilé -------------------------- // // 1/ Après compilation avec dev c++ vous obtenez Project 1.exe // 2/ Téléchargez UPX (j'utilise la version 0.72) sur http://www.exetools.com/compressors.htm // 3/ Mettez upx.exe dans votre répertoire de travail // 4/ Créez un fichier compress.bat dans votre répertoire de travail (enlevez les //) // // @echo off // del Crack.exe // upx -9 -oCrack.exe "Project 1.exe" // echo Crack pour Start Clean v1.2>file_id.diz // pause // // 5/ Double-cliquez sur compress.bat // 6/ Votre crack est maintenant de taille réduite (vous divisez la taille du crack par 4) // 7/ Vous pouvez le zipper et le diffuser sur internet :) // //------------------------------------------------------------------------------------------- //------------------------------------- Rendu graphique -------------------------------------

    <script type="text/javascript">document.write("")</script>

    //-------------------------------------------------------------------------------------------- //--------------------------------------- Code source ---------------------------------------- //Inclusion des bibliothèques #include <windows.h> #include <stdio.h> // pour sprintf //Déclaration des fonctions (autres que winmain) //Ici c'est inutile car winmain est à la fin du fichier //Quand on entre dedans il connait les fonctions définies avant puisque le fichier est lu de haut en bas // Variables globales char * nom_application = "Start Clean v1.2"; char * titre_application = "Crack pour Start Clean v1.2"; char cle_registre[] = "Start Clean"; char adresse_site_editeur[] = "http://www.nom_editeur.com"; char adresse_site_pifoman[] = "http://www.geocities.com/mitonnes/"; char adresse_mail[] = "pifoman@yahoo.com"; char titre_mail[] = "Remarques sur votre crack "; char corps_mail[] = "Bonjour"; char * date_crack = "24/09/2004"; char * date_prog = "20/05/1999"; char * fichier_infos = "infos.htm"; char * titre_boite_dialogue = "Sélectionner le fichier"; // Dimensions long largeur_fenetre = 330; long hauteur_fenetre = 270; long ordonnee_edit = 70; long ordonnee_static1 = 35; long ordonnee_static2 = ordonnee_static1+20; long ordonnee_static3 = ordonnee_static2+20; long ordonnee_static4 = ordonnee_static3+20; long ordonnee_static5 = ordonnee_static4+20; long ordonnee_static6 = ordonnee_static5+20; long ordonnee_static7 = ordonnee_static6+20; long abscisse_text_1 = 50; long abscisse_text_2 = 185; long ordonnee_checkbox = 160; long ordonnee_bouton = 190; long hauteur_bouton = 23; long largeur_bouton = 60; RECT titre = {0,10,largeur_fenetre,23}; //left,top,right,bottom RECT bienvenue = {abscisse_text_1,ordonnee_static2,abscisse_text_1 +80,ordonnee_static2+20}; //left,top,right,bottom RECT auteur = {abscisse_text_2,ordonnee_static2,abscisse_text_2 + 80,ordonnee_static2+20}; //left,top,right,bottom RECT icone = {largeur_fenetre * 85 / 100,35,largeur_fenetre * 85 / 100 +16 , 35+16}; //16x16 = dimension icône long point_gauche_fenetre = (GetSystemMetrics(SM_CXFULLSCREEN)-largeur_fenetre)/2 ; // On centre horizontalement la fenêtre du crack au lancement long point_haut_fenetre = (GetSystemMetrics(SM_CYFULLSCREEN)-hauteur_fenetre)/2 ; // On centre verticalement la fenêtre du crack au lancement bool checkbox = true; // Etat du bouton checkbox 1 par défaut (true = coché) bool verifier_integrite = true; //Paramétrages de l'application //Tableau des nom représentatifs des fichiers char * nom_fichiers[] = { "Start Clean v1.2", }; //Tableau des noms de fichiers exécutables char * liste_fichiers[] = { "STARTCLN.EXE", }; //Tableau des réglages des filtres sur la sélection des fichiers quand on cherche le programme à craquer char * liste_filtres[] = { "Start Clean v1.2 (STARTCLN.EXE)\0STARTCLN.EXE\0\0", }; //Tableau des modifications à effectuer sur le programme //Tableau structuré avec offset / valeur long matrice0[][5] = { {0x5DE,0x50}, {0x5DF,0x90}, {0x5E0,0x90}, {0x5E1,0x90}, {0x5E2,0x90}, }; //Tableau des taille des fichiers long taille_fichiers[] = { 31744, }; //Tableau des tailles des matrices long taille_matrices[] = {5}; //Somme des octets du fichiers pour vérifier l'intégrité long somme_octets[] = { 2151373, }; //Numéro du fichier à craquer (si on a une liste). Ici on n'a qu'un fichier) int numero_fichier_a_craquer=0; //Pour le debug : demande l'affichage de la somme des octet du fichier sélectionné bool afficher_somme=0; //Fin des paramétrages de l'application HWND hwnd; // Pointeur vers notre fenêtre
    HWND hwndButton1; // 1 ier bouton
    HWND hwndButton2; // 2 ieme bouton
    HWND hwndButton3; // 3 ieme bouton
    HWND hwndCheckBox1; // 1 iere boite à cocher



    char chemin_exe[100]; char chaine[100]; char chaine2[100]; char chemin_nom_exe[100]; char res[100]; HICON hBmp; RECT rc,rc2; HINSTANCE hThisInstance; // Déclarations nécessaires pour le choix de la police HDC hdc; LOGFONT lf; HFONT hfont; HFONT hfontOld; char f[32]={"Courier New"}; // Type de la police choisie /***********************************************************
    * *
    * Les fonctions *
    * *
    ***********************************************************/





    // Fonction qui ouvre le site web donné dans la variable adresse (adresse_site_editeur ou adresse_site_pifoman) // Retour : aucun mais ouvre la page web demandée du site dans le navigateur void site(char adresse[], bool mon_site) { if (mon_site) {sprintf(adresse,"%s?Crack pour %s",adresse,nom_application);} ShellExecute(NULL,"open",adresse,NULL,NULL,SW_SHOWNORMAL); } // Fonction qui affiche les infos // Retour : aucun void infos() { FILE * pFile = fopen(fichier_infos,"wb"); //On copie la ressource dans un fichier infos.htm que l'on ouvre ensuite if (pFile!=NULL) { static HINSTANCE hGlobInstance = NULL; static HGLOBAL hresource; static char *ptexte; // On charge une ressource binaire enregistrée sous le nom TEXTE dans Rsrc.rc hresource=LoadResource(hGlobInstance,FindResource(hGlobInstance,"TEXTE","BINARY")); ptexte=(char*) LockResource(hresource); fputs(ptexte,pFile); fclose(pFile); ShellExecute(NULL,"open",fichier_infos,NULL,NULL,SW_SHOWNORMAL); } else { MessageBox(NULL, "Impossible de créer le fichier d'informations.", nom_application, MB_OK|MB_ICONERROR); } } // Fonction qui envoie un mail au destinataire désigné par adresse_mail // Retour : aucun void mail() { sprintf(chaine, "mailto:%s?subject=%s%s&body=%s",adresse_mail,titre_mail,nom_application,corps_mail); ShellExecute(NULL,"open",chaine,NULL,NULL,SW_SHOWNORMAL); } // Fonction d'extraction du chemin de désinstallation de l'éxécutable à partir de la clé trouvée dans le registre // Fonction utilisée par GetFileAttributes (et lire_registre qui n'est pas utilisée) // Retour : chemin de l'éxécutable formaté char * extraire(char * ch) { int k=0; int debut=0,fin=0,guillemet_suivant=1; for (int i=0 ;ch[i] ;i++) { //if (ch[i]==' ') {debut=i+1;} //if ((ch[i]=='"' || ch[i]=='\'') && guillemet_suivant) {debut=i+1;guillemet_suivant=0;} //if (ch[i]=='\\') {fin=i;} if (ch[i]=='\\' || ch[i]=='/') {fin=i;} } for (int i=debut ;i<=fin ;i++) { res[k]=ch[i]; k++; } return res; } // Fonction qui lit le chemin d'accès de l'application exécutable depuis la clé uninstall du registre // Retour : valeur du chemin // Statut : non utilisée dans le programme; je la laisse pour information char * lire_registre() { HKEY hKey; DWORD dwLen = 255; char dwKeyEn[255]={'\0'}; sprintf(chaine,"SOFTWARE\\Microsoft\\windows\\CurrentVersion\\Uninstall\\%s",cle_registre); RegOpenKey(HKEY_LOCAL_MACHINE,chaine,&hKey); RegQueryValueEx(hKey,"UninstallString", NULL, NULL, (LPBYTE)&dwKeyEn, &dwLen); RegCloseKey(hKey); //On met le chemin trouvé dans chemin_exe sprintf(chemin_exe,"%s", extraire(dwKeyEn)); //On met le chemin de l'exécutable à vide car il n'y qu'une seule clef pour les applications installées dans le registre //sprintf(chemin_exe,"%s", ""); //Si l'extraction du registre renvoie un chaine vide on n'ajoute pas le nom de l'exe if(chemin_exe[0]=='\0') {sprintf(chaine,"%s", chemin_exe);} else {sprintf(chaine,"%s%s", chemin_exe,liste_fichiers[0]);} //MessageBox(NULL,chaine,"valeur de la clé du registre + liste_fichiers[0]",MB_OK); return chaine; } // Fonction qui dessine des objets sur la fenêtre principale // Retour : aucun void dessiner(HWND hwnd) { //Définition des variables de la fonction PAINTSTRUCT ps; HDC hdc; // Début du dessin hdc = BeginPaint (hwnd, &ps); // Initialisation de la structure LOGFONT ZeroMemory(&lf, sizeof(LOGFONT)); strcpy(lf.lfFaceName,f); lf.lfHeight = 14; lf.lfWidth = 7; lf.lfWeight = 0; lf.lfItalic = 0; lf.lfUnderline = 0; lf.lfEscapement= 0; // Création de la fonte hfont = CreateFontIndirect(&lf); hfontOld = (HFONT)SelectObject(hdc, hfont); // On récupère la taille de la fenêtre et on la met dans rc GetClientRect (hwnd, &rc); // L'arrière plan du dessin sera de la même couleur que le fond de la fenêtre qui est de couleurs rgb valant 0xCC,0xCC,0xCC // SetBkColor(hdc,RGB(0xCC,0xCC,0xCC)); SetBkMode(hdc,TRANSPARENT); // on ecrit en marron SetTextColor(hdc, RGB(128,00,00)); // on dessine le titre de l'application sur une seule ligne en l'alignant au centre DrawText(hdc, titre_application, -1, &titre, DT_SINGLELINE | DT_CENTER | DT_VCENTER); // on écrit en bleu navy SetTextColor(hdc, RGB(0,0,128)); // On dessine le texte dans la partie gauche de la fenêtre // On dessine dans le rectangle nommé bienvenue le mot cracker sur une seule ligne et aligné à gauche DrawText(hdc, "Cracker", -1, &bienvenue, DT_SINGLELINE | DT_LEFT); // La fonction strlen calcule la taille d'une chaine strlen est l'abbréviation de string length en anglais TextOut (hdc, abscisse_text_1,ordonnee_static3,"Date du crack",strlen("Date du crack")); TextOut (hdc, abscisse_text_1,ordonnee_static4,"Fichier cible",strlen("Fichier cible")); TextOut (hdc, abscisse_text_1,ordonnee_static5,"Taille fichier",strlen("Taille fichier")); TextOut (hdc, abscisse_text_1,ordonnee_static6,"Date fichier",strlen("Date fichier")); // on écrit en bleu noir SetTextColor(hdc, RGB(0,0,0)); // On dessine le texte dans la partie droite de la fenêtre // On dessine dans le rectangle nommé auteur le nom Pifoman sur une seule ligne et aligné à gauche DrawText(hdc, "Pifoman", -1, &auteur, DT_SINGLELINE | DT_LEFT); TextOut (hdc, abscisse_text_2,ordonnee_static3,date_crack,strlen(date_crack)); TextOut (hdc, abscisse_text_2,ordonnee_static4,liste_fichiers[numero_fichier_a_craquer],strlen(liste_fichiers[numero_fichier_a_craquer])); //on convertit la taille du fichier en une chaîne nommée chaine; %ld est le type (long decimal) de la variable taille_fichiers[numero_fichier_a_craquer] sprintf(chaine,"%ld octets",taille_fichiers[numero_fichier_a_craquer]); TextOut (hdc, abscisse_text_2,ordonnee_static5,chaine,strlen(chaine)); TextOut (hdc, abscisse_text_2,ordonnee_static6,date_prog,strlen(date_prog)); // On écrit en vert. // Les 3 paramètres de RGB vont de 0 à 255 pour régler dans le hdc le red,le green et le blue et déterminer la couleur choisie SetTextColor(hdc, RGB(0,128,128)); // On écrit le texte à coté de la case à cocher TextOut (hdc, largeur_fenetre * 20 / 100,ordonnee_checkbox+1,"Copie",strlen("Copie")); // Charger une icône située dans les ressource sous le numéro 500 // Remplacer le mot ICON par BITMAP pour charger une image de type bitmap à la place de l'icône HICON hBmp = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(500), IMAGE_ICON, 0, 0, 0); DrawState(hdc,NULL,NULL,(LPARAM)hBmp,(WPARAM)NULL,icone.left,icone.top,0,0,DST_ICON); // Fin du dessin EndPaint (hwnd, &ps); } // Fonction qui calcule la somme tous les octets du fichiers // Retour : booléen qui dit si la somme est égale à celle attendue bool verification_integrite_fichier(char * f,int numero_fichier_a_craquer) { FILE * pFile=fopen(f,"rb"); long i=0; long somme=0; // On somme tous les octets du fichier f while(i<taille_fichiers[numero_fichier_a_craquer]) { somme+=fgetc(pFile); i++; } fclose(pFile); // Si la somme des octets est demandée à l'affichage on l'affiche if(afficher_somme) { char chaine3[100]; sprintf(chaine3, "Somme octets de %s = %ld.", liste_fichiers[numero_fichier_a_craquer] , somme); MessageBox(hwnd, chaine3 , nom_application ,MB_OK|MB_ICONINFORMATION); } // On retourne à la fonction appelante (la fonction ecrire) un booleen qui dit si la somme // calculée est égale à la somme attendue return (somme==somme_octets[numero_fichier_a_craquer]); } // Fonction qui écrit dans les fichiers listés dans liste_fichiers // Retour : aucun void ecrire(int numero_fichier_a_craquer) { FILE * pFile; int nb_erreurs_fichier=0; // Chaine contenant la dernière erreur rencontrée char derniere_erreur[200]; // On détermine le nom donné au fichier de sauvagarde ici un fichier .bak sprintf(chaine2, "%s.bak", chemin_nom_exe); // Si le fichier existe et est en lecture seule on retire enlève la protection en écriture if ((GetFileAttributes(extraire(chemin_nom_exe)) == FILE_ATTRIBUTE_DIRECTORY ) && (GetFileAttributes(chemin_nom_exe) | FILE_ATTRIBUTE_READONLY)) { SetFileAttributes(chemin_nom_exe, FILE_ATTRIBUTE_NORMAL); } // On ouvre le fichier chemin_nom_exe en mode lecture binaire (read/binary) avec création si le fichier n'existe pas (+) pFile = fopen(chemin_nom_exe,"rb+"); // Si l'ouverture en mode lecture binaire a réussi if (pFile!=NULL) { // Obtenir la taille du fichier. fseek (pFile , 0 , SEEK_END); long Taille_reelle_fichier = ftell (pFile); rewind (pFile); if (Taille_reelle_fichier==taille_fichiers[numero_fichier_a_craquer]) { //On initialise la variable erreur_somme int erreur_somme=0; // Si la case est cochée on vérifie l'intégrité des fichiers if(verifier_integrite) { if (!verification_integrite_fichier(chemin_nom_exe,numero_fichier_a_craquer)) { // Si la verification d'intégrité sur le fichier rend faux on lève une exception nb_erreurs_fichier++; // On empile l'erreur trouvée dans la variable derniere_erreur sprintf(derniere_erreur, "Le fichier %s est déja cracké ou a été modifié !",liste_fichiers[numero_fichier_a_craquer]); // On spécifie qu'une erreur est apparue dans la calcul de la somme // En C tout ce qui n'est pas égal à 0 est vrai erreur_somme=1; } } // On écrit dans le fichier // ->; si on ne demande pas de vérification d'intégité du fichier // ->; s'il n'y a pas d'erreurs une fois la vérification de la somme du fichier effectuée if(!verifier_integrite || (verifier_integrite && erreur_somme==0)) { // On fait une copie de sauvegarde du fichier si le bouton checkbox1 est coché if(checkbox) { CopyFile(chemin_nom_exe,chaine2,0); } for(int j=0;j<taille_matrices[numero_fichier_a_craquer];j++) { int octet; // On examine le fichier à craquer et on écrit la valeur de l'octet matrice0[j][1] à l'offset matrice0[j][0] dans le fichier repéré par le pointeur pFile switch (numero_fichier_a_craquer) { case 0: // On positionne le curseur d'écriture au début du fichier repéré par le pointeur pFile fseek (pFile,matrice0[j][0],SEEK_SET); octet = matrice0[j][1]; break; } // On écrit dans le fichier à la position matrice[j][0] la valeur de la variable octet fputc(octet,pFile); } } } //fin du bloc Taille_reelle else { // Si la taille n'est pas bonne on lève une exception nb_erreurs_fichier++; // On empile l'erreur dans la pile nommée derniere_erreur sprintf(derniere_erreur, "La taille du fichier est incorrecte.\n%s aurait dû faire %ld octets.\nCe n'est probablement pas la bonne version.",liste_fichiers[numero_fichier_a_craquer],taille_fichiers[numero_fichier_a_craquer]); } // On ferme le fichier ouvert avec succès fclose(pFile); } else { // Si une erreur apparaît à l'ouverture du fichier on lève une exception nb_erreurs_fichier++; if(GetFileAttributes(extraire(chemin_nom_exe)) != FILE_ATTRIBUTE_DIRECTORY) { // Si le chemin d'accès du fichier est introuvable on renvoie une erreur sprintf(derniere_erreur, "Le chemin d'accès spécifié est introuvable."); } else { // Sinon le fichier est déja utilisé auquel cas il est inaccessible. On renvoie à ce moment une erreur sprintf(derniere_erreur, "Le fichier %s est inaccessible.",liste_fichiers[numero_fichier_a_craquer]); } } if(nb_erreurs_fichier==0) { // Si aucune erreur rencontrée on affiche ce message MessageBox(hwnd,"Le programme est maintenant cracké.\nVous pouvez saisir n'importe quel code d'enregistrement.",nom_application,MB_OK|MB_ICONINFORMATION); } else { //Sinon on affiche la dernière erreur rencontrée. MessageBox(hwnd,derniere_erreur,nom_application,MB_OK|MB_ICONERROR); } } // Fonction qui ouvre la boite de dialogue de sélection de fichiers // Retour : chaine correspondant au chemin d'accès + nom du fichier sélectionné void selection_fichier(HWND hwnd,long numero_fichier) { OPENFILENAME ofn; char szFileName[MAX_PATH]; ZeroMemory(&ofn, sizeof(ofn)); szFileName[0] = 0; ofn.lStructSize = sizeof(ofn); ofn.hwndOwner = hwnd; ofn.lpstrFilter = liste_filtres[numero_fichier]; ofn.lpstrTitle = titre_boite_dialogue; // szFileName = le fichier avec son chemin qui a été sélectionné dans la boite de dialogue ofn.lpstrFile = szFileName; ofn.lpstrInitialDir = chemin_exe; ofn.nMaxFile = MAX_PATH; ofn.lpstrDefExt = "exe"; ofn.Flags = OFN_EXPLORER | OFN_FILEMUSTEXIST | OFN_HIDEREADONLY; //Ouverture de la boîte de dialogue avec les paramètres précédents GetOpenFileName(&ofn); //Chemin + nom du fichier sélectionné dans la variable chaine sprintf(chemin_nom_exe, "%s", szFileName); //Si aucun fichier n'a été sélectionné on ne fait rien if (chemin_nom_exe[0]!='\0') ecrire(numero_fichier_a_craquer); } /***********************************************************
    * *
    * Composants minimum de l'application graphique *
    * *
    ***********************************************************/






    // Cette fonction est appelée par la fonction windows DispatchMessage( ) LRESULT CALLBACK WindowProcedure(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam) { switch (message) // pointeur des messages
    { // Evénement déclenché lors du coloriage des composants statics du groupe // WM signifie Windows Message case WM_CTLCOLORSTATIC: { // On déclare les variables que l'on va utiliser HDC hdcStatic = (HDC)wParam; HDC hdc = (HDC)wParam; HBRUSH g_hbrBackground; // On fixe la couleur de fond des composant de la même couleur que le fond de la fenêtre g_hbrBackground = CreateSolidBrush(RGB(0xCC,0xCC,0xCC)); SetTextColor(hdcStatic, RGB(50,50,255)); SetBkMode(hdcStatic, TRANSPARENT); return (LONG)g_hbrBackground; } break; // Evénement déclenché quand la fenêtre doit être redessinée case WM_PAINT: dessiner(hwnd); break; // Evénement déclenché lorsque la souris bouge sur le fenêtre case WM_MOUSEMOVE: // Déclaration d'un point static POINT MousePos; // Récupération de la position du pointeur de la souris GetCursorPos(&MousePos); // Transformation des coordonnées absolues de la souris en coordonnées relatives à la fenêtre de l'application ScreenToClient(hwnd,&MousePos); // Si l'utilisateur passe au dessus des rectangles nommés icone, bienvenue et auteur on change le curseur par une main if(MousePos.x>=icone.left && MousePos.x<=icone.right && MousePos.y<=icone.bottom && MousePos.y>=icone.top || MousePos.x>=bienvenue.left && MousePos.x<=bienvenue.right && MousePos.y<=bienvenue.bottom && MousePos.y>=bienvenue.top || MousePos.x>=auteur.left && MousePos.x<=auteur.right && MousePos.y<=auteur.bottom && MousePos.y>=auteur.top) { const long HandCursor = 32649; HCURSOR hCursor = SetCursor(LoadCursor(hThisInstance,MAKEINTRESOURCE(HandCursor))); ShowCursor(TRUE); } break; // Evénement déclenché lorsque le bouton gauche de la souris est pressé (LBUTTON = left button) case WM_LBUTTONDOWN: // Si l'utilisateur clique sur le rectangle nommé bienvenue on ouvre le site du cracker if(MousePos.x>=bienvenue.left && MousePos.x<=bienvenue.right && MousePos.y<=bienvenue.bottom && MousePos.y>=bienvenue.top) {site(adresse_site_pifoman,true);} // Si l'utilisateur clique sur l'icône on ouvre le site de l'éditeur du logiciel if(MousePos.x>=icone.left && MousePos.x<=icone.right && MousePos.y<=icone.bottom && MousePos.y>=icone.top) {site(adresse_site_editeur,false);} // Si l'utilisateur clique sur le rectangle nommé auteur on envoie un mail au cracker if(MousePos.x>=auteur.left && MousePos.x<=auteur.right && MousePos.y<=auteur.bottom && MousePos.y>=auteur.top) {mail();} break; // Evénement déclenché lorsque l'on ferme la fenêtre case WM_DESTROY: DeleteFile(fichier_infos); // On efface le fichier d'infos PostQuitMessage(0); // On envoie un message WM_QUIT à la pile break; // Evénement déclenché lorsqu'une commande est envoyée case WM_COMMAND: // si l'utilisateur fait un clic sur le bouton checkbox1 on transforme en coché on non l'état du bouton. if ((LOWORD(wParam) == 5)) { if(SendMessage(hwndCheckBox1,BM_GETCHECK,checkbox,0)==BST_CHECKED) {checkbox=true;} else {checkbox=false;} } // si l'utilisateur fait un clic sur le bouton n°2 ou ouvre la boîte de sélelection de fichier if ((LOWORD(wParam) == 2) && (HIWORD(wParam) == BN_CLICKED)) {selection_fichier(hwnd,numero_fichier_a_craquer);} // si l'utilisateur fait un clic sur le bouton n°3 ou ouvre le fichier d'infos if ((LOWORD(wParam) == 3) && (HIWORD(wParam) == BN_CLICKED)) {infos();} // si l'utilisateur fait un clic sur le bouton n°3 ou ferme le programme if ((LOWORD(wParam) == 4) && (HIWORD(wParam) == BN_CLICKED)) {PostMessage(hwnd, WM_CLOSE, 0, 0);} break; // Evénement déclenché lorsqu'une touche du clavier est pressée case WM_KEYDOWN: switch (wParam) { case VK_ESCAPE: // Si la touche échappe est pressée DeleteFile(fichier_infos); // On efface le fichier d'infos PostQuitMessage(0); } break; // Pour les messages qu'on ne traite pas default: return DefWindowProc(hwnd, message, wParam, lParam); } return 0; } //Point d'entrée du programme (équivaut à la procédure main en C) int WINAPI WinMain(HINSTANCE hThisInstance, HINSTANCE hPrevInstance, LPSTR lpszArgument, int nFunsterStil) { MSG messages; // Variable contenant les messages de l'application
    WNDCLASSEX wincl; // Structure de données pour windowclass

    // Structure de la fenêtre

    wincl.hInstance = hThisInstance; wincl.lpszClassName = "WindowsApp"; wincl.lpfnWndProc = WindowProcedure; // Cette fonction est appelée par windows
    wincl.style = CS_HREDRAW|CS_VREDRAW; // Réagir au demande de redessinage
    wincl.cbSize = sizeof(WNDCLASSEX); wincl.hIcon = LoadIcon(GetModuleHandle(NULL), MAKEINTRESOURCE(500)); wincl.hIconSm = (HICON)LoadImage(GetModuleHandle(NULL), MAKEINTRESOURCE(500), IMAGE_ICON, 16, 16, 0); // Le curseur par défaut est la flèche wincl.hCursor = LoadCursor(NULL, IDC_ARROW); wincl.lpszMenuName = NULL; // Pas de menu
    wincl.cbClsExtra = 0; // Pas d'octets supplémentaires après la classe window
    wincl.cbWndExtra = 0; // structure or the window instance

    // Fixons la couleur de fond de la fenêtre
    wincl.hbrBackground = CreateSolidBrush(RGB(0xCC, 0xCC, 0xCC)); // Enregistrons la classe window, si échec quittons le programme if(!RegisterClassEx(&wincl)) return 0; // Initialisation de la structure LOGFONT ZeroMemory(&lf, sizeof(LOGFONT)); strcpy(lf.lfFaceName,f); lf.lfHeight = 14; lf.lfWeight = 0; lf.lfItalic = 0; lf.lfEscapement=0; lf.lfQuality = PROOF_QUALITY; // Céation de la fonte hfont = CreateFontIndirect(&lf); hfontOld = (HFONT)SelectObject(hdc, hfont); // La classe est enregistrée , créons le programme // Créons la fenêtre principale hwnd = CreateWindowEx( 0, // Extended possibilites for variation
    "WindowsApp", // Nom de la classe
    nom_application, // Titre de la fenêtre
    WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX, // Style de la fenêtre
    point_gauche_fenetre, // coordonnée gauche du coin supérieur gauche de la fenêtre point_haut_fenetre, // coordonnée du haut du coin supérieur gauche de la fenêtre //CW_USEDEFAULT, Windows decide de la position de la fenêtre
    //CW_USEDEFAULT, Windows decide de la position de la fenêtre
    largeur_fenetre, // Largeur de la fenêtre en pixels
    hauteur_fenetre, // hautre de la fenêtre en pixels
    HWND_DESKTOP, // La fenêtre est fille du bureau
    NULL, // Pas de menu
    hThisInstance, // Pointeur de l'instance du programme
    NULL // Pas de données pour la création de la fenêtre
    ); // Créons le bouton 1 // Rectangle de coordonnées x coin supérieur gauche, y coin supérieur droit, largeur, hauteur hwndButton1 = CreateWindow ( "button", "Crack", WS_CHILD | WS_VISIBLE | BS_PUSHBUTTON | WS_TABSTOP | BS_FLAT, largeur_fenetre* 15 / 100 , ordonnee_bouton , largeur_bouton, hauteur_bouton, hwnd, (HMENU) 2, hThisInstance, NULL ); // On fixe la police du bouton à celle qu'on vient de définir SendMessage(hwndButton1,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // Créons le bouton 2 nommé infos hwndButton2 = CreateWindow ( "button", "Infos", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_FLAT, largeur_fenetre * 43 / 100, ordonnee_bouton, largeur_bouton, hauteur_bouton, hwnd, (HMENU) 3, hThisInstance, NULL ); // On fixe la police du bouton à celle qu'on vient de définir SendMessage(hwndButton2,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // Créons le bouton 3 nommé Fermé hwndButton3 = CreateWindow ( "Button", "Fermer", WS_CHILD | WS_VISIBLE | WS_TABSTOP | BS_FLAT, largeur_fenetre * 70 / 100 , ordonnee_bouton, largeur_bouton, hauteur_bouton, hwnd, (HMENU) 4, hThisInstance, NULL ); // On fixe la police du bouton à celle qu'on vient de définir SendMessage(hwndButton3,WM_SETFONT,(WPARAM)CreateFontIndirect (&lf),MAKELPARAM (TRUE,0)); // Créons le bouton checkBox 1 hwndCheckBox1 = CreateWindow ( "button", "", WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX, largeur_fenetre * 15 / 100 , ordonnee_checkbox, 13, 13, hwnd, (HMENU) 5, hThisInstance, NULL ); // On envoie un message pour initialiser l'état du bouton radio (coché ou non) : valeur booléenne de checkbox SendMessage(hwndCheckBox1, BM_SETCHECK, checkbox, 0); // Rendre la fenêtre visible à l'écran ShowWindow(hwnd, nFunsterStil); // Démarrer la boucle de messages // Elle fonctionnera jusqu'à ce que GetMessage() retourne 0 while(GetMessage(&messages, NULL, 0, 0)) { // Traduire les messages clé virtuel en messages avec caractères TranslateMessage(&messages); // Envoyer les messages à la fonction WindowProcedure DispatchMessage(&messages); } // Le programme retourne la valeur 0 // C'est la valeur donnée par la fonction PostQuitMessage( ) return messages.wParam; } //--------------------------------------------------------------------------------------------

    votre commentaire
  • Mon objectif : élaborer un crack en Turbo Pascal.

     

    1/ Le logiciel utile pour ce cours

    -> Le programme à craquer     :  Turbo Pascal compiler

     

    2/ Introduction

    Nous allons maintenant apprendre a faire un crack en langage TurboPascal... Rassurer vous, aucune connaissance n'est requise pour suivre ce tutorial !! Enfin, si : ca suppose que vous sachiez cracker un prog (cf cours 4) ...

    Comme je me vois mal vous apprendre a programmez en quelque leçons, je vais vous donnez un code source où vous ne modifierez que quelques lignes en fonction du crack que vous ferez :)

    Commencons par la théorie : ci-Dessous, le code source du patch en question...

    Tout ce qui ce trouve entre accolades en gris cela correspond à des commentaires en pascal.. Vous pouvez donc les supprimer si vous le souhaitez. Ce qui est en rouge, c'est ce qu'il faut changer c'est à dire adapater suivant votre programme ... Le reste du programme c'est le code donc n'y touchez pas si vous ne comprenez pas ce qui est écrit.

    Dernière remarque : dans le texte quand vous verrez des caractères bizarres des , ou des ... c'est normal c'est pour avoir les lettres accentuées sous dos.

    La version du code source est celle du 14/12/2004. Je l'ai complètement retouché (moi pifoman) au niveau du code et du graphisme et de la langue utilisée qui maintenant est le français.

     

    3/ Le code source

     

    ------------------------------------------------------------------------------------- début code ---------------------------------------------------------------------------------
    Program Crack;
    Uses CRT, DOS;
    
    Const
    
        FileNC               : string  = 'Start Clean 1.2';
        FileN                : String  = 'STARTCLN.EXE';
        DateCrack            : string  = '14/12/2004';		
        BytesToChange        : Integer = 6;  
        FileS                : LongInt = 31744; 
    
    
    
        {On force la comparaison du faux numéro de série au vrai dans la fonction KERNEL32.lstrcmpA}
        {Il suffit d'annuler pour cela le saut après la comparaison et écrivant une suite de 6 nop}
        {La ligne de code :004011EB 0F8580000000 jne 00401271 devient donc :004011EB 909090909090 nopnopnopnopnopnop}
    
        A                   : Array[1..6] of Record
        A : Longint;
        B : Byte;
        End =
        (
             (A:$5EB;B:$90),
             (A:$5EC;B:$90),
             (A:$5ED;B:$90),
             (A:$5EE;B:$90),
             (A:$5EF;B:$90),
             (A:$5F0;B:$90)
        );
    
    
    Var
      F     : File;
      Ch    : Char;
      I     : LongInt;
    
    Begin
     
    clrscr; 		     {on vide l'écran}
    Textcolor(3);	     {couleur du texte en bleu; 8 pour avoir la couleur blanc}
    
    Writeln('');
    Writeln('                     ÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜ');
    Writeln('                     Û                                   Û');
    Writeln('                     Û      Crack pour ',FILENC,'   Û');
    Writeln('                     Û            par Pifoman            Û');
    Writeln('                     Û                                   Û');
    Writeln('                     Û            le ',DateCrack,'          Û');
    Writeln('                     Û                                   Û');
    Writeln('                     Û          pifoman@yahoo.com        Û');
    Writeln('                     Û                                   Û');
    Writeln('                     ÛÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÜÛ');
    Writeln('');
    Writeln('');
    
    
    Assign(F,FileN);          {on assigne le fichier à la variable f}
    {$I-} Reset(F,1); {$I+}   {on ouvre le fichier en lecture/écriture}
    
    
    {Si le fichier exite et qu'on ne peut pas ouvrir le fichier en mode lecture/écriture}
    
    If (IOResult <> 0) and (FSearch(FileN,FExpand(FileN))<>'') then     
          begin      
    
             Writeln('');
             Writeln('      Le fichier ',FileN,' est d‚ja ouvert ou verrouill‚ en ‚criture.');
             Writeln('');
    
             halt(0);
    
          end;  
    
    
    
    If (FSearch(FileN,FExpand(FileN))='') then 
    
         begin
         
             Writeln('');
             Writeln('        Le fichier nomm‚ ',FileN,' n''existe pas dans ce r‚pertoire.');
             Writeln('');
             Writeln('                              Craquage abandonn‚...');
    
             Halt(1);
    
         end;  
    
    
    If FileSize(F)<>FileS then 
    
         begin
    
             Writeln('');
             Writeln('                V‚rification de la taille du fichier ... ERREUR!');
             Writeln('');
             Writeln('           Le fichier nomm‚ ',FileN,' a une taille incorrecte !!!');
             Writeln('');
             Writeln('                    La taille attendue est de : ', FileS ,' octets.');
             Writeln('                    La taille actuelle est de : ', FileSize(F) ,' octets.');
             Writeln('');
             Writeln('                              Craquage abandonn‚...');
             Writeln('');
             Writeln('');
    
             Close(F); 
             Halt(1);
    
         end 
    
    else
        
         begin
         
             Writeln('                 ² ²ÜÜÜ       ²ÜÜßßÜÜ     ÜÜßßÜܲ       ÜÜܲ ²');
             Writeln('  þ ßÜÜ        ²ÜÛÛÛÛÛÛÛÛÜÜ ±²Ûß    ²Û   Û²    ßÛ²± ÜÜÛÛÛÛÛÛÛÛܲ        ÜÜß þ');
             Writeln('      ²ÛßßÜ  ܲÛÛÛÛÛßßß²ÛÛÛÛÜ ß  ²  ²Û² ²Û²  ²   ß ÜÛÛÛÛ²ßßßÛÛÛÛÛ²Ü  ÜßßÛ²');
             Writeln('²  þ ܲÛÝ  ܲ²ÛÛÛÛ       ²ß²ÛÛÜ     ÜÛ   ÛÜ     ÜÛ۲߲       ÛÛÛÛ²²Ü  ÝÛ²Ü þ  ²');
             Writeln('Üß  ܲÛÛÛ Ü²²ÛÛÛÛ            ß²ÛÜÜÜÛß     ßÛÜÜÜÛ²ß            ÛÛÛÛ²²Ü ÛÛÛ²Ü  ßÜ');
             Writeln(' ßÛÛ²ÛÛß   ß²²Ûß                ²ßß        ßß²                ßÛ²²ß   ßÛÛ²ÛÛß');
             Writeln('');
             Writeln('');
     
             Writeln('                    V‚rification de la taille fichier ... OK');
             Writeln('');
    
          end; 
      
    
    For I := 1 to BytesToChange do
    
         begin 
    
    	       Seek(F,A[I].A);          {on positionne le curseur de lecture sur l'offset A[I].A du fichier F à craquer}
    	       Ch:=Char(A[I].B);        {on récupère la nouvelle valeur A[I].B à affecter à cet offset}
    	       Blockwrite(F,Ch,1);      {on écrit cette valeur à l'offset considéré.La valeur est sur 1 octet}
    
         end;
    
    Close(F);
    
    Writeln('');
    Writeln('                       Le programme est maintenant crack‚.'); 
     
    end.
    
    
    
    --------------------------------------------------------------------------------- Fin code ----------------------------------------------------------------------------------

     

    -------------------------------------------------------------------------- Rendu graphique ----------------------------------------------------------------------------

      <script type="text/javascript">document.write("")</script>

    ------------------------------------------------------------------------- Fin rendu graphique ----------------------------------------------------------------------------

     

     

    3/ Explications du code

    Au final, on s'appercoit qu'il n'y a que 3 endroits a modifier en fonction du patch qu'on veut faire. Ce sont les 3 premiers blocs de code où l'on fixe les paramètres du programme comme son nom sa taille en octets, la taille du tableau des offsets / valeurs et les offset / valeurs eux-mêmes. C'est pas sorcier et à mon avis, c'est a la portée de tout ceux qui veulent apprendre ..
     

    Bon, maintenant qu'on a vu la théorie, passons a la pratique !
    On va créer un crack pour le logiciel que nous avons cracké dans le 1er cours...
    Deja, on peut préparé les infos dont on a besoin pour faire le crack :

     

    Le code à modifier en rouge.

     

    • Le nombre de changements = 6 car on remplace 0F 84 80 00 00 00 par 90 90 90 90 90 90.
      J'ai ajouté des espaces entre les bytes pour la clarté du code mais ils n'existent pas.
    • Les offsets où on a fait les changements (à droite le byte d'origine) (cf cours 4) :

    5EB =>> 0F
    5EC =>> 84
    5ED =>> 80
    5EE =>> 00
    5EF =>> 00
    5F0 =>> 00

    • Pour chaque offset, la nouvelle valeur qu'on veut mettre : 90
    • Le nom du fichier EXE qu'il faut cracké, en version DOS : STARTCLN.EXE
    • La version du programme et son nom complet : StartClean v1.2

     

    Pour le code :

    • Une accolade { introduit un commentaire et une accolade } ferme un commentaire en pascal.
    • Un bloc d'instruction est encadré par la séquence de début begin la séquence de fin end.
    • Writeln affiche du texte à l'écran.

     

    Bien maintenant, il va falloir créer le fichier ".exe" grâce au compilateur... Là aussi, c'est très simple : lancer notepad et faites un copier / coller du code qui se trouve entre les ---début--- et ---fin--- du code précédent et enregistrez le fichier sous le nom crack.pas (pas comme pascal).Ensuite faites glisser le fichier crack.pas sur le programme TPC.EXE ...

    Un fichier .EXE est automatiquement généré à partir du code source !

     

    <script type="text/javascript">document.write("")</script>

     

    Alors là, si le compilateur vous dit qu'il y a une erreur, ça peut venir de plusieurs endroits :

     

    D'abord, vérifiez que vous n'avez pas mis de virgule a la dernière ligne des offset.

    Ensuite, assurer vous d'avoir bien compté le nombre de changement et de l'avoir indiquer au debut du crack et a la fin du crack...Enfin, regardez si vous n'avez pas mis une apostrophe dans les "Writeln"...
    Normalement, ce sont ces erreurs qui reviennent le plus souvent...
    Si vous avez un autre problème, essayez de revoir ligne à ligne votre code source...

    Ensuite, il vous faudra patcher ce crack avec TPPATCH.EXE , fournit en meme temps que TPC...
    Procedez de la meme maniere que pour generer le crack.exe :

     

    <script type="text/javascript">document.write("")</script>

     

    Normalement, ya un truc en allemand qui vous dit "Fertig "...ben ca veut dire que ca a marché :).

     

    Pourquoi est-ce qu'on a patcher le crack ?

    Parceque le Pentium 2 bug avec le Turbo Pascal...Et le remède, eh bien c'est TPPATCH.EXE ... ;)

    Voila, c'est fini, vous pouvez maintenant distribuer votre crack sur Internet...
    Enfin, assurez au moins qu'il fonctionne bien en le testant sur une version "saine" du programme à cracker.

    Pour vous entraînez, essayer de faire le patch du 3eme cours. Vous pouvez aussi essayer de faire les patches correspondant à l'annulation des JE et des JNE (cf cours 4)...

    En attendant de voir d'autres methodes de cracking dans le second numero de notre e-zine, entraînez vous a appliqué ce que nous avons deja expliqué...

    Et n'oubliez pas que pour apprendre, rien ne vaut la pratique !

     

    Remarques finales (pifoman) :

      1/ Si vous êtes sous windows XP et que vous lancez le fichier CRACK.EXE il s'ouvre et se ferme automatiquement sans qu'on ait le temps de voir quoi que ce soit. Pour empêcher cela 2 solutions.

      -> Faites un raccourci sur CRACK.EXE avec clic droit -> Créer un raccourci.
         Cliquez droit sur le raccourci crée et faites propriétés -> programme -> décochez la case "Fermer en quittant".

       -> Annuler toutes les fermetures automatiques des fenêtres dos en cliquant droit sur le fichier C:WINDOWS_default et en et faisant propriétés -> programme -> décochez la case "Fermer en quittant ".

    2/ Le précédent code source de smeita provoquait une erreur inattendue "File not found" quand STARTCLN.EXE était verrouillé en écriture. En effet STARTCLN.EXE était distribué dans le zip avec l'attribut lecture seule qui était la cause de l'erreur. J'ai corrigé le code de smeita ce qui fait que maintenant si vous mettez le fichier en lecture seule (clic droit dessus->propriétés) il vous dira que le fichier STARTCLN.EXE est bien verrouillé en écriture. J'en ai profité pour retirer l'attribut lecture seule dans le zip de STARTCLN.EXE.

    3/

    Le rendu graphique présenté plus haut est celui en cas de succès de la procédure de craquage.L'image en forme de vague disparaît dès qu'une erreur est rencontrée pour laisser la place au texte de l'erreur.Il y a 3 niveaux d'erreurs gérés par le programme :

     

      

    ->

    Le fichier à craquer nommé FileN est déja ouvert ou verrouillé en écriture ce qui empêche d'écrire sur le fichier à patcher.

     

      

    ->

    Le fichier à craquer n'existe pas dans le répertoire courant.

     

      

    ->

    Le fichier à craquer est de taille différente par rapport à celle attendue.


    votre commentaire
  • Dans cette 4eme partie, nous allons effectuer simplement quelques precisions importantes.
    Avant de lire tout ceci, il est preferable que vous ayez bien compris les cours precedents.
    Comme les sujets abordés ne sont pas liés, j'ai preferé les presenter dans des paragraphes independants.

     

    1/ Les logiciels utiles pour ce cours

    -> Le programme à craquer     :  Start Clean v1.2
    -> Un désassembleur             :  W32dasm 8.93
    -> Un éditeur hexa décimal     :  Winhex 10.2

     

    2/ Questions / réponses

     -> Qu'est ce qu'un offset

    Bonne question... L'offset, c'est l'adresse hexa décimale d'un byte...

    Offset vient de l'anglais. Ca veut dire déplacement par rapport à un adresse. Dans W2dasm l'offset est calculé par rapport à la position initiale du premier octet (quand on fait

    Goto->Code start

    ). Cette adresse de départ est toujours terminée par 3 zéros (début d'une zone de code pour un programme).

     

     -> C'est quoi un byte ?

    Bon, bien un byte, c'est une valeur hexadecimale de 2 chiffres...
    Pour etre plus concret, on a vu que
    JE =75 en hexa...Eh bien 75, c'est 1 byte ;)

     

     -> Pourquoi a-t-on besoin de l'offset ?

    Il se trouve que dans un programme, il y a plusieurs fois le meme byte...vous n'avez qu'a rechercher 75 dans le code hexadecimale de StartClean... Il y en a une bonne centaine !! Pourtant, chacun de ces 75 n'a qu'une seule et unique adresse : l'offset !

    Souvenez vous du dernier cours, on a fait une recherche sur 85C0742E8D84 alors qu'on voulais juste trouver le code 742E...Si on avait utiliser l'offset, on aurait pu aller directement a l'endroit voulu, sans tapez des ribambelles de bytes à droite et à gauche de 742E ...

     

     -> Où est-ce qu'on le trouve cet offset ?

     

    <script type="text/javascript">document.write("")</script>

     

    Vous voyez où c'est ! Dans la barre d'état...( NB : Agrandissez votre fenetre W32dasm si vous ne voyez pas de barre d'etat...)

     

     -> Comment est-ce qu'on se sert de l'offset ?

    Prenons une ligne en exemple... :

     

    <script type="text/javascript">document.write("")</script>

     

    Vous pouvez voir que l'offset donner par WinDasm est 00002F65h .Le petit h (h comme hexa décimal) a coté de l'offset, ca vous sert a rien, vous l'oubliez :) et tous les zeros avant le premier chiffre, vous pouvez les oublier aussi :) On se retrouve donc avec un offset qui est 2F65

     

     -> A quoi correspond cet offset ?

    Est-ce l'adresse hexa de 0F8478010000 ?
    NON ! Je vous ai dit que l'offset est l'addresse hexadecimale d'un seul byte (là vous en avez 6 ->
    0F 84 78 01 00 00 ) !

    Mais alors c'est quoi cet offset ?

    Eh ben, c'est l'adresse hexadecimale du premier byte de l'instruction 0F8478010000 ...En terme clair, c'est l'adresse hexadecimale de 0F... ET SEULEMENT DE 0F ! Donc 2F65 est l'offset de 0F

     

     -> Ok! Mais alors, les autres bytes de la ligne, c'est quoi leur adresse ?

    C'est là qu'il faut apprendre a compter en Hexadecimal... :

    En decimale, on compte de 0 a 9 (0 1 2 3 4 5 6 7 8 9), d'ou decimale : y'a dix chiffre...
    En Hexa, on compte de 0 a F (0 1 2 3 4 5 6 7 8 9 A B C D E F), donc seize chiffres...

    Maintenant, on va determiner les offsets de chaque byte de la ligne 0F8478010000 :

    • 0F = 2F65 (ca, on l'a expliqué juste avant...)
    • 84 = 2F66 (vous voyer la difference... ;)
    • 78 = 2F67 (ben vi, on ajoute 1 a chaque fois..)
    • 01 = 2F68
    • 00 = 2F69
    • 00 = 2F6A (OUBLIEZ PAS QU'ON COMPTE EN HEXADECIMALE...)

     

    Voila, c'est pas bien compliquez non ? La seule difficulté, c'est de compter en hexa...
    Tiens, un truc pour verifiez que vous vous etes pas trompé : regardez la ligne suivante :

     

    <script type="text/javascript">document.write("")</script>

     

    Vous voyer l'offset ? c'est bien 2F6B, la suite logique de 2F6A !!
    Bon, maintenant que vous savez ce qu'est un Offset, vous aller pouvoir vous en servir !

     

     -> J'en fais quoi de cet offset ?

    Dans l'editeur hexa décimal (winhex) , vous pouvez rentrez directement l'offset du byte a modifier...
    Comme ca, ca vous evite de tapez plein de valeurs Hexadecimal...
    Voici les menus concerné pour 2 editeurs :

    • HEdit : Edit -> Go to .. .
      Apres, tapez 0x avant l'offset... (
      0x2F65 par exemple)

      • WinHex : Position -> Go To ...
        Vous pouvez tapez directement l'offset (
        2F65 par exemple...)

    Malheureusement, je ne peux pas vous faire une liste exhaustive, mais c'est a peu pres le meme principe pour tous les editeur hexadecimal...

     

     -> Et si je veux connaître l'offset d'un byte depuis l'editeur hexa décimal, je fais comment ?

    Bon, là encore je ne peux pas faire une liste complete, mais de facon general, l'offset apparait dans la barre d'état de votre editeur hexadecimal...Voici l'exemple de Hedit(en haut) et de WinHex(en bas) :

     

    <script type="text/javascript">document.write("")</script>

    <script type="text/javascript">document.write("")</script>

     

     -> Et cet "Offset", ca sert qu'à trouver un byte en hexa ?

    Ben non ! Sinon, je vous aurais pas pris la tete avec !!
    Donc, la principale utilité de rechercher l'offset, c'est de faire un crack grace a notre petit code :)
    Et notre code source, il est expliqué dans le 5eme cours !! Vala !

     

     

    3/ Peut-on annuler un saut conditionnel autrement que par plein de 90 ?

    Si je pose la question, la reponse est forcement oui ! :))

     -> Bon, alors comment est-ce qu'on fait ?

    Ben, vous savez qu'on peut annuler un nombre par son inverse ? Par exemple, si on prend 34, on peut l'annuler avec -34
    Facile, non ? Eh bien, pour un saut conditionnel, c'est le meme principe ! Ainsi, un
    JE est annulé par un JNE...De meme, un JNE est annulé par un JE !

     

     -> Comment ça se traduit en hexadecimal ?

    C'est tres simple :)

    Pour annuler un 74 , on va mettre un 75 ! (rappel : 74 =JE et 75=JNE)
    Pour annuler un
    0F84xxxxxx, on va mettre un 0F85xxxxxx (rappel : 0F84=JE et 0F85=JNE)

    Reciproquement, pour annuler un 75, on va mettre un 74...
    Et pour annuler un
    0F85xxxxxx, on va mettre un 0F84xxxxxx !

    Normalement, vous devriez comprendre sans problème... ;)

     

     

     -> Ok! Mais pourquoi "annuler" au lieu de "nopper" ?

    L'utilité est de changer changer un minimum de byte... Par exemple, au lieu de changer un 0F8480000000 en 909090909090, on peut ne changer que le 85...ce qui donnera 0F8580000000 !

    Ca fait quand même plus propre, non ? Et puis surtout, vous verrez que quand vous allez ecrire la source du crack, ca sera moins fastidieux : 1 ligne au lieu de 6 ;) Vala !

     

     

    4/ Y'a t-il encore d'autre maniere de "cracker" un programme ?

    Bien sûr que oui !! Je dirais meme que chaque crack est "différent" d'un autre ! Et même un programme peut etre cracké de plusieurs manieres ... ! Il existe d'ailleurs d'autres manieres de cracker un StartClean ... On en a vu 2, mais j'en compte encore au moins 2 autres...(que l'on veras dans le prochain numero du zine, avec SoftIce)

    Tout dépend du raisonnement qu'on adopte...C'est pour ça qu'il est très dur de faire un cours qui permette réellement d'apprendre à craquer... Nous, on fait notre possible, mais n'oubliez pas :
     

    "C'est en forgeant qu'on devient Forgeron"

     

     

    5/ Comment faire sauter un nag-screen ?

    oOo...on peut pas vraiment faire un cours universel là dessus, mais il y a quand même une methode qui peut marcher... : si le Nag-Screen contient du texte ou une barre de titre, vous pouvez essayer de retrouver ces chaînes de caracteres dans le code hexa décimal du programme de facon a l'effacer...

    Bon, on va plutot faire un peu de pratique, ca sera plus simple... Prenons une fois encore StartClean...Lorsque vous le lancez, le nag-screen apparait...Relevez des lors le nom de la fenetre : "Register! "

     

    <script type="text/javascript">document.write("")</script>

     

    NB : Si il n'y a pas de barre de titre, faite une recherche sur le texte contenu dans le nag...

     

     -> Bon, maintenant, je vous explique brievement le principe :

    Si on efface le nom de la fenêtre dans le code hexadecimal, elle n'apparaîtra plus au lancement du programme...tout simplement...Donc plus de nag-screen...

     

     -> Comment je retrouve le "Register!" en hexadecimal ?

    Dans votre editeur hexadecimal, il suffit de faire une recherche sur ce mot !

     

    <script type="text/javascript">document.write("")</script>

     

    Maintenant faites OK...le programme va vous renvoyer "Data not Found!" ou un truc comme ca.

     

     -> Ben alors ?? Pourquoi ca marche pas ?

    En fait, c'est dû au fait que le programme est en 32bit....Et alors? allez vous me dire...ben en 32 bit, vous devez séparer chaque byte de lettre par un byte "00"...Oh lala ! c'est quoi ca ?! Rassurez vous, vous allez comprendre en regardant l'écran suivant :

     

    <script type="text/javascript">document.write("")</script>

     

    Vous comprenez toujours pas ?? Bon, regardez la premiere recherche...On a fait une recherche sur le mot "Register!", ce qui donne en 16bit :

    52 65 67 69 73 74 65 72

    Et bien en 32 bit, il faut ecrire ce meme code hexadecimal, mais entrelacé de "00", ce qui donnera :

    52 00 65 00 67 00 69 00 73 00 74 00 65 00 72

    NB : Certain programme, comme WinHex, peuvent faire la recherche de texte en 32bit, simplement en activant l'option "Unicode"...Là encore, il faut faire selon l'éditeur Hexadecimal que vous utilisez...

    Donc maintenant, en appuyant sur OK , vous allez tomber sur la phrase qui nous intéresse :)

     

     -> Et à l'avenir, comment je pourrais savoir qu'un programme est en 16bits ou en 32bits ?

    Et bien c'est simple : en general, les programmes windows 9x sont tous en 32bits, sauf quelque uns... Si c'est un programme Windows 3.x ou DOS, c'est forcement du 16bits ... Au pire des cas, si vous savez pas, ben vous essayer les deux methodes ! Compris ?...

     

     -> Ok! Je fais quoi maintenant ?

    Eh bien maintenant, il faut remplacer les valeurs hexa décimales des lettres par des zéros...Si vous comprenez pas, regardez les deux ecran ci-dessous :

     

    <script type="text/javascript">document.write("")</script>

    <script type="text/javascript">document.write("")</script>

     

    Normalement, vous devriez reussir a faire ça sans problème..Maintenant, lancer StartClean...La fenetre a bel et bien disparu :)

    NB : Pour certains programmes, vous verrez toujours la fenetre, mais la barre de titre sera vide...

     

    <script type="text/javascript">document.write("")</script> _______ <script type="text/javascript">document.write("")</script>


          -> Dans ce cas, il faut voir si il n'y aurait pas juste au dessus (dans le code hexa) une occurance du style "Shareware.Frm","Form.Shareware" ou un truc qui y ressemble...(bien sur, j'ai mis "Form.Shareware" parceque c'est le cas de notre exemple, mais ca correspond en fait a ce qu'il y a d'écrit dans la barre de titre...

          -> Vous pouvez aussi cherchez un truc du genre "Form.Nag" ou "Form.Splash" ou un autre truc qui vous parait suspect...)

          -> Si vous trouvez, essayez de le supprimer (avec des "00") et voyer si ca fonctionne...Si ca marche pas ou que vous ne trouvez pas, laissez tomber...

     

     -> OK! ca marche, mais la fenêtre principale du programme, pourquoi elle n'apparait plus ?

    Ah...ca c'est le petit inconvenient de la technique...rappelez vous : quand on lance StartClean, il faut cliquez sur "OK " dans le Nag-screen avant de pouvoir acceder a la fenetre principal... Mais nous, on a virer le nag, donc on peut plus appuyer sur "OK", donc le programme ne se lance plus...logique !

     

     -> Alors quel interet de nous faire un cours sur un truc qui marche pas !

    Du calme !! Qui a dit que ca ne marchait pas ? On a bien viré la fenêtre non ? En fait, ce qui nous gêne, c'est juste qu'on peut pas appuyer sur le bouton "OK"... D'ou la caracteristique suivante :

    Cette technique n'est valable que si le Nag-Screen ne requiert aucune action pour activer le programme...

    Donc dans le cas ou le nag-screen est "au dessus" du programme deja lancé, cette technique marche parfaitement... ;) Par contre, n'abusez pas de cette methode car elle n'est pas tres "fine"...C'est même plutot bourin... Personnellement je ne l'utilise que dans les cas ou toutes mes autres tentatives ont échouées...

     

    6/ Pourquoi certains programmes n'ont pas de "Data String References" ?

    Arff ! Avez vous deja programmé en VisualBasic ? Et bien dans ce language, tres pratique au demeurant, toutes les fonctions de creations de fenêtre, de comparaison de chaînes de caracteres, etc... sont prises en charge par les fameuse dll (Dynamic Link Library) qu'il nous manque tout le temps quand on recupère un programme sur Internet.

    Vous savez, les VBRUN300.DLL et autres MSVBVM50.DLL...Et c'est pour ça que quand vous allez décompiler le programme vous allez rien voir dans les "Data String References"...

    Il y a aussi d'autres programmes qui ne possede pas de Data String (bien qu'il ne soit pas programmer en VisualBasic). Dans ce cas, essayez de voir si le code n'est pas contenu dans un fichier DLL annexe... Sinon, considerez qu'il n'y a rien a faire (ca serait bien trop dur a expliquer a votre stade actuel). Nous aborderons le sujet dans un prochain numero du zine...

    Ceci dit, si vous etes confronté a un nag-screen, vous pouvez toujours essayer la technique decrite precedemment ! Avec un peu de chance, ca peut marcher :)

     

     

    7/ C'est quoi SoftIce ?

    SoftIce est un "Débuggeur". Il trace un programme pendant l'execution. Cet utilitaire est très pratique dans certains cas, mais comme il n'est pas si simple à utiliser, nous aborderons son utilisation dans le prochain numéro de notre e-zine... Patience...

     

     

    Voila ! je crois que nous avons vu le plus important pour l'instant.Maintenant, a vous de vous faire les dents sur des sharewares...
    Commencez par des petites production, parceque sinon, vous risquez de desesperez rapidement !

    En effet, les grand logiciels (ACDSee, Paint Shop Pro 5....) sont très difficile a cracker pour un debutant.En fait, je dirais même que vous n'y parviendrez pas avant un bon bout de temps.Mais tout arrive avec le temps ;) Donc patience... Et surtout bonne chance !

    Mais avant de vous lancer dans l'aventure, passer par le dernier cours ! Vous y apprendrez comment faire vos propres crack a l'aide d'un code source qu'on vous fournit :)

     


    votre commentaire
  •  

    Dans le second cours, nous avons aborde une erreur bien commune a tous les debutants...
    Maintenant, je vais tenter de vous expliquer comment trouver d'autres endroits "interessant" dans un listing...

     

    1/ Les logiciels utiles pour ce cours

    -> Le programme à craquer     :  Start Clean v1.2
    -> Un désassembleur             :  W32dasm 8.93
    -> Un éditeur hexa décimal     :  Winhex 10.2

     

    2/ Shareware contre full application

    Voyons d'abord les differences entre une version shareware et une version enregistrée.
    Voici ce qui est susceptible d'appparaitre dans un Shareware :

    • Un vilain NAG-SCREEN (écran de harcèlement) apparaît à chaque fois qu'on lance ou qu'on sort du programme...
    • Dans la barre de titre ou dans la barre d'état du programme, il y a marqué UNREGISTERED...
    • Dans la fenetre "About ", il y a marquer UNREGISTERED USER , ou quelque chose comme ça...
    • Dans les menus, il y a un bouton "Register " qui nous permet d'entrer un code pour s'enregistrer...
      • Au bout de 30 jours, le programme nous lance un nag screen qui nous dit qu'on doit s'enregistrer...

    Tout ça n'apparait plus dans la version "REGISTERED "...logique :)

    En fait, le programme doit chercher si on est enregistré ou non à chaque lancement...

     

    3/ L'enregistrement dans la base de registre

     -> Mais comment le prog sait si on s'est enregistré ??

    Eh bien, lorsqu'on s'enregistre correctement (avec un vrai code...), le programme inscrit les informations d'enregistrement dans un fichier annexe, ou dans la base de registre de Windows... Maintenant, un peu de pratique... On va reprendre notre bon vieux STARTCLEAN... ;)

    Comme on l'a vu precedemment, il nous met un mechant NAG SCREEN a chaque démarrage (If you intend to use Start clean for more than 30 days you must register). Si vous le craquer comme dans la 1ere partie du cours, vous pourrez vous enregistrer avec n'importe quel code...

    A partir du moment ou vous serez enregistré, StartClean va inscrire un truc dans la base de registre. Ce "truc" en question, c'est ce qui va permettre a StartClean de se "souvenir" que vous vous etes enregistré...Jusque la, j'espère que vous suivez :)

     

     -> Essayons donc d'analyser la logique du programe lorsqu'on le lance:

      1) le programme va acceder a la base de registre de Windows.
      
    2) si le prog ne trouve aucune information d'enregistrement, vous etes considerez comme UNREGISTERED :(
      
    3) si le prog trouve les informations d'enregistrement, vous etes considerer comme REGISTERED ;)

    Pas compliqué, n'est-ce pas ? Il suffit de retrouver ce saut conditionnel...Comment ?...humhum...voyons ça etape par etape....

         -> lancer StartClean...
         -> essayer de vous enregistrer. Là vous devez indiquez une valeur " Name " et une valeur " Code ".
         -> retenez le nom des deux valeurs : " name " pour le nom, " code " pour le serial...
         -> lancer WDasm et decompiler une copie de StartClean.exe...
         -> placer vous au debut du code (Goto -> code start) et faites une recherche sur le mot "Name"...
         -> là, vous devriez tombez a la ligne 175...
         -> en regardant un peu au dessus et un peu au dessous, ca donne ca :

     

    <script type="text/javascript">document.write("")</script>

     

    Là, vous pouvez voir 2 trucs interressant : RegOpenKeyA et RegQueryValueExA.Ces fonctions permettent au programme de prendre des informations contenues dans la base de registre...

    Elles sont suivis de LstrLenA et LstrCmpA, qui permettent de verifiez la longueur d'une chaîne de caractères et d'effectuer des comparaisons... On peut etre quasiment sûr que c'est le moment decisif ou le programme va determiner si vous êtes enregistré.

    Dans chacune des fonction LstrxxxA, il y a un Test eax, eax suivi d'un saut vers l'adresse 00401140 ...

     

    4/  Faire sauter la protection sur les fonctions de comparaison

     -> Essayons de "nopper" (cf cour 1) ces deux sauts...

    Pourquoi les deux (celui à l'adresse 00401110 et celui à l'adresse 00401139) ? Parceque si on élimine que le premier, on va sauter quand on va arriver au deuxieme... Et si on noppe que le deuxieme, on aura meme pas le temps d'y arriver puisqu'on aura déja sauter au premier.

         -> lancer l'editeur Hexadecimal
         -> faites une recherche sur 85C0742E8D84 (cf cour 2).
         -> remplacer le 742E par un 9090 ...
         -> ensuite, faites une nouvelle recherche sur 85C07505BB01
         -> remplacer le 7505 par un 9090 ...

    L' heure est venue de savoir si on a bien raisonner ou non...

         -> Lancer votre StartClean ainsi modifié.

    CA MARCHE !! Même pas besoin de s'enregistrer, le programme pense qu'il l'est deja :)

    Le principe est donc assez simple : le programme va chercher les informations d'enregistrement dans la base de registre, mais qu'il les trouve ou non, quelles soient bonnes ou non, le programme agira comme si tout etait OK !

     -> Pourquoi ?

    Parcequ'on a enlevé les sauts qui s'effectuaient si une des conditions n'etaient pas remplies...Je pense que maintenant vous avez assimilez le principe du saut conditionnel...A travers le petit programme qu'est StartClean, vous avez meme pu vous exercez un peu...Vous avez egalement appris a evitez un petit piege dans le 2eme cours...Cependant, le cours n'est pas tout a fait fini, et il est necessaire de vous apporter encore quelques precisions sur certains point que nous n'avons pas encore traité...

     


    votre commentaire