Question

J'ai découvert qu'il est possible d'extraire les chaînes codées en dur à partir d'un binaire.
Par exemple, les propriétés de vue affiche toutes la chaîne avec plus de 3 caractères.

Voici le code d'un simple exécutable que j'ai écrit pour tester simplement:

#ifndef _WIN32_WINNT
#define _WIN32_WINNT 0x0501
#endif
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>

int _tmain(int argc, _TCHAR* argv[])
{
    _TCHAR* hiddenString1 =_T("4537774B-CC80-4eda-B3E4-7A9EE77991F5");
    _TCHAR* hiddenString2 =_T("hidden_password_or_whatever");
    for (int i= 0; i<argc; i++) {
        if (0 == _tcscmp(argv[i],hiddenString1)) {
            _tprintf (_T("The guid argument is correct.\n")); }
        else if (0 == _tcscmp(argv[i],hiddenString2)) {
            _tprintf (_T("Do something here.\n")); }
    }

    _tprintf (_T("This is a visible string.\n"));
    //Keep Running
    Sleep(60000);
    return 0;
}

Les chaînes peuvent être extraites clairement de l'exécutable correspondant:
text alt

Je pense qu'il est un peu trop facile de trouver les chaînes.

Mes questions sont les suivantes:

  1. Comment simplement cacher hiddenString1 ou hiddenString2 dans la exécutable?
  2. Y at-il un monde plus sûr façon d'utiliser « cheat code » qu'avec une obscure entrée cachée?
Était-ce utile?

La solution

Bienvenue dans le monde de la programmation plus défensive.

Il y a deux options, mais je crois que tous dépendent d'une certaine forme de faux-fuyants; qui, bien qu'imparfait, est au moins quelque chose.

  1. Au lieu d'une valeur de chaîne droite vous pouvez stocker le texte dans une autre forme binaire (hex?).

  2. Vous pouvez crypter les chaînes qui sont stockés dans votre application, puis les déchiffrer lors de l'exécution.

  3. Vous pouvez les diviser à travers différents points dans votre code, et reconstituer plus tard.

Ou une combinaison de ceux-ci.

Gardez à l'esprit que certaines attaques vont plus loin que de regarder le binaire réel. Parfois, ils vont enquêter sur l'espace d'adressage mémoire du programme pendant qu'il est en cours d'exécution. MS est venu avec quelque chose appelé SecureString en .Net 2.0 . Le but étant de garder les chaînes cryptées lorsque l'application est en cours d'exécution.

Une quatrième idée est de ne pas stocker la chaîne dans l'application elle-même, mais plutôt compter sur un code de validation pour être soumis à un serveur que vous contrôlez. Sur le serveur, vous pouvez vérifier si elle est un « code de triche » legit ou non.

Autres conseils

Il y a plusieurs façons de obscurs données dans un fichier exécutable. D'autres ici ont posté de bonnes solutions - un peu plus fort que d'autres. Je ne vais pas ajouter à cette liste.

Il faut juste savoir: il est tout un jeu du chat et de la souris:. Il est impossible garantie que personne ne trouvera votre "secret"

Peu importe combien de cryptage ou d'autres trucs que vous utilisez; peu importe combien d'effort ou de l'argent que vous y mettez. Peu importe combien de "NASA / MIT / CIA / NSA" types sont impliqués dans le cacher.

Le tout se résume à la physique simple:
S'il était impossible pour any utilisateur de retirer votre secret de l'exécutable et « démasquer », puis l'ordinateur ne serait pas en mesure de l'afficher soit, et votre programme ne serait pas en mesure d'utiliser il. Tout développeur moyennement qualifié avec suffisamment incitatif trouvera le moyen de démasquer le secret.

Le moment que vous avez remis votre exécutable à un utilisateur, ils ont tout ce dont ils ont besoin pour découvrir le secret.

Le mieux que vous pouvez espérer est de faire si dur pour découvrir le secret que tous les avantages que vous pouvez obtenir de connaître le secret de devenir ne vaut pas la peine.

Alors, il est OK pour essayer de masquer les données si elle est simplement « pas bien » pour qu'il soit public ou si les conséquences de celui-ci devient publique serait tout simplement « pratique ». Mais ne pensez même pas de se cacher dans votre programme « le mot de passe à votre base de données client maître », une clé privée, ou d'un autre secret critique. Vous ne pouvez pas.

Si vous avez des informations vraiment un secret critique que votre programme aura besoin d'une certaine façon mais ne doit jamais devenir l'information du public (comme une clé privée), alors vous aurez besoin d'avoir parler de votre programme à un serveur distant sous votre contrôle, appliquez l'authentification appropriée et les contrôles d'autorisation ( qui est, assurez-vous que les personnes ou les ordinateurs approuvés sont en mesure de faire la demande au serveur ), et ont ce serveur garder le secret et l'utiliser.

