J'ai une application de console C ++ non gérée dans laquelle j'utilise Srand () et Rand (). Je n'ai pas besoin de cela pour résoudre un problème particulier, mais curieux: la graine d'origine est-elle passée à Srand () stockée quelque part en mémoire que je peux interroger? Y a-t-il un moyen de déterminer ce que la graine était? P>
4 Réponses :
La graine n'est pas nécessaire pour être stockée, seul le dernier nombre aléatoire renvoyé est.
Voici l'exemple de la manuelle: P>
static unsigned long next = 1; /* RAND_MAX assumed to be 32767 */ int myrand(void) { next = next * 1103515245 + 12345; return((unsigned)(next/65536) % 32768); } void mysrand(unsigned seed) { next = seed; }
théoriquement, pas - la valeur de la graine est utilisée pour calculer la valeur aléatoire suivante et cette valeur est (théoriquement) utilisée pour semer le numéro aléatoire suivant et ainsi de suite. p>
Security sage, être capable de jeter un coup d'œil sur la graine (que l'original unique ou un nouveau) est un problème de sécurité sérieux, donc je m'attends à ce que vous ne puissiez pas la regarder, même s'il doit être stocké quelque part. p>
Je suppose que "devrait" être censé être "ne devrait pas" (depuis que cela n'a pas beaucoup de sens)
Je ne sais pas quelle utilisation de votre rand () utilise, mais la plupart des bonnes conservent une table de shuffle, pas seulement un état de «courant».
-1. rand () n'est pas du tout cryptographiquement. Il est très facile de travailler en arrière.
Je n'ai jamais réclamé Rand () est cryptographiquement en sécurité, mais être capable de jeter un coup d'œil sur la graine, c'est problématique même si vous ne faites pas de cryptographie :-)
Si vous avez un générateur confortable linéaire simple, pour lequel vous avez plusieurs valeurs, cela donne un système d'équations: Si vous connaissez la première valeur, vous pouvez revenir en arrière dans la séquence. : p> Vous ne connaissez pas la graine de manière unique, vous ne le savez que MOD M (ce qui est généralement bien depuis (0 Vous pouvez également regarder le Théorème restant chinois , bien que ce n'est pas une correspondance exacte. P> p>
Avez-vous juste dit que "essayez simplement toutes les graines de 64 bits"? À quelle vitesse d'un ordinateur avez-vous? :RÉ
Essayez toutes les graines 64 bits? C'est 18 446 744,073 709 551 616 possibilités différentes - un peu au-delà de la réalisation.
Ce que vous pouviez faire avec un peu d'informations sur l'emplacement de la graine, essayez quelques millions de suppositions. Souvent, Srand est ensemencé avec l'heure actuelle. Si vous savez à peu près lorsque le générateur a été semé pour la première fois, vous pouvez faire une très bonne idée à ce que la valeur du temps () était à ce moment-là.
Oui, UM 64 peut-être un peu beaucoup maintenant, mais vous pouvez certainement essayer tous les 32 bits numéros avec du matériel moderne. Notez que vous n'avez pas besoin d'essayer les 2 ^ 64 valeurs, juste ceux
Je pense que vous pouvez récupérer les A et B pour le générateur congrandu linéaire, et une fois que vous savez, et que vous savez V1 et M, la graine suit.
Je ne sais pas quel est votre niveau de compétence de montage ou si vous avez accès aux symboles de code source / de débogage de l'application non gérés, mais en dehors de cette sorte de scandale, il n'y a pas de moyen réalisable de déterminer l'original Valeur de la graine. L'ensemble des générateurs de nombres aléatoires est de proposer un moyen de vous donner des nombres imprévisibles - la relation entre deux appels donnés à Rand () ne doit pas être déductible. Dans les générateurs de nombres aléatoires pseudo-aléatoires cryptographiquement, il serait considéré comme une faille grave de pouvoir deviner la graine sur la base d'un nombre aléatoire généré. P>
Le moyen le plus simple de le faire serait de démarrer l'application sous un débogueur et de définir un point d'arrêt dans lequel Suivant serait de désassembler l'application et de découvrir les circonstances de l'appel SRAND. Il est tout à fait possible que cela soit ensemencé avec l'heure actuelle - alors vous pouvez essayer un tas de suppositions (vous pouvez probablement le réduire à quelques milliers) et voir si vous donnez la même séquence de nombres aléatoires que l'application utilise . (Bien sûr, cela suppose que vous avez une façon de savoir quelles sont générées les valeurs aléatoires). Il est également possible que la graine soit quelque chose dure comme «0» tout le temps. p> srand () code> est appelé - alors il suffit de regarder le paramètre transmis. p>
-1. rand () n'est pas sécurisé cryptographiquement; Il retourne presque toujours les morceaux haut de gamme d'un LCG. La sortie d'un couple d'appels vers Rand () est généralement suffisante pour déduire l'état actuel et travailler ainsi en arrière.