首页
社区
课程
招聘
[求助]用_stricmp被批了
发表于: 2014-6-10 13:58 11280

[求助]用_stricmp被批了

2014-6-10 13:58
11280
说这个有风险的,尤其在底层做字符判断的
谁能帮我普及一下\0

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

收藏
免费 0
支持
分享
最新回复 (18)
雪    币: 2664
活跃值: (3401)
能力值: ( LV13,RANK:1760 )
在线值:
发帖
回帖
粉丝
2
用stricmp_s吧...
2014-6-10 14:02
0
雪    币: 80
活跃值: (109)
能力值: ( LV3,RANK:20 )
在线值:
发帖
回帖
粉丝
3
如果只是普通的字符串操作,不需要去管'\0',毕竟strcat,cpy啥的自己加上。
但是如果像有些字符串操作函数,你需要从尾部找起,又不能动用strlen(比如数据内有\0),就最好memset(buf, 0, len)一下,
把楼主发的内容又看了一遍,感觉。。

我是不是答非所问或者。。
和strcmp有关系么,strcmp遇到0结束
2014-6-10 14:04
0
雪    币: 243
活跃值: (209)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
建议用带_s字符串安全函数和StrSafe.h中的函数
2014-6-10 14:18
0
雪    币: 596
活跃值: (449)
能力值: ( LV12,RANK:320 )
在线值:
发帖
回帖
粉丝
5
如果你是写驱动程序的话 批你批的狠对
2014-6-10 14:56
0
雪    币: 1443
活跃值: (101)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
6
_stricmp是遇到结尾的0才停止的,UNICODE_STRING的Buffer不一定以0结尾。
因此如果Buffer里的字符一致但结尾后面的字符不一致,就认为不一致了,更坑爹的是万一结尾后面的字符也一致而且还都不是0,就一直比较下去,直到遇到不可访问的地址,就只能蓝了。
2014-6-10 23:18
0
雪    币: 1234
活跃值: (302)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
7
我都是用strnicmp
2014-6-10 23:25
0
雪    币: 952
活跃值: (1821)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
8
驱动中其实不应该用这些c函数
2014-6-11 07:49
0
雪    币: 134
活跃值: (11)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
9
正好看到了 《Windows核心编程 第五版》 第二章,应该可以解释一下这个问题,

原始的C字符串函数不需要传入缓冲区大小,所以可能会造成缓冲区溢出

所以推荐使用的是StrSafe.h 中包含的后缀为_s的函数。
书中原话  → “所有安全(后缀为_s)函数的首要任务就是验证传给它们的参数值,要检查的项目包括指针不为NULL,整数在有效范围内,枚举值是有效的,而且缓冲区足以容纳结果数据。”
2014-6-11 15:03
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
10
在vc中建议千万别用带_s的函数,要不然,你会死得很惨的
比如strcpy_s在允许截断的情况下,无论你是debug还是release版本,一但截断,就弹出错误框,接着程序报异常,
建议使用winapi ,lstrcpy,lstrcat一类带l的
2014-6-11 15:07
0
雪    币: 134
活跃值: (11)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
11
弹出错误框应该就是说明已经超出了设定的缓冲区大小,strcpy_s 在字符串被截断的情况下,errno_t不会返回STRUNCATE, 而是返回ERANGE,缓冲区第一个字符会被设置为\0

这应该就算是对缓冲区溢出的检测吧
2014-6-11 15:40
0
雪    币: 19
活跃值: (1086)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
12
不是有Rtl系列函数吗
2014-6-11 15:48
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
13
对是缓冲区溢出检测 ,
我是讲,不只是弹窗口的问题,弹窗口是小事,可是他会让程序异常,无论如何,在正式发布的产品中,即使软件出错,出现逻辑性错误,只要不影响业务,不能让程序异常,程序异常,会带来灾难性的后果。
健壮的程序,首先得要求不报异常,不至于停止工作,尤其是在发布版本的服务器程序中,软件异常,是个非常麻烦的事情,在某此情况下,明明允许字符串被截断,但是使用_s函数,会让你的软件异常,有违你的设计目的。
要不,你试试在你的产品中使用带_s的函数,看你会被批不?

