Memcpy()在安全编程中?

我最近偶然发现了一篇声称微软在其安全编程商店中禁止使用memcpy()函数的文章 。 我了解该function固有的漏洞,但是有必要完全禁止它的使用吗?

我写的程序应该完全避免使用memcpy() ,还是只是确保安全使用它? 有哪些替代品可以提供类似但更安全的function?

Microsoft提供了memcpy和wmemcpy的替代方法来validation其参数。

memcpy_s说,“嗯,在我从这个地址读取之前,让我自己validation它不是空指针;在我写入这个地址之前,我将再次执行该测试。我还将比较字节数我已被要求复制到所声称的目的地大小;当且仅当电话通过所有这些测试时,我才能执行复制。“

memcpy说“将目的地填入寄存器,将源填入寄存器,将计数填入寄存器,执行MOVSB或MOVSW。” (关于地理位置的例子,这个世界不长: http : //www.geocities.com/siliconvalley/park/3230/x86asm/asml1013.html )

编辑:对于memcpy的Your Wish Is My Command方法的例子,请考虑OpenSolaris,其中memcpy(对于某些配置) 是根据bcopy定义的 ,而bcopy (对于某些配置)是……

 void 33 bcopy(from, to, count) 34 #ifdef vax 35 unsigned char *from, *to; 36 int count; 37 { 38 39 asm(" movc3 12(ap),*4(ap),*8(ap)"); 40 } 41 #else 42 #ifdef u3b /* movblkb only works with register args */ 43 unsigned char *from, *to; 44 int count; 45 { 46 asm(" movblkb %r6, %r8, %r7"); 47 } 48 #else 49 unsigned char *from, *to; 50 int count; 51 { 52 while ((count--) > 0) 53 *to++ = *from++; 54 } 55 #endif 

编辑:谢谢,米莉史密斯! 以下是我在上面链接的地理位置页面上的内容:

MOVS

指令movs用于将源字符串复制到目标(是,复制,不移动)。 该指令有两个变体:movsb和movsw。 movsb(“移动字符串字节”)一次移动一个字节,而movsw一次移动两个字节。

由于我们希望一次移动几个字节,因此这些movs指令是使用rep前缀批量完成的。 移动次数由CX寄存器指定。 请参阅以下示例:

 : lds si, [src] les di, [dest] cld mov cx, 100 rep movsb : 

此示例将从src复制100个字节到dest。 如果用movsw替换movsb,则复制200个字节。 如果删除rep前缀,则CX寄存器将不起作用。 您将移动一个字节(如果它是movsb,或者如果它是movsw则移动2个字节)。

如果使用得当,电锯是安全的。 与memcpy()相同。 但在这两种情况下,如果你钉了一个钉子,它会飞,并伤害你。

简而言之,memcpy()是低级计算所必需的,不会消失,但对于高级编程,您不需要它。 Python中没有memcpy()。

不要打扰。 微软的替代方案并没有那么好。 主要价值在于这些导致您的代码无法移植到Linux。 与他们购买的Visual C ++副本相比,微软在向客户销售的操作系统上赚的钱要多得多。

文章本身描述了一个更安全的替代方法:memcpy_s,它要求您指定目标的最大长度。 如果提供的数字与要复制的字节数无关,则它可以作为防止缓冲区溢出的屏障。 当然,您可以通过向两者提供相同的数字来滥用它。

禁止在我的代码中使用memcpy()让我成为更好的程序员,我的应用程序更安全或更不兼容? 我不确定,如果MS真的想要改变任何东西,或者只是让任何新的C代码与其他编译器不兼容。 顺便说一句。 MS在很多function上都有这个技巧,而且很烦人。 strcpy – > strcpy_s – > StringCchCopy。

我认为C应该为程序员留下一个选择自己的脚。 如果操作正确,手动内存管理是安全的。

你自己说:“微软正在其安全的编程商店禁止memcpy()function,我理解该function固有漏洞 ,”

memcpy()和众多其他标准函数已知会导致漏洞,那么为什么安全的编程工作室允许在(虽然增量)改进微不足道时使用它们?

毫无疑问,在他们努力提高自己产品的安全性时,代码审查清楚地表明这些function是造成很大一部分漏洞,缓冲区溢出等的原因。而不是仅仅为内部使用包装,他们将它们引入标准库并为所有人的利益添加了编译器警告(不是禁令)。

另一种方法是调用memcpy_s

如果您使用的是旧版本(如C99或C ++ 98)或Solaris,则不能使用memcpy_s,除非您安装了Safe C库。

memcpy_s()是一种特定于Microsoft的实现,根据它们自己的标准,在C11之前的非MS实现(包括ANSI)上不存在。

我会把pro-MS和反MS的东西放在一边,因为它无关紧要。

memmove()无论如何都是一个更好的解决方案,因为它解决了重叠问题。 memmove_s()更强大,但同样,只有你在C11或更高版本。

您应该使用memcpy_s()代替。 对于被认为是不安全的各种其他function,存在相同类型的_s版本。