Cacher le contenu d'un Executable

Signaler
Messages postés
87
Date d'inscription
dimanche 20 août 2006
Statut
Membre
Dernière intervention
13 janvier 2011
-
Messages postés
180
Date d'inscription
mercredi 22 décembre 2004
Statut
Membre
Dernière intervention
16 août 2012
-
Bonjour,
J'utilise Microsoft Visual Studio 2008 et je souhaite savoir si il existe un moyen de cacher les chaine de caractères qui sont contenu dans le Release.

Exemple : Mon exécutable est tees léger, 7 Ko il suffit de l'ouvrir avec Notepad pour voir la Clé de license, ou le mot de pass utilisateur pour accéder à l'application...

Si vous avez un moyen pour cacher ces chaines cela m'intéresse, merci.

Ianis

10 réponses

Messages postés
3983
Date d'inscription
jeudi 14 juillet 2005
Statut
Membre
Dernière intervention
30 juin 2013
13
Tu peux hasher les données sensibles, mais attention : tu ne peux retrouver les données que tu as hashées. Tu ne pourras que comparer le hash des données entrées à celles dans ton programme. Voici une procédure de hash utilisant l'API de Windows permettant d'utiliser plusieurs algorithmes cryptographiques fiables, dont MD5 :
#define WIN32_LEAN_AND_MEAN
#define _CRT_SECURE_NO_WARNINGS
#include <windows.h>
#include <wincrypt.h>
#include <stdio.h>
#include <stdlib.h>

char* GenericHash(unsigned int AlgId,char* Buffer, int lBuffer)
{
HCRYPTPROV hProv; HCRYPTHASH hHash;
BYTE* Hash; DWORD lHash, len;
char* sHash; unsigned char i;

if (CryptAcquireContext(&hProv,NULL,NULL,PROV_RSA_FULL,CRYPT_VERIFYCONTEXT | CRYPT_MACHINE_KEYSET))
{
if (CryptCreateHash(hProv,AlgId,0,0,&hHash))
{
if (CryptHashData(hHash,(BYTE*)Buffer,lBuffer,0))
{
if (CryptGetHashParam(hHash,HP_HASHSIZE,(BYTE*)&lHash,&len,0))
{
Hash = malloc(lHash);
if (!Hash) return NULL;
if (!CryptGetHashParam(hHash,HP_HASHVAL,Hash,&lHash,0))
{
free(Hash);
return NULL;
}
}
}
else return NULL;
}
else return NULL;
}
else return NULL;

CryptDestroyHash(hHash);
CryptReleaseContext(hProv,0);

sHash = malloc(lHash*2+1); memset(sHash,0,lHash*2+1);
for (i = 0; i <= lHash-1; i++) sprintf(sHash+(i*2),"%02X",Hash[i]);
free(Hash);
return sHash;
}

Pour l'appeler, tu donnes en paramètre :[list][*] L'algo de hash, par exemple CALG_MD5
[*] L'adresse du buffer à hasher
[*] Sa taille en bytes/list---
VB.NET is good ... VB6 is better
Messages postés
87
Date d'inscription
dimanche 20 août 2006
Statut
Membre
Dernière intervention
13 janvier 2011

J'ai déjà penser a cette idée je pense que je l'utiliserait si je trouve rien d'autre.
Si il y a une solution pour tout simplement cacher les string dans l'exécutable ça serait préférable.
Messages postés
3983
Date d'inscription
jeudi 14 juillet 2005
Statut
Membre
Dernière intervention
30 juin 2013
13
Cette méthode pour garder un mot de passe est inviolable, car tu ne peux pas retrouver le pass à partir du hash. Les cacher ne servirait à rien, on pourrait quand même les retrouver d'une façon ou d'une autre.
---
VB.NET is good ... VB6 is better
Messages postés
14
Date d'inscription
vendredi 19 novembre 2004
Statut
Membre
Dernière intervention
18 novembre 2009

L'anti reverse-code engineering te permettra peut-être d'atteindre ton objectif.
Telock : http://www.softpedia.com/progDownload/Telock-Download-23.html (gratuit)


jules
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Il y a un moyen assez simple de cacher les chaines, mais qui n'empèchera pas de les retrouver par désassemblage.

Au lieu d'écrire par exemple :

int ok = ! strcmp(licence_saisie,"LICENCE");

tu peux faire :

char licence[8];

puis initialiser cette variable dans le désordre à différents endroits du programme, avant le test bien sûr.

licence[3] = 67; // code ascii de 'C'
...
licence[0] = 76; // code ascii de 'L'
etc...

et enfin

int ok = ! strcmp(licence_saisie,licence);

ainsi "LICENCE" n'apparaitra pas dans l'exe.
Messages postés
3983
Date d'inscription
jeudi 14 juillet 2005
Statut
Membre
Dernière intervention
30 juin 2013
13
Pas grave, le cracker collera un breakpoint à l'appel de strcmp et regardera le contenu de la chaine passée en paramètre.
---
VB.NET is good ... VB6 is better
Messages postés
276
Date d'inscription
lundi 8 septembre 2008
Statut
Membre
Dernière intervention
15 avril 2013
2
Ben oui, je l'ai écrit que ça n'empêchera pas un crack par désassemblage.

