Protéger l'exécutable de l'ingénierie inverse?


210

J'ai réfléchi à la façon de protéger mon code C / C ++ contre le désassemblage et la rétro-ingénierie. Normalement, je ne tolérerais jamais ce comportement moi-même dans mon code; cependant le protocole actuel sur lequel je travaille ne doit jamais être inspecté ou compréhensible, pour la sécurité de diverses personnes.

Maintenant, c'est un nouveau sujet pour moi, et Internet n'est pas vraiment ingénieux pour la prévention contre l'ingénierie inverse, mais dépeint plutôt des tonnes d'informations sur façon de procéder à la rétro-ingénierie

Voici certaines des choses auxquelles j'ai pensé jusqu'à présent:

  • Injection de code (appel de fonctions factices avant et après des appels de fonction réels)
  • Obfustication de code (gêne le démontage du binaire)
  • Écrire mes propres routines de démarrage (plus difficile à associer aux débogueurs)

    void startup();  
    int _start()   
    {  
        startup( );  
        exit   (0)   
    }  
    void startup()  
    {  
        /* code here */  
    }
  • Vérification de l'exécution des débogueurs (et forcer la sortie si détecté)

  • Trampolines fonctionnels

     void trampoline(void (*fnptr)(), bool ping = false)  
     {  
       if(ping)  
         fnptr();  
       else  
         trampoline(fnptr, true);  
     }
  • Allocations et désallocations inutiles (la pile change beaucoup)

  • Appels factices et trampolines inutiles (tonnes de sauts en sortie de démontage)
  • Des tonnes de coulée (pour le démontage obscurci)

Je veux dire que ce sont quelques-unes des choses auxquelles j'ai pensé, mais elles peuvent toutes être travaillées et / ou déterminées par les analystes de code en fonction du délai approprié. Y a-t-il autre chose que j'ai?


172
"Cependant, le protocole actuel sur lequel je travaille ne doit jamais être inspecté ou compréhensible, pour la sécurité de diverses personnes." -- bonne chance avec ça.
Amber

62
Vous pouvez rendre votre application difficile à inverser. Vous ne pouvez pas le rendre impossible, pas tant que l'autre gars a une partie substantielle de vos morceaux entre les mains. Attention à garantir une sécurité totale, surtout si des vies sont en jeu - vous ne pouvez pas livrer.
Michael Petrotta

127
Si votre ordinateur peut comprendre le code, une personne aussi.
Courses de légèreté en orbite le

78
Rendez le code Open Source, et personne ne le désossera.
utilisateur inconnu

28
"La sécurité par l'obscurité n'a jamais fonctionné."
bot47

Réponses:


151

Ce que Amber a dit est tout à fait vrai. Vous pouvez rendre l'ingénierie inverse plus difficile, mais vous ne pouvez jamais l'empêcher. Vous ne devriez jamais faire confiance à la «sécurité» qui repose sur la prévention de l'ingénierie inverse .

Cela dit, les meilleures techniques anti-ingénierie inverse que j'ai vues ne se concentraient pas sur l'obscurcissement du code, mais plutôt sur la rupture des outils que les gens utilisent généralement pour comprendre comment fonctionne le code. Trouver des moyens créatifs de briser les désassembleurs, les débogueurs, etc. est à la fois plus efficace et aussi plus satisfaisant intellectuellement que de simplement générer des rames de code de spaghetti horrible. Cela ne fait rien pour bloquer un attaquant déterminé, mais cela augmente la probabilité que J Random Cracker s'éloigne et travaille à la place sur quelque chose de plus facile.


14
Je comprends cela, et j'ai lu quelques articles sur la sécurité de Skype expliqués et j'ai envisagé les mêmes idées que Skype a déjà essayées comme méthode pour ne pas empêcher mais plutôt protéger mon protocole. Quelque chose qui s'est avéré assez digne compte tenu des circonstances évidentes pour Skype.
graphitemaster

8
Skype est en fait le premier exemple qui m'est venu à l'esprit, donc je suis heureux que vous cherchiez déjà à émuler leurs méthodes.
Ricket

176

mais ils peuvent tous être contournés et / ou déterminés par des analyseurs de code selon le bon délai.

Si vous donnez aux gens un programme qu'ils sont capables d'exécuter, ils pourront également le désosser avec suffisamment de temps. Telle est la nature des programmes. Dès que le binaire est disponible pour quelqu'un qui veut le déchiffrer, vous ne pouvez pas empêcher une éventuelle rétro-ingénierie. Après tout, l'ordinateur doit être capable de le déchiffrer pour le faire fonctionner, et un humain est tout simplement un ordinateur plus lent.


113
+1. Découvrez les jours glorieux de la protection contre la copie sur l'Apple II, la guerre sans cesse croissante entre les obscurcisseurs et les crackers, les trucs fous avec le moteur pas à pas de la disquette et les instructions 6502 non documentées et ainsi de suite ... dormir, parce que vous n'allez pas mettre en œuvre quelque chose d'aussi élaboré et ils ont tous fini par se fissurer.
Nemo

2
plus facile à utiliser un simulateur et obtenir une meilleure visibilité que d'essayer de rétro-ingénierie visuellement ou avec un démonteur. Si la sécurité n'est pas intégrée au matériel que vous utilisez, je pense que le monde met en moyenne environ deux jours à deux semaines pour faire de l'ingénierie inverse et vaincre à peu près tout ce qui sort. Si cela vous prend plus de deux jours pour créer et implémenter cela, vous avez passé trop de temps.
old_timer

5
Le seul DRM fonctionnant raisonnablement aujourd'hui est la combinaison d'une clé et d'un serveur Internet vérifiant qu'une seule instance de la clé est active à un moment donné.
Thorbjørn Ravn Andersen

2
@ Rotsor: L'ordinateur ne peut pas le comprendre parce que nous n'avons pas encore été en mesure de réduire ce type d'intelligence à un algorithme, pas parce qu'il existe une sorte de barrière physique ou technologique. L'humain peut le comprendre parce qu'il peut faire tout ce que l'ordinateur peut (bien que plus lentement) aussi bien que raisonner .
Adam Robinson

3
À quel moment quelqu'un essaiera de procéder à une rétro-ingénierie de l'ordinateur, à moins qu'il ne soit disponible que dans un environnement que vous contrôlez.
Amber

