精华内容
下载资源
问答
  • 常见软件测试类型分类

    万次阅读 2018-09-20 09:48:05
    软件测试类型 1)回归测试 回归测试: (regression testing): 回归测试两类:用例回归和错误回归;用例回归是过一段时间以后再回头以前使用过的用例在重新进行测试,看看会重新发现问题。错误回归,就是在新...

    软件测试类型

    1)回归测试

    回归测试: (regression   testing): 回归测试有两类:用例回归和错误回归;用例回归是过一段时间以后再回头对以前使用过的用例在重新进行测试,看看会重新发现问题。错误回归,就是在新版本中,对以前版本中出现并修复的缺陷进行再次验证,并以缺陷为核心,对相关修改的部分进行测试的方法。

    2)黑盒测试

    已知产品的功能设计规格,可以进行测试证明每个实现了的功能是否符合要求。
     也叫功能测试,是把测试对象看作一个黑盒子。利用黑盒测试法进行动态测试时,需要测试软件产品的功能,不需测试软件产品的内部结构和处理过程。采用黑盒技术设计测试用例的方法有:等价类划分、边界值分析、错误推测、因果图和综合策略。 

    3)白盒测试

     

    已知产品的内部工作过程,可以通过测试证明每种内部操作是否符合设计规格要求,所有内部成分是否以经过检查。
      黑盒测试又叫功能测试或数据驱动测试。黑盒测试主要是为了发现以下几类错误:
      1、是否有不正确或遗漏的功能?
      2、在接口上,输入是否能正确的接受?能否输出正确的结果?
      3、是否有数据结构错误或外部信息(例如数据文件)访问错误?
      4、性能上是否能够满足要求?
      5、是否有初始化或终止性错误?
      白盒测试又称为结构测试或逻辑驱动测试。白盒测试主要是想对程序模块进行如下检查:
      1、对程序模块的所有独立的执行路径至少测试一遍。
      2、对所有的逻辑判定,取“真”与取“假”的两种情况都能至少测一遍。
      3、在循环的边界和运行的界限内执行循环体。
      4、测试内部数据结构的有效性,等等。

    Q: 黑盒测试和白盒测试各自的优点和缺点      

    黑盒测试的优点有:比较简单,不需要了解程序内部的代码及实现;与软件的内部实现无关;  从用户角度出发,能很容易的知道用户会用到哪些功能,会遇到哪些问题;基于软件开发文档,所以也能知道软件实现了文档中的哪些功能;在做软件自动化测试时较为方便。

    黑盒测试的缺点有:不可能覆盖所有的代码,覆盖率较低,大概只能达到总代码量的30%;自动化测试的复用性较低。

    白盒测试的优点有:帮助软件测试人员增大代码的覆盖率,提高代码的质量,发现代码中隐    藏的问题。

    白盒测试的缺点有:程序运行会有很多不同的路径,不可能测试所有的运行路径;测试基于代码,只能测试开发人员做的对不对,而不能知道设计的正确与否,可能会漏掉一些功能需求;系统庞大时,测试开销会非常大。

     

    4)单元测试(模块测试)

     

    是开发者编写的一小段代码,用于检验被测代码的一个很小的、很明确的功能是否正确。通常而言,一个单元测试是用于判断某个特定条件(或者场景)下某个特定函数的行为。
      单元测试是由程序员自己来完成,最终受益的也是程序员自己。可以这么说,程序员有责任编写功能代码,同时也就有责任为自己的代码编写单元测试。执行单元测试,就是为了证明这段代码的行为和我们期望的一致。
     内容包括 模块接口测试、局部数据结构测试、路径测试、错误处理测试、边界测试

      策略包括逻辑覆盖、循环覆盖、同行评审、桌前检查、代码走查、代码评审、景泰数据流分析

    Q: 单元测试策略

      单元测试策略主要有三种方式:

    1) 自顶向下的单元测试策略:从顶层调用的单元做成桩模块; 对第二层测试,使用上面已测试的单元做驱动模块; 依次类推,直到全部单元测试结束。(比孤立单元测试的成本高很多)

    2) 自底向上的单元测试策略:先对模块调用的最底层模块进行测试,模拟调用该模块的模块为驱动模块; 其次,对上一层模块进行单元测试,用已经被测试过的模块做桩模块,依次类推,直到全部单元测试结束。(比较合理的单元测试策略,但测试周期较长)

    3) 孤立测试的单元测试策略:无需考虑每个模块与其他模块之间的关系,分别为每个模块单独设计桩模块和驱动模块,逐一完成所有单元模块的测试。(最好的单元测试策略)

     

    Q: 单元测试主要内容

     

    单元测试大多数由开发人员来完成,测试人员技术背景较好或者开发系统软件时可能会安排测试人员进行单元测试,大多数进行的单元测试都是开发人员调试程序或者开发组系统联合调试的过程。讨论这个问题主要是扩充一下读者的视野。

    单元测试一般包括五个方面的测试:

    模块接口测试

    模块接口测试是单元测试的基础。只有在数据能正确流入、流出模块的前提下,其他测试才有意义。模块接口测试也是集成测试的重点,这里进行的测试主要是为后面打好基础。测试接口正确与否应该考虑下列因素:

    -输入的实际参数与形式参数的个数是否相同;

    -输入的实际参数与形式参数的属性是否匹配;

    -输入的实际参数与形式参数的量纲是否一致;

    -调用其他模块时所给实际参数的个数是否与被调模块的形参个数相同;

    -调用其他模块时所给实际参数的属性是否与被调模块的形参属性匹配;

    -调用其他模块时所给实际参数的量纲是否与被调模块的形参量纲一致;

    -调用预定义函数时所用参数的个数、属性和次序是否正确;

    -是否存在与当前入口点无关的参数引用;

    -是否修改了只读型参数;

    -对全程变量的定义各模块是否一致;

    -是否把某些约束作为参数传递。

    如果模块功能包括外部输入输出,还应该考虑下列因素:

    -文件属性是否正确;

    -OPEN/CLOSE语句是否正确;

    -格式说明与输入输出语句是否匹配;

    -缓冲区大小与记录长度是否匹配;

    -文件使用前是否已经打开;

    -是否处理了文件尾;

    -是否处理了输入/输出错误;

    -输出信息中是否有文字性错误。

    -局部数据结构测试;

    -边界条件测试;

    -模块中所有独立执行通路测试;

    局部数据结构测试

     

    检查局部数据结构是为了保证临时存储在模块内的数据在程序执行过程中完整、正确,局部功能是整个功能运行的基础。重点是一些函数是否正确执行,内部是否运行正确。局部数据结构往往是错误的根源,应仔细设计测试用例,力求发现下面几类错误:

    -不合适或不相容的类型说明;

    -变量无初值;

    -变量初始化或省缺值有错;

    -不正确的变量名(拼错或不正确地截断);

    -出现上溢、下溢和地址异常。

    边界条件测试

    边界条件测试是单元测试中最重要的一项任务。众所周知,软件经常在边界上失效,采用边界值分析技术,针对边界值及其左、右设计测试用例,很有可能发现新的错误。边界条件测试是一项基础测试,也是后面系统测试中的功能测试的重点,边界测试执行的较好,可以大大提高程序健壮性。

    模块中所有独立路径测试

    在模块中应对每一条独立执行路径进行测试,单元测试的基本任务是保证模块中每条语句至少执行一次。测试目的主要是为了发现因错误计算、不正确的比较和不适当的控制流造成的错误。具体做法就是程序员逐条调试语句。常见的错误包括:

    -误解或用错了算符优先级;

    -混合类型运算;

    -变量初值错;

    -精度不够;

    -表达式符号错。

    比较判断与控制流常常紧密相关,测试时注意下列错误:

    -不同数据类型的对象之间进行比较;

    -错误地使用逻辑运算符或优先级;

    -因计算机表示的局限性,期望理论上相等而实际上不相等的两个量相等;

    -比较运算或变量出错;

    -循环终止条件或不可能出现;

    -迭代发散时不能退出;

    -错误地修改了循环变量。

    模块的各条错误处理通路测试:程序在遇到异常情况时不应该退出,好的程序应能预见各种出错条件,并预设各种出错处理通路。如果用户不按照正常操作,程序就退出或者停止工作,实际上也是一种缺陷,因此单元测试要测试各种错误处理路径。一般这种测试着重检查下列问题:

    -输出的出错信息难以理解;

    -记录的错误与实际遇到的错误不相符;

    -在程序自定义的出错处理段运行之前,系统已介入;

    -异常处理不当;

    -错误陈述中未能提供足够的定位出错信息。

     

    5) 集成测试(组装测试,联合测试)

    是单元测试的逻辑扩展。它的最简单的形式是:两个已经测试过的单元组合成一个组件,并且测试它们之间的接口。从这一层意义上讲,组件是指多个单元的集成聚合。在现实方案中,许多单元组合成组件,而这些组件又聚合成程序的更大部分。方法是测试片段的组合,并最终扩展进程,将您的模块与其他组的模块一起测试。最后,将构成进程的所有模块一起测试。

    Q: 集成测试主要内容

     (1)在把各个模块连接起来的时候,穿越模块接口的数据是否会丢失;

     (2)一个模块的功能是否会对另一个模块的功能产生不利的影响;

     (3)各个子功能组合起来,能否达到预期要求的父功能;

     (4)全局数据结构是否有问题;

     (5)单个模块的误差累积起来,是否会放大,从而达到不能接受的程度。

    Q: 集成测试策略

    1大爆炸集成:属于非增值式集成的一种方法,也称为一次性组装或整体拼装。这种集成策略的做法就是把所有通过单元测试的模块一次性集成到一起进行测试,不考虑组件之间的互相依赖性及可能存在的风险适应于一个维护型项目或被测试系统较小)

    2三明治集成:一种混合增量式测试策略,综合了自顶向下和自底向上两种集成方法的优点,因此也属于基于功能分解的集成。这种方法桩和开发工作都比较小,但增加了定位缺陷的难度

    3自顶向下集成:就是按照系统层次结构图,以主程序模块为中心,自上而下按照深度优先或者广度优先策略,对各个模块一边组装一边进行测试。又可分为深度优先集成和广度优先集成两种方式。

    (适应于产品控制结构比较清晰和稳定;高层接口变化较小;底层接口未定义或经常可能被修改;产口控制组件具有较大的技术风险,需要尽早被验证;希望尽早能看到产品的系统功能行为。)

    4自底向上集成:从依赖性最小的底层模块开始,按照层次结构图,逐层向上集成,验证系统的稳定性。

    (适应于底层接口比较稳定;高层接口变化比较频繁;底层组件较早被完成。)

    5高频集成:高频集成测试是指同步于软件开发过程,每隔一段时间对开发团队的现有代码进行一次集成测试。

    6、分层集成、分布式集成、基于路径、功能、进度、风险、事件、使用等的集成等13种。

    基于进度的集成
         优点:具有较高的并行度;能够有效缩短项目的开发进度。
         缺点:桩和驱动工作量较大;有些接口测试不充分;有些测试重复和浪费。

     

    6) 系统测试

     

    是将经过测试的子系统装配成一个完整系统来测试。它是检验系统是否确实能提供系统方案说明书中指定功能的有效方法。(常见的联调测试)
    系统测试的目的是对最终软件系统进行全面的测试,确保最终软件系统满足产品需求并且遵循系统设计。
     

    6.1) 安全性测试

    属于软件测试的哪个阶段?并试阐述安全测试的概念和用以评判系统安全性性能的主要指标。

      是系统测试的一种类型,测试系统是否存在安全隐患和漏洞

      安全性测试就是要验证系统内的保护机制能否抵御入侵者的攻击。安全性测试的测试人员需要在测试活动中,撒气不同的入侵方式来攻击系统的安全机制,想尽一切办法来获取系统内的保密信息。

      系统安全性性能的指标:

    有效性:启动严格的安全性性能所花费的时间占启动整个系统所花费时间的比例。

    生存性:当错误发生时,系统对紧急操作的支持,对错误的补救措施以及恢复到正常操作的能力,即抗挫能力

    精确性:衡量系统安全性控制的精度指标,围绕所出现的错误数量、发生频率及其严重性判断

    反应时间出错时系统响应速度的快慢,一个安全性较强的系统要具备快速的反应速度。

    吞吐量用户和服务请求的峰值和平均值。

    Q: 软件的安全性应从哪几个方面去测试?

    (1) 用户认证机制:如数据证书、智能卡、双重认证、安全电子交易协议

    (2) 加密机制

    (3) 安全防护策略:如安全日志、入侵检测、隔离防护、漏洞扫描

    (4) 数据备份与恢复手段:存储设备、存储优化、存储保护、存储管理

    (5) 防病毒系统

     

    6.2) 恢复性测试

    属于软件测试的哪个阶段?并试阐述恢复性测试的概念和进行恢复性测试分析时主要应考虑的问题。

    恢复性测试使系统测试阶段的一种方法,也叫容错测试,用来检查系统的容错能力。通常若计算机系统出现错误,就必须在一定时间内从错误中恢复过来,修正错误并重新启动系统。在进行恢复性测试时,要考虑的主要问题有:恢复期间的安全性过程。恢复处理日志方面的能力。当出现供电问题时的恢复能力。恢复操作后系统性能是否下降。  常用的恢复测试用例的设计方法:规范导出法、错误猜测法、基于故障的测试。

    Q: 单元测试、集成测试、系统测试的侧重点是什么? 
      单元测试针对的是软件设计的最小单元--程序模块(面向过程中是函数、过程;面向对象中是类。), 进行正确性检验的测试工作, 在于发现每个程序模块内部可能存在的差错. 一般有两个步骤: 人工静态检查\动态执行跟踪 
     
    集成测试针对的是通过了单元测试的各个模块所集成起来的组件进行检验,其主要内容是各个单元模块之间的接口,以及各个模块集成后所实现的功能
     
    系统测试针对的是集成好的软件系统,作为整个计算机系统的一个元素,与计算机硬件\外设\某些支持软件\数据和人员等其他系统元素结合在一起,要在实际的运行环境中,对计算机系统进行一系列的集成测试和确认测试.
    1)集成测试的主要依据概要设计说明书,系统测试的主要依据是需求设计说明书

    2)集成测试是系统模块的测试,系统测试是对整个系统的测试,包括相关的软硬件平台、网络以及相关外设的测试。

     

    7) 验收测试

    是部署软件之前的最后一个测试操作。验收测试的目的是确保软件准备就绪,并且可以让最终用户将其用于执行软件的既定功能和任务。
    验收测试是向未来的用户表明系统能够像预定要求那样工作。经集成测试后,已经按照设计把所有的模块组装成一个完整的软件系统,接口错误也已经基本排除了,接着就应该进一步验证软件的有效性,这就是验收测试的任务,即软件的功能和性能如同用户所合理期待的那样。

      包括正式验收测试、alpha测试、beta测试三种测试。

    7.1) Beta testing (β测试)

    测试是软件的多个用户在一个或多个用户的实际使用环境下进行的测试。开发者通常不在测试现场
     

    7.2)Alpha testing (α测试)

     

    是由一个用户开发环境下进行的测试,也可以是公司内部的用户在模拟实际操作环境下进行的受控测试

     

    8) 兼容性测试

     

    也称“Configuration testing(配置测试)”,测试软件是否和系统的其它与之交互的元素之间兼容,如:浏览器、操作系统、硬件等。验证测试对象在不同的软件和硬件配置中的运行情况。兼容测试主要是检查软件在不同的硬件平台、软件平台上是否可以正常的运行,即是通常说的软件的可移植性

    兼容的类型,如果细分的话,有平台的兼容,网络兼容,数据库兼容,以及数据格式的兼容

    包括向下兼容和交错兼容,向下兼容是测试软件新版本保留它早期版本功能的情况,交错兼容是验证共同存在的两个相关但不相同的产品之间的兼容性。

    Q: 配置和兼容性测试的区别是什么?

    配置测试的目的是保证软件在其相关的硬件上能够正常运行,而兼容性测试主要是测试软件能否与不同的软件正确协作。

    配置测试的核心内容就是使用各种硬件来测试软件的运行情况,一般包括:

    1)软件在不同的主机上的运行情况,例如Dell和Apple;

    2)软件在不同的组件上的运行情况,例如开发的拨号程序要测试在不同厂商生产的Modem上的运行情况;

    3)不同的外设;

    4)不同的接口;

    5)不同的可选项,例如不同的内存大小;

    兼容性测试的核心内容:

    1)测试软件是否能在不同的操作系统平台上兼容;

    2)测试软件是否能在同一操作系统平台的不同版本上兼容;

    3)软件本身能否向前或者向后兼容;

    4)测试软件能否与其它相关的软件兼容;

    5)数据兼容性测试,主要是指数据能否共享

    配置和兼容性测试通称对开发系统类软件比较重要,例如驱动程序、操作系统、数据库管理系统等。具体进行时仍然按照测试用例来执行。

     

    9) 性能测试

    系统在大并发下的响应速度和健壮性

    通过自动化的测试工具模拟多种正常、峰值以及异常负载条件来对系统的各项性能指标进行测试。负载测试和压力测试都属于性能测试,两者可以结合进行。通过负载测试,确定在各种工作负载下系统的性能,目标是测试当负载逐渐增加时,系统各项性能指标的变化情况。压力测试是通过确定一个系统的瓶颈或者不能接收的性能点,来获得系统能提供的最大服务级别的测试。包括负载测试、强度测试、数据库容量测试、基准测试等类型。

    10) 界面测试

    界面是软件与用户交互的最直接的层,界面的好坏决定用户对软件的第一印象。而且设计良好的界面能够引导用户自己完成相应的操作,起到向导的作用。同时界面如同人的面孔,具有吸引用户的直接优势。设计合理的界面能给用户带来轻松愉悦的感受和成功的感觉,相反由于界面设计的失败,让用户有挫败感,再实用强大的功能都可能在用户的畏惧与放弃中付诸东流。
      区别在于,功能测试关注产品的所有功能上,要考虑到每个细节功能,每个可能存在的功能问题。性能测试主要关注于产品整体的多用户并发下的稳定性和健壮性。界面测试更关注于用户体验上,用户使用该产品的时候是否易用,是否易懂,是否规范(快捷键之类的),是否美观(能否吸引用户的注意力),是否安全(尽量在前台避免用户无意输入无效的数据,当然考虑到体验性,不能太粗鲁的弹出警告)?做某个性能测试的时候,首先它可能是个功能点,首先要保证它的功能是没问题的,然后再考虑该功能点的性能测试

    11) 易用性测试

    界面的友好性,操作方便性等。

    12) 需求测试的注意事项

    是否使用了公司的模板、

    文档内容是否符合规范、

    所有的需求是分级是否清析适当、

    所有的需求是否具有一致性

    需求是否可行(即,该需求组合有解决方案)、

    需求可否用己知的约束来实现、

    需求是否足够(即,可以把它送到一个规范的开发组织,并有一个生产出所需要产品的合理的可能性)、

    所有的其它需求是交叉引用是否正确、

    用户描述是否清楚、

    是否用客户的语言来描述需求、

    每个需求描述是否清楚没有岐义,可以移交给一个独立的组去实现时也能理解、

    是否所有的需求都是可验证的、

    是否每条需求都具有独立性,即使发生了变化也不会影响其它需求、

    性能指标是否明确、

    非功能性需求是否得到充分表现、

    是否完整列出适用的标准或协议、

    标准和协议之间是否存在冲突

     

    展开全文
  • 对缓冲区的理解

    千次阅读 多人点赞 2019-01-31 09:43:21
    一、什么是缓冲缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。 缓冲...

    一、什么是缓冲区

    缓冲区(buffer),它是内存空间的一部分。也就是说,在内存空间中预留了一定的存储空间,这些存储空间用来缓冲输入或输出的数据,这部分预留的空间就叫做缓冲区,显然缓冲区是具有一定大小的。
    缓冲区根据其对应的是输入设备还是输出设备,分为输入缓冲区和输出缓冲区。

    二、为什么要引入缓冲区

    我们为什么要引入缓冲区呢?
    高速设备与低速设备的不匹配,势必会让高速设备花时间等待低速设备,我们可以在这两者之间设立一个缓冲区。
    缓冲区的作用:
    1.可以解除两者的制约关系,数据可以直接送往缓冲区,高速设备不用再等待低速设备,提高了计算机的效率。例如:我们使用打印机打印文档,由于打印机的打印速度相对较慢,我们先把文档输出到打印机相应的缓冲区,打印机再自行逐步打印,这时我们的CPU可以处理别的事情。
    2.可以减少数据的读写次数,如果每次数据只传输一点数据,就需要传送很多次,这样会浪费很多时间,因为开始读写与终止读写所需要的时间很长,如果将数据送往缓冲区,待缓冲区满后再进行传送会大大减少读写次数,这样就可以节省很多时间。例如:我们想将数据写入到磁盘中,不是立马将数据写到磁盘中,而是先输入缓冲区中,当缓冲区满了以后,再将数据写入到磁盘中,这样就可以减少磁盘的读写次数,不然磁盘很容易坏掉。
    简单来说,缓冲区就是一块内存区,它用在输入输出设备和CPU之间,用来存储数据。它使得低速的输入输出设备和高速的CPU能够协调工作,避免低速的输入输出设备占用CPU,解放出CPU,使其能够高效率工作。

    三、缓冲区的类型

    缓冲区 分为三种类型:全缓冲、行缓冲和不带缓冲。
    1、全缓冲
    在这种情况下,当填满标准I/O缓存后才进行实际I/O操作。全缓冲的典型代表是对磁盘文件的读写。
    2、行缓冲
    在这种情况下,当在输入和输出中遇到换行符时,执行真正的I/O操作。这时,我们输入的字符先存放在缓冲区,等按下回车键换行时才进行实际的I/O操作。典型代表是键盘输入数据。
    3、不带缓冲
    也就是不进行缓冲,标准出错情况stderr是典型代表,这使得出错信息可以直接尽快地显示出来。

    四、缓冲区的刷新

    下列情况会引发缓冲区的刷新:
    缓冲区满时;
    关闭文件。
    可见,缓冲区满或关闭文件时都会刷新缓冲区,进行真正的I/O操作。
    大家要仔细理解缓冲区刷新的意思,刷新字面上的意思是用刷子刷,把原来旧的东西变新了,这里就是改变的意思,例如像缓冲区溢出的时候,多余出来的数据会直接将之前的数据覆盖,这样缓冲区里的数据就发生了改变。
    比如在Linux下,操作命令行就属于常见的行缓冲模式 输入一行命令例如ls,命令ls就会进入到缓冲区内,不输入回车的话,什么也不会发生,当输入回车就会执行真正的IO操作
    https://www.cnblogs.com/mlgjb/p/7991903.html

    展开全文
  • 常见总线类型

    万次阅读 多人点赞 2016-08-15 10:53:54
    一些比较高档的UART还提供输入输出数据的缓冲区。常用TXD,RXD,/RTS,/CTS。 JTAG: JTAG (Joint Test Action Group 联合测试行动小组)是一种国际标准测试协议(IEEE1149.1兼容),主要用于芯片...

    谈总线之前,首先应该明白总线是什么?度娘的完整定义是:总线是计算机各种功能部件之间传送信息的公共通信干线,它是由导线组成的传输线束,按照计算机所传输的信息种类。


    其实,小编觉得,总线就是是一种内部结构,它是cpu、内存、输入、输出设备传递信息的公用通道。工程师为了简化硬件电路设计、简化系统结构,常用一组线路,配置以适当的接口电路,与各部件和外围设备连接,这组共用的连接线路被称为总线。另外就是采用总线结构便于部件和设备的扩充,尤其制定了统一的总线标准则容易使不同设备间实现互连。


    总线分类:

    1、总线按功能和规范可分为五大类型:数据总线、地址总线、控制总线、扩展总线及局部总线。


    数据总线、地址总线和控制总线也统称为系统总线,即通常意义上所说的总线。常见的数据总线为ISA、EISA、VESA、PCI等。


    地址总线:是专门用来传送地址的,由于地址只能从CPU传向外部存储器或I/O端口,所以地址总线总是单向三态的,这与数据总线不同,地址总线的位数决定了CPU可直接寻址的内存空间大小。


    控制总线:用来传送控制信号和时序信号。控制信号中,有的是微处理器送往存储器和I/O接口电路的;也有是其它部件反馈给CPU的,比如:中断申请信号、复位信号、总线请求信号、设备就绪信号等。


    2、按照传输数据的方式划分,可以分为串行总线和并行总线。串行总线中,二进制数据逐位通过一根数据线发送到目的器件;并行总线的数据线通常超过2根。常见的串行总线有SPI、I2C、USB及RS232等。


    3、按照时钟信号是否独立,可以分为同步总线和异步总线。同步总线的时钟信号独立于数据,而异步总线的时钟信号是从数据中提取出来的。SPI、I2C是同步串行总线,RS232采用异步串行总线。


    4、微机中总线一般有内部总线、系统总线和外部总线。内部总线是微机内部各外围芯片与处理器之间的总线,用于芯片一级的互连;而系统总线是微机中各插件板与系统板之间的总线,用于插件板一级的互连;外部总线则是微机和外部设备之间的总线,微机作为一种设备,通过该总线和其他设备进行信息与数据交换,它用于设备一级的互连。


    那么多分类,小编也只能选择一种介绍了,就选择内部总线、系统总线和外部总线咯。


    内部总线


    I2C总线:I2C(Inter-IC)总线10多年前由Philips公司推出,是近年来在微电子通信控制领域广泛采用的一种新型总线标准。它是同步通信的一种特殊形式,具有接口线少,控制方式简化,器件封装形式小,通信速率较高等优点。在主从通信中,可以有多个I2C总线器件同时接到I2C总线上,通过地址来识别通信对象。


    SCI总线:串行通信接口SCI也是由Motorola公司推出的。它是一种通用异步通信接口UART,与MCS-51的异步通信功能基本相同。


    IIS:I2S(Inter-IC Sound Bus)是飞利浦公司为数字音频设备之间的音频数据传输而制定的一种总线标准。I2S有3个主要信号:1.串行时钟SCLK,也叫位时钟,即对应数字音频的每一位数据,SCLK有1个脉冲。2.帧时钟LRCK,用于切换左右声道的数据。LRCK为“1”表示正在传输的是左声道的数据,为“0”则表示正在传输的是右声道的数据。3.串行数据SDATA,就是用二进制补码表示的音频数据。有时为了使系统间能够更好地同步,还需要另外传输一个信号MCLK,称为主时钟,也叫系统时钟(Sys Clock)。


    SPI:SPI(Serial Peripheral Interface:串行外设接口);SPI是Motorola首先在其MC68HCXX系列处理器上定义的。SPI接口主要应用在EEPROM,FLASH,实时时钟,AD转换器,还有数字信号处理器和数字信号解码器之间。SPI接口是以主从方式工作的,这种模式通常有一个主器件和一个或多个从器件,其接口包括以下四种信号:(1)MOSI – 主器件数据输出,从器件数据输入 (2)MISO – 主器件数据输入,从器件数据输出 (3)SCLK – 时钟信号,由主器件产生(4)/SS – 从器件使能信号,由主器件控制。


    UART:UART(Universal Asynchronous Receiver Transmitter:通用异步收发器)。将由计算机内部传送过来的并行数据转换为输出的串行数据流。将计算机外部来的串行数据转换为字节,供计算机内部使用并行数据的器件使用。在输出的串行数据流中加入奇偶校验位,并对从外部接收的数据流进行奇偶校验。在输出数据流中加入启停标记,并从接收数据流中删除启停标记。处理由键盘或鼠标发出的中断信号(键盘和鼠票也是串行设备)。可以处理计算机与外部串行设备的同步管理问题。有一些比较高档的UART还提供输入输出数据的缓冲区。常用TXD,RXD,/RTS,/CTS。


    JTAG:JTAG (Joint Test Action Group 联合测试行动小组)是一种国际标准测试协议(IEEE1149.1兼容),主要用于芯片内部测试。标准的JTAG接口是4线:TMS、TCK、TDI、TDO,分别为模式选择、时钟、数据输入和数据输出线。测试复位信号(TRST,一般以低电平有效)一般作为可选的第五个端口信号。一个含有JTAGDebug接口模块的CPU,只要时钟正常,就可以通过JTAG接口访问CPU的内部寄存器和挂在CPU总线上的设备,如FLASH,RAM,内置模块的寄存器,象UART,Timers,GPIO等等的寄存器。


    CAN:CAN全称为“Controller Area Network”,即控制器局域网,是国际上应用最广泛的现场总线之一。最初,CAN被设计作为汽车环境中的微控制器通讯,在车载各电子控制装置ECU之 间交换信息,形成汽车电子控制网络。比如:发动机管理系统、变速箱控制器、仪表装备、电子主干系统中,均嵌入CAN控制装置。一个由CAN总线构成的单一网络中,理论上可以挂接无数个节点。实际应用中,节点数目受网络硬件的电气特性所限制。例如,当使用Philips P82C250作为CAN收发器时,同一网络中允许挂接110个节点。CAN 可提供高达1Mbit/s的数据传输速率,这使实时控制变得非常容易。另外,硬件的错误检定特性也增强了CAN的抗电磁干扰能力。


    SDIO:SDIO是SD型的扩展接口,除了可以接SD卡外,还可以接支持SDIO接口的设备,插口的用途不止是插存储卡。支持 SDIO接口的PDA,笔记本电脑等都可以连接象GPS接收器,Wi-Fi或蓝牙适配器,调制解调器,局域网适配器,条型码读取器,FM无线电,电视接收 器,射频身份认证读取器,或者数码相机等等采用SD标准接口的设备。


    GPIO:GPIO (General Purpose Input Output 通用输入/输出)或总线扩展器利用工业标准I²C、SMBus™或SPI™接口简化了I/O口的扩展。当微控制器或芯片组没有足够的I/O端口,或当系统 需要采用远端串行通信或控制时,GPIO产品能够提供额外的控制和监视功能。


    系统总线


    ISA总线:ISA(industrialstandardarchitecture)总线标准是IBM公司1984年为推出PC/AT机而建立的系统总线标准,所以也叫AT总线。它是对XT总线的扩展,以适应8/16位数据总线要求。它在80286至80486时代应用非常广泛,以至于现在奔腾机中还保留有ISA总线插槽。ISA总线有98只引脚。


    EISA总线:EISA总线是1988年由Compaq等9家公司联合推出的总线标准。它是在ISA总线的基础上使用双层插座,在原来ISA总线的98条信号线上又增加了98条信号线,也就是在两条ISA信号线之间添加一条EISA信号线。在实用中,EISA总线完全兼容ISA总线信号。


    VESA总线:VESA(videoelectronicsstandardassociation)总线是1992年由60家附件卡制造商联合推出的一种局部总线,简称为VL(VESAlocalbus)总线。它的推出为微机系统总线体系结构的革新奠定了基础。该总线系统考虑到CPU与主存和Cache的直接相连,通常把这部分总线称为CPU总线或主总线,其他设备通过VL总线与CPU总线相连,所以VL总线被称为局部总线。它定义了32位数据线,且可通过扩展槽扩展到64位,使用33MHz时钟频率,最大传输率达132MB/s,可与CPU同步工作。是一种高速、高效的局部总线,可支持386SX、386DX、486SX、486DX及奔腾微处理器。


    PCI总线:PCI(peripheralcomponentinterconnect)总线是当前最流行的总线之一,它是由Intel公司推出的一种局部总线。它定义了32位数据总线,且可扩展为64位。PCI总线主板插槽的体积比原ISA总线插槽还小,其功能比VESA、ISA有极大的改善,支持突发读写操作,最大传输速率可达132MB/s,可同时支持多组外围设备。PCI局部总线不能兼容现有的ISA、EISA、MCA(microchannelarchitecture)总线,但它不受制于处理器,是基于奔腾等新一代微处理器而发展的总线。


    外部总线


    RS-232-C总线:RS-232-C是美国电子工业协会EIA制定的一种串行物理接口标准。RS是英文“推荐标准”的缩写,232为标识号,C表示修改次数。RS-232-C总线标准设有25条信号线,包括一个主通道和一个辅助通道,在多数情况下主要使用主通道,对于一般双工通信,仅需几条信号线就可实现,如一条发送线、一条接收线及一条地线。RS-232-C标准规定的数据传输速率为每秒50、75、100、150、300、600、1200、2400、4800、9600、19200波特。RS-232-C标准规定,驱动器允许有2500pF的电容负载,通信距离将受此电容限制,例如,采用150pF/m的通信电缆时,最大通信距离为15m;若每米电缆的电容量减小,通信距离可以增加。传输距离短的另一原因是RS-232属单端信号传送,存在共地噪声和不能抑制共模干扰等问题,因此一般用于20m以内的通信。


    RS-485总线:在要求通信距离为几十米到上千米时,广泛采用RS-485串行总线标准。RS-485采用平衡发送和差分接收,因此具有抑制共模干扰的能力。加上总线收发器具有高灵敏度,能检测低至200mV的电压,故传输信号能在千米以外得到恢复。RS-485采用半双工工作方式,任何时候只能有一点处于发送状态,因此,发送电路须由使能信号加以控制。RS-485用于多点互连时非常方便,可以省掉许多信号线。应用RS-485可以联网构成分布式系统,其允许最多并联32台驱动器和32台接收器。


    IEEE-488总线:IEEE-488总线用来连接系统,如微计算机、数字电压表、数码显示器等设备及其他仪器仪表均可用IEEE-488总线装配起来。它按照位并行、字节串行双向异步方式传输信号,连接方式为总线方式,仪器设备直接并联于总线上而不需中介单元,但总线上最多可连接15台设备。最大传输距离为20米,信号传输速度一般为500KB/s,最大传输速度为1MB/s。


    USB总线:通用串行总线USB是由Intel、Compaq、Digital、IBM、Microsoft、NEC、NorthernTelecom等7家世界著名的计算机和通信公司共同推出的一种新型接口标准。它基于通用连接技术,实现外设的简单快速连接,达到方便用户、降低成本、扩展PC连接外设范围的目的。它可以为外设提供电源,而不像普通的使用串、并口的设备需要单独的供电系统。


    另外,汽车电子最近这么火,小编想谈一下汽车网络中的LIN与CAN总线:


    早在1983年,博世公司开始开发控制器局域网(CAN)总线,并且在1986年正式发布相关协议。目前有多种不同汽车总线标准,但是CAN仍然是最流行的标准。在CAN网络中,所有节点(源于不同的ECU)都担当主节点(即,不存在主从拓扑结构),而且并不分配具体地址。而是由消息携带标识符。


    在给定时间,多个节点可以同时向CAN总线发送数据。然后由消息标识符帮助确定消息的优先级。最高优先级的消息会使CAN总线进入显性状态,而所有其他节点会停止发送。这些节点实际上是收发器,除发送消息之外,其可以根据特定功能从总线查找特定消息。因此,CAN总线所连接的不同节点之间会出现信息流。


    由于CAN会进行填充错误、误码、校验和错误、误帧以及应答错误等多项错误检查, 因此具有高可靠性。CAN支持高达1Mbps的数据传输速率,从而成为连接汽车关键功能ECU(如:变速箱、温度传感器等)的默认选择。


    但汽车为什么选择LIN?


    汽车电子的作用并非仅仅局限于这些关键单元。车身电子市场多年来一直在增长。典型车身控制应用包括座椅、车窗、智能雨刷以及汽车空调传感器等。对车身电子的关键要求是确保汽车更舒适、更安全。尽管这些系统可能不要求像关键ECU那样的高安全性,但是它们仍然需要一定的汽车网络通信标准。


    LIN与CAN对比:


    实现CAN比实现LIN的成本高。导致CAN成本更高的因素包括:

    - CAN网络中的每个节点都需要时钟发生器或晶体;

    - CAN的芯片级实现起来更复杂;

    - 采用双线传输。


    最重要的是,整个昂贵的架构对于不需要高可靠性和高数据速率的应用来说过于奢侈。

    展开全文
  •  缓冲区以前可能被定义为“包含相同数据类型的实例的一个连续计算机内存块”。在 C 和 C++ 中,缓冲区通常是使用数组和诸如 malloc() 和 new 这样的内存分配例程来实现的。极其常见缓冲区种类是简单的...

    from:http://blog.csdn.net/ruibird/archive/2007/01/23/1491425.aspx

    什么是缓冲区溢出?
      缓冲区以前可能被定义为“包含相同数据类型的实例的一个连续计算机内存块”。在 C 和 C++ 中,缓冲区通常是使用数组和诸如 malloc() 和 new 这样的内存分配例程来实现的。极其常见的缓冲区种类是简单的字符数组。溢出 是指数据被添加到分配给该缓冲区的内存块之外。 
      
      如果攻击者能够导致缓冲区溢出,那么它就能控制程序中的其他值。虽然存在许多利用缓冲区溢出的方法,不过最常见的方法还是“stack-smashing”攻击。Elias Levy (又名为 Aleph One)的一篇经典文章“Smashing the Stack for Fun and Profit”解释了 stack-smashing 攻击,Elias Levy 是 Bugtraq 邮件列表(请参阅 参考资料 以获得相关链接)的前任主持人。 
      
      为了理解 stack-smashing 攻击(或其他任何缓冲区攻击)是如何进行的,您需要了解一些关于计算机在机器语言级实际如何工作的知识。在类 UNIX 系统上,每个进程都可以划分为三个主要区域:文本、数据和堆栈。文本区域 包括代码和只读数据,通常不能对它执行写入操作。数据区域 同时包括静态分配的内存(比如全局和静态数据)和动态分配的内存(通常称为 堆)。堆栈区域 用于允许函数/方法调用;它用于记录函数完成之后的返回位置,存储函数中使用的本地变量,向函数传递参数,以及从函数返回值。每当调用一个函数,就会使用一个新的 堆栈帧 来支持该调用。了解这些之后,让我们来考察一个简单的程序。 
      
      清单 1. 一个简单的程序
      
      void function1(int a, int b, int c) {
        char buffer1[5];
        gets(buffer1); /* DON'T DO THIS */
      }
      
      void main() {
       function(1,2,3);
      }
      
      假设使用 gcc 来编译清单 1 中的简单程序,在 X86 上的 Linux 中运行,并且紧跟在对 gets()的调用之后中止。此时的内存内容看起来像什么样子呢?答案是它看起来类似图 1,其中展示了从左边的低位地址到右边的高位地址排序的内存布局。
      
      内存的底部    内存的顶部 
       buffer1 sfp ret a b c  
      <--- 增长 --- [ ] [ ] [ ] [ ] [ ] [ ] ... 
      堆栈的顶部    堆栈的底部 
      
      许多计算机处理器,包括所有 x86 处理器,都支持从高位地址向低位地址“倒”增长堆栈。因此,每当一个函数调用另一个函数,更多的数据将被添加到左边(低位地址),直至系统的堆栈空间耗尽。在这个例子中,当 main() 调用 function1()时,它将 c 的值压入堆栈,然后压入 b 的值,最后压入 a 的值。之后它压入 return (ret)值,这个值在 function1()完成时告诉 function1() 返回到 main() 中的何处。它还把所谓的“已保存的帧指针(saved frame pointer,sfp)”记录到堆栈上;这并不是必须保存的内容,此处我们不需要理解它。在任何情况下,function1()在启动以后,它会为 buffer1()预留空间,这在图 1 中显示为具有一个低地址位置。 
      
      现在假设攻击者发送了超过 buffer1() 所能处理的数据。接下来会发生什么情况呢?当然,C 和 C++ 程序员不会自动检查这个问题,因此除非程序员明确地阻止它,否则下一个值将进入内存中的“下一个”位置。那意味着攻击者能够改写 sfp(即已保存的帧指针),然后改写 ret(返回地址)。之后,当 function1() 完成时,它将“返回”—— 不过不是返回到 main(),而是返回到攻击者想要运行的任何代码。 
      
      通常攻击者会使用它想要运行的恶意代码来使缓冲区溢出,然后攻击者会更改返回值以指向它们已发送的恶意代码。这意味着攻击者本质上能够在一个操作中完成整个攻击!Aleph On 的文章(请参阅 参考资料)详细介绍了这样的攻击代码是如何创建的。例如,将一个 ASCII 0 字符压入缓冲区通常是很困难的,而该文介绍了攻击者一般如何能够解决这个问题。 
      
      除了 smashing-stack 和更改返回地址外,还存在利用缓冲区溢出缺陷的其他途径。与改写返回地址不同,攻击者可以 smashing-stack(使堆栈上的缓冲区溢出),然后改写局部变量以利用缓冲区溢出缺陷。缓冲区根本就不必在堆栈上 —— 它可以是堆中动态分配的内存(也称为“malloc”或“new”区域),或者在某些静态分配的内存中(比如“global”或“static”内存)。基本上,如果攻击者能够溢出缓冲区的边界,麻烦或许就会找上你了。 然而,最危险的缓冲区溢出攻击就是 stack-smashing 攻击,因为如果程序对攻击者很脆弱,攻击者获得整个机器的控制权就特别容易。 
      
      为什么缓冲区溢出如此常见?
      在几乎所有计算机语言中,不管是新的语言还是旧的语言,使缓冲区溢出的任何尝试通常都会被该语言本身自动检测并阻止(比如通过引发一个异常或根据需要给缓冲区添加更多空间)。但是有两种语言不是这样:C 和 C++ 语言。C 和 C++ 语言通常只是让额外的数据乱写到其余内存的任何位置,而这种情况可能被利用从而导致恐怖的结果。更糟糕的是,用 C 和 C++ 编写正确的代码来始终如一地处理缓冲区溢出则更为困难;很容易就会意外地导致缓冲区溢出。除了 C 和 C++ 使用得 非常 广泛外,上述这些可能都是不相关的事实;例如,Red Hat Linux 7.1 中 86% 的代码行都是用 C 或 C ++ 编写的。因此,大量的代码对这个问题都是脆弱的,因为实现语言无法保护代码避免这个问题。 
      
      在 C 和 C++ 语言本身中,这个问题是不容易解决的。该问题基于 C 语言的根本设计决定(特别是 C 语言中指针和数组的处理方式)。由于 C++ 是最兼容的 C 语言超集,它也具有相同的问题。存在一些能防止这个问题的 C/C++ 兼容版本,但是它们存在极其严重的性能问题。而且一旦改变 C 语言来防止这个问题,它就不再是 C 语言了。许多语言(比如 Java 和 C#)在语法上类似 C,但它们实际上是不同的语言,将现有 C 或 C++ 程序改为使用那些语言是一项艰巨的任务。 
      
      然而,其他语言的用户也不应该沾沾自喜。有些语言存在允许缓冲区溢出发生的“转义”子句。Ada 一般会检测和防止缓冲区溢出(即针对这样的尝试引发一个异常),但是不同的程序可能会禁用这个特性。C# 一般会检测和防止缓冲区溢出,但是它允许程序员将某些例程定义为“不安全的”,而这样的代码 可能 会导致缓冲区溢出。因此如果您使用那些转义机制,就需要使用 C/C++ 程序所必须使用的相同种类的保护机制。许多语言都是用 C 语言来实现的(至少部分是用 C 语言来实现的 ),并且用任何语言编写的所有程序本质上都依赖用 C 或 C++ 编写的库。因此,所有程序都会继承那些问题,所以了解这些问题是很重要的。 
      
      导致缓冲区溢出的常见 C 和 C++ 错误
      从根本上讲,在程序将数据读入或复制到缓冲区中的任何时候,它需要在复制 之前 检查是否有足够的空间。能够容易看出来的异常就不可能会发生 —— 但是程序通常会随时间而变更,从而使得不可能成为可能。 
      
      遗憾的是,C 和 C++ 附带的大量危险函数(或普遍使用的库)甚至连这点(指检查空间)也无法做到。程序对这些函数的任何使用都是一个警告信号,因为除非慎重地使用它们,否则它们就会成为程序缺陷。您不需要记住这些函数的列表;我的真正目的是说明这个问题是多么普遍。这些函数包括 strcpy(3)、strcat(3)、sprintf(3)(及其同类 vsprintf(3))和 gets(3)。scanf()函数集(scanf(3)、fscanf(3)、sscanf(3)、vscanf(3)、vsscanf(3) 和 vfscanf(3))可能会导致问题,因为使用一个没有定义最大长度的格式是很容易的(当读取不受信任的输入时,使用格式“%s”总是一个错误)。
      
      其他危险的函数包括 realpath(3)、getopt(3)、getpass(3)、streadd(3)、strecpy(3) 和 strtrns(3)。 从理论上讲,snprintf()应该是相对安全的 —— 在现代 GNU/Linux 系统中的确是这样。但是非常老的 UNIX 和 Linux 系统没有实现 snprintf() 所应该实现的保护机制。
      
      Microsoft 的库中还有在相应平台上导致同类问题的其他函数(这些函数包括 wcscpy()、_tcscpy()、_mbscpy()、wcscat()、_tcscat()、_mbscat() 和 CopyMemory())。注意,如果使用 Microsoft 的 MultiByteToWideChar() 函数,还存在一个常见的危险错误 —— 该函数需要一个最大尺寸作为字符数目,但是程序员经常将该尺寸以字节计(更普遍的需要),结果导致缓冲区溢出缺陷。 
      
      另一个问题是 C 和 C++ 对整数具有非常弱的类型检查,一般不会检测操作这些整数的问题。由于它们要求程序员手工做所有的问题检测工作,因此以某种可被利用的方式不正确地操作那些整数是很容易的。特别是,当您需要跟踪缓冲区长度或读取某个内容的长度时,通常就是这种情况。但是如果使用一个有符号的值来存储这个长度值会发生什么情况呢 —— 攻击者会使它“成为负值”,然后把该数据解释为一个实际上很大的正值吗?当数字值在不同的尺寸之间转换时,攻击者会利用这个操作吗?数值溢出可被利用吗? 有时处理整数的方式会导致程序缺陷。 
      
      防止缓冲区溢出的新技术
      当然,要让程序员 不 犯常见错误是很难的,而让程序(以及程序员)改为使用另一种语言通常更为困难。那么为何不让底层系统自动保护程序避免这些问题呢?最起码,避免 stack-smashing 攻击是一件好事,因为 stack-smashing 攻击是特别容易做到的。
      
      一般来说,更改底层系统以避免常见的安全问题是一个极好的想法,我们在本文后面也会遇到这个主题。事实证明存在许多可用的防御措施,而一些最受欢迎的措施可分组为以下类别: 
      
      基于探测方法(canary)的防御。这包括 StackGuard(由 Immunix 所使用)、ProPolice(由 OpenBSD 所使用)和 Microsoft 的 /GS 选项。
      
      非执行的堆栈防御。这包括 Solar Designer 的 non-exec 补丁(由 OpenWall 所使用)和 exec shield(由 Red Hat/Fedora 所使用)。
      
      其他方法。这包括 libsafe(由 Mandrake 所使用)和堆栈分割方法。 
      
      遗憾的是,迄今所见的所有方法都具有弱点,因此它们不是万能药,但是它们会提供一些帮助。 
      
      基于探测方法的防御
      研究人员 Crispen Cowan 创建了一个称为 StackGuard 的有趣方法。Stackguard 修改 C 编译器(gcc),以便将一个“探测”值插入到返回地址的前面。“探测仪”就像煤矿中的探测仪:它在某个地方出故障时发出警告。在任何函数返回之前,它执行检查以确保探测值没有改变。如果攻击者改写返回地址(作为 stack-smashing 攻击的一部分),探测仪的值或许就会改变,系统内就会相应地中止。这是一种有用的方法,不过要注意这种方法无法防止缓冲区溢出改写其他值(攻击者仍然能够利用这些值来攻击系统)。人们也曾扩展这种方法来保护其他值(比如堆上的值)。Stackguard(以及其他防御措施)由 Immunix 所使用。 
      
      IBM 的 stack-smashing 保护程序(ssp,起初名为 ProPolice)是 StackGuard 的方法的一种变化形式。像 StackGuard 一样,ssp 使用一个修改过的编译器在函数调用中插入一个探测仪以检测堆栈溢出。然而,它给这种基本的思路添加了一些有趣的变化。 它对存储局部变量的位置进行重新排序,并复制函数参数中的指针,以便它们也在任何数组之前。这样增强了ssp 的保护能力;它意味着缓冲区溢出不会修改指针值(否则能够控制指针的攻击者就能使用指针来控制程序保存数据的位置)。默认情况下,它不会检测所有函数,而只是检测确实需要保护的函数(主要是使用字符数组的函数)。从理论上讲,这样会稍微削弱保护能力,但是这种默认行为改进了性能,同时仍然能够防止大多数问题。考虑到实用的因素,它们以独立于体系结构的方式使用 gcc 来实现它们的方法,从而使其更易于运用。从 2003 年 5 月的发布版本开始,广受赞誉的 OpenBSD(它重点关注安全性)在他们的整个发行套件中使用了 ssp(也称为 ProPolice)。 
      
      Microsoft 基于 StackGuard 的成果,添加了一个编译器标记(/GS)来实现其 C 编译器中的探测仪。 
      
      非执行的堆栈防御
      另一种方法首先使得在堆栈上执行代码变得不可能。 遗憾的是,x86 处理器(最常见的处理器)的内存保护机制无法容易地支持这点;通常,如果一个内存页是可读的,它就是可执行的。一个名叫 Solar Designer 的开发人员想出了一种内核和处理器机制的聪明组合,为 Linux 内核创建了一个“非执行的堆栈补丁”;有了这个补丁,堆栈上的程序就不再能够像通常的那样在 x86 上运行。 事实证明在有些情况下,可执行程序 需要 在堆栈上;这包括信号处理和跳板代码(trampoline)处理。trampoline 是有时由编译器(比如 GNAT Ada 编译器)生成的奇妙结构,用以支持像嵌套子例程之类的结构。Solar Designer 还解决了如何在防止攻击的同时使这些特殊情况不受影响的问题。 
      
      Linux 中实现这个目的的最初补丁在 1998 年被 Linus Torvalds 拒绝,这是因为一个有趣的原因。即使不能将代码放到堆栈上,攻击者也可以利用缓冲区溢出来使程序“返回”某个现有的子例程(比如 C 库中的某个子例程),从而进行攻击。简而言之,仅只是拥有非可执行的堆栈是不足够的。 
      
      一段时间之后,人们又想出了一种防止该问题的新思路:将所有可执行代码转移到一个称为“ASCII 保护(ASCII armor)”区域的内存区。要理解这是如何工作的,就必须知道攻击者通常不能使用一般的缓冲区溢出攻击来插入 ASCII NUL 字符(0)这个事实。 这意味着攻击者会发现,要使一个程序返回包含 0 的地址是很困难的。由于这个事实,将所有可执行代码转移到包含 0 的地址就会使得攻击该程序困难多了。
      
      具有这个属性的最大连续内存范围是从 0 到 0x01010100 的一组内存地址,因此它们就被命名为 ASCII 保护区域(还有具有此属性的其他地址,但它们是分散的)。与非可执行的堆栈相结合,这种方法就相当有价值了:非可执行的堆栈阻止攻击者发送可执行代码,而 ASCII 保护内存使得攻击者难于通过利用现有代码来绕过非可执行堆栈。这样将保护程序代码避免堆栈、缓冲区和函数指针溢出,而且全都不需重新编译。
      
      然而,ASCII 保护内存并不适用于所有程序;大程序也许无法装入 ASCII 保护内存区域(因此这种保护是不完美的),而且有时攻击者 能够 将 0 插入目的地址。 此外,有些实现不支持跳板代码,因此可能必须对需要这种保护的程序禁用该特性。Red Hat 的 Ingo Molnar 在他的“exec-shield”补丁中实现了这种思想,该补丁由 Fedora 核心(可从 Red Hat 获得它的免费版本)所使用。最新版本的 OpenWall GNU/Linux (OWL)使用了 Solar Designer 提供的这种方法的实现(请参阅 参考资料 以获得指向这些版本的链接)。 
      
      其他方法
      还有其他许多方法。一种方法就是使标准库对攻击更具抵抗力。Lucent Technologies 开发了 Libsafe,这是多个标准 C 库函数的包装,也就是像 strcpy() 这样已知的对 stack-smashing 攻击很脆弱的函数。Libsafe 是在 LGPL 下授予许可证的开放源代码软件。那些函数的 libsafe 版本执行相关的检查,确保数组改写不会超出堆栈桢。然而,这种方法仅保护那些特定的函数,而不是从总体上防止堆栈溢出缺陷,并且它仅保护堆栈,而不保护堆栈中的局部变量。它们的最初实现使用了 LD_PRELOAD,而这可能与其他程序产生冲突。Linux 的 Mandrake 发行套件(从 7.1 版开始)包括了 libsafe。 
      
      另一种方法称为“分割控制和数据堆栈”—— 基本的思路是将堆栈分割为两个堆栈,一个用于存储控制信息(比如“返回”地址),另一个用于控制其他所有数据。Xu et al. 在 gcc 中实现了这种方法,StackShield 在汇编程序中实现了这种方法。这样使得操纵返回地址困难多了,但它不会阻止改变调用函数的数据的缓冲区溢出攻击。 
      
      事实上还有其他方法,包括随机化可执行程序的位置;Crispen 的“PointGuard”将这种探测仪思想引申到了堆中,等等。如何保护当今的计算机现在已成了一项活跃的研究任务。 
      
      一般保护是不足够的
      如此多不同的方法意味着什么呢?对用户来说,好的一面在于大量创新的方法正在试验之中;长期看来,这种“竞争”会更容易看出哪种方法最好。而且,这种多样性还使得攻击者躲避所有这些方法更加困难。然而,这种多样性也意味着开发人员需要避免 编写会干扰其中任何一种方法的代码。这在实践上是很容易的;只要不编写对堆栈桢执行低级操作或对堆栈的布局作假设的代码就行了。即使不存在这些方法,这也是一个很好的建议。 
      
      操作系统供应商需要参与进来就相当明显了:至少挑选一种方法,并使用它。缓冲区溢出是第一号的问题,这些方法中最好的方法通常能够减轻发行套件中几乎半数已知缺陷的影响。可以证明,不管是基于探测仪的方法更好,还是基于非可执行堆栈的方法更好,它们都具有各自的优点。可以将它们结合起来使用,但是少数方法不支持这样使用,因为附加的性能损失使得这样做不值得。我并没有其他意思,至少就这些方法本身而言是这样;libsafe 和分割控制及数据堆栈的方法在它们所提供的保护方面都具有局限性。当然,最糟糕的解决办法就是根本不对这个第一号的缺陷提供保护。还没有实现一种方法的软件供应商需要立即计划这样做。从 2004 年开始,用户应该开始避免使用这样的操作系统,即它们至少没有对缓冲区溢出提供某种自动保护机制。 
      
      然而,没有哪种方法允许开发人员忽略缓冲区溢出。所有这些方法都能够被攻击者破坏。 攻击者也许能够通过改变函数中其他数据的值来利用缓冲区溢出;没有哪种方法能够防止这点。如果能够插入某些难于创建的值(比如 NUL 字符),那么这其中的许多方法都能被攻击者绕开;随着多媒体和压缩数据变得更加普遍,攻击者绕开这些方法就更容易了。从根本上讲,所有这些方法都能减轻从程序接管攻击到拒绝服务攻击的缓冲区溢出攻击所带来的破坏。遗憾的是,随着计算机系统在更多关键场合的使用,即使拒绝服务通常也是不可接受的。因而,尽管发行套件应该至少包括一种适当的防御方法,并且开发人员应该使用(而不是反对)那些方法,但是开发人员仍然需要最初就编写无缺陷的软件。 
      
      C/C++ 解决方案
      针对缓冲区溢出的一种简单解决办法就是转为使用能够防止缓冲区溢出的语言。毕竟,除了 C 和 C++ 外,几乎每种高级语言都具有有效防止缓冲区溢出的内置机制。但是许多开发人员因为种种原因还是选择使用 C 和 C++。那么您能做什么呢? 
      
      事实证明存在许多防止缓冲区溢出的不同技术,但它们都可划分为以下两种方法:静态分配的缓冲区和动态分配的缓冲区。首先,我们将讲述这两种方法分别是什么。然后,我们将讨论静态方法的两个例子(标准 C strncpy/strncat 和 OpenBSD 的 strlcpy/strlcat),接着讨论动态方法的两个例子(SafeStr 和 C++ 的 std::string)。 
      
      重要选择:静态和动态分配的缓冲区
      缓冲区具有有限的空间。因此实际上存在处理缓冲区空间不足的两种可能方式。 
      
      
      “静态分配的缓冲区”方法:也就是当缓冲区用完时,您抱怨并拒绝为缓冲区增加任何空间。 
      
      “动态分配的缓冲区”方法:也就是当缓冲区用完时,动态地将缓冲区大小调整到更大的尺寸,直至用完所有内存。 
      
      静态方法具有一些缺点。事实上,静态方法有时可能会带来不同的缺陷。静态方法基本上就是丢弃“过多的”数据。如果程序无论如何还是使用了结果数据,那么攻击者会尝试填满缓冲区,以便在数据被截断时使用他希望的任何内容来填充缓冲区。如果使用静态方法,应该确保攻击者能够做的最糟糕的事情不会使得预先的假设无效,而且检查最终结果也是一个好主意。 
      
      动态方法具有许多优点:它们能够向上适用于更大的问题(而不是带来任意的限制),而且它们没有导致安全问题的字符数组截断问题。但它们也具有自身的问题:在接受任意大小的数据时,可能会遇到内存不足的情况 —— 而这在输入时也许不会发生。任何内存分配都可能会失败,而编写真正很好地处理该问题的 C 或 C++ 程序是很困难的。甚至在内存真正用完之前,也可能导致计算机变得太忙而不可用。简而言之,动态方法通常使得攻击者发起拒绝服务攻击变得更加容易。因此仍然需要限制输入。此外,必须小心设计程序来处理任意位置的内存耗尽问题,而这不是一件容易的事情。 
      
      标准 C 库方法
      最简单的方法之一是简单地使用那些设计用于防止缓冲区溢出的标准 C 库函数(即使在使用 C ++,这也是可行的),特别是 strncpy(3) 和 strncat(3)。这些标准 C 库函数一般支持静态分配方法,也就是在数据无法装入缓冲区时丢弃它。这种方法的最大优点在于,您可以肯定这些函数在任何机器上都可用,并且任何 C/C++ 开发人员都会了解它们。许许多多的程序都是以这种方式编写的,并且确实可行。 
      
      遗憾的是,要正确地做到这点却是令人吃惊的困难。下面是其中的一些问题: 
      
      strncpy(3) 和 strncat(3) 都要求您给出 剩余的 空间,而不是给出缓冲区的总大小。这之所以会成为问题是因为,虽然缓冲区的大小一经分配就不会变化,但是缓冲区中剩余的空间量会在每次添加或删除数据时发生变化。这意味着程序员必须始终跟踪或重新计算剩余的空间。这种跟踪或重新计算很容易出错,而任何错误都可能给缓冲区攻击打开方便之门。
      
      在发生了溢出(和数据丢失)时,两个函数都不会给出简单的报告,因此如果要检测缓冲区溢出,程序员就必须做更多的工作。
      
      如果源字符串至少和目标一样长,那么函数 strncpy(3) 还不会使用 NUL 来结束字符串;这可能会在以后导致严重破坏。因而,在运行 strncpy(3)之后,您通常需要重新结束目标字符串。
      
      函数 strncpy(3)还可以用来仅把源字符串的一部分复制到目标中。 在执行这个操作时,要复制的字符的数目通常是基于源字符串的相关信息来计算的。 这样的危险之处在于,如果忘了考虑可用的缓冲区空间,那么 即使在使用 strncpy(3) 时也可能会留下缓冲区攻击隐患。这个函数也不会复制 NUL 字符,这可能也是一个问题。
      
      可以通过一种防止缓冲区溢出的方式使用 sprintf(),但是意外地留下缓冲区溢出攻击隐患是非常容易的。sprintf() 函数使用一个控制字符串来指定输出格式,该控制字符串通常包括“%s”(字符串输出)。如果指定字符串输出的精确指定符(比如 %.10s),那么您就能够通过指定输出的最大长度来防止缓冲区溢出。甚至可以使用“*”作为精确指定符(比如“%.*s”),这样您就可以传入一个最大长度值,而不是在控制字符串中嵌入最大长度值。这样的问题在于,很容易就会不正确地使用 sprintf()。一个“字段宽度”(比如“%10s”)仅指定了最小长度 —— 而不是最大长度。“字段宽度”指定符会留下缓冲区溢出隐患,而字段宽度和精确宽度指定符看起来几乎完全相同 —— 唯一的区别在于安全的版本具有一个点号。另一个问题在于,精确字段仅指定一个参数的最大长度,但是缓冲区需要针对组合起来的数据的最大尺寸调整大小。
      
      scanf() 系列函数具有一个最大宽度值,至少 IEEE Standard 1003-2001 清楚地规定这些函数一定不能读取超过最大宽度的数据。遗憾的是,并非所有规范都清楚地规定了这一点,我们不清楚是否所有实现都正确地实现了这些限制(这在如今的 GNU/Linux 系统上就 不能 正确地工作)。如果您依赖它,那么在安装或初始化期间运行小测试来确保它能正确工作,这样做将是明智的。 
      
      strncpy(3) 还存在一个恼人的性能问题。从理论上讲,strncpy(3) 是 strcpy(3)的安全替代者,但是 strncpy(3) 还会在源字符串结束时使用 NUL 来填充整个目标空间。 这是很奇怪的,因为实际上并不存在这样做的很好理由,但是它从一开始就是这样,并且有些程序还依赖这个特性。这意味着从 strcpy(3) 切换到 strncpy(3) 会降低性能 —— 这在如今的计算机上通常不是一个严重的问题,但它仍然是有害的。 
      
      那么可以使用标准 C 库的例程来防止缓冲区溢出吗?是的,不过并不容易。如果计划沿着这条路线走,您需要理解上述的所有要点。或者,您可以使用下面几节将要讲述的一种替代方法。
      
      OpenBSD 的 strlcpy/strlcat
      OpenBSD 开发人员开发了一种不同的静态方法,这种方法基于他们开发的新函数 strlcpy(3) 和 strlcat(3)。这些函数执行字符串复制和拼接,不过更不容易出错。这些函数的原型如下:
      
      size_t strlcpy (char *dst, const char *src, size_t size);
      size_t strlcat (char *dst, const char *src, size_t size);
      
      strlcpy() 函数把以 NUL 结尾的字符串从“src”复制到“dst”(最多 size-1 个字符)。strlcat()函数把以 NUL 结尾的字符串 src 附加到 dst 的结尾(但是目标中的字符数目将不超过 size-1)。
      
      初看起来,它们的原型和标准 C 库函数并没有多大区别。但是事实上,它们之间存在一些显著区别。这些函数都接受目标的总大小(而不是剩余空间)作为参数。这意味着您不必连续地重新计算空间大小,而这是一项易于出错的任务。此外,只要目标的大小至少为 1,两个函数都保证目标将以 NUL 结尾(您不能将任何内容放入零长度的缓冲区)。如果没有发生缓冲区溢出,返回值始终是组合字符串的长度;这使得检测缓冲区溢出真正变得容易了。 
      
      遗憾的是,strlcpy(3) 和 strlcat(3) 并不是在类 UNIX 系统的标准库中普遍可用。OpenBSD 和 Solaris 将它们内置在 <string.h> 中,但是 GNU/Linux 系统却不是这样。这并不是一件那么困难的事情;因为当底层系统没有提供它们时,您甚至可以将一些小函数直接包括在自己的程序源代码中。 
      
      SafeStr
      Messier 和 Viega 开发了“SafeStr”库,这是一种用于 C 的动态方法,它自动根据需要调整字符串的大小。使用 malloc() 实现所使用的相同技巧,Safestr 字符串很容易转换为常规的 C“char *”字符串:safestr 在传递指针“之前”的地址处存储重要信息。这种技术的优点在于,在现有程序中使用 SafeStr 将会很容易。SafeStr 还支持“只读”和“受信任”的字符串,这也可能是有用的。这种方法的一个问题在于它需要 XXL(这是一个给 C 添加异常处理和资源管理支持的库),因此您实际上要仅为了处理字符串而引入一个重要的库。Safestr 是在开放源代码的 BSD 风格的许可证下发布的。 
      
      C++ std::string
      针对 C++ 用户的另一种解决方案是标准的 std::string类,这是一种动态的方法(缓冲区根据需要而增长)。它几乎是不需要伤脑筋的,因为 C++ 语言直接支持该类,因此不需要做特殊的工作就可使用它,并且其他库也可能会使用它。就其本身而言,std::string 通常会防止缓冲区溢出,但是如果通过它提取一个普通 C 字符串(比如使用 data() 或 c_str()),那么上面讨论的所有问题都会重新出现。还要记住 data()并不总是返回以 NUL 结尾的字符串。 
      
      由于种种历史原因,许多 C++ 库和预先存在的程序都创建了它们自己的字符串类。这可能使得 std::string 更难于使用,并且在使用那些库或修改那些程序时效率很低,因为不同的字符串类型将不得不连续地来回转换。并非其他所有那些字符串类都会防止缓冲区溢出,并且如果它们对 C 不受保护的 char* 类型执行自动转换,那么缓冲区溢出缺陷很容易引入那些类中。 
      
      工具
      有许多工具可以在缓冲区溢出缺陷导致问题之前帮助检测它们。 例如,像我的 Flawfinder 和 Viega 的 RATS 这样的工具能够搜索源代码,识别出可能被不正确地使用的函数(基于它们的参数来归类)。这些工具的一个缺点在于,它们不是完美的 —— 它们会遗漏一些缓冲区溢出缺陷,并且它们会识别出一些实际上不是问题的“问题”。但是使用它们仍然是值得的,因为与手工查找相比,它们将帮助您在短得多的时间内识别出代码中的潜在问题。 
      
      结束语
      借助知识、谨慎和工具,C 和 C++ 中的缓冲区溢出缺陷是可以防止的。不过做起来并没有那么容易,特别是在 C 中。如果使用 C 和 C++ 来编写安全的程序,您需要真正理解缓冲区溢出和如何防止它们。 
      
      一种替代方法是使用另一种编程语言,因为如今的几乎其他所有语言都能防止缓冲区溢出。但是使用另一种语言并不会消除所有问题。许多语言依赖 C 库,并且许多语言还具有关闭该保护特性的机制(为速度而牺牲安全性)。但是即便如此,不管您使用哪种语言,开发人员都可能会犯其他许多错误,从而带来引入缺陷。 
      
      不管您做什么,开发没有错误的程序都是极其困难的,即使最仔细的复查通常也会遗漏其中一些错误。 开发安全程序的最重要方法之一是 最小化特权。那意味着程序的各个部分应该具有它们需要的唯一特权,一点也不能多。这样,即使程序具有缺陷(谁能无过?),也可能会避免将该缺陷转化为安全事故。但是在实践中如何做到这点呢?下一篇文章将研究如何实际地最小化 Linux/UNIX 系统中的特权,以便您能防止自己不可避免的错误所带来安全隐患。 

    展开全文
  • 常见的网络攻击类型

    万次阅读 2019-02-20 12:23:46
    常见的网络攻击类型 一、拒绝服务攻击 1.拒绝服务攻击 Dos(Denial of Service)是一种利用合理的服务请求占用过多的服务资源,从而使合法用户无法得到服务响应的网络攻击行为。 被DOS攻击时的现象大致: 被...
  • channel是Go语言中的一个核心类型,可以把它看成管道。并发核心单元通过它就可以发送或者接收数据进行通讯,这在一定程度上又进一步降低了编程的难度。 channel是一个数据类型,主要用来解决go程的同步问题以及...
  • 缓冲

    千次阅读 2014-12-16 11:06:46
    输入字符的回显是非缓冲区(ubuffered)或直接(direct)输入的一个实例,它表示所键入的的字符正在等待的程序立即变为可用的。相反,延迟回显缓冲缓冲输入的实例,这种情况下所输入的字符被收集并存储在一个被...
  • ...本文讨论 Linux/UNIX 系统中最...本文首先解释什么是缓冲区溢出,以及它们为何如此常见和如此危险。然后讨论广泛用于解决缓冲区溢出的新 Linux 和 UNIX 方法 ―― 以及为什么这些方法还不足够。随后将展示 C
  • socket缓冲区 每个 socket 被创建后,都会...一旦将数据写入到缓冲区,函数就可以成功返回,不管它们没有到达目标机器,也不管它们何时被发送到网络,这些都是TCP协议负责的事情。TCP协议独立于 write()/send() ...
  • 常见的端口扫描类型及原理

    千次阅读 2015-05-05 17:10:33
    常见的扫描类型有以下几种:   秘密扫描 秘密扫描是一种不被审计工具所检测的扫描技术。 它通常用于在通过普通的防火墙或路由器的筛选(filtering)时隐藏自己。 秘密扫描能躲避IDS、防火墙、包过滤器和...
  • STM32进阶之串口环形缓冲区实现

    万次阅读 多人点赞 2018-06-04 10:03:13
    如需转载请说明出处:STM32进阶之串口环形缓冲区实现 队列的概念 在此之前,我们来回顾一下队列的基本概念: 队列 (Queue):是一种先进先出(First In First Out ,简称 FIFO)的线性表,只允许在一端插入(入队),...
  • C/C++ 的全缓冲、行缓冲和无缓冲

    千次阅读 2017-03-19 11:58:47
    为了使程序的运行效率最高,流对象通常会提供缓冲区,以减少调用系统I/O库函数的次数。 在Linux中,缓冲方式存在三种,分别是: (1)全缓冲。输入或输出缓冲区被填满,会进行实际I/O操作。其他情况,如强制刷新、...
  • OpenGL之帧缓冲

    千次阅读 2019-04-17 13:37:02
    文章目录概要帧缓冲附件函数纹理附件渲染缓冲对象附件附件类型的选择后处理离屏渲染离屏渲染与双缓冲来源 概要 所谓帧缓冲是做什么用的,就是用来存储渲染数据的地方,可以理解为显存。几何数据(顶点坐标、纹理坐标...
  • java的双缓冲技术

    千次阅读 2016-03-19 23:54:17
    在Java游戏编程和动画编程中最常见的就是对于屏幕闪烁的处理。本文从J2SE的一个再现了屏幕闪烁的Java Appilication简单动画实例展开,屏幕闪烁的原因进行了分析,找出了闪烁成因的关键:update(Graphics g)函数...
  • 缓冲区溢出

    千次阅读 2016-11-13 10:02:28
    缓冲区溢出漏洞是程序由于缺乏对缓冲区边界条件检查而引起的一种异常行为,通常是程序向缓冲区中写数据,但内容超过了程序员设定的缓冲区边界,从而覆盖了相邻的内存区域,造成覆盖程序中的其他变量甚至影响控制流的...
  • gui 中的显示功能 gui 中的显示最终通过调用...与 gui 而言,所有的在调用 lcd 驱动刷新 framebuffer 到屏幕上显示之前都是通过 framebuffer 的操作完成。这里提及的操作主要使用 memcpy、memset 来完成,这也...
  • 【Java基础-3】吃透Java IO:字节流、字符流、缓冲

    万次阅读 多人点赞 2020-09-23 20:12:33
    什么是Java-IO?字符流和字节流的区别与适用场景是什么?缓冲流到底实现了什么?如何高效地读写文件? 本文用大量的示例图和实例,带你吃透Java IO。
  • 多图详解缓冲区溢出问题

    千次阅读 多人点赞 2020-11-18 23:43:21
    缓冲区溢出一个常见的后果是:黑客利用函数调用过程中程序的返回地址,将存放这块地址的指针精准指向计算机中存放攻击代码的位置,造成程序异常中止。为了防止发生严重的后果,计算机会采用栈随机化,利用金丝雀值...
  • 缓冲区和通道

    万次阅读 2019-01-16 18:07:49
    缓冲区 java.nio包提供了对缓冲区的支持,缓冲区是一种对象,表示存储在内存中的数据流。...对于java的每种基本数据类型,都相应的缓冲区:ByteBuffer,CharBuffer,DoubleBuffer,FloatBuffer,IntBuffer,Lon...
  • 浅析缓冲区溢出

    千次阅读 2018-08-14 11:34:35
    所以研究透彻还需要不少的时间,这里简单的做一个学习的总结,通过具体的实验案例对缓冲区溢出进行简要的解析。 汇编语言及编程语言是基础,其次是反编译工具的使用:比如gdb、IDA pro、objdump等。汇编语言的...
  • IO缓冲

    千次阅读 2018-05-21 16:40:46
    我们把常见的显示器、硬盘、键盘和鼠标都被称为 IO 设备,这里面的 “I” 就是 Input,“O” 就是 Output,合起来就是输入输出设备的意思。想必大家都知道 IO 设备的访问速度与 CPU 的速度相差好几个数量级,为了...
  • OpenGL 帧缓冲

    千次阅读 2017-02-24 23:20:31
    窗口都一个默认的帧缓冲,来存放最终要显示的所有信息。OpenGL允许用户自定义帧缓冲,用户自定义帧缓冲有什么用呢?试想,如果你想实现这样一个功能,就是希望能够在最终显示在窗口中的画面的基础上再每一帧图片...
  • 详解缓冲区溢出

    千次阅读 2019-09-14 17:49:04
    段错误的原理缓冲区溢出的原理攻击手段导致缓冲区溢出的常见 C 和 C++ 错误防止缓冲区溢出的一些技术重要选择:静态和动态分配的缓冲区实例研究 内存对齐 内存对齐系数 说道内存对齐,就不得不说内存对齐系数, 对齐...
  • 缓冲区的三种模式

    千次阅读 2019-05-14 19:13:32
    缓冲区分三种mode 分别是_IOFBF全缓冲区是指缓冲区系统默认4k的方式设定的缓冲区大小 除非缓冲区满 或者调用fflush(stdout)才可以将标准输入的数据全部读取 如printf _IOLBF行缓冲区:是指当输入一行的时候 通过\n...
  • Java提高篇 —— String缓冲

    千次阅读 2018-08-15 18:48:16
    一、String缓冲池    首先我们要明确,String并不是基本数据类型,而是一个对象,并且是不可变的对象。查看源码就会发现String类为final型的(当然也不可被继承),而且通过查看JDK文档会发现几乎每一个修改...
  • 环形缓冲

    千次阅读 2012-05-14 18:33:36
    为了防止人给咱扣上“过度设计”的大帽子,事先声明一下:只有当存储空间的分配/释放非常频繁 并且确实产生了明显 的影响,你才应该考虑环形缓冲区的使用。否则的话,还是老老实实用最基本、最简单的队列缓冲区 ...
  • 缓冲区溢出攻击

    千次阅读 2019-01-15 11:15:12
    缓冲区溢出攻击——攻击者利用程序漏洞,将自己的攻击代码植入有缓冲区溢出漏洞的程序执行体中,改变该程序的执行过程,来获取目标系统的控制权。如果用户输入的数据长度超出了程序为其分配的内存空间,这些溢出的...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 140,855
精华内容 56,342
关键字:

常见的缓冲对类型有