Le niveau de protection dépend de qui on souhaite se protéger, s'il s'agit simplement de cacher les textes dans l'exe afin de décourager rapidement un amateur, ma méthode suffit.

Mais si on souhaite une vraie protection, qui de toute manière ne résistera pas longtemps à un cracker expérimenté alors oui, il faut crypter et utiliser un anti-désassembleur.
Messages postés
87
Date d'inscription
dimanche 20 août 2006
Statut
Membre
Dernière intervention
13 janvier 2011

Houla Houla :)
Je cherche juste a faire en sorte que les chaines de caractères ressemble au reste de l'exécutable ( incompréhensible ).
J'ai penser au Packer, mai je voulai savoir si c'était possible de le faire a partir du compilateur de VS08.
Finalement je vais sans doute utiliser 2 Methodes d'enryption.
MD5 pour mot de pass et une autre pour les chaines autres.
Messages postés
3983
Date d'inscription
jeudi 14 juillet 2005
Statut
Membre
Dernière intervention
30 juin 2013
13
MD5 n'est pas une encryption, tu ne peux plus jamais retrouver ce que tu as passé en paramètre à la fonction. Mais elle donne toujours le même résultat avec les mêmes paramètres. Ca ne sert à rien d'utiliser un autre algo.

@ed73 : Un amateur sait quand même regarder une zone mémoire à un certain point de l'exécution du programme ! Et un anti-disasm ne résistera pas à un bon cracker. Je ne connais pas de méthode infaillible ...
---
VB.NET is good ... VB6 is better
Messages postés
180
Date d'inscription
mercredi 22 décembre 2004
Statut
Membre
Dernière intervention
16 août 2012
2
Bonsoir tout le monde,

j'ai trouvé une solution au problème posé dont voici un exemple d'utilisation :

/*________________________________________________________________________
*/
#include 
#include <string>
/*________________________________________________________________________
*/
template < int p1 '\0' , int p2 '\0' , int p3 = '\0' , int p4 = '\0' >
struct password 
{
static int const c_key = 0x80808080 ;
static int const c_block_nb = 4 ;

bool check( const std::string & s )	
{
static int const v[] = { c_key | p1 , c_key | p2 , c_key | p3 , c_key | p4 } ;
if ( s.size() > c_block_nb * sizeof( int ) ) 
return false ;
for ( size_t i = 0 ; i < c_block_nb ; ++i ) 
{
int n = 0 ;
for ( size_t j = 0 ; j < c_block_nb ; ++j ) 
{
if ( i * c_block_nb + j < s.size() ) 
{
n <<= 8 ;
n |= s[ i * c_block_nb + j ] ;
}
}
n |= c_key ;
if ( v[ i ] != n ) 
return false ;
}
return true ;
}
};
/*________________________________________________________________________
*/
int main()
{
password<'supe','r_pa','sswo','rd'> pwd ;

std::string in ;
while ( std::cout << "password ? " && std::cin >> in )
std::cout << "good password : " << std::boolalpha << pwd.check( in ) << std::endl ;
}
/*________________________________________________________________________
*/


L'idée de base est de cacher la chaîne de caractères sensible en la cryptant pendant la compilation - cela est possible en utilisant la métaprogrammation ( ie les templates c++ ).
Toutefois, une limitation des templates est qu'on ne peut pas utiliser directement les chaînes littérales comme paramètres d'initialisation ( j'aurais aimé pouvoir écrire password<"super_password"> ).
Pour contourner ce problème, j'ai utilisé les multi-caractères ( je crois que ça s'appelle comme ça ) en m'inspirant d'un exemple de la librairie boost : on découpe la chaîne de caractères en paquets de 4 et on instancie le template comme ceci : password<'supe','r_pa','sswo','rd'>.
Mon système de cryptage ( ou plutôt de camouflage ) est très rudimentaire : je lève le bit de poids fort de chacun des caractères du mot de passe.

Bilan : en 30 lignes de code, je réponds au cahier des charges à savoir que le mot de passe n'apparaît plus en clair dans le binaire et ce, sans appel à des bibliothèques externes.
Mais... je ne suis pas super satisfait quand même :
- le code n'est pas super portable ( Machine 64 bits ? Unicode ? ) ;
- le mot de passe est limité à 16 caractères dans l'exemple et pour rendre la taille dynamique, il faut bosser pas mal encore...
- esthétiquement, le découpage 'supe','r_pa','sswo','rd',' me ','plaî','t mo','yen' ;
- et pour couronner le tout - comme certains l'ont fort justement souligné, cette méthode va décourager ma petite soeur de 6 ans et encore...

Cordialement,

Lucky92.