41

Safe Net Sentinel (anciennement Aladdin). Avertissements cependant - leur API craint, la documentation craint, et les deux sont excellents par rapport à leurs outils SDK.

J'utilise leur méthode de protection matérielle ( Sentinel HASP HL ) depuis de nombreuses années. Il nécessite un porte-clés USB propriétaire qui sert de «licence» pour le logiciel. Leur SDK chiffre et obscurcit votre exécutable et vos bibliothèques et vous permet de lier différentes fonctionnalités de votre application à des fonctionnalités gravées dans la clé. Sans clé USB fournie et activée par le donneur de licence, le logiciel ne peut pas être déchiffré et ne fonctionnera donc pas. La clé utilise même un protocole de communication USB personnalisé (en dehors de mon domaine de connaissances, je ne suis pas un pilote de périphérique) pour rendre difficile la création d'une clé virtuelle ou la falsification de la communication entre l'encapsuleur d'exécution et la clé. Leur SDK n'est pas très convivial pour les développeurs et il est assez pénible d'intégrer l'ajout de protection à un processus de génération automatisé (mais possible).

Avant de mettre en œuvre la protection HASP HL, 7 pirates connus avaient retiré les «protections» du dotfuscator du produit. Nous avons ajouté la protection HASP en même temps qu'une mise à jour majeure du logiciel, qui effectue des calculs lourds sur la vidéo en temps réel. Du mieux que je puisse en juger par le profilage et l'analyse comparative, la protection HASP HL ​​n'a ralenti les calculs intensifs que d'environ 3%. Depuis la sortie de ce logiciel il y a environ 5 ans, aucun nouveau pirate du produit n'a été trouvé. Le logiciel qu'il protège est en forte demande sur son segment de marché, et le client est au courant de plusieurs concurrents essayant activement de faire de l'ingénierie inverse (sans succès jusqu'à présent). Nous savons qu'ils ont tenté de solliciter l'aide de quelques groupes en Russie qui annoncent un service pour briser la protection des logiciels,

Récemment, nous avons essayé leur solution de licence logicielle (HASP SL) sur un projet plus petit, qui était assez simple pour fonctionner si vous êtes déjà familier avec le produit HL. Cela semble fonctionner; aucun incident de piratage n'a été signalé, mais la demande de ce produit est beaucoup plus faible.

Bien sûr, aucune protection ne peut être parfaite. Si quelqu'un est suffisamment motivé et a de sérieuses liquidités à dépenser, je suis sûr que les protections offertes par HASP pourraient être contournées.


19
Note du modérateur: Les commentaires sous cette réponse ont été supprimés en raison de la digression dans le bruit antagoniste.
Tim Post

2
+1 pour l'expérience, mais je voudrais répéter que ce n'est pas parfait. Maya (suite 3D) a utilisé un dongle matériel (je ne sais pas si c'était HASP), ce qui n'a pas dissuadé les pirates pendant très longtemps. Quand il y a une volonté, il y a un moyen.
Robert Fraser

1
AutoCAD utilise un système similaire, qui a été piraté à plusieurs reprises. HASP et d'autres personnes comme celle-ci garderont les honnêtes gens honnêtes et empêcheront le piratage occasionnel. Si vous construisez le prochain produit de conception de plusieurs milliards de dollars, vous aurez toujours des craquelins à affronter. Il s'agit de rendements décroissants - combien d'heures d'effort cela vaut-il la peine de casser la protection de votre logiciel plutôt que de simplement le payer.
RyanR

6
Je veux également faire sonner le point de vue de quelqu'un qui a utilisé un logiciel sécurisé HASP. Les HASP sont une douleur royale dans le cul pour l'utilisateur final . J'ai eu affaire à un Dallas iButton et à un Aladdin HASP, et les deux étaient vraiment bogués et ont provoqué l'arrêt aléatoire du logiciel, ce qui a nécessité la déconnexion et la reconnexion du HASP.
Fake Name

4
En outre, il convient de noter que les mesures de sécurité HASP ne sont pas nécessairement plus sécurisées que l'obfuscation de code - bien sûr, elles nécessitent une méthodologie différente pour effectuer une rétro-ingénierie, mais il est très possible de les inverser - Voir: flylogic.net/blog/?p=14 flylogic.net/blog/?p=16 flylogic.net/blog/?p=11
Fake Name

22

Les meilleures astuces anti-désassembleur, en particulier sur les jeux d'instructions à longueur de mot variable, sont en code assembleur / machine, pas C. Par exemple

CLC
BCC over
.byte 0x09
over:

Le désassembleur doit résoudre le problème qu'une destination de branche est le deuxième octet dans une instruction multi-octets. Un simulateur de jeu d'instructions n'aura cependant aucun problème. La dérivation vers des adresses calculées, que vous pouvez provoquer à partir de C, rend également le démontage difficile, voire impossible. Le simulateur de jeu d'instructions n'aura aucun problème avec lui. L'utilisation d'un simulateur pour trier les destinations des branches pour vous peut faciliter le processus de démontage. Le code compilé est relativement propre et facile pour un désassembleur. Je pense donc qu'un assemblage est nécessaire.

Je pense que c'était au début du Zen of Assembly Language de Michael Abrash où il a montré un simple truc anti-démonteur et anti-débogueur. Le 8088/6 avait une file d'attente de prélecture ce que vous avez fait était d'avoir une instruction qui a modifié la prochaine instruction ou un couple à venir. Si la progression est unique, vous avez exécuté l'instruction modifiée, si votre simulateur de jeu d'instructions n'a pas complètement simulé le matériel, vous avez exécuté l'instruction modifiée. Sur du matériel réel fonctionnant normalement, l'instruction réelle serait déjà dans la file d'attente et l'emplacement de mémoire modifié ne causerait aucun dommage tant que vous n'exécuteriez pas à nouveau cette chaîne d'instructions. Vous pourriez probablement encore utiliser une astuce comme celle-ci aujourd'hui alors que les processeurs en pipeline récupèrent l'instruction suivante. Ou si vous savez que le matériel a une instruction séparée et un cache de données, vous pouvez modifier un certain nombre d'octets à l'avance si vous alignez correctement ce code dans la ligne de cache, l'octet modifié ne sera pas écrit via le cache d'instructions mais le cache de données, et un simulateur de jeu d'instructions qui ne disposait pas de simulateurs de cache appropriés ne s'exécuterait pas correctement. Je pense que les solutions logicielles ne vous mèneront pas très loin.

Les éléments ci-dessus sont anciens et bien connus, je ne connais pas suffisamment les outils actuels pour savoir s'ils fonctionnent déjà autour de telles choses. Le code d'auto-modification peut / va déclencher le débogueur, mais l'humain peut / se limiter au problème, puis voir le code d'auto-modification et le contourner.

Auparavant, les pirates mettaient environ 18 mois pour résoudre quelque chose, des DVD par exemple. Maintenant, ils sont en moyenne d'environ 2 jours à 2 semaines (s'ils sont motivés) (rayon bleu, iphones, etc.). Cela signifie pour moi que si je passe plus de quelques jours sur la sécurité, je perds probablement mon temps. La seule véritable sécurité que vous obtiendrez sera le matériel (par exemple, vos instructions sont chiffrées et seul le cœur du processeur bien à l'intérieur de la puce se déchiffre juste avant l'exécution, de manière à ne pas exposer les instructions déchiffrées). Cela pourrait vous faire gagner des mois au lieu de jours.

