2010-08-14 20 views
8

Je lis Piratage: L'art de l'exploitation (2e édition), et je suis actuellement sur la section sur les débordements de tampon.Pourquoi la variable int ne viendra-t-elle pas avant le tableau char en termes d'adressage, peu importe comment je le code en C?

Dans le premier exemple, les variables sont déclarées/initialisés dans cet ordre:

int auth_flag = 0; 
char password_buffer[16]; 

L'exemple explique ensuite que vous pouvez utiliser gdb pour examiner les adresses de auth_flag et password_buffer, et vous Notez que l'adresse de auth_flag est supérieure à password_buffer. Choses à garder à l'esprit: Je cours tout cela dans Ubuntu dans Virtualbox sur un Macbook Pro (processeur Intel, 64 bits).

Je compilé le code du premier exemple comme ceci: gcc -g -fno-stack-protector -o auth_overflow auth_overflow.c

Comme prévu, auth_flag 's adresse est supérieure à password_buffer' s.

Pour remédier au problème présenté ci-dessus, l'auteur vous explique devez changer l'ordre des déclarations:

char password_buffer[16]; 
int auth_flag = 0; 

Je compilé le code de la même manière: gcc -g -fno-stack-protector -o auth_overflow2 auth_overflow2.c

Malheureusement, je ne l'ai pas vu auth_flag L'adresse de l'abonné est inférieure à password_buffer. En fait, c'était encore plus élevé. Pourquoi est-ce? Qu'est-ce que je fais mal?

+6

Le compilateur aura tendance à organiser les variables dans l'ordre des exigences d'alignement décroissantes pour minimiser le remplissage. Cela dit, il est étrange que le «int» soit toujours plus élevé et pas toujours inférieur.Quoi qu'il en soit, vous ne pouvez pas compter sur l'ordre de déclaration pour faire la moindre différence, donc c'est un point étrange pour le livre. Bravo pour l'exécution de l'expérience et de trouver la BS. – Potatoswatter

+0

Aussi, bienvenue à SO et +1 pour le libellé éloquent. – Potatoswatter

+3

Je me demande pourquoi Potatoswatter n'a pas posté son commentaire comme réponse ... –

Répondre

1

Les compilateurs sont libres de réorganiser les variables comme ils le jugent le meilleur. Je crois que la seule restriction dans l'ordre des membres struct. Ceux-ci doivent être en mémoire dans le même ordre que déclaré dans la structure.

5

Le compilateur est autorisé à choisir l'ordre qu'il veut, afin de fournir un code plus optimal, ou même simplement aléatoire car il est plus facile à implémenter. Une chose que vous pouvez essayer est -O0 drapeau qui désactive toutes les optimisations.

0

Apple a une fonction de sécurité pour éviter tout type de vous piratage parle de - Il y a un certain degré de randomisation à l'endroit où tout est stocké en mémoire, de sorte que vous ne pouvez pas par exemple trouver la mémoire allouée pour un certain programme, et aller à la 1502e par te où se trouve la fonction d'ouverture des verrous de coffre haute sécurité, car elle n'est pas toujours au même endroit en mémoire.

Voir http://en.wikipedia.org/wiki/Address_space_layout_randomization pour les détails sur comment cela fonctionne.

Funny coïncidence que vous rencontreriez ceci, et que Matt Joiner trébucherait sur la réponse en essayant de brûler la pomme.

+0

A la réflexion ... avez-vous dit qu'Ubuntu est l'OS actif? Je pourrais avoir complètement tort si c'est le cas. –

+3

Tout d'abord, l'OP a dit qu'il exécute l'expérience dans une machine virtuelle Ubuntu. Deuxièmement, Ubuntu a ASLR activé aussi. Et troisièmement, ASLR randomise la base de la pile, mais ne randomise pas les positions relatives de deux variables de pile. – caf