Aller au menu - Aller au contenu
Inscris-toi au e-camp "Héberge ton jeu Facebook sur Azure" de Microsoft vendredi 25 mai à 13h30 !

[gcc] Re-arrangement de la pile

Pour accéder à cette section
Connectez-vous !
connexion_rpx
Page 1 
Auteur Message
1 visiteur sur ce sujet (1 Anonyme)
Page 1 
Hors ligne Kurapix # Posté le 20/02/2009 à 09:44:09
Avatar

Salut les zéros!

Actuellement, j'expérimente avec gcc et gdb afin d'étudier plus en profondeur les éventuels problêmes que peuvent amener des buffers overflows, off-by-one et autre.
Je fais cette démarche dans un but purement éducatif. En effet, je pense que le meilleur moyen de fiabiliser, de sécuriser, ...... son application, c'est de connaître les dangers que peuvent amener les erreurs de programmation qui peuvent paraître banal pour le non initié.

Dans cette quête éducative, je m'aperçois évidemment que gcc intègre des mécanismes de protection tel que la protection de la pile avec StackGuard et autres (depuis la 2.95 apparemment).
J'ai donc décider de désactiver ces protections pour approfondir mon étude.
Malheureusement, je me rends compte que gcc re-ordonne la pile.

Exemple sans re-arrangement de la pile :

Un code tel que :

Code : C
1
2
3
4
5
6
7
void proc (int a)
{
     char buffer[256];
     int i;

     // code
}


Donnerait une pile comme suit :
Code : Console
-------------------    |       ^
|        a        |    |       |
-------------------    |       |
|       ret       |    |       |
-------------------    |       |
|       sfp       |    |       |
-------------------    |       |
|   buffer[255]   |    |       |
-------------------    |       |
|   buffer[254]   |    |       |
-------------------    |       |
|     ......      |    |       |
-------------------    |       |
|   buffer[0]     |    |       |
-------------------    |       |
|      i          |    |       |
-------------------    |       |
                       V       |
                     PUSH     POP


Alors que le code suivant :

Code : C
1
2
3
4
5
6
7
void proc (int a)
{
     int i;
     char buffer[256];

     // code
}


donnerait la pile suivante :
Code : Console
-------------------    |       ^
|        a        |    |       |
-------------------    |       |
|       ret       |    |       |
-------------------    |       |
|       sfp       |    |       |
-------------------    |       |
|        i        |    |       |
-------------------    |       |
|   buffer[255]   |    |       |
-------------------    |       |
|     ......      |    |       |
-------------------    |       |
|   buffer[0]     |    |       |
-------------------    |       |
                       V       |
                     PUSH     POP


"Le problême" est qu'avec le re-arrangement de la pile par gcc, les deux codes donnent la deuxième pile (ceci est mis en place afin de protéger les variables importantes un minimum).

La commande utilisée pour compiler le code est la suivante :
Code : Console
$ gcc -o vuln main.c -fno-stack-protector -mpreferred-stack-boundary=2


L'option -fno-stack-protector permet de désactiver certaines protections de la pile (StackGuard notament) mais pas toutes. L'option -fno-stack-protector-all n'a plus l'air de fonctionner dans les dernières versions de gcc (4.3.x).
L'option -mpreferred-stack-boundary permet de supprimer le padding que GCC ajoute (à quoi peut servir ce padding à part pour aligner les adresses?).

La question est donc la suivante :
Comment désactiver cette protection de GCC?
Y-a-t'il d'autres protection que GCC intègre si oui lesquel? et comment les désactiver?

Par ailleurs, une des documentation dans laquelle j'ai dû chercher mais pas trouver la solution à mon problême :
Gcc Option Summary
Je vous remerci d'avance pour vos réponses.

Cordialement,

kurapix

P.S. : Je vous pris de poster en prenant en compte la charte du site, je n'aimerais pas voir ce sujet fort intéressant être dévié de son but initial : étude éducative et non illégale.

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 
Publicité # Posté le 20/02/2009 à 09:44:09

Hors ligne ok # Posté le 20/02/2009 à 10:46:03
#!/bin/sh
Avatar

Études : CNAM

Citation : Kurapix
Par ailleurs, une des documentation dans laquelle j'ai dû chercher mais pas trouver la solution à mon problême :
Gcc Option Summary
Je vous remerci d'avance pour vos réponses.

Bah déjà merci pour cette doc, je ne connaissais pas. Après pour ton problème c'est autre chose :waw: ...
Édité le 20/02/2009 à 10:46:21 par ok

OS utilisés couramment : CentOS, Fedora, Suse, Kubuntu, Windows
Langages utilisés : C, Java, PHP, JS, xHTML/CSS, Bash, SQL, PL/PgSQL, Perl
SGBD utilisés : PostgreSQL, MySQL
Méthodes d'analyse et langages de conception connus : Merise, UML
=> Liens : InfosLinux (mon site) | Exercices Bash (dvp.com)
 