Lisez également le livre de Kevin Mitnick, The Art of Deception. Une personne comme celle-ci pourrait décrocher un téléphone et demander à vous ou à un collègue de vous confier les secrets du système en pensant qu'il s'agit d'un gestionnaire ou d'un autre collègue ou ingénieur matériel dans une autre partie de l'entreprise. Et votre sécurité est détruite. La sécurité ne consiste pas uniquement à gérer la technologie, je dois aussi gérer les humains.


1
De plus, vous n'avez pas besoin d'avoir accès au code source (ou même au code source démonté) pour trouver une faille de sécurité. Ce pourrait être par accident, ou en utilisant le fait que la plupart des trous proviennent des mêmes problèmes dans le code (comme les débordements de tampon).
asmeurer

2
Il y a de gros problèmes avec le code auto-modifiable. La plupart des OS / matériels modernes ne vous permettent pas de le faire sans privilèges très élevés, il peut y avoir des problèmes de cache et le code n'est pas thread-safe.
Martin James

1
Avec les processeurs x86 modernes, de telles astuces sont souvent mauvaises pour les performances. L'utilisation du même emplacement de mémoire dans le cadre de plusieurs instructions a probablement un effet similaire à une branche mal prévue. Le code auto-modifiable amène le processeur à supprimer les lignes de cache pour maintenir la cohérence entre l'instruction et les caches de données (si vous exécutez le code modifié beaucoup plus souvent que vous le modifiez, cela peut toujours être une victoire).
jilles

2
Je l'ai rencontré il y a 20 ans. Cela nous a pris près d'une demi-heure pour comprendre ce qui s'est passé. Pas très bon si vous avez besoin d'une protection plus longue.
Bo Persson

1
«l'instruction réelle serait déjà dans la file d'attente et l'emplacement de mémoire modifié ne causerait aucun dommage» Jusqu'à ce qu'une interruption se produise entre les deux, vidant le pipeline d'instructions et rendant le nouveau code visible. Maintenant, votre obscurcissement a causé un bug pour vos utilisateurs légitimes.
Ben Voigt

21

Prenons, par exemple, l' algorithme AES . C'est un algorithme très, très public, et il est TRÈS sécurisé. Pourquoi? Deux raisons: il a été examiné par de nombreuses personnes intelligentes, et la partie "secrète" n'est pas l'algorithme lui-même - la partie secrète est la clé qui est l'une des entrées de l'algorithme. C'est une bien meilleure approche pour concevoir votre protocole avec un "secret" généré qui est en dehors de votre code, plutôt que de rendre le code lui-même secret. Le code peut toujours être interprété, peu importe ce que vous faites, et (idéalement) le secret généré ne peut être compromis que par une approche de force brute massive ou par le vol.

Je pense qu'une question intéressante est " Pourquoi voulez-vous brouiller votre code?" Vous voulez qu'il soit difficile pour les attaquants de casser vos algorithmes? Pour qu'il soit plus difficile pour eux de trouver des bogues exploitables dans votre code? Vous n'auriez pas besoin de brouiller le code si le code n'était pas craquable en premier lieu. La racine du problème est un logiciel crackable. Corrigez la racine de votre problème, ne vous contentez pas de le masquer.

De plus, plus vous confondez votre code, plus il vous sera difficile de trouver des bogues de sécurité. Oui, ce sera difficile pour les pirates, mais vous devez aussi trouver des bugs. Le code devrait être facile à entretenir dans des années, et même un code clair bien écrit peut être difficile à maintenir. N'aggrave pas.


3
+1 pour le bon sens: pourquoi vous compliquer la tâche alors que vous pourriez simplement concevoir un meilleur système.
Necrolis

1
Comme je le dis toujours, si vous gardez tout côté serveur, c'est plus sécurisé
liamzebedee

20

Rendre le code difficile à rétroconcevoir est appelé obscurcissement de code.

La plupart des techniques que vous mentionnez sont assez faciles à contourner. Ils se concentrent sur l'ajout de code inutile. Mais le code inutile est facile à détecter et à supprimer, vous laissant avec un programme propre.

Pour un obscurcissement efficace, vous devez faire dépendre le comportement de votre programme des bits inutiles en cours d'exécution. Par exemple, plutôt que de faire ceci:

a = useless_computation();
a = 42;

faites ceci:

a = complicated_computation_that_uses_many_inputs_but_always_returns_42();

Ou au lieu de faire ceci:

if (running_under_a_debugger()) abort();
a = 42;

