Cacher le contenu d'un Executable

ianis24 Messages postés 87 Date d'inscription dimanche 20 août 2006 Statut Membre Dernière intervention 13 janvier 2011 - 11 nov. 2009 à 18:24
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 - 16 nov. 2009 à 21:16
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

cs_ghuysmans99 Messages postés 3983 Date d'inscription jeudi 14 juillet 2005 Statut Membre Dernière intervention 30 juin 2013 16
11 nov. 2009 à 19:19
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
0
ianis24 Messages postés 87 Date d'inscription dimanche 20 août 2006 Statut Membre Dernière intervention 13 janvier 2011
11 nov. 2009 à 21:02
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.
0
cs_ghuysmans99 Messages postés 3983 Date d'inscription jeudi 14 juillet 2005 Statut Membre Dernière intervention 30 juin 2013 16
13 nov. 2009 à 19:19
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
0
vintrouj Messages postés 14 Date d'inscription vendredi 19 novembre 2004 Statut Membre Dernière intervention 18 novembre 2009
15 nov. 2009 à 08:00
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
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
15 nov. 2009 à 09:54
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.
0
cs_ghuysmans99 Messages postés 3983 Date d'inscription jeudi 14 juillet 2005 Statut Membre Dernière intervention 30 juin 2013 16
15 nov. 2009 à 11:25
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
0
ed73 Messages postés 276 Date d'inscription lundi 8 septembre 2008 Statut Membre Dernière intervention 15 avril 2013 2
15 nov. 2009 à 11:57
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.
0
ianis24 Messages postés 87 Date d'inscription dimanche 20 août 2006 Statut Membre Dernière intervention 13 janvier 2011
15 nov. 2009 à 15:25
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.
0
cs_ghuysmans99 Messages postés 3983 Date d'inscription jeudi 14 juillet 2005 Statut Membre Dernière intervention 30 juin 2013 16
15 nov. 2009 à 20:30
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
0
cs_Lucky92 Messages postés 180 Date d'inscription mercredi 22 décembre 2004 Statut Membre Dernière intervention 16 août 2012 2
16 nov. 2009 à 21:16
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.
0
Rejoignez-nous