La façon la plus simple est de les chiffrer avec quelque chose de trivial comme XOR ou pourriture 13, puis les déchiffrer à la volée quand ils sont utilisés. Cela éliminera l'affichage occasionnel d'entre eux, mais il ne sera pas arrêter tout le monde avec beaucoup d'expérience à la marche arrière.

En plus de ces méthodes Chris mentionne que vous pouvez également utiliser un algorithme de hachage. Si tout ce que vous voulez faire est de vérifier si le bon code a été spécifié que vous n'avez pas réellement besoin de stocker l'ensemble ID dans votre programme.

  • Créer un hachage (MD5, SHA, etc.) de la chaîne / mot de passe / vous voulez comparer contre, peut-être ajouter une valeur « salée » à elle. Conservez dans votre programme
  • Lorsque le programme est exécuté, faire le même algorithme sur la chaîne d'entrée / mot de passe / identifiant et comparer les deux hash pour voir si elles correspondent.

De cette façon, le texte actuel ne sont jamais stockées dans votre programme et ils ne peuvent pas de désosser votre programme pour savoir ce que le texte original était parce que les algorithmes de hachage sont à sens unique.

  

Il y a des URL pour les requêtes HTTP que je voudrais cacher aussi.

Si votre application fait la demande, il n'y a pas de point cacher cela. Exécution d'une application comme Fiddler, analyseur de http, ou l'une des dizaines d'autres méthodes libres et facilement disponibles montrera tout le trafic de votre application crée.

Est-ce que tous vos codes secrets ou être GUIDs est que juste un exemple?

Peut-être stocker votre secret comme guid binaire:

const GUID SecretGuid =
    { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };

Ensuite, convertir vos fournies Guid de chaîne au format binaire et comparer les deux binaires GUIDs.

S'il y a une chaîne spécifique que vous ne voulez pas que les gens puissent voir, puis chiffrer et déchiffrer à l'exécution.

Si vous ne voulez pas que les gens voir votre GUID, puis construire à partir d'octets, plutôt que construit à partir d'une chaîne:

const GUID SecretGuid = 
      { 0x4537774B, 0xCC80, 0x4eda, { 0x7A, 0x9E, 0xE7, 0x79, 0x91, 0xF5 } };

Le mieux que vous pouvez faire est de coder votre mot de passe ou toute autre chaîne que vous souhaitez masquer tableau en tant que char. Par exemple:

std::string s1 = "Hello";   // This will show up in exe in hex editor
char* s2 = "World";   // this will show up in exe in hex editor
char s3[] = {'G', 'O', 'D'}; // this will not show up in exe in hex editor.

Voici la méthode que je l'utilise à cet effet. Tout d'abord, j'utilise le Cordes outil par Sysinternals pour afficher les chaînes dans un fichier EXE ou DLL. J'utilise alors le suivant petit outil (voir article ) pour remplacer ces chaînes avec un réseau codé de caractères stockés sous forme d'une expression arithmétique: pour exemple: au lieu de la chaîne: "Ceci est un test" Je placerai le code suivant: (qui est généré automatiquement par cet outil )

WCHAR T1[28];
 T1[22] = 69;
 T1[15] = 121 - 17;
 T1[9] = L':' + -26;
 T1[12] = L't' - 1;
 T1[6] = 116 - 1;
 T1[17] = 117 - 12;
 T1[3] = 116 - 1;
 T1[14] = L'' - 3;
 T1[13] = L'w' - 3;
 T1[23] = 69;
 T1[26] = L'Y' + 3;
 T1[19] = 111 + 0;
 T1[21] = L'k' - 34;
 T1[27] = L'\\' - 8;
 T1[20] = L'B' + 32;
 T1[4] = 42 + -10;
 T1[25] = L'm' - 17;
 T1[16] = L'H' + 18;
 T1[18] = L'A' + 56;
 T1[24] = 68;
 T1[1] = 105 - 1;
 T1[11] = L'k' - 6;
 T1[10] = 66 + 50;
 T1[2] = 105;
 T1[0] = 117 - 1;
 T1[5] = L'k' - 2;
 T1[8] = 89 + 8;
 T1[7] = 32;

Il existe de nombreuses solutions à ce problème et aucun d'entre eux (y compris le mien) est parfait, mais il existe des moyens pour brouiller, déguisement, et cacher les cordes sensibles. Vous pouvez bien sûr les chiffrer et déchiffrer lors de l'exécution (voir cet article), mais je trouve plus important de ces chaînes disparaissent parmi les bits et les octets du fichier exécutable et il fonctionne. Après avoir exécuté mon outil, vous ne trouverez pas « ceci est un test » dans le fichier exécutable.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top