Faites ceci (où running_under_a_debuggerne devrait pas être facilement identifiable comme une fonction qui teste si le code s'exécute sous un débogueur - il doit mélanger des calculs utiles avec la détection du débogueur):

a = 42 - running_under_a_debugger();

L'obfuscation efficace n'est pas quelque chose que vous pouvez faire uniquement au stade de la compilation. Quoi que le compilateur puisse faire, un décompilateur peut le faire. Bien sûr, vous pouvez augmenter la charge des décompilateurs, mais cela n'ira pas loin. Les techniques d'obscurcissement efficaces, dans la mesure où elles existent, impliquent l'écriture de la source obscurcie dès le premier jour. Rendez votre code auto-modifiable. Portez votre code avec des sauts calculés, dérivés d'un grand nombre d'entrées. Par exemple, au lieu d'un simple appel

some_function();

faites cela, où vous connaissez la disposition exacte attendue des bits dans some_data_structure:

goto (md5sum(&some_data_structure, 42) & 0xffffffff) + MAGIC_CONSTANT;

Si vous êtes sérieux au sujet de l'obscurcissement, ajoutez plusieurs mois à votre planification; l'obscurcissement n'est pas bon marché. Et considérez que de loin le meilleur moyen d'éviter que les gens ne procèdent à une rétro-ingénierie de votre code est de le rendre inutile afin qu'il ne dérange pas. C'est une simple considération économique: ils procéderont à une rétro-ingénierie si la valeur pour eux est supérieure au coût; mais augmenter leur coût augmente également beaucoup votre coût, alors essayez de réduire la valeur pour eux.

Maintenant que je vous ai dit que l' obfuscation est difficile et coûteuse, je vais vous dire que ce n'est pas pour vous de toute façon . vous écrivez

le protocole actuel sur lequel je travaille ne doit jamais être inspecté ou compréhensible, pour la sécurité de diverses personnes

Cela soulève un drapeau rouge. C'est la sécurité par obscurité , qui a un très mauvais bilan. Si la sécurité du protocole dépend de personnes ne connaissant pas le protocole, vous avez déjà perdu .

Lecture recommandée:


1
@Gilles, c'est votre déclaration, qui est très forte, donc la charge de la preuve vous incombe. Cependant, je vais fournir un exemple simple: 2+2peut être simplifié par le compilateur 4, mais le décompilateur ne peut pas le ramener 2+2(et si c'était le cas 1+3?).
Rotsor

7
@Rotsor 4et 2+2sont équivalents sur le plan de l'observation, ils sont donc les mêmes à cet effet, à savoir pour comprendre ce que fait le programme. Oui, bien sûr, le décompilateur ne peut pas reconstruire le code source, mais ce n'est pas pertinent. Ce Q&A concerne la reconstruction du comportement (ie l'algorithme, et plus précisément un protocole).
Gilles 'SO- arrête d'être méchant'

1
Vous n'avez rien à faire pour reconstruire le comportement. Vous avez déjà le programme! Ce dont vous avez généralement besoin, c'est de comprendre le protocole et d'y changer quelque chose (comme remplacer un 2 en 2+2par 3, ou remplacer le +par un *).
Rotsor

1
Si vous considérez tous les programmes à comportement équivalent comme les mêmes, alors oui, le compilateur ne peut rien faire car il effectue juste une transformation d'indentité. Le décompilateur est également inutile, car il s'agit à nouveau d'une transformation d'identité. Si vous ne le faites pas, cependant, 2+2-> 4est un exemple valide de transformation irréversible effectuée par le compilateur. Que cela rend la compréhension plus facile ou plus difficile est un argument distinct.
Rotsor

2
@Gilles Je ne peux pas étendre votre analogie avec Apple parce que je ne peux pas imaginer une pomme structurellement différente mais comportementalement équivalente. :)
Rotsor

13

Plusieurs fois, la crainte que votre produit ne fasse l'objet d'une ingénierie inverse est déplacée. Oui, il peut être inversé; mais deviendra-t-il si célèbre sur une courte période de temps, que les pirates trouveront qu'il vaut la peine de revenir en arrière. il ? (ce travail n'est pas une petite activité de temps, pour des lignes de code importantes).

Si cela devient vraiment une source de revenus, alors vous devriez avoir rassemblé suffisamment d'argent pour le protéger en utilisant les moyens légaux comme les brevets et / ou les droits d'auteur .

À mon humble avis, prenez les précautions de base que vous allez prendre et relâchez-le. Si cela devient un point d'ingénierie inverse qui signifie que vous avez fait du très bon travail, vous trouverez vous-même de meilleures façons de le surmonter. Bonne chance.


1
Je veux dire, c'est une réponse viable et applicable, mais la ligne que vous tracez entre la protection et gagner un revenu de quelques millions pour que d'autres protègent votre produit pour vous est une très longue ligne.
graphitemaster

12

Lisez http://en.wikipedia.org/wiki/Security_by_obscurity#Arguments_against . Je suis sûr que d'autres pourraient probablement également fournir de meilleures sources expliquant pourquoi la sécurité par obscurité est une mauvaise chose.

Il devrait être tout à fait possible, en utilisant des techniques cryptographiques modernes, d'avoir votre système ouvert (je ne dis pas qu'il devrait être ouvert, juste qu'il pourrait l'être), et d'avoir toujours une sécurité totale, tant que l'algorithme cryptographique ne le fait pas. ont un trou (peu probable si vous choisissez un bon), vos clés privées / mots de passe restent privés, et vous n'avez pas des trous de sécurité dans votre code ( c'est ce que vous devriez se soucier).


2
Je serais d'accord avec cela. Je pense que vous pouvez avoir un problème conceptuel ou de conception. Existe-t-il un analogue avec une solution de paire de clés privée-publique? Vous ne divulguez jamais la clé privée, elle reste avec le propriétaire dont le client sécurisé la traite. Pouvez-vous garder le code sécurisé hors de leur ordinateur et ne transmettre les résultats qu'à l'utilisateur?
Dizzley

8

Depuis juillet 2013, il y a un regain d'intérêt pour une obfuscation cryptographiquement robuste (sous la forme d'une obscurcissement par indiscernabilité ) qui semble avoir découlé des recherches originales d' Amit Sahai .

Vous pouvez trouver des informations distillées dans cet article de Quanta Magazine et dans cet article IEEE Spectrum .

Actuellement, le montant des ressources nécessaires pour utiliser cette technique la rend peu pratique, mais AFAICT le consensus est plutôt optimiste quant à l'avenir.

Je dis cela avec beaucoup de désinvolture, mais à tous ceux qui ont l'habitude de rejeter instinctivement la technologie d'obfuscation - c'est différent. S'il est prouvé qu'il fonctionne vraiment et qu'il est rendu pratique, c'est en effet majeur, et pas seulement pour l'obscurcissement.


7

