переполнение буфера c (получает функцию) - PullRequest
0 голосов
/ 04 октября 2018

Существует следующий код, мне нужно вернуть уровень доступа, который меньше 0x30 и не равен 0 или 2:

int login() {
int accessLevel = 0xff;
char username[16];
char password[32];
printf("Username (max 15 characters): ");
gets(username);
printf("Password (max 31 characters): ");
gets(password);

if (!strcmp(username, "admin") && !strcmp(password, "{{ create_long_password() }}")) {
    accessLevel = 2;
} else if (!strcmp(username, "root") && !strcmp(password, "{{ create_long_password() }}")) {
    accessLevel = 0;
} else if (!strcmp(username, "artist") && !strcmp(password, "my-password-is-secret")) {
    accessLevel = 0x80;
}

return accessLevel;
}

Я ввел имя пользователя 16 'a', которое сбрасывает accessLevelв 0 (а затем добавил пробел, который устанавливает доступ к 20 и дает мне желаемый вывод).Но я бы ожидал, что буфер перезаписывает пароль, а не accessLevel, так как это «следующая память».Я полагаю, что я неправильно понимаю, как работает буфер, и хотел бы получить объяснение.Кроме того, почему 16-й символ сбрасывается на 0?

Заранее спасибо!

Ответы [ 2 ]

0 голосов
/ 04 октября 2018

Упорядочение локальных переменных в стеке (при условии, что равно стеку) не гарантируется в каком-либо конкретном порядке.Это во многом зависит от типов переменных и требуемого выравнивания каждой из них, и может меняться в зависимости от компилятора или настроек оптимизации.

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

0 голосов
/ 04 октября 2018

Strcmp будет соответствовать произвольному количеству символов, заданному первым экземпляром нулевого символа завершения.Все строковые литералы должны заканчиваться нулем с \ 0

Использование strncmp будет сравнивать только количество символов, указанное в аргументах

...