Hors ligne Kurapix # Posté le 20/02/2009 à 20:03:10
Avatar

Aucun soucis pour la doc.

Merci pour la réponse quand même.

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 
Hors ligne dap # Posté le 20/02/2009 à 21:19:09
Script kiddie
Avatar

Bonjour,

Je ne trouve pas -fno-stack-protector dans la documentation la plus récente (http://gcc.gnu.org/onlinedocs/gcc-4.3. [...] imize-Options). Apparemment le lien que tu as donné est pour la version en cours de développement.

Chez moi ce programme

Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
#include <stdio.h>

static void proc (int a);

int
main (void)
{
  proc(0);

  return 0;
}

static void
proc (int a)
{
  volatile int i;
  volatile char buffer[256];

  printf("%p\n%p\n%p\n", (void*)&a, (void*)&i, (void*)buffer);
}


En compilant sans option particulière :
Code : Console
0xbfb51b10
0xbfb51b04
0xbfb51a04


Avec tes options :
Code : Console
0xbf941114
0xbf941108
0xbf941008


Ça me semble normal (si je sais encore compter en hexadécimal). J'utilise GCC 4.3.3.

Citation : Kurapix
L'option -mpreferred-stack-boundary permet de supprimer le padding que GCC ajoute (à quoi peut servir ce padding à part pour aligner les adresses?).


C'est un mystère... Personnellement je préfère ne pas toucher à la tambouille interne du compilateur avec des options comme ça.

:wq
 
Hors ligne Kurapix # Posté le 21/02/2009 à 00:29:26
Avatar

Je te remerci de ta réponse dap.

Effectivement c'est bizarre ... chez toi il n'y a aucun problême de re-arrangement de la pile.

Sans l'option -mpreferred-stack-boundary j'ai du padding qui s'ajoute (et ce n'est pas du padding d'alignement).

Je vais continuer à regarder ça ... c'est surement lié à ma distribution (je me demande s'ils ont patché gcc ... bizarre).
Pour info, je suis sous arch linux.

kurapix

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 
Hors ligne dap # Posté le 21/02/2009 à 00:31:09
Script kiddie
Avatar

Citation : Kurapix
Pour info, je suis sous arch linux.


Moi aussi. :)

:wq
 
Hors ligne Kurapix # Posté le 22/02/2009 à 01:15:15
Avatar

Tiens bizarre ... j'ai toujours le problême de re-arrangement de la pile (gdb me le confirme bien ...).

Le code testé :
Code : C
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
#include <stdio.h>
#define BUFFER_SIZE 256

void func1 (char *str)
{
    char buffer[BUFFER_SIZE];
    size_t i;    

    for(i = 0; i <= BUFFER_SIZE; i++)
        buffer[i] = str[i];
}

int main(int argc, char** argv)
{
    // check args
    if (argc < 2)
    {
        printf("Usage : %s string\n", argv[0]);
        exit(-1);
    }

    func1 (argv[1]);

    return 0;
}


Commande de compilation :
Code : Console
$ gcc -o prog main.c -g -fno-stack-protector -mpreferred-stack-boundary=2


Le code qui nous intéresse se trouve évidemment dans func1 (le nom de la fonction a été choisie de manière arbitraire exprès).
La pile devrait donner ceci sans re-arrangement :
Code : Console
---------------------    |    ^
|        str        |    |    |
---------------------    |    |
|        ret        |    |    |
---------------------    |    |
|        sfp        |    |    |
---------------------    |    |
|    buffer[255]    |    |    |
---------------------    |    |
|       ...         |    |    |
---------------------    |    |
|     buffer[0]     |    |    |
---------------------    |    |
|        i          |    |    |
---------------------    V    |
                       PUSH  POP


Mais gcc ré-arrange la pile comme ceci :
Code : Console
---------------------    |    ^
|        str        |    |    |
---------------------    |    |
|        ret        |    |    |
---------------------    |    |
|        sfp        |    |    |
---------------------    |    |
|         i         |    |    |
---------------------    |    |
|    buffer[255]    |    |    |
---------------------    |    |
|       ...         |    |    |
---------------------    |    |
|     buffer[0]     |    |    |
---------------------    V    |
                       PUSH  POP


La pile se comporte ainsi dans les schémas précédents :
- Plus on va vers le bas de la pile et plus on va vers les adresses mémoires hautes
- Plus on va vers le haut de la pile et plus on va vers les adresses mémoires basses


