Ненулевое значение, приводящее к тому, что StrCmp возвращает 0? - PullRequest
0 голосов
/ 23 ноября 2018

У меня есть следующий код:

_Bool grantAccess(char *password){
    char goodPassWord[]= "goodpass";
    return (0 == strcmp(password, goodPassWord));

}

_Bool grantAccessExercise(void){
    char password[9];
    int allow = 0;

    printf("Please enter password: ");

    gets(password); 

    if (grantAccess(password)) {
         allow = 1;
    }

    return (allow != 0);
    }

Когда я ввожу любую комбинацию из 10 символов для пароля, она переполняется и перезаписывает нулевой терминатор.Может кто-нибудь объяснить, почему значение, не заканчивающееся нулем, заставляет StrCmp возвращать 0?

Ответы [ 2 ]

0 голосов
/ 23 ноября 2018

Дальнейшее уточнение: что вы наблюдаете здесь, это stack corruption.Если вы введете достаточно длинную строку в качестве пароля, вы даже получите stack smashing.Вы можете поиграть с массивом password разных размеров, что может привести к переупорядочению вещей в стеке.Хорошее объяснение разрушения стека или переполнения буфера стека приведено здесь .

Вы также можете изменить свой код для выделения массива password в куче, используя malloc.Вы можете получить, казалось бы, работающий код, поскольку в большинстве областей памяти при увеличении в некоторый момент очень вероятно будет 0, что интерпретируется как терминатор NULL.Это было бы намного более коварным поведением, поскольку ваша grantAccess функция может показаться работать правильно.

0 голосов
/ 23 ноября 2018

Кто-нибудь может объяснить, почему значение, не заканчивающееся нулем, заставляет StrCmp возвращать 0?

Это не то, что происходит.

Что происходит:

  • переполнение буфера при password перезаписывает байты, которые являются частью расположенной в стеке переменной allow
  • , в результате allow больше не содержит значение ноль, но некоторыедругое значение.
  • вызов grantAccess () возвращает false, а allow не изменяется.
  • в конце, allow содержит ненулевое значение из-за переполнения.

Чтобы убедиться в этом, я сделал тест следующим образом:

  • Я ввел пароль "0123456789"
  • Я заметил, что allow == 57, что является кодом ASCII символа '9'.
...