2013-02-25 2 views
-2
#include <conio.h> 
#include <windows.h> 
#include <stdio.h> 

int main() 
{ 
char input[255]; 
int i = 0; 
for(;;i++) /* Infinite loop, exited when RETURN is pressed */ 
{ 
    char temp; 
    temp = getch(); /* Get the current character of the password */ 
    if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */ 
    { 
     input[i]='\0'; 
     break; 
    } 
    input[i] = temp; 
    printf("*"); /* Print a star */ 
} 
//printf("%s",input); 
if(strcmp(input,"kamal")==0) 
{ 
        printf("ACCEPTED"); 
        } 
        else 
        printf("not"); 
_getch(); 
return EXIT_SUCCESS; /* Program was executed successfully */ 
} 

Это мой код. Как я могу предотвратить переполнение буфера, если я буду вводить пароль больше, тогда моя программа выйдет из строя. есть ли в любом случае я могу решить эту проблему?Как предотвратить маскирование паролей из bufferoverflow

+2

Вам нужно остановить бесконечную петлю в разумной точке. – Paul

+1

* «Если я буду вводить пароль больше, тогда моя программа выйдет из строя» * Это не английский ... Не могли бы вы прояснить причину сбоев, так как это не совсем понятно? В противном случае вам будет сложно больше – Veger

+0

, если у меня больше персонажа, чем 255, он сбой, и это делает мою программу уязвимой. –

ответ

2

Локальный вход переменной символ [255] хранится в стеке. Границы в массиве нет. Проблема заключается в том, что при добавлении более 255 символов значение другой переменной, хранящейся в стеке, может измениться. Это может привести к сбою.

одно решение прочитать символы и назначать только входной массив, если диапазон (я) меньше 255.

#include <conio.h> 
#include <windows.h> 
#include <stdio.h> 

int main() 
{ 
    char input[255]; 
    int i = 0; 
    int flag = 0; 
    for(;;i++) /* Infinite loop, exited when RETURN is pressed */ 
    { 
     char temp; 
     temp = getch(); /* Get the current character of the password */ 
     if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */ 
     { 
      input[i]='\0'; 
      break; 
     } 
     if (i< 255) 
     { 
      input[i] = temp; 
     } 
     else  
     { 
      flag = 1; 
     } 

     printf("*"); /* Print a star */ 
} 
//printf("%s",input); 
if(strcmp(input,"kamal")==0 && flag == 0) 
{ 
     printf("ACCEPTED"); 
} 
else 
     printf("not"); 
getch(); 
return EXIT_SUCCESS; /* Program was executed successfully */ 
} 

Другим решением является динамически выделять (перераспределить()) размер входного массива.

+0

oh, что хорошо, любые другие изменения, которые я должен сделать в своем коде? –

+0

@KamalKafkaesque Я думаю, что этот код будет в порядке для вас – Rajesh

+0

есть одна проблема, когда я нажимаю клавишу backspace, она обрабатывает ее как ключ, она не удаляет последний caharacter –

1

Всегда проверяйте границы. Всегда проверяйте значение i относительно длины буфера.

+0

вы можете быть более конкретным пожалуйста. –

0

Try упаковка что-то вроде:

if(i<255) { 
    ... 
} 

... вокруг вашего процесса сбора символов.

- РЕДАКТИРОВАТЬ -

#include <conio.h> 
#include <windows.h> 
#include <stdio.h> 

int main() 
{ 
char input[255]; 
int i = 0; 
for(;;i++) /* Infinite loop, exited when RETURN is pressed */ 
{ 
    if(i < 255) 
    { 
     char temp; 
     temp = getch(); /* Get the current character of the password */ 
     if (GetAsyncKeyState (VK_RETURN)) /* If the user has pressed return */ 
     { 
      input[i]='\0'; 
      break; 
     } 
     input[i] = temp; 
     printf("*"); /* Print a star */ 
    } 
} 
//printf("%s",input); 
if(strcmp(input,"kamal")==0) 
{ 
        printf("ACCEPTED"); 
        } 
        else 
        printf("not"); 
_getch(); 
return EXIT_SUCCESS; /* Program was executed successfully */ 
} 
+0

не понял –

+0

Я отредактировал сообщение, чтобы развернуть то, что я впервые разместил. – Paul

+0

Вы проверили этот код? Что произойдет, если вы попытаетесь ввести более 255 символов? zzzap. Неопределенное поведение. – Sebivor

0

Как вы укажете, программа прерывается, если пользователь предоставляет более 255 символов.

Итак, вы должны проверить количество символов, которые уже были предоставлены, если он достигает максимума (вашего буфера), вы должны прекратить захватывать больше ключей (поскольку пароль уже не прав, на самом деле это не имеет значения .. .):

#define BUFFER_MAX 255 

// +1 so we can always add the 0-terminator 
char input[BUFFER_MAX + 1]; 
do { 
    char temp; 
    temp = getch(); /* Get the current character of the password */ 
    // Check if char does fit in the buffer 
    if(i < BUFFER_MAX) { 
     // add to buffer 
     input[i] = temp; 
     i++; 
    } 
    printf("*"); /* Print a star */ 
    // Check if the user pressed return 
} while(GetAsyncKeyState (VK_RETURN) == false); 
input[i]='\0'; 

Примечание: Я также изменил свой цикл, как это «некрасиво» (плохая практика и ненужный в данном случае), чтобы использовать бесконечные циклы и нарушение из них ...

+0

Привет, Вегер, Могу ли я предоставить окончательный общий код, это было бы очень заметно. –

+0

Ну ... просто поставьте его в свою основную функцию и сохраните часть проверки пароля! (О ... и поместите макрос ('# define') за пределы основной функции ...) – Veger

+0

компилятор имеет ошибку в строке while (GetAsyncKeyState (VK_RETURN) == false); говоря, что false не определено, сначала определите его. –

1

в некоторых случаев, допустимо расширять буфер. Это редко бывает идеальным, поскольку неограниченное расширение может вызвать другие проблемы.

В других случаях допустимо усечение ввода. Это может быть вариант здесь, но это тоже не идеально.

В этом случае, поскольку вы сравниваете строку, которая не изменяется, вы можете пропустить этап «сохранить вход в массив» и сравнить входные данные, полученные по байтам, с паролем , Такой код должен выглядеть примерно так, хотя остерегайтесь, как это непроверенная:

char password[] = "kamal"; 
size_t position = 0; 
char c = getch(); 
while (password[position] != '\0' || strchr("\r\n", (unsigned char) c) == NULL) { 
    if (c != password[position++] || position == sizeof password) { 
     // Password mismatch. Discard the rest of the password, then tell the user... 
     while (strchr("\r\n", (unsigned char) c) == NULL) { 
      c = getch(); 
     } 
     position = 0; 
     puts("Invalid password. Please retry."); 
    } 
    c = getch(); 
} 

... Если нет буфера переполнения, то, что вас беспокоит?

+0

i am little noob in c, так что, пожалуйста, дайте мне полный код этого, потому что я не могу понять, где разместить этот код. –

+0

Если вам нужно задать мне полное решение, то метод, который вы используете для обучения, очевидно, не работает для вас. Вы считали книгу? – Sebivor

+0

нет, я не имею, могу ли вы порекомендовать мне один? –

Смежные вопросы