Voilà la preuve sous GDB :
Code : Console
$ gdb prog
GNU gdb 6.8
Copyright (C) 2008 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law.  Type "show copying"
and "show warranty" for details.
This GDB was configured as "i686-pc-linux-gnu"...
(gdb) break func1 
Breakpoint 1 at 0x8048500: file main.c, line 9.
(gdb) r
Starting program: /home/kurapix/devel/study/bugs/prog 

Breakpoint 1, func1 (str=0xbfd47190 '\220' <repeats 200 times>...) at main.c:9
9            for(i = 0; i <= BUFFER_SIZE; i++)
(gdb) print &buffer
$1 = (char (*)[256]) 0xbfd47070
(gdb) print &i
$2 = (size_t *) 0xbfd47170
(gdb) print $ebp
$3 = (void *) 0xbfd47174
(gdb) print $esp
$4 = (void *) 0xbfd47070


Voilà l'analyse :
(gdb) print &buffer
$1 = (char (*)[256]) 0xbfd47070
(gdb) print &i
$2 = (size_t *) 0xbfd47170


On voit donc que i se trouve en dessous de buffer[255] et donc au dessus de sfp (comme la deuxième pile ...).

Et pour ebp et esp (le bas et le haut de la pile :
(gdb) print $ebp
$3 = (void *) 0xbfd47174
(gdb) print $esp
$4 = (void *) 0xbfd47070


On voit que ebp pointe au dessus de i, c'est-à-dire sur sfp :
Code : Console
(gdb) x/x 0xbfd47174
0xbfd47174:        0xbfd4739c
(gdb) x/x 0xbfd47178
0xbfd47178:        0x08048633


On a donc : *ebp == 0xbfd47174
et : *(ebp+4) == return address

Ce qui correspond exactement à notre deuxième pile.

On vérifie qu'il n'y a pas de padding :
ebp - esp = 0xbfd47174 0xbfd47070 = 0x104 = 260 octets (256 octets du buffer + 4 octets de i)


Mon analyse met ainsi en évidence ceci :
- Ré-arrangement de la pile par gcc
- Pas de padding ajouté par gcc



Si quelqu'un a une idée pour résoudre ce "problême" de re-arrangement de la stack, je suis preneur.

Je vous remercie d'avance pour vos réponses.

kurapix
Édité le 22/02/2009 à 01:19:22 par Kurapix

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 
Connecté minirop # Posté le 22/02/2009 à 01:24:54
I can't face the Dark w/o you!
Avatar
Groupe : Anciens

Ville : Reims
Pays : France métropolitaine
Études : SUPINFO China à Tianjin

et tu as testé les autres options contenant "stack" ?
dans le lien que tu as donné il y a "-fconserve-stack"

Mes figurines :pirate: - Mes Manga - vive la contrefaçon \o/ - lecteur audio en console - Bot IRC fait avec Qt - Envoyez des formulaires HTML avec Qt
"O Zozor, Zozor! wherefore art thou Zozor? Deny thy father and refuse thy name; Or, if thou wilt not, be but sworn my love, And I'll no longer be a Zero."
"To conquer thee and thy blood for glore, Art thou my afeared and reluctant whore."
 
Hors ligne Kurapix # Posté le 22/02/2009 à 02:08:04
Avatar

:)

Citation : Gcc Options Summary
-fconserve-stack
Attempt to minimize stack usage. The compiler will attempt to use less stack space, even if that makes the program slower. This option implies setting the large-stack-frame parameter to 100 and the large-stack-frame-growth parameter to 400.


Donc en gros ça ne sert qu'à minimiser l'utilisation de la pile ... donc non ça ne résoud en rien mon problême ><.
Édité le 22/02/2009 à 02:08:38 par Kurapix

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 
Hors ligne Kurapix # Posté le 23/02/2009 à 00:00:42
Avatar

Décidemment ... même problême sous Ubuntu ...

-fno-stack-protector est pourtant censer désactiver le support ProPolice pour l'exécutable actuellement à compiler ...
Si quelqu'un avait une idée ..... je suis toujours preneur.
Ma version de gcc sous Ubuntu est la 4.3.2.
Je vais tester des versions ultérieures pour voir ce que ça donne .... mais j'aimerais beaucoup pourvoir résoudre ce problême avec les versions récentes de gcc.

Je vous remerci d'avance pour vos réponses.

kurapix

Image utilisateur
Rejet de la loi HADOPI

;) La puissance n'est rien sans maîtrise.
-----------------------------------------------------------------------
[GCC] Re-arrangement de la pile
[Bash] Script d'installation de C::B a partir des sources.
[ASM][ARM][GBA] Procédure hline : tracé d'une ligne horizontale
srand(), rand() ... gné?

-----------------------------------------------------------------------

To follow the path:
look to the master,
follow the master,
walk with the master,
see through the master,
become the master.
 

Retour au forum "Langage C" ou à la liste des forums

Pour accéder à cette section
Connectez-vous !
connexion_rpx