2015-02-26 1 views
0
void display(const char *path) 
{ 
    char msg[128]; 
    int8_t size; 
    memset(msg, 0, 128); 

    FILE *file = fopen(path, "r"); 
    size_t n = fread(&size, 1, 1, file); 
    if (n == 0 || size > 128) 
    return; 
    n = fread(msg, 1, size, file); 

    puts(msg); 
} 


int main(int argc, char *argv[]) 
{ 
    if (argc != 2) 
    return 1; 

    display(argv[1]); 
    return 0; 
} 

Comment faire pour que ce tampon déborde? Je veux dire, le tampon est de 128 octets. Mais le code ne vérifie-t-il pas si la taille est supérieure à 128? Si c'est le cas, alors il retournera juste au début, et sinon, il copiera seulement moins de 128 octets du fichier au msg?Comment faire pour que ce tampon déborde?

Répondre

0

int8_t size; est une valeur signée de 8 bits, donc elle se situe dans la plage [-128,127].

Lorsque ce code est exécuté:

size_t n = fread(&size, 1, 1, file); 
    if (n == 0 || size > 128) 
    return; 

Si la taille a est bit le plus significatif (qui est la taille est> = 0x80), alors il est traité a un nombre négatif, échappant/évitant ainsi le contrôle . Supposons que le code lit la taille avec une valeur de 0x8F (c'est 143 en décimal), mais comme le type int8_t a une taille de 8 bits et une plage de valeurs de [-128,127], le bit le plus significatif est mis à "1". et indique une valeur signée, ce qui signifie que la valeur est -113.

Ainsi size est inférieur à 128 en (n == 0 || size > 128) simplement parce que -113 > 128 est faux.

Ce qui signifie que le code lira plus d'octets que la taille du tableau. Il lira 143 octets mais la taille du tableau est seulement 128, déclenchant ainsi un débordement de tampon basé sur la pile.