2017-07-26 7 views
4

Je lis sur le fonctionnement des exploits, et il semble que beaucoup d'entre eux fonctionnent en écrasant l'adresse de retour sur la pile. Beaucoup d'efforts ont été déployés pour rendre cela plus difficile (Canaries de pile, ASLR, DEP, etc), mais il me semble qu'il serait plus facile pour les fabricants de matériel d'ajouter un registre, accessible uniquement par les instructions call et ret, cela tiendrait l'adresse de retour. De cette façon, l'adresse de retour n'a pas pu être écrasée par un dépassement de tampon par définition. Parce que call et ret sont toujours présents et fonctionnent toujours comme dans les processeurs d'aujourd'hui (la seule différence est où ils stockent l'adresse de retour), il me semble qu'il n'y aurait pas trop de problèmes de compatibilité. Et puisque vous utilisez un registre au lieu de RAM pour accéder à l'adresse, l'impact sur les performances serait probablement positif (quoique insignifiant).Utiliser un registre séparé pour stocker l'adresse de retour?

Intel dispose apparemment de l'espace nécessaire pour allouer plus de registres à des fins de sécurité, puisque MPX est implémenté malgré le besoin de deux registres supplémentaires. Alors pourquoi ne pas ajouter un registre spécial pour stocker l'adresse de retour?

+0

Ce n'est pas une idée totalement malsaine, j'ai lu à ce sujet quelque part (malheureusement, je ne me souviens pas où). L'éléphant dans la pièce est que nous avons besoin d'une structure de pile pour permettre des appels de fonction arbitrairement imbriqués. Une pile call/ret séparée (c'est l'idée dont je parlais précédemment) semble plus robuste. Les problèmes de compatibilité sont inévitables, certains outils dépendent de la façon dont la pile est remplie pendant les appels de fonction, mais je crois que nous pouvons nous permettre (encore une autre) période de transition. –

+0

Alors, comment avez-vous résolu les appels imbriqués? (excepté le stockage de la valeur dans la mémoire, qui peut ensuite être manipulée par le code) – Ped7g

+1

L'avantage de performance d'avoir une adresse de retour sur puce peut être atteint par un [cache d'adresse de retour] (https: //priorart.ip. com/IPCOM/000108056) pour prédire le résultat de l'instruction RET. –

Répondre

2

Cela existe déjà un peu. Je sais que trois architectures et une langue avec des fonctionnalités telles que:

  • SPARC a quelque chose appelé register windows où le fond de la CPU sauvegarde et restaure les registres une fonction d'appel/retour. Par convention, l'adresse de retour est stockée dans le registre o7 lors de l'appel de fonction, qui est ensuite tourné vers i7 lorsque l'appelé établit sa trame de pile. Lorsque l'appelé appelle une autre fonction, cette adresse est retournée dans la pile de registre interne, intouchable par un code dangereux.
  • Le MMIX de Knuth a une conception similaire, mais l'adresse de retour est stockée directement dans la pile de registres la plus inaccessible de l'appel de fonction, donc à peu près ce que vous voulez. ARM et ARM64 ont juste un registre de lien . Lors d'un appel de fonction, l'adresse de retour est stockée dans le registre de liaison, une fonction de retour est simplement un saut indirect vers l'adresse dans le registre de liaison. Cela ne fait pas vraiment ce que vous voulez car le contenu du registre de liens doit être stocké dans la pile dans les appels de fonction imbriqués, en détruisant sa sécurité supplémentaire dans tout sauf les fonctions feuille (c'est-à-dire les fonctions qui n'appellent aucune autre fonction).
  • Le langage de programmation Forth a par définition une pile pour les valeurs et une pile séparée pour les adresses de retour. Les deux piles peuvent être manipulées librement par les programmes, mais vous devez faire attention lorsque vous manipulez la pile de retour. En pratique, ceci est implémenté en utilisant un des registres de l'architecture pour la pile de retour et un pour la pile de données. Cela résout également le problème que vous avez mentionné, mais un programmeur suffisamment intelligent peut encore gâcher en permettant une mauvaise entrée pour écraser la pile de retour.
+0

La fenêtre d'enregistrement n'est qu'une caractéristique matérielle qui entrave la mise en pipeline matérielle ainsi qu'une meilleure optimisation du compilateur ... ce n'est pas la fonctionnalité que vous recherchez. Ils sont un défaut avec lequel Sparc doit vivre. – cb88

+0

@ cb88 Comment entravent-ils le pipelining? – fuz

+0

A l'origine, ils ont été mis en place parce que les compilateurs étaient trop bêtes pour programmer le chargement/stockage des instructions, mais cela a changé et les fenêtres d'enregistrement sont plus lentes et moins efficaces qu'un bon compilateur. pipelines beaucoup plus complexe et augmente les chances de stalles et ou de bulles en fonction de la façon dont il est mis en œuvre ... aucun autre transformateurs les faire ces jours-ci pour une bonne raison. Et Sparc ne le fait que parce qu'ils le doivent parce que c'est dans le Spec. – cb88