导致 StrCmp 为 return 0 的非 Null 终止值?

Non Null-terminated value causing StrCmp to return 0?

我有以下代码:

_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 为 return 0?

Can anyone explain why the non null-terminated value causes StrCmp to return 0?

事实并非如此。

发生的事情是:

  • 超过 password 的缓冲区溢出覆盖了属于堆栈定位变量 allow
  • 的字节
  • 因此,allow 不再包含值零,而是包含其他值。
  • 对 grantAccess() 的调用 returns false,并且 allow 未修改。
  • 最后,allow 包含由于溢出导致的非零值。

为了验证这一点,我做了如下测试:

  • 我输入密码“0123456789”
  • 我观察到allow == 57,这是字符'9'的ASCII码。

进一步说明:您在这里观察到的是stack corruption。如果您输入足够长的字符串作为密码,您甚至会得到 stack smashing。您可以尝试为 password 数组提供不同的大小,这可能会导致堆栈上的内容重新排序。 stack smashing or stack buffer overflow is here.

很好的解释

您还可以更改代码以使用 malloc 在堆上分配 password 数组。您可能会得到看似有效的代码,因为大多数内存位置在递增时很可能在某个时候包含 0,它被解释为 NULL 终止符。这将是一种更加阴险的行为,因为您的 grantAccess 函数可能 似乎 可以正常工作。