科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道基础软件体验Visual C++ 2005的现代语言特性

体验Visual C++ 2005的现代语言特性

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

当年Visual Studio.NET 2003 C++编译器的面世,令无数C++语言爱好者都对此垂涎不已。

作者:谢启东编译 来源:天极开发 2007年11月16日

关键字:

  • 评论
  • 分享微博
  • 分享邮件
可靠的安全

  在2002年,Bill Gates宣布进行的可信赖计算,已对微软公司开发的所有产品带来了深刻的影响。Windows操作系统的开发者花了数月的时间来进行安全方面的训练及代码重审,带来的结果就是,Windows Server 2003成了该公司有史以来发布的最安全的操作系统。Microsoft Office 2003也包含了许多的安全功能,像IRM(Information Rights Management)、加强的宏安全、Outlook中阻止下载HTML等等。而Visual C++ 2005编译器的开发者,在此方面也取得了长足的进步,使编译器及它们生成的代码都更加安全。

  Visual Studio .NET 2002在编译器中引入了一个缓冲区安全检查选项/GS,如果编译器认为某些函数可能导致缓冲区溢出攻击,那么此选项可在函数的返回地址之前,在堆栈上分配一定的空间,并在函数入口处,把一个带有已知数值的安全cookie放在此缓冲区中,而在函数退出时,会检查此cookie是否已被损坏,cookie值的改变表示对返回地址,有潜在的改写(overwrite),此时会产生一个错误,并终止程序。当然,这不能防止所有类型的溢出攻击。

  Visual Studio .NET 2003扩展了/GS选项,通过把本地变量在堆栈上排序,以便数组可在比本地变量更高地址的内存中分配空间,从而防止本地变量超出限度。此方法能防止vtable劫持和其他指针攻击。


图5:老式 /GS

  而Visual C++ 2005在此基础上又更进了一步,通常当有函数调用发生时,函数激活运行时的结构就如图5所示,如果其中的一个本地缓冲区超出限度了,攻击者可能改写堆栈中在此之上的任何东西,包括例外处理、安全cookie、帧指针、返回地址和函数参数。而这些值的大多数被不同的机制所保护(如安全例外处理),但对一个有函数指针作参数的函数来说,仍有机会被溢出。如果一个函数接受一个函数指针(或结构、类中包含有函数指针)作为参数,攻击者就有可能改写指针中的值,使代码执行任何他想要的函数。鉴于此,Visual C++ 2005编译器分析所有可能存在此漏洞的函数参数,并把函数激活时的结构如插8所示排列,此时复制了一份函数参数——并不使用原有的函数参数,并把它们放在堆栈中本地变量之下。如果原有函数参数被溢出改写了,只要副本中的值仍保持不变,整个函数就不会被攻破。

  
图6:新式 /GS

  为遵循“默认安全”的可信赖计算,Visual C++ 2005编译器是默认打开缓冲区安全检查选项,这可保证通过Visual C++编译的软件产品更加安全。事实上,微软已经用此选项重新构建了包括Windows、Office、SQL Server在内的所有产品。

  有关Visual C++ 2005另一方面大的改进,就是使代码在编写时,安全思想就始终贯彻其中。绝大多数的应用程序依赖C运行时库(CRT)和标准模板库(STL),而这些库最初在设计时,代码安全并不是处在一个重要的位置,现今常用的很多攻击方法当时并不为人所知,结果,这些库中的多数函数,经常处于一种不安全的使用方法中,为潜在的攻击打开了方便之门。

  在Visual C++ 2005中,微软引入了这些库的新版本。在新版本里,这些库已被基于所有的函数都会导致常见的安全问题这一认识而重写,并提供了一些函数可供替换的更安全的版本,对此的长期目标是以这些更健壮的副本来逐步取代它们所有“不安全”的版本。仅在新版本的CRT中,就引入了超过400个新的“安全”函数,并确保所有的指针参数都检查是否带有空值(NULL),所有进行内存复制操作的函数,包括源和目的地址,都明确带有需复制的字节数。

  结论

  Visual C++ 2005带来了许多激动人心的功能,如:对混合映像的CLR延迟加载、本地AppDomain API、新的declspecs对AppDomains和进程的全局变量可提供更好的支持、模块构造函数、对obj文件和 .NET模块的链接器支持、隐式装箱(boxing)、(C#的开发者可能会喜欢的相同的)XML注释语法、针对 .NET Framework的STL的新版本、param数组、别名提示、新的浮点模式、操作符重载等等;在此难以一一叙述,但相信每一种新的功能,都会给大家带来不同的编程体验。

  任何基于 .NET Framework的语言新版本经常会引起这样的疑问:“如果编写 .NET平台程序,那我的开发小组该用哪种语言?”今天,如果你经常有一些本地interop操作,答案就简单了,C++是可用作本地interop操作最容易的语言,而且还最有效率。另外,如果你想移植一个现有的C++程序到 .NET平台,实际上,除了Visual C++,没有更好的路可选,同时,在把现有应用程序移植到 .NET平台上时,这也是微软最推荐的方法。

  对开发新的应用程序来说,你可能会问,在选择基于 .NET的语言时,为什么开发者会显得茫然和不知所措,对此,没有一个直截了当的答案,因为每种语言都有它的长处,但对纯 .NET程序来说,C#、Visual Basic、C++的体验是相同的。作为一个开发者,如果你已经习惯了一种特定的语言,没有必要换到另一种去。
 
  也许你会选择C++,不管怎样,在进行任何interop操作时,因为直接内置了对interop的大量支持,所以C++的体验比其他任何一种语言都要好。另外,除了避免资源泄漏和保证程序的正确性,析构函数提供的确定性清理没有任何价值。同时,C++也有一些强大的功能,可与上述CLR提供的功能组合使用,例如,C++不只是支持模板和泛型,而且支持两者结合起来使用,这样,可比单独使用其中一者的功能更强大,也更具表现力;特别地,一个实用的编写库文件的技巧是,编写一个模板,并实现一个泛型接口,这样得到的模板不但功能强大,而且具有高度可伸缩性,如模板特定化,这样其他语言也可直接使用通过模板泛型接口实例化的对象。总而言之,C++绝非浪得虚名,终于站在了它应该站的位置上。

查看本文来源

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章