导致 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
函数可能 似乎 可以正常工作。
我有以下代码:
_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
函数可能 似乎 可以正常工作。