非以Null结尾的值导致StrCmp返回0?

时间:2018-11-23 12:43:32

标签: c buffer-overflow strcmp

我有以下代码:

_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个字符的任意组合作为密码时,它将溢出并覆盖空终止符。谁能解释为什么非null值导致StrCmp返回0?

2 个答案:

答案 0 :(得分:4)

  

谁能解释为什么非null终止值导致StrCmp返回0?

这不会发生。

会发生什么:

  • ^\d*\w$上的缓冲区溢出将覆盖属于堆栈定位变量password的字节
  • 结果,allow不再包含零值,而是其他值。
  • 对GrantAccess()的调用返回false,并且allow未被修改。
  • 最后,由于溢出,allow包含非零值。

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

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

答案 1 :(得分:0)

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

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