Pour vous informer, lisez la littérature académique sur l' obscurcissement du code . Christian Collberg de l'Université de l'Arizona est un universitaire réputé dans ce domaine; Salil Vadhan de l'Université Harvard a également fait du bon travail.

Je suis en retard sur cette littérature, mais l'idée essentielle que je connais est que vous ne pouvez pas empêcher un attaquant de voir le code que vous exécuterez, mais vous pouvez l'entourer de code qui n'est pas exécuté, et cela coûte un temps exponentiel d'attaquant (en utilisant les meilleures techniques connues) pour découvrir quels fragments de votre code sont exécutés et lesquels ne le sont pas.


7

Il existe un article récent intitulé " Obfuscation de programmes et programmes ponctuels" ". Si vous souhaitez vraiment protéger votre application. L'article en général contourne les résultats théoriques de l'impossibilité en utilisant du matériel simple et universel.

Si vous ne pouvez pas vous permettre d'avoir besoin de matériel supplémentaire, alors il y a aussi un autre document qui donne l'obscurcissement théoriquement le meilleur possible " Sur le meilleur obscurcissement possible ", parmi tous les programmes avec la même fonctionnalité et la même taille. Cependant, le document montre que la théorie de l'information au mieux implique un effondrement de la hiérarchie polynomiale.

Ces articles devraient au moins vous donner suffisamment de références bibliographiques pour parcourir la littérature connexe si ces résultats ne répondent pas à vos besoins.

Mise à jour: Une nouvelle notion d'obscurcissement, appelée obscurcissement indiscernable, peut atténuer le résultat d'impossibilité (papier)


6

Si quelqu'un veut passer du temps à inverser votre binaire, vous ne pouvez absolument rien faire pour les arrêter. Vous pouvez faire si modérément plus difficile, mais c'est à peu près tout. Si vous voulez vraiment en savoir plus, procurez-vous une copie de http://www.hex-rays.com/idapro/ et démontez quelques binaires.

Le fait que le CPU ait besoin d'exécuter le code est votre annulation. Le CPU exécute uniquement le code machine ... et les programmeurs peuvent lire le code machine.

Cela étant dit ... vous avez probablement un problème différent qui peut être résolu d'une autre manière. Qu'essayez-vous de protéger? Selon votre problème, vous pouvez probablement utiliser le cryptage pour protéger votre produit.


6

Pour pouvoir sélectionner la bonne option, vous devez penser aux aspects suivants:

  1. Est-il probable que les "nouveaux utilisateurs" ne veuillent pas payer mais utiliser votre logiciel?
  2. Est-il probable que les clients existants aient besoin de plus de licences qu'ils n'en ont?
  3. Combien les utilisateurs potentiels sont-ils prêts à payer?
  4. Voulez-vous attribuer des licences par utilisateur / utilisateurs simultanés / poste de travail / entreprise?
  5. Votre logiciel a-t-il besoin d'une formation / personnalisation pour être utile?

Si la réponse à la question 5 est "oui", ne vous inquiétez pas des copies illégales. Ils ne seraient de toute façon pas utiles.

Si la réponse à la question 1 est «oui», pensez d'abord à la tarification (voir question 3).

Si vous répondez «oui» aux questions 2, un modèle de «paiement à l'utilisation» pourrait vous convenir.