比如下面一个情景:
比如在服务器登陆程序,你得检查用户名吧,你不能强制要求客户端传过来的用户名长度必须小于某个值,(如果你告诉我,你强硬要求客户端传过来的用户名长度小于某值,所以我的情景不适用,那么我将告诉你,你的程序不强壮,黑客不会按你的要求来做,他会将用户名长度超出你的值,所以我假设的情况是存在的。)

如果你在服务器端使用strlen来取字符串长度,对大于某值的字符串,进行丢弃,那么我将告诉你,黑客会传一个没有0结尾的字符串,那么你的程序一样会出问题。所以我假设的情况依然存在。

如果在这个时候,你取用户名的时候,使用了strcpy_s,那么我将告诉你,你的程序可以挂了,将会停止 工作,因为我会传入一个比你的缓冲区大的字符串。

要不你试试看?
当然你可以说,你在协议中规定了字符串长度,如果长度大于缓冲区, 多出部分,直接丢弃,那么我告诉你,这道理 与lstrcpyn是一个道理 ,
lstrcpyn是是复制字符串,直到达到缓冲区长度-1位置时,退出。
而你的做法是先比较字符串长度与缓冲区长度的关系,再作出跳转分支处理。两者没有本质区别。
而我将会告诉你,你这样的做法与strcpy_s没关系,

所以,就本贴所讨论的问题,我认为我可以总结如下:
1.千万别用strcpy_s安全函数,因为他一点也不安全,为什么不安全,不得而知了,或者是需要开启某个所我不知道的隐藏宏。

2.替代函数可以使用winapi,带l开头,n结束的函数,比如lstrcpyn
2014-6-12 10:30
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
14
别迷信书中内容了,请看我的回复,或者你自己做验证,带_s的函数一点也不安全,至少对于vc库函数不太了解的人,一点不安全。
2014-6-12 10:33
0
雪    币: 134
活跃值: (11)
能力值: ( LV3,RANK:30 )
在线值:
发帖
回帖
粉丝
15
感谢讲解,我明白你的意思,在软件使用中因这个函数的异常导致程序终止确实是需要避免的,因为我对C/C++实际使用的经验很少,常用的是C# ,所以我当时看到这个函数在出错时会报异常,我个人想到的是像C#里面那样使用try catch语句来进行处理,这样我即可以通过异常明确程序发生了什么,又不会导致程序终止,我知道C/C++中也有try catch(也只是知道,从没用过...),所以刚才想试试看能不能通过try catch处理来避免程序终止,但是我发现我虚拟机里的VC没有strsafe.h

有机会的话我会试验一下的,感谢您的指导

对了,还有我想说其实我不算迷信书,因为书上对这个说的很清楚,也包括了这个函数在调试模式下会弹出一个Debug Assertion Failed,而在release下直接终止应用程序的执行,只是因为想到在C#下的对应方法,所以并没有认为这是不可取的
2014-6-12 14:50
0
雪    币: 239
活跃值: (190)
能力值: ( LV8,RANK:130 )
在线值:
发帖
回帖
粉丝
16
直接终止程序,本来就是一个极大的错误
2014-6-12 20:31
0
雪    币: 49
活跃值: (11)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
17
你对*_s安全函数的理解有误啊,它不是让你的代码可以无异常的运行,而是让错误立即暴露,让你修改程序.它在万一你忘了检查或者截断数据的情况下,告诉你"黑,这里有问题".通过迫使你修改程序,从根本过上提高安全性,而不是默默代替你处理一切,毕竟_s函数不会知道这里的数据是否可以截断.
2014-6-13 00:13
0
雪    币: 8835
活跃值: (2404)
能力值: ( LV12,RANK:760 )
在线值:
发帖
回帖
粉丝
18
使用RtlEqualString
或者RtlEqualUnicodeString

格式化必须用ntstrsafe.h里的才行,不是的话,很多会被批的~

先用RtlStringCbCopyNW来复制到数组,再wcsicmp也可以不挨批~但是不如RtlEqualUnicodeString
2014-6-16 00:08
0
雪    币: 405
活跃值: (2295)
能力值: ( LV4,RANK:50 )
在线值:
发帖
回帖
粉丝
19
只有你自己处理的字符串,只要自己确保没问题,用啥函数都可以,但你要处理别人或系统过来的字符串的时候,就需要用安全的函数,否则可能会挂。
2014-6-17 11:43
0
游客
登录 | 注册 方可回帖
返回
//