💡
tecnologie3
  • Tecnologie
  • Codifica numeri
    • Conversione dei numeri con parte frazionaria
    • Esercizi numeri
  • Numeri interi e linguaggio C
  • La rappresentazione dei simboli alfanumerici
  • Funzione di conversione da alfanumerici a numerici - esempi in C
  • Codifica immagini e unità misura
  • Segnali, dall'analogico al digitale
  • Rappresentazione dei suoni
  • Rappresentazioni delle informazioni complesse
  • Riepilogo codifiche
  • ARCHITETTURA COMPUTER
    • Architettura generale
    • Memoria principale
    • Il processore
    • La memoria secondaria (di massa)
    • Periferiche (dispositivi) e loro controllo/1
    • Periferiche (dispositivi) e loro controllo/2
    • Esempio di Architettura Computer - Macchina von Neumann
    • I concetti chiave
    • Esercizi
  • Sistema Operativo
    • Il sistema operativo
    • Gestione dei processi
    • Gestione della memoria
    • I Gestori di Periferiche
    • Il modello di sicurezza di Unix/Linux
  • Esercitazione gestione processi
  • Esercitazione memoria
    • Svolgimento
    • Progetto calcolatore indirizzi fisici
  • Corso Linux base
    • Lavorare con testo: more, grep
    • Utilizzo pipe
    • Lavorare con il comando find
  • Tecnologie 2
  • Operating Systems: Three Easy Pieces
  • Computing for the Socio-Techno Web
  • Software libero ed istruzione
Powered by GitBook
On this page
  • Overflow di lunghezza
  • Esempio conseguenze
  • Arithmetic overflows

Was this helpful?

Numeri interi e linguaggio C

PreviousEsercizi numeriNextLa rappresentazione dei simboli alfanumerici

Last updated 4 years ago

Was this helpful?

Analizziamo il problema dell'overflow con alcuni esempi di programmi in C.

Da:

Overflow di lunghezza

Un overflow di un intero può essere dovuto al tentativo di immagazzinare un valore in una variabile che è troppo piccola per poterlo contenere. L'esempio più semplice può essere visto dalla semplice assegnamento del contenuto di una variabile grande a una più piccola:

    /* ex1.c - loss of precision */
    #include <stdio.h>

    int main(void){
            int l;
            short s;
            char c;

            l = 0xdeadbeef;
            s = l;
            c = l;

            printf("l = 0x%x (%d bits)\n", l, sizeof(l) * 8);
            printf("s = 0x%x (%d bits)\n", s, sizeof(s) * 8);
            printf("c = 0x%x (%d bits)\n", c, sizeof(c) * 8);

            return 0;
    }
    /* EOF */
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./ex1
l = 0xdeadbeef (32 bits)
s = 0xffffbeef (16 bits)
c = 0xffffffef (8 bits)
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$

Esempio conseguenze

    /* width1.c - exploiting a trivial widthness bug */
    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>

    int main(int argc, char *argv[]){
            unsigned short s;
            int i;
            char buf[80];

            if(argc < 3){
                    return -1;
            }

            i = atoi(argv[1]);
            s = i;

            if(s >= 80){            /* [w1] */
                    printf("Oh no you don't!\n");
                    return -1;
            }

            printf("s = %d\n", s);

            memcpy(buf, argv[2], i);
            buf[i] = '\0';
            printf("%s\n", buf);

            return 0;
    }
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./width1 6 ciao
s = 6
ciao
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ 
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./width1 80 ciao
Oh no you don't!
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./width1 65536 ciao
s = 0
Segmentation fault (core dumped)
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$

Arithmetic overflows

Come mostrato negli esempi precedenti, se viene fatto un tentativo di immagazzinare un valore intero che è più grande che il massimo valore che la variabile può contenere, il valore verrà troncato. Se il valore immagazzinato è il risultato di un'operazione aritmatica, qualsisi parte del programma che in seguito utilizzerà il risultato, sarà incorretto.

Sotto un esempio:

    /* ex2.c - an integer overflow */
    #include <stdio.h>

    int main(void){
            unsigned int num = 0xffffffff;

            printf("num is %d bits long\n", sizeof(num) * 8);
            printf("num = 0x%x\n", num);
            printf("num + 1 = 0x%x\n", num + 1);

            return 0;
    }
    /* EOF */
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./ex2
num is 32 bits long
num = 0xffffffff
num + 1 = 0x0
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$

Poichè un inero è signed di default, un overflow di un intero può causare un cambiamento nel segno che può avere significativi impatti nel codice che segue.

Vediamo questo esempio:

    /* ex3.c - change of signedness */
    #include <stdio.h>

    int main(void){
            int l;

            l = 0x7fffffff;

            printf("l = %d (0x%x)\n", l, l);
            printf("l + 1 = %d (0x%x)\n", l + 1 , l + 1);

            return 0;
    }
    /* EOF */
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./ex3
l = 2147483647 (0x7fffffff)
l + 1 = -2147483648 (0x80000000)
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$

L'addizione non è la sola operazione aritmetica che può causare l'overflow di un indice. Quasi ogni operazione che causa il cambiamento del valore di una variabile può provocare un overflow.

Vediamo qui sotto un esempio:

    /* ex4.c - various arithmetic overflows */
    #include <stdio.h>

    int main(void){
            int l, x;

            l = 0x40000000;

            printf("l = %d (0x%x)\n", l, l);

            x = l + 0xc0000000;
            printf("l + 0xc0000000 = %d (0x%x)\n", x, x);

            x = l * 0x4;
            printf("l * 0x4 = %d (0x%x)\n", x, x);

            x = l - 0xffffffff;
            printf("l - 0xffffffff = %d (0x%x)\n", x, x);

            return 0;
    }
    /* EOF */
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$ ./ex4
l = 1073741824 (0x40000000)
l + 0xc0000000 = 0 (0x0)
l * 0x4 = 0 (0x0)
l - 0xffffffff = 1073741825 (0x40000001)
massimo@massimo-VirtualBox:~/workspace/BasicIntegerOverflow$

http://phrack.org/issues/60/10.html
LogoGitHub - checksound/BasicIntegerOverflowExamplesGitHub