D'après mon expérience, le paiement à l'utilisation + la personnalisation et la formation sont la meilleure protection pour votre logiciel, car:

  • Les nouveaux utilisateurs sont attirés par le modèle de tarification (peu d'utilisation -> peu de rémunération)
  • Il n'y a presque pas "d'utilisateurs anonymes", car ils ont besoin de formation et de personnalisation.
  • Aucune restriction logicielle n'effraie les clients potentiels.
  • Il existe un flux continu d'argent provenant des clients existants.
  • Vous obtenez de précieux commentaires pour le développement de vos clients, en raison d'une relation commerciale à long terme.

Avant de penser à introduire le DRM ou l'obfuscation, vous pourriez penser à ces points et s'ils s'appliquent à votre logiciel.


Très bon conseil (et je l'ai voté), mais il ne répond pas vraiment à cette question particulière
Mawg dit réintégrer Monica

5

Au départ, le code protégé dans une machine virtuelle semblait impossible à rétroconcevoir. Themida Packer

Mais ce n'est plus aussi sûr. Et peu importe comment vous empaquetez votre code, vous pouvez toujours faire un vidage de mémoire de tout exécutable chargé et le démonter avec n'importe quel désassembleur comme IDA Pro.

IDA Pro est également livré avec un transformateur de code source en code source C bien que le code généré ressemble plus à un désordre mathématique pointeur / adresse. Si vous le comparez avec l'original, vous pouvez corriger toutes les erreurs et tout arracher.


5

Pas de dés, vous ne pouvez pas protéger votre code contre le démontage. Ce que vous pouvez faire est de configurer le serveur pour la logique métier et d'utiliser le service Web pour le fournir pour votre application. Bien sûr, ce scénario n'est pas toujours possible.


8
bien dit, la seule façon d'éviter que les gens démontent votre code est de ne jamais leur laisser un accès physique, ce qui signifie offrir votre application exclusivement en tant que SAAS, prendre les demandes des clients distants et restituer les données traitées. Placez le serveur dans une pièce verrouillée dans un bunker souterrain entouré d'un fossé d'alligator et d'un fil de rasoir électrifié de 5 m de hauteur dans lequel vous jetez la clé avant de tout recouvrir de 10 m de béton armé, puis j'espère que vous n'avez pas oublié d'installer des tonnes des systèmes logiciels pour empêcher les intrusions sur le réseau.
jwenting

6
J'espère que je n'aurai jamais le contrat pour maintenir vos serveurs
Colin Pickard

5

Pour éviter l'ingénierie inverse, vous ne devez pas donner le code aux utilisateurs. Cela dit, je recommande d'utiliser une application en ligne ... cependant (puisque vous n'avez donné aucun contexte) qui pourrait être inutile sur le vôtre.


c'est la vraie solution ... à savoir mettre vos joyaux de la couronne dans votre propre serveur sur votre propre machine VPS et exposer uniquement les appels API dans ce serveur à partir du client (navigateur ou client api)
Scott Stensland

5

Votre meilleure alternative est peut-être toujours d'utiliser la virtualisation, qui introduit un autre niveau d'indirection / obscurcissement nécessaire à contourner, mais comme SSpoke l'a dit dans sa réponse , cette technique n'est pas non plus sécurisée à 100%.


Le fait est que vous n'obtiendrez pas une protection ultime, car il n'y a rien de tel, et si jamais, cela ne durera pas longtemps, ce qui signifie que ce n'était pas la protection ultime en premier lieu.

Tout ce que l'homme assemble peut être démonté.

Il est généralement vrai que le démontage (correct) est souvent (un peu ou plus) une tâche plus difficile, donc votre adversaire doit être plus habile , mais vous pouvez supposer qu'il y a toujours quelqu'un de cette qualité, et c'est une valeur sûre.

Si vous voulez protéger quelque chose contre les ER, vous devez connaître au moins les techniques courantes utilisées par les ER.

Ainsi les mots

Internet n'est pas vraiment ingénieux pour la prévention contre la rétro-ingénierie, mais représente plutôt des tonnes d'informations sur la façon de procéder à la rétro-ingénierie

montrez votre mauvaise attitude. Je ne dis pas que pour utiliser ou intégrer une protection, vous devez savoir comment la briser, mais pour l'utiliser à bon escient, vous devez connaître ses faiblesses et ses pièges. Vous devez le comprendre .

(Il existe des exemples de logiciels utilisant la protection de manière erronée, rendant cette protection pratiquement inexistante. Pour éviter de parler vaguement, je vais vous donner un exemple brièvement décrit sur Internet: Oxford English Dictionary Second Edition sur CD-ROM v4. son échec d'utilisation de SecuROM à la page suivante: Oxford English Dictionary (OED) sur CD-ROM dans un environnement Windows 16, 32 ou 64 bits: installation du disque dur, bogues, macros de traitement de texte, mise en réseau, polices et ainsi de suite )

Tout prend du temps.

Si vous êtes nouveau sur le sujet et que vous n'avez pas de mois ou plutôt d'années pour vous familiariser correctement avec les sources d'énergie renouvelables, optez pour les solutions disponibles proposées par d'autres. Le problème ici est évident, ils sont déjà là, donc vous savez déjà qu'ils ne sont pas sûrs à 100%, mais créer votre propre nouvelle protection ne vous donnerait qu'un faux sentiment d'être protégé, à moins que vous ne connaissiez vraiment bien l'état de l'art en reverse engineering et protection (mais vous ne le faites pas, du moins en ce moment).

Le but de la protection logicielle est d'effrayer les débutants, de bloquer les ER courants et de mettre un sourire sur le visage des ER chevronnés après son voyage (si tout va bien intéressant) au centre de votre application.

Dans les discussions commerciales, vous pouvez dire qu'il s'agit de retarder la concurrence, autant que possible.

(Jetez un œil à la belle présentation Silver Needle dans le Skype de Philippe Biondi et Fabrice Desclaux présentée sur Black Hat 2006).


Vous savez qu'il y a beaucoup de choses sur les énergies renouvelables, alors commencez à le lire. :)

J'ai parlé de virtualisation, je vais donc vous donner un lien vers un exemple de thread d' EXETOOLS FORUM : Meilleur logiciel de protection: Themida ou Enigma Protector? . Cela peut vous aider un peu dans vos recherches ultérieures.


4

Je ne pense pas qu'un code soit impossible à pirater, mais les récompenses doivent être excellentes pour que quelqu'un veuille l'essayer.

Cela dit, vous devez faire certaines choses, telles que:

  • Utilisez le niveau d'optimisation le plus élevé possible (l'ingénierie inverse ne consiste pas seulement à obtenir la séquence d'assemblage, mais également à comprendre le code et à le porter dans un langage de niveau supérieur tel que C). Le code hautement optimisé peut être un b --- h à suivre.
  • Rendez les structures denses en ne disposant pas de types de données plus importants que nécessaire. Réorganisez les membres de la structure entre les versions officielles du code. Les champs de bits réarrangés dans les structures sont également quelque chose que vous pouvez utiliser.
  • Vous pouvez vérifier la présence de certaines valeurs qui ne doivent pas être modifiées (un message de copyright est un exemple). Si un vecteur d'octets contient "vwxyz", vous pouvez avoir un autre vecteur d'octets contenant "abcde" et comparer les différences. La fonction qui le fait ne doit pas passer de pointeurs aux vecteurs mais utiliser des pointeurs externes définis dans d'autres modules comme (code pseudo-C) "char * p1 = & string1 [539];" et "char p2 = & string2 [-11731];". De cette façon, il n'y aura pas de pointeurs pointant exactement vers les deux chaînes. Dans le code de comparaison, vous comparez ensuite pour " (p1-539 + i) - * (p2 + 11731 + i) == une valeur". Le pirate pensera qu'il est sûr de changer string1 car personne ne semble y faire référence. Enterrez le test dans un endroit inattendu.

Essayez de pirater le code d'assemblage vous-même pour voir ce qui est facile et ce qui est difficile à faire. Des idées devraient apparaître que vous pouvez expérimenter pour rendre le code plus difficile à rétroconcevoir et rendre le débogage plus difficile.


2
votre premier point n'a pas de sens, le code optimisé supprime la cruauté, cela rend plus facile à inverser (je parle d'expérience). votre troisième point est également une perte de temps, et le rétro-ingénieur digne de ce nom sait comment effectuer un point d'arrêt d'accès à la mémoire. c'est pourquoi il est probablement préférable de ne pas concevoir un système vous-même, mais nous, les bibliothèques tierces qui n'ont pas encore été `` craquées '', car cela devrait durer un peu plus longtemps que tout ce qu'une `` recrue '' pourrait créer ...
Necrolis

Comme il semble que je ne sache rien sur le sujet, je devrais peut-être me tourner vers un professionnel comme vous pour mes besoins de développement logiciel au lieu d'écrire moi-même n'importe quel code.
Olof Forshell

4

Comme beaucoup l'ont déjà dit: sur un CPU normal, vous ne pouvez pas les empêcher de le faire, vous pouvez simplement les retarder. Comme mon ancien professeur de crypto me l'a dit: vous n'avez pas besoin d'un cryptage parfait, casser le code doit être juste plus cher que le gain. Il en va de même pour votre obscurcissement.

Mais 3 notes supplémentaires:

  1. Il est possible de rendre l'ingénierie inverse impossible, MAIS (et c'est un très très gros mais), vous ne pouvez pas le faire sur un processeur conventionnel. J'ai également fait beaucoup de développement matériel, et souvent des FPGA sont utilisés. Par exemple, le Virtex 5 FX possède un processeur PowerPC et vous pouvez utiliser l'APU pour implémenter ses propres opcodes CPU dans votre matériel. Vous pouvez utiliser cette fonctionnalité pour vraiment décrypter les incstuctions pour le PowerPC, qui n'est pas accessible par l'extérieur ou par un autre logiciel, ou même exécuter la commande dans le matériel. Comme le FPGA a intégré le cryptage AES pour sa configuration bitstream, vous ne pouvez pas le désosser (sauf si quelqu'un parvient à casser AES, mais je suppose que nous avons d'autres problèmes ...). De cette façon, les fournisseurs de matériel IP protègent également leur travail.

  2. Vous parlez du protocole. Vous ne dites pas de quel type de protocole il s'agit, mais lorsqu'il s'agit d'un protocole réseau, vous devez au moins le protéger contre les reniflements réseau. Vous pouvez en effet le faire par cryptage. Mais si vous souhaitez protéger le en / décryptage d'un propriétaire du logiciel, vous êtes de retour à l'obfuscation.

  3. Rendez votre programme non débogable / non exécutable. Essayez d'utiliser une sorte de détection de débogage et appliquez-la, par exemple, dans une formule ou en ajoutant un contenu de registre de débogage à une constante magique. Il est beaucoup plus difficile si votre programme semble en mode débogage s'il s'exécute normalement, mais effectue un calcul, une opération ou autre incorrect. Par exemple, je connais certains jeux écologiques, qui avaient une protection contre la copie vraiment désagréable (je sais que vous ne voulez pas de protection contre la copie, mais c'est similaire): La version volée a modifié les ressources minées après 30 minutes de jeu, et tout à coup, vous n'avez obtenu qu'un seul Ressource. Le pirate vient de le casser (c'est-à-dire qu'il a fait de l'ingénierie inverse) - a vérifié s'il fonctionnait, et volia l'a libéré. De tels changements de comportement légers sont très difficiles à détecter, en particulier. s'ils n'apparaissent pas instantanément à la détection, mais seulement retardés.

Donc, finalement, je suggérerais: Estimer quel est le gain pour les gens de l'ingénierie inverse de votre logiciel, traduire cela en un certain temps (par exemple en utilisant le salaire indien le moins cher) et rendre l'ingénierie inverse si coûteuse en temps qu'elle est plus grande.


3

Contrairement à ce que la plupart des gens disent, sur la base de leur intuition et de leur expérience personnelle, je ne pense pas que l'obscurcissement de programme cryptographiquement sûr se soit avéré impossible en général.

Ceci est un exemple d'une déclaration de programme parfaitement obscurcie pour démontrer mon point:

printf("1677741794\n");

On ne peut jamais deviner que ce qu'il fait est

printf("%d\n", 0xBAADF00D ^ 0xDEADBEEF);

Il existe un article intéressant sur ce sujet, qui prouve certains résultats d'impossibilité. Cela s'appelle "Sur la (Im) possibilité d'obscurcir les programmes" .

Bien que le document prouve que l'obscurcissement rendant le programme indissociable de la fonction qu'il met en œuvre est impossible, l'obscurcissement défini d'une manière plus faible peut toujours être possible!


7
1. Votre exemple n'est pas pertinent ici; les deux programmes que vous montrez sont équivalents sur le plan du comportement, et cette question consiste à déterminer le comportement d'un programme, et non à reconstruire son code source (ce qui, évidemment, est impossible). 2. Ce document est un document théorique; il est impossible d'écrire l'obfuscateur parfait, mais il est également impossible d'écrire le décompilateur parfait (pour les mêmes raisons qu'il est impossible d'écrire l'analyseur de programme parfait). En pratique, c'est une course aux armements: qui peut écrire le meilleur (dé) obfuscateur.
Gilles 'SO- arrête d'être méchant'

1
@Gilles, le résultat de la désobfuscation (correcte) sera toujours équivalent sur le plan du comportement au code obscurci. Je ne vois pas comment cela sape l'importance du problème.
Rotsor

Aussi, sur la course aux armements: il ne s'agit pas de savoir qui investit le plus dans la recherche, mais plutôt de savoir qui a raison. Les preuves mathématiques correctes ne se trompent pas simplement parce que quelqu'un les veut vraiment.
Rotsor

1
D'accord, vous avez peut-être raison sur la course aux armements dans la pratique. Je pense que j'ai mal compris celui-ci. :) J'espère qu'une sorte d'obscurcissement cryptographiquement sûr est possible.
Rotsor

