2015-11-26 1 views
1

Si certaines conditions ne sont pas remplies, je veux bloquer mon programme en sautant vers un emplacement aléatoire. Je veux également randomiser les registres par des déclarations commeEnregistrements aléatoires

asm("rdtsc \n"); 
asm ("movq %rax, %r15 \n"); 
... 
asm ("xor %rbp, %r13 \n"); 
... 

Existe-t-il une méthode meilleure/plus furtive pour le faire? Je suis préoccupé, car rdtsc n'est pas une déclaration fréquente dans les programmes. L'appeler continuellement génère des résultats similaires. À côté de cela, puis-je effacer/rendre aléatoire le contenu de la pile?

+2

Créez un code de déroulement de pile qui randomise les cadres de pile à chaque niveau ... –

Répondre

3

Si vous juste voulez planter, votre choix aléatoire de destination pourrait sauter quelque part légal. Exécutez simplement l'instruction ud2 (0F 0B), ce qui garantit une exception d'instruction non valide (aboutissant à SIGILL) sur tous les futurs processeurs x86. c'est-à-dire qu'il est réservé, donc aucune future extension d'ensemble d'instructions n'utilisera jamais cette séquence de deux octets au début d'une instruction. Si vous vous souciez de l'aléatoire de haute qualité pour contrecarrer tout backtrace potentiel ou core dump, appelez un générateur de nombres aléatoires pour remplir un tampon de données aléatoires (ou juste une valeur aléatoire de 32 bits que vous répétez). Remplissez tous les registres avec ces données de vidage. Dans le code 32 bits, vous pouvez utiliser une instruction popa pour remplir tous les registres avec ces données parasites. En mode 64 bits, vous devez les charger manuellement. Puis gribouillez sur la pile avec ces données, afin que votre programme s'arrête avec un segfault lorsque vous essayez d'écrire sur une adresse non mappée (parce que vous êtes sorti de la zone de pile).

Vous pourriez faire ce gribouillage avec un rep stosd ou quelque chose. Dans la mesure où "plus furtif", vous devrez être beaucoup plus élaboré sur ce que votre modèle de menace est, et ce que vous essayez d'empêcher quiconque d'apprendre/faire. c'est-à-dire défendre contre quelqu'un qui modifie votre binaire de ne pas s'écraser de cette façon?

1

En plus des suggestions de Peter Cordes, j'ajouterais que l'OP veut coder le code pour que cette obfuscation reste hors de portée (furtif). L'instruction causant l'accident doit être ailleurs, sinon le code d'obfuscation sera évident à partir d'un vidage sur incident et le code sera facile à corriger pour retirer la bombe.

Une solution est assez facile de localiser le RET opcode d'une fonction de bibliothèque commune tels que read ou strlen et sauter là-bas en poussant l'adresse sur la pile et exécuter une instruction RET. Cette solution n'est pas parfaite: il existe des débogueurs avancés qui stockent la trace d'exécution et pourront revenir en arrière vers l'obfuscator depuis l'emplacement de l'accident. Afin de vaincre cela, vous pouvez préférer entrer une boucle infinie au lieu de s'écraser, mais cette boucle peut être facilement trouvée et supprimée.

Vous pouvez également intégrer un code complexe dans votre application qui calcule pendant un certain temps en exécutant de nombreuses fonctions différentes de manière aléatoire et l'utiliser comme un pot de miel à partir de l'obfuscator.