Pergunta

Eu tenho um aplicativo de console C ++ não gerenciado, no qual estou usando srand () e rand (). Não preciso disso para resolver um problema específico, mas fiquei curioso: a semente original passou para srand () armazenada em algum lugar na memória que posso consultar? Existe alguma maneira de descobrir qual era a semente?

Foi útil?

Solução

Não é necessário armazenar a semente, apenas o último número aleatório retornado é.

Aqui está o exemplo da Manpage:

       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;
       }

Outras dicas

Se você tem um gerador congruente linear simples, pelo qual você tem vários valores, isso produz um sistema de equações:

 v1 = ( seed * a + b ) % m
 v2 = (   v1 * a + b ) % m;
 v3 = (   v2 * a + b ) % m;
... 

Se você conhece o primeiro valor, pode voltar na sequência:

seed = (v1 - b)/a (mod m)

Você não conhece a semente exclusivamente, apenas a conhece (o que geralmente é bom, pois (0 <semente <m) de qualquer maneira) se v1 - b for negativo, você precisará adicionar m's até ser positivo novamente.

Você também pode olhar para o Teorema do restante chinês, embora não seja uma correspondência exata.

Não sei qual é o seu nível de proficiência em montagem ou se você tem acesso ao código -fonte / símbolos de depuração para o aplicativo não gerenciado, mas fora desse tipo de truque, não há uma maneira viável de determinar o valor original da semente. O ponto principal dos geradores de números aleatórios é encontrar uma maneira de fornecer números imprevisíveis - o relacionamento entre duas chamadas dadas para Rand () não deve ser dedutível. Em geradores de números aleatórios criptograficamente fortes, seria considerado uma falha séria para adivinhar a semente com base em um número aleatório gerado.

A maneira mais fácil de fazer isso seria iniciar o aplicativo sob um depurador e definir um ponto de interrupção onde srand() é chamado - basta olhar para o parâmetro aprovado.

Em seguida, seria desmontar o aplicativo e descobrir as circunstâncias da chamada SRAND. É perfeitamente possível que esteja sendo semeado com a hora atual - então você pode tentar um monte de suposições (provavelmente pode reduzi -lo a alguns milhares) e ver se algum dê a mesma sequência de números aleatórios que o aplicativo está usando . (É claro que isso pressupõe que você tenha alguma maneira de saber quais são os valores aleatórios gerados). Também é possível que a semente seja algo idiota como '0' o tempo todo.

Teoricamente, não - o valor da semente é usado para calcular o próximo valor aleatório e esse valor é (teoricamente) usado para semear o próximo número aleatório e assim por diante.

Em termos de segurança, ser capaz de espiar a semente (seja a original ou uma nova) é um sério problema de segurança, por isso espero que você não consiga examiná -la, mesmo que deva ser armazenado em algum lugar.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top