Pour un cas intéressant d'obscurcissement, essayez les cartes à puce, où le problème est que l'attaquant a un accès physique (obfuscation en boîte blanche). Une partie de la réponse consiste à limiter l'accès par des moyens physiques (l'attaquant ne peut pas lire directement les clés secrètes); mais l'obscurcissement logiciel joue également un rôle, principalement pour que les attaques comme DPA ne donnent pas de résultats utiles. Je n'ai pas une bonne référence à offrir, désolé. Les exemples de ma réponse sont vaguement inspirés des techniques utilisées dans ce domaine.
Gilles 'SO- arrête d'être méchant'

3

La sécurité par l'obscurité ne fonctionne pas, comme l'ont démontré des gens beaucoup plus intelligents que nous deux. Si vous devez protéger le protocole de communication de vos clients, vous êtes moralement obligé d'utiliser le meilleur code qui soit ouvert et minutieusement examiné par des experts.

C'est pour la situation où les gens peuvent inspecter le code. Si votre application doit s'exécuter sur un microprocesseur intégré, vous pouvez en choisir un qui possède une fonction de scellage, ce qui rend impossible l'inspection du code ou l'observation de paramètres plus que triviaux comme l'utilisation actuelle pendant son exécution. (C'est, sauf par des techniques d'envahissement matériel, où vous démontez soigneusement la puce et utilisez un équipement avancé pour inspecter les courants sur les transistors individuels.)

