能力值:
( LV13,RANK:1760 )
|
-
-
2 楼
用stricmp_s吧...
|
能力值:
( LV3,RANK:20 )
|
-
-
3 楼
如果只是普通的字符串操作,不需要去管'\0',毕竟strcat,cpy啥的自己加上。
但是如果像有些字符串操作函数,你需要从尾部找起,又不能动用strlen(比如数据内有\0),就最好memset(buf, 0, len)一下,
把楼主发的内容又看了一遍,感觉。。
我是不是答非所问或者。。
和strcmp有关系么,strcmp遇到0结束
|
能力值:
( LV2,RANK:10 )
|
-
-
4 楼
建议用带_s字符串安全函数和StrSafe.h中的函数
|
能力值:
( LV12,RANK:320 )
|
-
-
5 楼
如果你是写驱动程序的话 批你批的狠对
|
能力值:
( LV2,RANK:10 )
|
-
-
6 楼
_stricmp是遇到结尾的0才停止的,UNICODE_STRING的Buffer不一定以0结尾。
因此如果Buffer里的字符一致但结尾后面的字符不一致,就认为不一致了,更坑爹的是万一结尾后面的字符也一致而且还都不是0,就一直比较下去,直到遇到不可访问的地址,就只能蓝了。
|
能力值:
( LV2,RANK:10 )
|
-
-
7 楼
我都是用strnicmp
|
能力值:
( LV2,RANK:10 )
|
-
-
8 楼
驱动中其实不应该用这些c函数
|
能力值:
( LV3,RANK:30 )
|
-
-
9 楼
正好看到了 《Windows核心编程 第五版》 第二章,应该可以解释一下这个问题,
原始的C字符串函数不需要传入缓冲区大小,所以可能会造成缓冲区溢出
所以推荐使用的是StrSafe.h 中包含的后缀为_s的函数。
书中原话 → “所有安全(后缀为_s)函数的首要任务就是验证传给它们的参数值,要检查的项目包括指针不为NULL,整数在有效范围内,枚举值是有效的,而且缓冲区足以容纳结果数据。”
|
能力值:
( LV8,RANK:130 )
|
-
-
10 楼
在vc中建议千万别用带_s的函数,要不然,你会死得很惨的
比如strcpy_s在允许截断的情况下,无论你是debug还是release版本,一但截断,就弹出错误框,接着程序报异常,
建议使用winapi ,lstrcpy,lstrcat一类带l的
|
能力值:
( LV3,RANK:30 )
|
-
-
11 楼
弹出错误框应该就是说明已经超出了设定的缓冲区大小,strcpy_s 在字符串被截断的情况下,errno_t不会返回STRUNCATE, 而是返回ERANGE,缓冲区第一个字符会被设置为\0
这应该就算是对缓冲区溢出的检测吧
|
能力值:
( LV2,RANK:10 )
|
-
-
12 楼
不是有Rtl系列函数吗
|
能力值:
( LV8,RANK:130 )
|
-
-
13 楼
对是缓冲区溢出检测 ,
我是讲,不只是弹窗口的问题,弹窗口是小事,可是他会让程序异常,无论如何,在正式发布的产品中,即使软件出错,出现逻辑性错误,只要不影响业务,不能让程序异常,程序异常,会带来灾难性的后果。
健壮的程序,首先得要求不报异常,不至于停止工作,尤其是在发布版本的服务器程序中,软件异常,是个非常麻烦的事情,在某此情况下,明明允许字符串被截断,但是使用_s函数,会让你的软件异常,有违你的设计目的。
要不,你试试在你的产品中使用带_s的函数,看你会被批不?
比如下面一个情景:
比如在服务器登陆程序,你得检查用户名吧,你不能强制要求客户端传过来的用户名长度必须小于某个值,(如果你告诉我,你强硬要求客户端传过来的用户名长度小于某值,所以我的情景不适用,那么我将告诉你,你的程序不强壮,黑客不会按你的要求来做,他会将用户名长度超出你的值,所以我假设的情况是存在的。)
如果你在服务器端使用strlen来取字符串长度,对大于某值的字符串,进行丢弃,那么我将告诉你,黑客会传一个没有0结尾的字符串,那么你的程序一样会出问题。所以我假设的情况依然存在。
如果在这个时候,你取用户名的时候,使用了strcpy_s,那么我将告诉你,你的程序可以挂了,将会停止 工作,因为我会传入一个比你的缓冲区大的字符串。
要不你试试看?
当然你可以说,你在协议中规定了字符串长度,如果长度大于缓冲区, 多出部分,直接丢弃,那么我告诉你,这道理 与lstrcpyn是一个道理 ,
lstrcpyn是是复制字符串,直到达到缓冲区长度-1位置时,退出。
而你的做法是先比较字符串长度与缓冲区长度的关系,再作出跳转分支处理。两者没有本质区别。
而我将会告诉你,你这样的做法与strcpy_s没关系,
所以,就本贴所讨论的问题,我认为我可以总结如下:
1.千万别用strcpy_s安全函数,因为他一点也不安全,为什么不安全,不得而知了,或者是需要开启某个所我不知道的隐藏宏。
2.替代函数可以使用winapi,带l开头,n结束的函数,比如lstrcpyn
|
能力值:
( LV8,RANK:130 )
|
-
-
14 楼
别迷信书中内容了,请看我的回复,或者你自己做验证,带_s的函数一点也不安全,至少对于vc库函数不太了解的人,一点不安全。
|
能力值:
( LV3,RANK:30 )
|
-
-
15 楼
感谢讲解,我明白你的意思,在软件使用中因这个函数的异常导致程序终止确实是需要避免的,因为我对C/C++实际使用的经验很少,常用的是C# ,所以我当时看到这个函数在出错时会报异常,我个人想到的是像C#里面那样使用try catch语句来进行处理,这样我即可以通过异常明确程序发生了什么,又不会导致程序终止,我知道C/C++中也有try catch(也只是知道,从没用过...),所以刚才想试试看能不能通过try catch处理来避免程序终止,但是我发现我虚拟机里的VC没有strsafe.h
有机会的话我会试验一下的,感谢您的指导
对了,还有我想说其实我不算迷信书,因为书上对这个说的很清楚,也包括了这个函数在调试模式下会弹出一个Debug Assertion Failed,而在release下直接终止应用程序的执行,只是因为想到在C#下的对应方法,所以并没有认为这是不可取的
|
能力值:
( LV8,RANK:130 )
|
-
-
16 楼
直接终止程序,本来就是一个极大的错误
|
能力值:
( LV2,RANK:10 )
|
-
-
17 楼
你对*_s安全函数的理解有误啊,它不是让你的代码可以无异常的运行,而是让错误立即暴露,让你修改程序.它在万一你忘了检查或者截断数据的情况下,告诉你"黑,这里有问题".通过迫使你修改程序,从根本过上提高安全性,而不是默默代替你处理一切,毕竟_s函数不会知道这里的数据是否可以截断.
|
能力值:
( LV12,RANK:760 )
|
-
-
18 楼
使用RtlEqualString
或者RtlEqualUnicodeString
格式化必须用ntstrsafe.h里的才行,不是的话,很多会被批的~
先用RtlStringCbCopyNW来复制到数组,再wcsicmp也可以不挨批~但是不如RtlEqualUnicodeString
|
能力值:
( LV4,RANK:50 )
|
-
-
19 楼
只有你自己处理的字符串,只要自己确保没问题,用啥函数都可以,但你要处理别人或系统过来的字符串的时候,就需要用安全的函数,否则可能会挂。
|
|
|