J'utilisais Unity pour créer un jeu 2D complètement hors ligne (ce qui est le problème), le jeu nécessite que vous saisissiez certaines chaînes à certains niveaux et Unity compile en DLL, ce qui peut être facilement inversé. existe-t-il un moyen de protéger ces chaînes (le jeu est hors ligne, je ne peux donc pas le récupérer depuis une autre source)?
Le jeu repose énormément sur ces chaînes, et oui je suis conscient de l’obfuscation mais je veux quelque chose de plus robuste. Et je sais que la solution de facilité serait de tout faire en ligne à partir d'une source de données, mais je me demandais si c'était possible.
unity
c#
anti-cheat
TheBinaryGuy
la source
la source
strings
programme dessus.Réponses:
Ne stockez pas ces chaînes, stockez leur hachage (cryptographique).
Une fonction de hachage (cryptographique), comme le cryptage, est un moyen de transformer une chaîne en "charabia" (appelé hachage), mais contrairement au cryptage, vous ne pouvez pas obtenir la chaîne d'origine à partir de ce hachage (sauf si vous pouvez le forcer brutalement ou le hachage la fonction est cassée). La plupart (sinon toutes) des fonctions de hachage prennent une chaîne de longueur arbitraire et retournent une chaîne de longueur constante (dépend de la fonction).
Comment vérifier que la chaîne entrée par l'utilisateur est la bonne? Étant donné que vous ne pouvez pas obtenir la chaîne valide du hachage, vous ne pouvez que hacher l'estimation de l'utilisateur et la comparer au hachage correct.
Avertissement (par Eric Lippert): N'UTILISEZ PAS la fonction intégrée en
GetHashCode
tant que telle. Son résultat peut différer selon les versions .NET et les plates-formes. Votre code ne fonctionne que sur des versions et une plate-forme spécifiques du framework .NET.la source
Ce que vous essayez de faire est à la fois inutile et inutile.
C'est inutile car il n'y a aucun moyen de cacher correctement les informations qui se trouvent sur la machine de l'utilisateur. Toute personne assez dévouée le trouvera. Vous pouvez le rendre plus difficile, mais vous ne pouvez jamais l’empêcher. Si vous le chiffrez, vous devez alors stocker la clé de chiffrement et l'algorithme quelque part. Peu importe le nombre de couches de cryptage que vous ajoutez, la couche la plus éloignée devra toujours être non cryptée pour que votre jeu fonctionne.
C'est également inutile, car nous vivons à l'ère d'Internet. Lorsque votre jeu devient très populaire à distance, ces codes d'authentification seront publiés sur tout le Web.
Tout ce que vous pouvez faire est de faire confiance au joueur pour ne pas gâcher sa propre expérience de jeu en recherchant des informations que le jeu n'est pas censé leur dire encore. De toute façon, la grande majorité des joueurs ne se lancera pas dans l’ingénierie inverse. Et si les quelques personnes qui possèdent les compétences nécessaires le font, alors c'est de leur faute.
la source
Si une telle chose est vraiment souhaitée, au lieu du hachage, vous pouvez envisager de construire les chaînes à partir d'une valeur d'entrée numérique au moment de l'exécution.
L'avantage est que, comme l'a souligné @Philipp, il est un peu inutile d'essayer de cacher des codes dans l'exécutable si vous pouvez vous attendre à ce qu'ils soient postés sur Internet de toute façon. Haché ou non, le même mot trouvé sur Internet et entré dans le jeu donnera le même hachage et fonctionnera dans les deux sens.
Sauf que ... sauf si le code de quelqu'un d'autre ne fonctionne pas pour vous. Ce que vous pouvez trivialement faire - pas à 100% inviolable mais raisonnablement difficile à contourner pour l'utilisateur moyen. N'importe quel élément aussi simple que le "Générateur de noms elfes en ligne" fera l'affaire (peut être arbitrairement simple, n'a pas vraiment besoin d'un moteur de Markov text gen, extraire 4 à 5 syllabes d'une liste aléatoire est suffisant).
Générez simplement un numéro quelque peu spécifique à l'utilisateur ou à la machine, il n'est même pas nécessaire qu'il soit parfaitement unique ou très inviolable. Quelque chose qui est probablement différent pour la plupart des gens et qui ne changera pas régulièrement, par exemple le nom de réseau de l'ordinateur, l'adresse MAC ou le GUID du lecteur de disque système, peu importe (le numéro de série du GPU peut être un très mauvaisidée puisque les utilisateurs sont susceptibles de mettre à niveau les GPU). Ajoutez à cela le code numérique auquel le code de déverrouillage fait référence et introduisez-le dans votre générateur de mots. Mais soyez prêt à répondre aux demandes d'assistance lorsque les joueurs utilisent deux ordinateurs ou changent de carte réseau (ce qui est inhabituel, mais pas impossible). Ce pourrait être un bon plan de ne générer qu'une seule fois l'identifiant aléatoire et de le stocker avec les paramètres du jeu. De cette façon, au moins, cela ne casse pas les installations existantes sur la même machine si quelque chose change.
Ou vous pouvez simplement utiliser le numéro de série du jeu qui est unique et fonctionnera si l'utilisateur change de matériel (paradoxalement, cela pourrait favoriser le piratage, car les codes de déverrouillage partagés fonctionnent pour les publications en série piratées mais pas pour les clients légitimes!).
Notez qu'empêcher les utilisateurs de tricher n'est pas nécessairement une bonne chose. Dans un jeu hors ligne (c'est-à-dire un jeu non compétitif), il n'y a généralement pas de problème si l'utilisateur triche et obtient les codes quelque part plutôt qu'en jouant. Il se trompe seulement. On s'en fout.
D'autre part, se mettre trop dans le droit chemin s'ils veulent vraiment tricher est une excellente occasion de faire chier complètement les clients qui paient.
Alors ... avant de faire quelque chose de cette façon, réfléchissez bien si vous le voulez vraiment et ce que vous voulez. Il est fort possible que disposer de chaînes lisibles par l'homme (ou rendu trivialement "illisible" avec xor) soit suffisant et même préférable.
la source
hash(serial + 1)
pour obtenir un nombre correspondant au premier code. Introduisez ensuite ces informations dans votre générateur de mots, qui extrait, par exemple, une syllabe d’une liste de 16 pour 4 bits d’entrée. Voilà, des "mots" individuels pour chaque utilisateur.hash(serial+1)
après le téléchargement, qu'est-ce qui empêche l'utilisateur de calculerhash(serial+1)
? Une fois le programme téléchargé, l'utilisateur a accès à tout ce qu'il fait.hash(serial + 1)
. Et alors? Ce n'est pas un problème. Regardez, si quelqu'un investit une à deux heures (probablement entre 6 et 8 heures pour un "utilisateur" typique sans antécédents de développeur de logiciel), il suffit de se tromper, eh bien ... laissez-le. Le problème, c’est que cela fonctionne pour une personne, mais pas pour tout le monde, et que ce n’est pas concurrentiel… alors, pas de problème.Si vous n'avez pas besoin de montrer les chaînes, alors l'idée de hachage est probablement la voie à suivre. Par contre, si vous avez besoin de les montrer à l'utilisateur, vous pouvez les empêcher autrement de les afficher directement dans votre DLL.
En plus de chiffrer ou d’obscurcir les chaînes, une solution consiste à les décomposer. Peut-être avez-vous simplement un dictionnaire alphabétiquement trié de tous les mots possibles de toutes les chaînes du jeu. Ensuite, installez un tableau quelque part qui vous permet de rassembler les mots dans la chaîne dont vous avez besoin en les indexant dans le tableau de mots. De cette façon, vous ne possédez pas les chaînes complètes dans le jeu. Aucune clé principale n'est nécessaire pour déchiffrer les chaînes. Et les données qui indiquent leur ordre peuvent se trouver partout dans votre source, si, par exemple, chaque fonction qui utilisait une chaîne ne contenait qu'un tableau d'index local à la fonction. Je ne sais pas si c'est pratique dans votre cas, mais c'est une façon de le faire.
Vous pourriez même avoir une chaîne composée de quelques mots, mais ils finissent par être placés dans des ordres différents. Par exemple, vous pourriez avoir besoin des 2 chaînes suivantes:
Votre liste de phrases contiendrait à la fois "un ours" et "ma maison", mais vous auriez une longue liste d'autres phrases pouvant être insérées entre elles, afin de déterminer laquelle serait aussi difficile que de déterminer réellement le puzzle dans le jeu (ou autre). Par exemple, les phrases d'action pourraient être "traverser", "brûler", "pousser sur", "me protéger de", "me séparer de", "produire de façon magique", etc.
Vous pouvez intégrer cela dans votre jeu en faisant en sorte que les index soient basés sur quelque chose que le joueur a collecté ou fait. Donc, il n'y aurait pas de liste maîtresse d'index n'importe où dans le jeu. Ils seraient générés par le joueur jouant le jeu.
la source
strings
contre l’exécutable.