Je suis l'auteur d'un assembleur de reverse engineering pour le x86. Si vous êtes prêt pour une froide surprise, envoyez-moi le résultat de vos meilleurs efforts. (Contactez-moi via mes sites Web.) Peu de choses que j'ai vues dans les réponses me présenteraient un obstacle important. Si vous voulez voir comment fonctionne un code d'ingénierie inverse sophistiqué, vous devriez vraiment étudier les sites Web avec des défis d'ingénierie inverse.

Votre question pourrait nécessiter quelques éclaircissements. Comment prévoyez-vous de garder un protocole secret si le code informatique se prête à la rétro-ingénierie? Si mon protocole consistait à envoyer un message chiffré RSA (même une clé publique), que gagnez-vous à garder le protocole secret? À toutes fins pratiques, un inspecteur serait confronté à une séquence de bits aléatoires.

Groetjes Albert


3

Les techniques d'ingénierie inverse traditionnelles dépendent de la capacité d'un agent intelligent à utiliser un désassembleur pour répondre aux questions sur le code. Si vous voulez une sécurité renforcée, vous devez faire des choses qui empêchent de manière prouvée l'agent d'obtenir de telles réponses.

Vous pouvez le faire en vous appuyant sur le programme Halting ("le programme X s'arrête-t-il?") Qui en général ne peut pas être résolu. L'ajout de programmes difficiles à raisonner à votre programme rend votre programme difficile à raisonner. Il est plus facile de construire de tels programmes que de les déchirer. Vous pouvez également ajouter du code au programme qui a différents degrés de difficulté pour raisonner; un excellent candidat est le programme de raisonnement sur les alias ("pointeurs").

Collberg et al ont un article ("Manufacturing Cheap, Resilient and Stealthy Opaque Constructs") qui discute de ces sujets et définit une variété de prédicats "opaques" qui peuvent rendre très difficile de raisonner sur le code:

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.39.1946&rep=rep1&type=pdf

Je n'ai pas vu les méthodes spécifiques de Collberg appliquées au code de production, en particulier pas le code source C ou C ++.

L'obfuscateur DashO Java semble utiliser des idées similaires. http://www.cs.arizona.edu/~collberg/Teaching/620/2008/Assignments/tools/DashO/


2

PREMIÈRE CHOSE À SE RAPPELER DE CACHER VOTRE CODE : Tout votre code n'a pas besoin d'être caché.

L'OBJECTIF FINAL : Mon objectif final pour la plupart des logiciels est la possibilité de vendre différentes licences qui activeront et désactiveront des fonctionnalités spécifiques au sein de mes programmes.

MEILLEURE TECHNIQUE : Je trouve que la construction d'un système de crochets et de filtres comme WordPress est la meilleure méthode absolue lorsque vous essayez de confondre vos adversaires. Cela vous permet de crypter certaines associations de déclencheurs sans réellement crypter le code.

La raison pour laquelle vous effectuez cette opération est que vous souhaiterez crypter le moins de code possible.

CONNAISSEZ VOS CRACKERS : Sachez ceci: La principale raison du craquage de code n'est pas à cause de la distribution malveillante de licences, c'est en fait parce qu'il faut changer votre code et ils n'ont pas vraiment besoin de distribuer des copies gratuites.

POUR COMMENCER : Mettez de côté la petite quantité de code que vous allez crypter, le reste du code devrait essayer d'être entassé dans UN fichier pour augmenter la complexité et la compréhension.

PRÉPARATION AU CHIFFREMENT : Vous allez crypter en couches avec mon système, cela va également être une procédure très complexe, alors construisez un autre programme qui sera responsable du processus de cryptage.

LA PREMIÈRE ÉTAPE : Obscurcissez en utilisant des noms base64 pour tout. Une fois cela fait, base64 le code obscurci et enregistrez-le dans un fichier temporaire qui sera plus tard utilisé pour déchiffrer et exécuter ce code. Ça a du sens?

Je vais répéter car vous ferez cela encore et encore. Vous allez créer une chaîne base64 et l'enregistrer dans un autre fichier en tant que variable qui sera déchiffrée et rendue.

ÉTAPE DEUX : Vous allez lire ce fichier temporaire sous forme de chaîne et l'obscurcir, puis le base64 et l'enregistrer dans un deuxième fichier temporaire qui sera utilisé pour le déchiffrer et le rendre pour l'utilisateur final.

ÉTAPE TROIS : Répétez l'étape deux autant de fois que vous le souhaitez. Une fois que cela fonctionnera correctement sans erreurs de décryptage, vous voudrez commencer à construire des mines terrestres pour vos adversaires.

LAND MINE ONE : Vous allez vouloir garder le fait que vous êtes notifié un secret absolu. Donc, intégrez un système de messagerie d'avertissement de sécurité pour la couche 2. Ce sera tiré vous permettant de connaître les détails de votre adversaire en cas de problème.

LAND MINE TWO : Dépendances. Vous ne voulez pas que votre adversaire puisse exécuter la couche 1, sans la couche 3 ou 4 ou 5, ni même le programme réel pour lequel il a été conçu. Assurez-vous donc qu'au sein de la couche un, vous incluez une sorte de script kill qui s'activera si le programme n'est pas présent, ou les autres couches.

Je suis sûr que vous pouvez trouver vos propres mines terrestres, amusez-vous avec.

À RETENIR : Vous pouvez réellement crypter votre code au lieu de le base64. De cette façon, un simple base64 ne déchiffrera pas le programme.

RÉCOMPENSE : Gardez à l'esprit que cela peut en fait être une relation symbiotique entre vous et votre adversaire. Je place toujours un commentaire à l'intérieur de la première couche, le commentaire félicite le pirate et lui donne un code promo à utiliser afin de recevoir une récompense en espèces de votre part.

Faites en sorte que la récompense en espèces soit importante sans préjudice. Je dis normalement quelque chose comme 500 $. Si votre mec est le premier à déchiffrer le code, alors payez-le et devenez son ami. S'il est un de vos amis, il ne distribuera pas votre logiciel. Demandez-lui comment il l'a fait et comment vous pouvez vous améliorer!

BONNE CHANCE!


4
Avez-vous même lu la question? Je n'ai jamais demandé de méthodes pour se protéger du piratage. L'application sera gratuite, c'est le protocole sous-jacent utilisé qui doit être protégé en raison de la nature de la sécurité.
graphitemaster

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.