CN110837472B - 一种浏览器测试方法、装置及计算机设备 - Google Patents
一种浏览器测试方法、装置及计算机设备 Download PDFInfo
- Publication number
- CN110837472B CN110837472B CN201911076694.6A CN201911076694A CN110837472B CN 110837472 B CN110837472 B CN 110837472B CN 201911076694 A CN201911076694 A CN 201911076694A CN 110837472 B CN110837472 B CN 110837472B
- Authority
- CN
- China
- Prior art keywords
- browser
- test
- javascript
- testing
- tool
- Prior art date
- Legal status (The legal status is an assumption and is not a legal conclusion. Google has not performed a legal analysis and makes no representation as to the accuracy of the status listed.)
- Active
Links
Images
Classifications
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3672—Test management
- G06F11/3684—Test management for test design, e.g. generating new test cases
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F11/00—Error detection; Error correction; Monitoring
- G06F11/36—Preventing errors by testing or debugging software
- G06F11/3668—Software testing
- G06F11/3672—Test management
- G06F11/3688—Test management for test execution, e.g. scheduling of test suites
-
- G—PHYSICS
- G06—COMPUTING; CALCULATING OR COUNTING
- G06F—ELECTRIC DIGITAL DATA PROCESSING
- G06F21/00—Security arrangements for protecting computers, components thereof, programs or data against unauthorised activity
- G06F21/50—Monitoring users, programs or devices to maintain the integrity of platforms, e.g. of processors, firmware or operating systems
- G06F21/57—Certifying or maintaining trusted computer platforms, e.g. secure boots or power-downs, version controls, system software checks, secure updates or assessing vulnerabilities
- G06F21/577—Assessing vulnerabilities and evaluating computer system security
Landscapes
- Engineering & Computer Science (AREA)
- Theoretical Computer Science (AREA)
- Computer Hardware Design (AREA)
- General Engineering & Computer Science (AREA)
- Computer Security & Cryptography (AREA)
- Physics & Mathematics (AREA)
- General Physics & Mathematics (AREA)
- Software Systems (AREA)
- Quality & Reliability (AREA)
- Computing Systems (AREA)
- Debugging And Monitoring (AREA)
Abstract
本申请涉及一种浏览器测试方法、装置及计算机设备,所述浏览器测试方法、装置及计算机设备,在进行浏览器测试时,保持了完整的浏览器环境,仍运行了整体浏览器,在此基础上,通过将测试工具及被测对象也即浏览器在进程上进行隔离,将测试工具运行于低权限的测试进程,将已完成插桩的待测浏览器代码运行于高权限的浏览器进程,模拟了用户正常访问浏览器的情景,实现了对浏览器进行模拟正常交互情景下的跨进程、跨权限测试,这样的测试更符合用户日常操作浏览器时的实际情况,更容易挖掘出浏览器的通用、易复现的安全漏洞,从而能够进一步对浏览器漏洞进行准确、全面的挖掘。
Description
技术领域
本申请属于浏览器漏洞挖掘技术领域,尤其涉及一种浏览器测试方法、装置及计算机设备。
背景技术
浏览器漏洞挖掘是浏览器安全机制中的一个重要环节,目前,在进行浏览器测试以挖掘浏览器漏洞时,主要采用的测试工具为AFL或LibFuzzer这两种开源软件。
AFL,即American fuzzy lop,是一种面向安全的模糊测试工具,它采用遗传算法来有效地增加测试用例的代码覆盖率,AFL是开源的,由Zalewski在他的网站上托管。LibFuzzer是一个由谷歌开发的开源软件,它是进程内的、覆盖导向的、突变测试的模糊测试引擎,LibFuzzer与被测的库链接,并通过特定的模糊入口点(也称为“目标函数”)将模糊化的输入反馈到库,然后Fuzzer跟踪代码的哪些区域被到达,并在输入数据的语料库上生成突变,以便最大化代码覆盖率。
上述两种测试工具,都需要在同一个进程(单进程)中进行浏览器测试,也即,将需要测试的浏览器功能模块代码引入测试工具,并在测试工具启动的进程中运行与测试该代码(AFL虽然是多进程模型,但也只是不断的启动自己,本质上仍相当于基于单进程来测试浏览器),由此,一方面,AFL和libfuzzer在进行浏览器测试时,被测试模块会脱离浏览器整体环境而孤立运行,相应会影响测试效果;另一方面,AFL和libfuzzer只能模拟单进程中的操作,无法模拟正常使用情景中用户与浏览器间的交互,这同样会影响对浏览器的测试效果,无法准确、全面地挖掘出浏览器的潜在漏洞。
发明内容
有鉴于此,本申请的目的在于提供一种浏览器测试方法、装置及计算机设备,以用于基于一种跨进程跨权限的测试架构,通过模拟正常使用情景中用户与浏览器间的交互来进行浏览器测试,相应达到改善测试效果,更准确、全面地挖掘浏览器漏洞的目的。
为实现上述目的,一方面,本申请提供了一种浏览器测试方法,该方法包括:
启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
利用每个测试进程中运行的Javascript测试工具生成测试用例;
各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;
每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
又一方面,本申请还提供了一种浏览器测试装置,该装置包括:
第一启动单元,用于启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
第二启动单元,用于启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
生成单元,用于利用每个测试进程中运行的Javascript测试工具生成测试用例;
传递单元,用于各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
测试单元,用于在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;并由每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
再一方面,本申请还提供了一种计算机设备,该计算机设备包括:
存储器,用于存储计算机可执行指令;
处理器,用于执行所述计算机可执行指令,所述计算机可执行指令在被调用时至少能用于执行如上所述的浏览器测试方法。
发明人发现,在实际的浏览器框架中,如基于Chromium的浏览器框架中,Javascript运行的Render进程属于被限制的极低权限进程,而Browser所在的进程属于高权限进程。鉴于这一特点,本申请提供的浏览器测试方法、装置及计算机设备,在进行浏览器测试时,保持了完整的浏览器环境,仍运行了整体浏览器,在此基础上,通过将测试工具及被测对象也即浏览器在进程上进行隔离,将测试工具运行于低权限的测试进程,将已完成插桩的待测浏览器代码运行于高权限的浏览器进程,模拟了用户正常访问浏览器的情景,实现了对浏览器进行模拟正常交互情景下的跨进程、跨权限测试,这样的测试更符合用户日常操作浏览器时的实际情况,更容易挖掘出浏览器的通用、易复现的安全漏洞,从而能够进一步对浏览器漏洞进行准确、全面的挖掘。
附图说明
为了更清楚地说明本申请实施例或现有技术中的技术方案,下面将对实施例或现有技术描述中所需要使用的附图作简单地介绍,显而易见地,下面描述中的附图仅仅是本申请的实施例,对于本领域普通技术人员来讲,在不付出创造性劳动的前提下,还可以根据提供的附图获得其他的附图。
图1是本申请可选实施例中浏览器测试方法的跨进程跨权限应用场景示意图;
图2是本申请可选实施例中浏览器测试方法所适用的计算机设备的结构示意图;
图3是本申请可选实施例中浏览器测试方法的预处理过程的流程示意图;
图4是本申请可选实施例中直接向源代码插入插桩代码的示例图;
图5是本申请可选实施例中浏览器测试方法的一种流程示意图;
图6是本申请可选实施例中浏览器测试方法的另一种流程示意图;
图7是本申请可选实施例中一种应用实例实现浏览器测试的逻辑示意图;
图8(a)是本申请可选实施例中实现浏览器测试的应用实例中第一阶段的处理逻辑示意图;
图8(b)是本申请可选实施例中实现浏览器测试的应用实例中第二阶段的处理逻辑示意图;
图8(c)是本申请可选实施例中实现浏览器测试的应用实例中第三阶段的处理逻辑示意图;
图8(d)是本申请可选实施例中实现浏览器测试的应用实例中第四阶段的处理逻辑示意图;
图8(e)是本申请可选实施例中实现浏览器测试的应用实例中第五阶段的处理逻辑示意图;
图9是本申请可选实施例中插桩点位置信息与哈希值的对应关系示例图;
图10是本申请可选实施例中测试覆盖信息的可视化界面示意图;
图11是本申请可选实施例中插桩点的hash block的移动浮层示意图;
图12是目前的AFL的测试覆盖信息的界面示意图;
图13是本申请可选实施例中浏览器测试装置的一种结构示意图;
图14是本申请可选实施例中浏览器测试装置的另一种结构示意图。
具体实施方式
下面将结合本申请实施例中的附图,对本申请实施例中的技术方案进行清楚、完整地描述,显然,所描述的实施例仅仅是本申请一部分实施例,而不是全部的实施例。基于本申请中的实施例,本领域普通技术人员在没有做出创造性劳动前提下所获得的所有其他实施例,都属于本申请保护的范围。
作为本申请实施例的一个方面,本申请提供了一种浏览器测试方法,用于基于一种跨进程跨权限的测试架构,通过模拟正常使用情景中用户与浏览器间的交互来进行浏览器测试,相应达到改善测试效果,更准确、全面地挖掘浏览器漏洞的目的。
可选的,上述浏览器测试方法可以应用在计算机设备中,该计算机设备可以是服务器,如具体地可以是部署在网络端的能用于运行浏览器的服务器,或者,该计算机设备还可以是移动端或PC端终端设备,如智能手机、平板电脑、笔记本、一体机、台式机等,执行本申请方法的执行主体可以是多样化的,本申请实施例对此不作限定。
以下首先对本申请的应用场景作简单介绍。
发明人发现,在实际的浏览器框架中,如基于Chromium的浏览器框架中,Javascript运行的Render进程属于被限制的极低权限进程,而Browser所在的进程属于高权限进程。鉴于这一特点,当将本申请方法应用于终端设备或服务器以通过浏览器测试来挖掘浏览器漏洞时,如图1所示,区别于现有技术的基于单进程单权限的浏览器测试方式,本申请提出了一种跨进程跨权限的测试方式,其中,启动浏览器进程(Browser进程),在启动的浏览器进程中运行预先完成插桩、携带有插桩代码的浏览器代码,除此之外,还启动一个或多个测试进程,本申请实施例中,该测试进程具体为渲染进程(Render进程),在每个渲染进程中运行网页形式的Javascript测试工具(与现有技术的APP形式的测试工具不同),具体可以为模糊测试工具fuzzer,Render进程被沙箱限制在低权限上运行,网页在此进程上被渲染,Browser进程属于在沙箱外的高权限进程,Render进程通过远程指令来向Browser申请高权限操作,高权限操作由Browser执行,并返回结果给Render。通常情况下,为了模拟正常的多用户与浏览器的交互情景,可启动多个Render进程,通过启动多个Render进程,并在每个Render进程运行Javascript测试工具,使得Javascript测试工具以跨进程跨权限方式与浏览器侧进行测试交互,以此来实现模拟多用户与浏览器的正常交互情景。
参阅图2,其示出了本申请方法所适用的计算机设备的一种组成结构示意图,该计算机设备也即本申请作为另一方面所公开的计算机设备。如图2所示,该计算机设备可以包括:处理器201和存储器202。当然,还可以包括通信接口203、输入单元204、显示器205和通信总线206。
其中,处理器201、存储器202、通信接口203、输入单元204及显示器205,均通过通信总线206完成相互间的通信。
在本申请实施例中,该处理器201,可以为中央处理器(Central ProcessingUnit,CPU),特定应用集成电路(application-specific integrated circuit,ASIC),数字信号处理器(DSP)、专用集成电路(ASIC)、现成可编程门阵列(FPGA)或者其他可编程逻辑器件等。
该处理器201可以调用存储器202中存储的程序。
存储器202中用于存放一个或者一个以上程序,程序可以包括程序代码,所述程序代码包括计算机操作指令,在本申请实施例中,该存储器202中至少存储有用于实现以下功能的程序:
启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
利用每个测试进程中运行的Javascript测试工具生成测试用例;
由各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;
由每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
在一种可能的实现方式中,该存储器202可包括存储程序区和存储数据区,其中,存储程序区可存储操作系统、以及至少一个功能(比如声音播放功能、图像播放功能等)所需的应用程序等;存储数据区可存储根据计算机的使用过程中所创建的数据,比如,用户数据、用户访问数据以及音频数据等等。
此外,存储器202可以包括高速随机存取存储器,还可以包括非易失性存储器,例如至少一个磁盘存储器件、闪存器件、或其他易失性固态存储器件。
通信接口203可以为通信模块的接口,如GSM模块的接口。
输入单元204可以为触摸感应单元、键盘等等。显示器305可以包括显示面板,如触摸显示面板等。
当然,图2所示的终端设备结构并不构成对本申请实施例中终端设备的限定,在实际应用中该终端设备可以包括比图2所示的更多或更少的部件,或者组合某些部件。
另外,为了引用和清楚起见,这里同时对本申请下文所涉及的一些技术名词、简写或缩写总结解释如下:
Chromium:是Google的Chrome浏览器背后的引擎,其目的是为了创建一个安全、稳定和快速的通用浏览器;
基于Chromium内核的浏览器:Chromium是一个开源的工程,各大厂商可以使用它的代码定制自己的浏览器。常见的,除Chrome以外,市面上绝大部分的浏览器如Brave,Opera,QQ浏览器,360浏览器,搜狗浏览器等均是基于Chromium的浏览器;
JavaScript:一种高级编程语言,是一门动态类型,面向对象(基于原型)的脚本语言;
沙箱:沙箱利用操作系统提供的安全性,允许无法对计算机进行永久更改或访问机密信息的代码执行。沙箱提供的体系结构和确切的保证取决于操作系统;
Render:渲染进程,通常被沙箱限制在极低权限上运行网页在此进程上被渲染。一个浏览器会有多个Render进程;
Browser:浏览器进程,在沙箱外的高权限进程,Render进程通过远程指令来向Browser申请高权限操作。高权限操作由Browser执行,并返回结果给Render。一个浏览器一般会有一到两个Browser进程;
插桩:程序插桩,是在保证被测程序原有逻辑完整性的基础上在程序中插入一些探针(又称为“探测仪”,本质上就是进行信息采集的代码段,可以是赋值语句或采集覆盖信息的函数调用),通过探针的执行并抛出程序运行的特征数据,通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,从而实现测试目的的方法;
突变、突变测试:用于软件测试和评估现有软件的质量。突变测试即通过对程序输入进行小的修改,观测输出是否正常,以测试程序稳定性和发现安全漏洞;
模糊测试:即Fuzz,是一种软件测试技术。其核心思想是自动或半自动的生成随机数据输入到一个程序中,并监视程序异常,以发现可能的程序错误。模糊测试常常用于检测软件或计算机系统的安全漏洞;
分支点(插桩点):根据算法,可以在不同的位置进行插桩。一般插桩的方案有:在函数入口插桩;在函数入口以及各个分支(如if-else、switch-case、循环)处插桩;各语句插桩;
覆盖:运行时代码流每命中一个插桩点,则记为一个覆盖;
边缘:一串覆盖组成的一条执行流,也可称为路径,有时也特指一条执行流上的最终覆盖点;
位翻转:对选定数据的随机二进制位的翻转,即1翻转为0,0翻转为1。翻转的数量取决于算法。全位随机翻转即取随机数;
模块化:分割,组织和打包系统。每个模块完成一个特定的子功能,所有的模块按某种方法组装起来,成为一个整体,完成整个系统所要求的功能;
黑盒测试:黑盒指在完全或大部分不知道目标程序的源代码或实现的情况下进行的测试。
测试用例:用于测试的数据或步骤的集合称为测试用例。
以下将基于本申请实施例涉及的上述共性方面,对本申请实施例进一步详细说明。其中,在对被测程序进行测试时,需要以已预先在被测程序中执行并完成插桩为前提,除此之外,可能还需要一些其他准确工作,如对完成插桩的被测程序进行编译、链接等,由此,当需要基于本申请的跨进程跨权限模式对浏览器进行测试时,可首先对浏览器执行以下的预处理,该预处理过程也即是指浏览器测试之前的前期准备工作。
如图3所示,该预处理过程可以包括:
步骤S301、确定浏览器中需测试的至少一个目标模块。
被测程序一般会有大量的功能,为了方便后续跟踪命中情况,一般对于一次测试只选定其中一个或几个目标模块进行插桩(当然,可选地,也可以选择对被测程序进行全程序插桩),鉴于此,本实施例中在对浏览器进行插桩时,优选地,可根据需求确定出浏览器中的一个或多个目标模块作为被测对象来对其执行插桩。
步骤S302、利用插桩工具在浏览器源代码的各个目标模块对应的代码中执行插桩处理,得到包括浏览器原始代码及插桩代码的浏览器代码;
也即,在针对浏览器中各个目标模块的代码执行插桩处理后,所得的浏览器代码中除了包括浏览器原始代码(源代码),还携带了插桩代码。
在从浏览器中选定需要测试的一个或多个目标模块后,进一步执行预先编写的插桩程序(插桩工具)对各个目标模块进行插桩,本实施例在执行插桩时,不解析目标模块代码中所有的C++/C关键字,而只是查找符合插桩要求的语法段,并设置其为插桩点,将其他不重要的关键字当作普通单词对待,这样可以快速跳略大量不相关的代码,实现快速插桩。
该插桩处理的过程可以包括:
1)查找所述各个目标模块的代码中包括的各个分支,将每个分支设置为插桩点,并在每个插桩点处插入插桩代码;
具体来讲,就是查找到目标模块中所有的分支(分支即为符合插桩要求的语法段),如if-else、switch-case、循环等,并将其设置为插桩点向其插入插桩代码。
2)获取每个插桩点对应的插桩位置信息;
所述插桩位置信息,可以包括但不限于插桩点对应的被插桩文件名和行号。
3)生成对应于所述插桩位置信息的哈希值,并建立与记录每个插桩点的插桩位置信息与哈希值之间的对应关系信息;
该对应于插桩点的插桩位置信息的哈希值,具体可以是但不限于基于插桩点对应的被插桩文件名和行号生成的哈希值。
采用哈希值而非插桩点的原始位置信息(如文件名字符串+行号)的原因是,这样在Render进程侧的Javascript中可以通过比较哈希值整数来判断覆盖情况,相比于直接比较位置字符串,更为简洁,效率更高。但是因为哈希值是单向的、不可逆,为了在展示页面上提供可以阅读的数据,还需要记录插桩点位置的哈希值对应的原始位置信息,并建立插桩点的位置哈希值与其原始位置信息之间的对应关系,如针对每个插桩点,建立其哈希值与被插桩文件名和行号的对应关系等,并将各个插桩点的对应关系信息形成的信息组合,记录在插桩工具的相应存储位置。
4)传递每个插桩点的插桩位置与哈希值之间的对应关系信息至每个测试进程的Javascript测试工具,以使得Javascript测试工具保存该对应关系信息。
具体可以将生成的各个插桩点的对应关系信息组合拷贝到Javascript测试工具的引擎目录下,如Fuzz引擎目录下,以便后续Fuzz引擎通过读取这些由插桩程序生成的插桩点信息来进行测试结果界面的展示处理。
且在进行插桩时,与AFL、libFuzzer在编译器中插桩不同,本实施例采用直接将插桩代码插入源码(如C++源代码)的方式进行插桩,其中,具体基于相关配置信息(如目标模块对应的文件名等)在浏览器源代码中对目标模块的程序进行插桩,这就使得对编译器没有任何特定要求,不需要如AFL和Libfuzzer一般,在执行插桩时需要使用特定的编译器(具有插桩功能的特定编译器)、或者需对开源的编译器修改编译选项、修改编译环境。
参阅图4提供的向浏览器源代码中的目标模块代码处添加插桩代码的示例图,其中,不具备灰度背景的部分为目标模块的原始源代码,具有灰度背景的部分为插桩程序加入的插桩代码,这些插桩代码用于作为目标模块的程序的探针,通过探针的执行抛出程序运行的特征数据,后期通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,实现测试目的。
步骤S303、对所述浏览器代码进行差量式重编译;所述差量式重编译包括:在对浏览器源代码已预先完成编译的基础上,仅再次编译其中因插桩而导致携带了插桩代码的各个目标模块,得到携带了插桩代码的各个目标模块的编译结果;
通常情况下,浏览器程序已在先前的运行中被编译过,从而,在插桩完成后,需要重新编译浏览器程序。由于插桩代码只对浏览器中被选定的目标模块生效,而其他部分维持不变,因此在重编译的过程中,仅采用差量式重编译方式有针对性地编译其中因插桩而导致携带了插桩代码的各个目标模块即可,并对浏览器完成对该部分编译结果的差量更新。
步骤S304、链接差量式重编译后所得的所述携带了插桩代码的各个目标模块的编译结果。
之后,重新链接该差量更新的携带了插桩代码的各个目标模块的编译结果,即可得到在相应目标模块的代码处插入有插桩代码的完整浏览器可执行文件。
本实施例采用直接将插桩代码插入源码(如C++源代码)的方式进行插桩,可以使得对编译器没有任何特定要求,不需要如AFL和Libfuzzer一般,在执行插桩时需要使用特定的编译器(具有插桩功能的特定编译器),或者需对开源的编译器修改编译选项,修改编译环境。
在基于上述的前期准备工作实现向浏览器的目标模块添加插桩代码、并增量式编译、重链接后,可进一步基于本申请提出的跨进程跨权限模式,通过执行本申请方法对浏览器进行测试以挖掘其存在的漏洞,如图5所示,为本申请一可选实施例提供的一种浏览器测试方法的流程示意图,该方法包括:
步骤S501、启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码。
所述浏览器进程也即Browser进程,下文所述的测试进程在本实施例中具体可以为Render进程(渲染进程),从而,本申请具体提出了一种基于Render-Browser模式的分散测试工具与被测对象的跨进程、跨权限的浏览器测试方案。
当需要对浏览器进行测试时,可在沙箱外的高权限的Browser进程中运行携带有插桩代码的完整浏览器程序,以此模拟实际交互情景中整体浏览器的实际运行情况(区别于目前的已有技术中仅能在测试工具的测试进程中运行需测试的浏览器特定功能模块,而非运行整体浏览器)。
本申请实施例中,对浏览器的测试主要是指模糊测试,也即Fuzz。
步骤S502、启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限。
优选地,可以启动多个Render进程,并在每个Browser进程上运行Javascript测试工具,本申请实施例中,Javascript测试工具本质上是基于Javascript编写的一个网页文件,从而可通过在启动的多个Render进程中运行多个Javascript网页形式的测试工具,来模拟多用户使用浏览器的情形。
实施中,可直接在被测的浏览器上打开至少一个目标网页文件(Javascript测试工具对应的网页文件),以此实现至少一个Render进程的启动以及Javascript测试工具在Render进程上的运行,在此基础上,可进一步基于Javascript测试工具的默认入口点在打开的网页上使用该工具的测试功能开始测试。
步骤S503、利用每个测试进程中运行的Javascript测试工具生成测试用例。
本实施例利用Javascript测试工具,基于根据需求不断生成的伪随机数,来不断循环生成浏览器的多轮测试用例,其中,每轮测试用例均可包括循环生成的多个测试用例,以尽可能提高对浏览器中所选定的目标模块的代码覆盖度。
该生成测试用例的过程可以包括:
1)Javascript测试工具在初始被打开时生成一个种子伪随机数;该种子伪随机数用于作为预定伪随机数算法的初始种子,使所述伪随机数算法能根据需求不断地生成伪随机数,所述伪随机数算法以最近一次生成的伪随机数为输入而输出新的伪随机数;
2)基于预先制定的测试用例生成规则及Javascript测试工具实时生成的当前伪随机数确定第一被测函数;所述第一被测函数为相应目标模块中的函数;
举例来说,假设当前的可选被测函数包括fuction_a、fuction_b、fuction_c…fuction_n,可基于测试用例生成规则中的函数选择规则,根据当前的伪随机数选择相应的函数(如fuction_c)作为当前需测试的第一被测函数。
3)基于所述测试用例生成规则及Javascript测试工具在所述当前伪随机数之后实时生成的相应数量的其他伪随机数,对所述第一被测函数中的相应数量的参数一一进行赋值,得到测试用例;
在选择出第一被测函数后,第一被测函数中的参数数量是固定的,可进一步基于第一被测函数中的参数数量生成相应数量的伪随机数,并将该相应数量的伪随机数分别作为各个参数的取值对各个参数进行赋值,以此生成当前的测试用例。
其中,在浏览器进程基于测试用例执行对浏览器的一次测试后,Javascript测试工具循环执行以上的确定第一被测函数及其参数值的处理过程,以使得基于不同的测试用例循环对浏览器的测试过程,直至达到设定的循环次数时结束当前轮的测试,并开启下一轮测试时所需的测试用例的生成过程,之后直至需结束测试时终止测试用例的生成。
这样,每一轮循环通常都可以一定程序上使得对各个目标模块中的不同函数进行测试,以达到尽可能对目标模块的不同代码进行覆盖的目的。
步骤S504、各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程。
Render进程侧的Javascript测试工具可通过调用相应API(ApplicationProgramming Interface,应用程序接口),将生成的测试用例传递至Browser进程侧。对于多个Render进程来说,则相应有多个Render进程进行API调用向Browser侧传递信息,从而模拟了多用户与浏览器的正常交互情景中多进程间消息传递时可能出现的时序问题。
另外,本申请实施例还提出了心跳(heartbeat)的概念,每间隔一定时间,Render进程侧向Browser进程侧上报一次当前的伪随机数(也即当前的种子seed),以便于后续Browser进程侧以心跳数据方式反馈浏览器测试过程中的插桩点覆盖信息等测试所产生的特征数据。
步骤S505、在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据。
Browser进程侧执行接收的各个测试用例,并在执行测试用例过程中基于浏览器代码中运行的插桩代码捕获测试过程中产生的相关特征数据,如,可以包括但不限于哪些插桩点被命中、被命中的次数等。
更具体地,匹配于上述的心跳方式,Browser进程侧可基于心跳方式确定当前心跳周期内的插桩点命中信息等特征数据,并基于当前心跳周期内的插桩点命中信息以及当前对应的伪随机数(种子)生成心跳数据。
步骤S506、每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
具体地,Render进程侧的Javascript测试工具跨进程获得所述Browser进程侧传递的所述心跳数据,也即,插桩代码抓取的测试过程中产生的特征数据可以以心跳数据形式反馈至Render进程侧,在此基础上,Render进程侧的Javascript测试工具基于所述心跳数据,以及Javascript测试工具保存的每个插桩点的插桩位置信息与哈希值之间的对应关系信息(如Fuzz引擎目录下的哈希值与被测文件名和行号的对应关系),生成并在Javascript网页上显示可视化的测试覆盖信息;该可视化的测试覆盖信息可以包括但不限于:插桩点覆盖数与心跳数之间的关系曲线,覆盖路径数与心跳数之间的关系曲线,插桩点覆盖比例与心跳数之间的关系曲线,以及各插桩点的命中状态可视化信息。
基于Javascript网页上呈现的上述可视化信息,测试人员可方便、直观地得知测试过程对每个插桩点的命中状态、不同心跳节点下不同插桩点的覆盖变化、覆盖路径变化等等。
除此之外,如果Browser进程侧的浏览器程序发生任何的崩溃,如因控制帧解引用、内存访问违例等原因导致的崩溃等,相应会导致Render进程侧发生闪退等异常现象,在该情况下,测试人员可基于心跳数据从测试中途确定出用于测试复现的伪随机数(而不必从作为初始种子的伪随机数开始进行测试复现),进而快速确定导致浏览器崩溃的语句。
本实施例在进行浏览器测试时,保持了完整的浏览器环境,仍运行了整体浏览器,在此基础上,通过将测试工具及被测对象也即浏览器在进程上进行隔离,将测试工具运行于低权限的测试进程,将已完成插桩的待测浏览器代码运行于高权限的浏览器进程,模拟了用户正常访问浏览器的情景,实现了对浏览器进行模拟正常交互情景下的跨进程、跨权限测试,这样的测试更符合用户日常操作浏览器时的实际情况,更容易挖掘出浏览器的通用、易复现的安全漏洞,从而能够进一步对浏览器漏洞进行准确、全面的挖掘。
基于以上的通过实时生成伪随机数方式进行浏览器测试的处理过程,可以对浏览器进行粗放式测试,为了实现更深入、细致地对浏览器进行细粒度测试,进一步提升测试时的代码覆盖度,在基于以上实施例的处理过程对浏览器进行测试后,参阅图6示出的浏览器测试方法的流程示意图,该方法还可以包括以下处理:
步骤S601、Javascript测试工具从预定数组中获取一个伪随机数,基于所述测试用例生成规则及该伪随机数确定第二被测函数;所述第二被测函数为相应目标模块中的函数,所述预定数组中预存有以基于所述伪随机数算法实时生成的各伪随机数为参照而设定的低随机性的一组伪随机数;
所述预定数组中的各个伪随机数是在以上的粗放式测试基础上,相比于基于所述伪随机数算法实时生成的各个伪随机数而言,以生成的各个伪随机数为参照而设定的随机性有所降低(如不同随机数之间的差异变小)的一系列伪随机数。以此使得在基于以上实施例对浏览器进行粗放式测试的基础上,基于本实施例对浏览器进行进一步的深入、细致的测试。
在本步骤S601中,举例来说,假设当前的可选被测函数包括fuction_a、fuction_b、fuction_c…fuction_n,可基于测试用例生成规则中的函数选择规则,根据当前从所述预定数组中读取出的伪随机数,选择相应的函数作为当前需测试的第二被测函数,更具体地,比如,如果当前从数组中取出的为第三个伪随机数,则可选择fuction_c作为当前需测试的第二被测函数。
步骤S602、Javascript测试工具从所述预定数组中获取相应数量的其他伪随机数,并利用获取的该相应数量的其他伪随机数对所述第二被测函数中的相应数量的参数进行一一赋值,得到测试用例;
在选择出第二被测函数后,第二被测函数中的参数数量是固定的,可进一步基于第二被测函数中的参数数量从所述预定数组中获取相应数量的伪随机数,并将该相应数量的伪随机数分别作为各个参数的取值对各个参数进行赋值,以此生成当前的测试用例。
步骤S603、在浏览器进程基于生成的该测试用例执行对浏览器的一次测试后,Javascript测试工具基于所述预定数组更新伪随机数,并基于更新的伪随机数循环执行以上的确定第二被测函数及其参数值的处理过程,以使得对浏览器进行循环测试,直至达到设定的循环次数时结束当前轮的测试;之后,若基于当前轮的测试未产生新的覆盖路径,则重新触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试,若产生新的覆盖路径,对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试;之后直至需结束测试时终止测试用例的生成过程。
其中,所述突变处理包括在一个比较微小的粒度上对产生新的覆盖路径时使用的伪随机数(也即种子)进行突变,如对该种子进行随机位翻转、添加、删除等操作,之后基于突变后的伪随机数进一步生成测试用例对浏览器进行测试,也即浏览器的突变测试。
每一轮中循环或调用(调用测试用例对被测函数进行测试)的次数可以由用户自由配置。
步骤S604、在一轮循环测试结束后,浏览器进程确定当前轮的循环测试对应的插桩点命中信息,并基于当前轮的循环测试对应的插桩点命中信息生成当前轮测试对应的统计数据文件;
所述当前轮的循环测试对应的插桩点命中信息,可以包括但不限于当前轮命中了哪些插桩点及各个所命中插桩点的命中次数。具体地,在一轮循环结束后,Browser进程统计这一轮中命中了哪些插桩点,然后将插桩点连接起来,形成一条路径,并统计各个插桩点的命中次数生成一个统计数据文件。
步骤S605、浏览器进程将当前轮的循环测试对应的统计数据文件传递至相应测试进程中的Javascript测试工具;
之后,Browser进程将该统计数据文件跨进程传递至Render进程。
步骤S606、Javascript测试工具基于所述统计数据文件确定是否产生新的覆盖路径,如果未产生新的覆盖路径,则触发基于所述预定数组更新伪随机数,并基于更新的伪随机数开启下一轮测试的处理过程;如果产生新的覆盖路径,则触发所述对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试的处理过程。
Render进程侧的Javascript测试工具可以通过AJAX读取生成的统计数据文件,并基于读取的统计信息检查是否有新的覆盖路径,如果没有则重新触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试;如果有新的路径,则基于本次产生新路径所使用的伪随机数(种子)进行随机位翻转、添加、删除等突变操作,进而基于突变操作后的伪随机数生成测试用例并对浏览器进行突变测试。
当然,除此之外,render进程侧还可以结合当前轮的统计数据文件在网页上进行插桩点覆盖信息(如各插桩点的命中状态、各插桩点的路径条数变化等)的可视化展示。
基于本实施例可以实现通过JavaScript代码自动编写、生成用于测试的测试用例,并可以基于上述的循环、突变测试机制快速地生成出准确的导致问题的API调用代码。实现了在Render-Browser框架下,在不破坏多进程模型机制的前提下进行浏览器模糊测试。
为了便于对本申请的浏览器测试方法进行理解,以下进一步结合本申请实施例的一个应用示例对本申请方法进行介绍。在该示例中,参阅图7,具体可应用本申请方法通过如下五个阶段的处理,来实现跨进程跨权限的浏览器测试:
第一阶段(①):选定被测目标、插桩阶段;
第二阶段(②):被测程序编译准备阶段;
第三阶段(③):Fuzz初始化阶段;
第四阶段(④):Fuzz循环阶段;
第五阶段(⑤):数据上报、突变、重启阶段。
以下对该五个阶段展开详述:
第一阶段(①):选定被测目标、插桩阶段
该第一阶段的处理过程具体可参阅图8(a)所示。在该阶段中,因为作为被测程序的浏览器有大量的功能,为了方便后续跟踪命中情况,一般一次只选定其中一个或几个目标模块进行插桩(当然,可选地,也可以选择浏览器全程序进行插桩)。在选定被测的目标模块后,对其执行插桩工具中的插桩程序。插桩程序即会找到目标模块中的所有的分支并设置其为插桩点,然后向插桩点插入插桩代码,其中,向插桩点插入的插桩代码为对插桩头文件单例类的调用。
在此阶段中,插桩程序会提供每个插桩点对应的被插桩文件名和行号,单例类根据文件名和行号,分别计算两个循环冗余校验码,其中,具体根据插桩文件名计算一个循环冗余校验码,记为CRC-16(1),根据行号计算一个循环冗余校验码,记为CRC-16(2),并使用CRC-16(1)<<8|CRC-16(2)的方式组合出一个无符号32位整数,作为哈希值,该哈希值也即为上文中所说的插桩点的插桩位置信息的哈希值。在此基础上记录并存储哈希值-文件名-行号的对应关系至插桩工具的相应存储位置。
采用CRC16哈希的原因是,这样在Render进程侧Javascript测试工具可以通过比较整数来判断覆盖情况,相比于直接比较字符串(文件名和行号的字符串),效率更高。但是由于CRC16是单向的、不可逆的哈希,为了在展示页面上提供给用户可以阅读的数据,还需要记录哈希值,其中,针对各个插桩点所记录的哈希值-文件名-文件号的对应关系信息具体可参阅图9的示例。
生成的该对应关系信息数据可以被拷贝到Javascript测试工具的引擎目录下,如Fuzz引擎目录下,以便Fuzz引擎通过AJAX读取这些由插桩程序生成的信息数据、并应用于后续的测试覆盖信息的可视化展示中。
第二阶段(②):被测程序编译准备阶段;
该第二阶段的处理过程具体可参阅图8(b)所示。
与AFL、libFuzzer在编译器中插桩不同,本示例基于本申请的方法,使用直接插入C++代码的方式来对被测的目标模块进行插桩。因此,在插桩完成后,需要重新编译浏览器程序。由于插桩程序只对被选定的目标模块生效,因此重编译的过程只是重新差量式编译携带了插桩代码的目标模块代码,并重新链接即可,效率高、耗时少。
参阅图5提供的向浏览器源代码中的目标模块代码处添加插桩代码的示例图,其中,不具备灰度背景的部分为目标模块的原始源代码,具有灰度背景的部分为插桩程序加入的插桩代码,这些插桩代码用于作为目标模块的程序的探针,通过探针的执行抛出程序运行的特征数据,后期通过对这些数据的分析,可以获得程序的控制流和数据流信息,进而得到逻辑覆盖等动态信息,实现测试目的。
第三阶段(③):Fuzz初始化阶段;
该第三阶段的处理过程具体可参阅图8(c)所示。
在前两个阶段的准备工作完成后,可以在Browser进程上运行插入了插桩代码的浏览器代码。且本申请中,由于测试工具实际上是基于Javascript编写的一个网页文件,因此在前两个阶段的准备工作完成后,可以在作为被测程序的浏览器上直接打开Javascript测试工具(可称之为Fuzzer)对应的网页文件,Fuzzer默认的入口点是SmartFuzz,基于该入口点可使用Fuzzer的功能对浏览器进行跨进程测试。
在SmartFuzz状态下,Javascript测试工具会检测自己是否是首次执行,如果是刚刚在浏览器中被打开,它会随机(调用Math.random())生成一个种子(即作为初始种子),然后基于心跳机制把种子报告给Browser进程,以使得Browser进程记录随机测试开始时的第一个种子值。
该用于作为初始种子的伪随机数是Javascript测试工具基于系统时间利用Math.random()生成的,难以重现,初始种子除外的后续所有涉及“随机”的处理都由内建的伪随机数算法来完成。作为一个示例,该伪随机数算法可以描述为:
该伪随机数算法的输入为最近一次生成的伪随机数(种子),输出为基于该输入生成的新的伪随机数(种子),容易理解的是,只要知道初始种子,即可推算出后续所有的伪随机数值。
为了方便对此测试进行中途复现,本示例基于心跳机制每间隔一定时间,由Render进程侧的Javascript测试工具向Browser侧上报一次当前的伪随机数(seed),这样就可以根据不同的间隔来确认从哪个seed开始重现,如以下的表1是某次测试的一个例子:
表1
测试次数 | 浏览器状态 |
[1,100) | 无问题 |
[100,200) | 无问题 |
[200,300) | 崩溃 |
基于心跳机制,当浏览器产生崩溃时,只需要取出200次时上报的Seed,并从它开始进行测试复现,即可在100次测试内确定导致崩溃的语句,而不用从第1次开始连续复现接近300次。
第四阶段(④):Fuzz循环阶段
该第四阶段的处理过程具体可参阅图8(d)所示。
上述的第三个阶段,可实现对浏览器进行粗放式测试,本阶段则是可以进一步对浏览器更深入、细致的测试。
本阶段中,为了方便实现位翻转等突变处理,预先提供了一个包括多个伪随机数的数组SEED_ARR,该数组中的各随机数的随机性低于基于上述的伪随机数算法生成的各伪随机数的随机性,并具体以基于上述的伪随机数算法生成的各伪随机数为参照而设定。
Javascript测试工具从该数组SEED_ARR中读取伪随机数,并根据所读取值的内容,基于测试用例生成规则确定被测函数、生成测试用例,其中,被测函数的函数名、函数参数均由从SEED_ARR中读取的随机数决定,如,假设根据规则,基于当前读取的随机数,可确定出需将函数fuction_c作为被测函数,且假设该函数fuction_c具有两个参数,可继续从数组SEED_ARR读取两个随机数作为参数值,以此得到测试用例,之后,将测试用例传递至Browser侧进行浏览器测试。
一轮测试中循环的次数/调用的次数,可由用户自由配置,如果一轮调用未完成,则重复上述过程,直至达到设定的循环次数时结束当前轮的测试;之后,若基于当前轮的测试未产生新的覆盖路径,重新触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试,若产生新的覆盖路径,对本次产生新的覆盖路径时使用的伪随机数进行突变处理,如随机位翻转、删除、添加等,以使得基于突变处理后的伪随机数对浏览器进行突变测试;之后直至需结束测试时终止。
第五阶段(⑤):数据上报、突变、重启阶段
该第五阶段的处理过程具体可参阅图8(e)所示。
在一轮循环结束后,Render进程向Browser进程上报结束,Browser进程统计这一轮中命中了哪些插桩点,然后将插桩点连接起来,形成一条路径。并基于每个插桩点的命中次数生成一个统计数据文件;在生成统计数据文件时,具体地,可以针对路径(Edge)中的每个插桩点,计算出一个基于两个CRC-16(CRC16(插桩点位置)以及CRC16(命中数))的哈希值,并生成一个数据统计文件,将该数据统计文件传递至Render进程侧。
随后,Render进程侧的Javascript测试工具通过AJAX读取生成出的数据统计文件,并基于该文件检查是否有新的Edge,如果没有则更换Seed重新开启一轮测试,即重新从第三阶段开始新一轮测试。如果有新的Edge,则基于本次Edge使用的SEED_ARR伪随机数,进行选定并随机位翻转、添加、删除等操作,然后重复第四阶段。
另外,Browser进程侧在通过执行测试用例实现浏览器测试的过程中,会根据接收的伪随机数(种子)不断产生心跳数据,并反馈给Render进程侧,Render进程侧则相应基于Javascript测试工具读取Fuzz页面传递来的心跳数据,对其数据进行可视化展示处理。
图10示出了该可视化展示处理中所呈现的测试覆盖信息的一个示例,其中,在图10示出的测试覆盖信息的可视化展示界面中,展示结果共分为四个区域。前三个区域是实时的,是通过读取Fuzz页面传递来的实时心跳数据,对其数据进行的可视化展示,其中第一个曲线为插桩点覆盖数与心跳数之间的关系曲线,纵坐标为插桩点覆盖数,横坐标为心跳数;第二个曲线为覆盖路径数与心跳数之间的关系曲线,纵坐标为覆盖路径数,横坐标为心跳数;第三个曲线为插桩点覆盖比例与心跳数之间的关系曲线,纵坐标为插桩点覆盖比例,横坐标为心跳数。
第四个区域是由Javascript测试工具结合插桩工具插桩时生成的插桩点的哈希值-文件名-行号信息,将每一个插桩点呈现为一个Hash block展示,同时结合心跳数据上报来的插桩点实时命中量,对其进行覆盖状态展示。实施中,可以采用不同的显示效果(如不同颜色、不同的浮凸度或不同的背景图案等)对插桩点的不同覆盖状态进行区分显示,在图10的示例中,具体使用了三种不同的背景图案区分三种命中状态:黑色无纹线背景-未命中过,栅格背景-命中过,竖纹背景-命中过且命中量超过10%(分支过热状态)。此处的三个背景图案可以替换成任意其他三种不同的背景图案或替换成任意三种不同的颜色/浮凸度等。
为了方便识别Hash数据,如图11所示,本实施例还为每个插桩点的hash block设计了移动浮层,当用户将鼠标移动到Hash block框上时,会显示其对应的原始文件名和行号,以及对应的Hash、命中次数,方便使用者快速迭代功能。参阅图12示出的AFL的插桩点覆盖信息展示界面,本申请相比于目前AFL仅能以字符形式、从统计角度简单展示不同时间的插桩点覆盖信息而言,显然可以更方便、直观、详细地展示浏览器测试过程中插桩点的覆盖情况信息。
综上所述,本申请所提供的浏览器测试方案,相比于目前的基于AFL、libFuzzer的测试方案,可以具备以下几方面的技术优势:
1)基于AFL、libFuzzer的测试模型,都需要在同一个进程(单进程)中进行测试,AFL虽然是多进程模型,也但也只是不断的启动自己,无法模拟正常用户交互。本申请基于Render-Browser架构,通过对浏览器进行跨进程跨权限的交互测试,可有效解决该问题;
2)本申请直接对浏览器源码进行插桩,不需要如AFL、libFuzzer一般在编译器中插桩,从而不要求强制修改编译器选项,并实现插桩功能,而AFL和Libfuzzer都需要使用特定的编译器,或者修改编译选项,修改编译环境;
3)本申请可以模拟正常用户请求,模拟多进程间消息传递时可能出现的时序问题,而libfuzzer和AFL只能模拟单进程中的操作;
4)本申请基于被测软件即浏览器的特性,使用了基于H5的插桩率变化图,相比AFL和libfuzzer的反馈更加友好,同时基于插桩点的位置与哈希值对应关系列表可以告知用户新增的Edge命中了哪一条分支线,而AFL则只能显示出一组数字,无法很直观的看到命中情况,用户也难以修改测试策略;
5)本申请的Javascript测试工具的测试引擎基于Javascript编写,后端插桩代码基于C++编写,前端展示基于HTML混合编写,而AFL和libfuzzer则全部基于C++完成,本申请更易实施;
6)本申请可给予基于Javascript的代码能够和二进制插桩结合起来的Fuzz系统,提升了模拟生成的模糊测试脚本的运行质量,使随机生成的脚本更像是日常使用中调用接口时的状态,通过增大循环深度和完善规则,可以极大提高黑盒测试的代码覆盖度。
另一方面,本申请还提供了一种浏览器测试装置。
参阅图13,其示出了本申请浏览器测试装置的一种结构示意图,该装置具体可应用于服务器或移动端/PC端终端设备等计算机设备中,其中,本申请装置所适用的该计算机设备的组成结构可以参阅前文的相关介绍,这里不再赘述。
如图13所示,本申请实施例的浏览器测试装置可以包括:
第一启动单元1301,用于启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
第二启动单元1302,用于启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
生成单元1303,用于利用每个测试进程中运行的Javascript测试工具生成测试用例;
传递单元1304,用于各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
测试单元1305,用于在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;并由每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
在本申请实施例的一可选的实施方式中,参阅图14,所述浏览器测试装置还可以包括:预处理单元1301’,用于:
确定浏览器中需测试的至少一个目标模块;
利用插桩工具在浏览器源代码的各个目标模块对应的代码中执行插桩处理,得到包括浏览器原始代码及插桩代码的浏览器代码;
对所述浏览器代码进行差量式重编译;所述差量式重编译包括:在对浏览器源代码已预先完成编译的基础上,仅再次编译其中因插桩而导致携带了插桩代码的各个目标模块,得到携带了插桩代码的各个目标模块的编译结果;
链接差量式重编译后所得的所述携带了插桩代码的各个目标模块的编译结果。
在本申请实施例的一可选的实施方式中,所述预处理单元1301’利用插桩工具在浏览器源代码的各个目标模块对应的代码中执行插桩处理,具体包括:
查找所述各个目标模块的代码中包括的各个分支,将每个分支设置为插桩点,并在每个插桩点处插入插桩代码;
获取每个插桩点对应的插桩位置信息;
生成对应于所述插桩位置信息的哈希值,并建立与记录每个插桩点的插桩位置信息与哈希值之间的对应关系信息;
传递各插桩点的插桩位置信息与哈希值之间的对应关系信息至每个测试进程的Javascript测试工具,以使得Javascript测试工具保存该对应关系信息。
在本申请实施例的一可选的实施方式中,所述浏览器进程为沙箱外的高权限进程,所述测试进程为渲染进程,所述渲染进程为运行于沙箱环境内被沙箱限制的低权限进程;
所述第二启动单元1302,具体用于:在浏览器上打开至少一个目标网页文件,所述目标网页文件为Javascript测试工具对应的网页文件,以使得启动至少一个渲染进程,并在每个渲染进程上运行Javascript测试工具。
在本申请实施例的一可选的实施方式中,所述生成单元1303,具体用于:
Javascript测试工具在初始被打开时生成一个种子伪随机数;该种子伪随机数用于作为预定伪随机数算法的初始种子,使所述伪随机数算法能根据需求不断地生成伪随机数,所述伪随机数算法以最近一次生成的伪随机数为输入而输出新的伪随机数;
基于预先制定的测试用例生成规则及Javascript测试工具实时生成的当前伪随机数确定第一被测函数;所述第一被测函数为相应目标模块中的函数;
基于所述测试用例生成规则及Javascript测试工具在所述当前伪随机数之后实时生成的相应数量的其他伪随机数,对所述第一被测函数中的相应数量的参数一一进行赋值,得到测试用例;
其中,在浏览器进程基于测试用例执行对浏览器的一次测试后,Javascript测试工具循环执行以上的确定第一被测函数及其参数值的处理过程,以使得基于不同的测试用例循环对浏览器的测试过程,直至达到设定的循环次数时结束当前轮的测试,之后直至需结束测试时终止测试用例的生成过程。
在本申请实施例的一可选的实施方式中,所述生成单元1303还可以用于:
由Javascript测试工具从预定数组中获取一个伪随机数,基于所述测试用例生成规则及该伪随机数确定第二被测函数;所述第二被测函数为相应目标模块中的函数,所述预定数组中预存有以基于所述伪随机数算法实时生成的各伪随机数为参照而设定的低随机性的一组伪随机数;
Javascript测试工具从所述预定数组中获取相应数量的其他伪随机数,并利用获取的该相应数量的其他伪随机数对所述第二被测函数中的相应数量的参数进行一一赋值,得到测试用例;
在浏览器进程基于生成的该测试用例执行对浏览器的一次测试后,Javascript测试工具基于所述预定数组更新伪随机数,并基于更新的伪随机数循环执行以上的确定第二被测函数及其参数值的处理过程,以使得对浏览器进行循环测试,直至达到设定的循环次数时结束当前轮的测试;之后,若基于当前轮的测试未产生新的覆盖路径,则重新触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试,若产生新的覆盖路径,则对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试;之后直至需结束测试时终止测试用例的生成过程。
在本申请实施例的一可选的实施方式中,所述测试单元1305还可以用于:
在一轮循环测试结束后,浏览器进程确定当前轮的循环测试对应的插桩点命中信息,并基于当前轮的循环测试对应的插桩点命中信息生成当前轮测试对应的统计数据文件;
浏览器进程将当前轮的循环测试对应的统计数据文件传递至相应测试进程中的Javascript测试工具;
Javascript测试工具基于所述统计数据文件确定是否产生新的覆盖路径,如果未产生新的覆盖路径,则触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试;如果产生新的覆盖路径,则触发所述对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试的处理过程。
再一方面,本申请还提供了一种存储介质,该存储介质中存储有计算机程序,所述计算机程序被处理器加载并执行时,实现如上任意一个实施例中所描述的浏览器测试方法。
需要说明的是,本说明书中的各个实施例均采用递进的方式描述,每个实施例重点说明的都是与其他实施例的不同之处,各个实施例之间相同相似的部分互相参见即可。
为了描述的方便,描述以上系统或装置时以功能分为各种模块或单元分别描述。当然,在实施本申请时可以把各单元的功能在同一个或多个软件和/或硬件中实现。
通过以上的实施方式的描述可知,本领域的技术人员可以清楚地了解到本申请可借助软件加必需的通用硬件平台的方式来实现。基于这样的理解,本申请的技术方案本质上或者说对现有技术做出贡献的部分可以以软件产品的形式体现出来,该计算机软件产品可以存储在存储介质中,如ROM/RAM、磁碟、光盘等,包括若干指令用以使得一台计算机设备(可以是个人计算机,服务器,或者网络设备等)执行本申请各个实施例或者实施例的某些部分所述的方法。
最后,还需要说明的是,在本文中,诸如第一、第二、第三和第四等之类的关系术语仅仅用来将一个实体或者操作与另一个实体或操作区分开来,而不一定要求或者暗示这些实体或操作之间存在任何这种实际的关系或者顺序。而且,术语“包括”、“包含”或者其任何其他变体意在涵盖非排他性的包含,从而使得包括一系列要素的过程、方法、物品或者设备不仅包括那些要素,而且还包括没有明确列出的其他要素,或者是还包括为这种过程、方法、物品或者设备所固有的要素。在没有更多限制的情况下,由语句“包括一个……”限定的要素,并不排除在包括所述要素的过程、方法、物品或者设备中还存在另外的相同要素。
以上所述仅是本申请的优选实施方式,应当指出,对于本技术领域的普通技术人员来说,在不脱离本申请原理的前提下,还可以做出若干改进和润饰,这些改进和润饰也应视为本申请的保护范围。
Claims (10)
1.一种浏览器测试方法,其特征在于,包括:
启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
利用每个测试进程中运行的Javascript测试工具生成测试用例;
各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;
每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
2.根据权利要求1所述的方法,其特征在于,在所述运行已预先完成插桩的浏览器代码之前,还包括:
确定浏览器中需测试的至少一个目标模块;
利用插桩工具在浏览器源代码的各个目标模块对应的代码中执行插桩处理,得到包括浏览器原始代码及插桩代码的浏览器代码;
对所述浏览器代码进行差量式重编译;所述差量式重编译包括:在对浏览器源代码已预先完成编译的基础上,仅再次编译其中因插桩而导致携带了插桩代码的各个目标模块,得到携带了插桩代码的各个目标模块的编译结果;
链接差量式重编译后所得的所述携带了插桩代码的各个目标模块的编译结果。
3.根据权利要求2所述的方法,其特征在于,所述利用插桩工具在浏览器源代码的各个目标模块对应的代码中执行插桩处理,包括:
查找所述各个目标模块的代码中包括的各个分支,将每个分支设置为插桩点,并在每个插桩点处插入插桩代码;
获取每个插桩点对应的插桩位置信息;
生成对应于所述插桩位置信息的哈希值,并建立与记录每个插桩点的插桩位置信息与哈希值之间的对应关系信息;
传递各插桩点的插桩位置信息与哈希值之间的对应关系信息至每个测试进程的Javascript测试工具,以使得Javascript测试工具保存该对应关系信息。
4.根据权利要求3所述的方法,其特征在于,所述浏览器进程为沙箱外的高权限进程,所述测试进程为渲染进程,所述渲染进程为运行于沙箱环境内被沙箱限制的低权限进程;
所述启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具,包括:在浏览器上打开至少一个目标网页文件,所述目标网页文件为Javascript测试工具对应的网页文件,以使得启动至少一个渲染进程,并在每个渲染进程上运行Javascript测试工具。
5.根据权利要求4所述的方法,其特征在于,所述利用每个测试进程中运行的Javascript测试工具生成测试用例,包括:
Javascript测试工具在初始被打开时生成一个种子伪随机数;该种子伪随机数用于作为预定伪随机数算法的初始种子,使所述伪随机数算法能根据需求不断地生成伪随机数,所述伪随机数算法以最近一次生成的伪随机数为输入而输出新的伪随机数;
基于预先制定的测试用例生成规则及Javascript测试工具实时生成的当前伪随机数确定第一被测函数;所述第一被测函数为相应目标模块中的函数;
基于所述测试用例生成规则及Javascript测试工具在所述当前伪随机数之后实时生成的相应数量的其他伪随机数,对所述第一被测函数中的相应数量的参数一一进行赋值,得到测试用例;
其中,在浏览器进程基于测试用例执行对浏览器的一次测试后,Javascript测试工具循环执行以上的确定第一被测函数及其参数值的处理过程,以使得基于不同的测试用例循环对浏览器的测试过程,直至达到设定的循环次数时结束当前轮的测试,之后直至需结束测试时终止测试用例的生成过程。
6.根据权利要求5所述的方法,其特征在于,在基于Javascript测试工具实时生成的伪随机数生成测试用例以进行浏览器测试之后,还包括:
Javascript测试工具从预定数组中获取一个伪随机数,基于所述测试用例生成规则及该伪随机数确定第二被测函数;所述第二被测函数为相应目标模块中的函数,所述预定数组中预存有以基于所述伪随机数算法实时生成的各伪随机数为参照而设定的低随机性的一组伪随机数;
Javascript测试工具从所述预定数组中获取相应数量的其他伪随机数,并利用获取的该相应数量的其他伪随机数对所述第二被测函数中的相应数量的参数进行一一赋值,得到测试用例;
在浏览器进程基于生成的该测试用例执行对浏览器的一次测试后,Javascript测试工具基于所述预定数组更新伪随机数,并基于更新的伪随机数循环执行以上的确定第二被测函数及其参数值的处理过程,以使得对浏览器进行循环测试,直至达到设定的循环次数时结束当前轮的测试;之后,若基于当前轮的测试未产生新的覆盖路径,则重新触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试,若产生新的覆盖路径,则对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试;之后直至需结束测试时终止测试用例的生成过程。
7.根据权利要求6所述的方法,其特征在于,所述基于插桩代码获取浏览器代码运行的特征数据,包括:
基于心跳方式确定当前心跳周期内插桩代码捕获的插桩点命中信息,并基于当前心跳周期内的插桩点命中信息以及当前对应的伪随机数生成心跳数据;
所述基于特征数据生成与显示测试覆盖信息,包括:
Javascript测试工具基于所述心跳数据以及Javascript测试工具保存的各插桩点的插桩位置信息与哈希值之间的对应关系信息,生成并在Javascript网页上显示可视化的测试覆盖信息;
其中,所述可视化的测试覆盖信息包括:插桩点覆盖数与心跳数之间的关系曲线,覆盖路径数与心跳数之间的关系曲线,插桩点覆盖比例与心跳数之间的关系曲线,以及各插桩点的命中状态可视化信息。
8.根据权利要求7所述的方法,其特征在于,还包括:
在一轮循环测试结束后,浏览器进程确定当前轮的循环测试对应的插桩点命中信息,并基于当前轮的循环测试对应的插桩点命中信息生成当前轮测试对应的统计数据文件;
浏览器进程将当前轮的循环测试对应的统计数据文件传递至相应测试进程中的Javascript测试工具;
Javascript测试工具基于所述统计数据文件确定是否产生新的覆盖路径,如果未产生新的覆盖路径,则触发基于实时生成伪随机数的方式进行浏览器测试的处理以开启下一轮测试;如果产生新的覆盖路径,则触发所述对本次产生新的覆盖路径时使用的伪随机数进行突变处理,以使得基于突变处理后的伪随机数对浏览器进行突变测试的处理过程。
9.一种浏览器测试装置,其特征在于,包括:
第一启动单元,用于启动浏览器进程,并在所述浏览器进程中运行已预先完成插桩的浏览器代码,所述预先完成插桩的浏览器代码包括浏览器原始代码及插桩代码;
第二启动单元,用于启动至少一个测试进程,并在每个测试进程中运行Javascript测试工具;其中,测试进程的权限低于浏览器进程的权限;
生成单元,用于利用每个测试进程中运行的Javascript测试工具生成测试用例;
传递单元,用于各个测试进程中的Javascript测试工具将测试用例传递至浏览器进程;
测试单元,用于在浏览器进程的浏览器代码上执行各个测试用例,以进行浏览器测试,并基于插桩代码获取浏览器代码运行的特征数据;并由每个测试进程中的Javascript测试工具获取浏览器进程中插桩代码针对与该测试进程相匹配的测试用例获得的特征数据,并基于特征数据生成与显示测试覆盖信息;或者,每个测试进程在浏览器进程产生异常时,响应浏览器进程的异常而产生相应异常。
10.一种计算机设备,其特征在于,包括:
存储器,用于存储计算机可执行指令;
处理器,用于执行所述计算机可执行指令,所述计算机可执行指令在被调用时至少能用于执行如权利要求1-8任一项所述的浏览器测试方法。
Priority Applications (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201911076694.6A CN110837472B (zh) | 2019-11-06 | 2019-11-06 | 一种浏览器测试方法、装置及计算机设备 |
Applications Claiming Priority (1)
Application Number | Priority Date | Filing Date | Title |
---|---|---|---|
CN201911076694.6A CN110837472B (zh) | 2019-11-06 | 2019-11-06 | 一种浏览器测试方法、装置及计算机设备 |
Publications (2)
Publication Number | Publication Date |
---|---|
CN110837472A CN110837472A (zh) | 2020-02-25 |
CN110837472B true CN110837472B (zh) | 2021-05-14 |
Family
ID=69576193
Family Applications (1)
Application Number | Title | Priority Date | Filing Date |
---|---|---|---|
CN201911076694.6A Active CN110837472B (zh) | 2019-11-06 | 2019-11-06 | 一种浏览器测试方法、装置及计算机设备 |
Country Status (1)
Country | Link |
---|---|
CN (1) | CN110837472B (zh) |
Families Citing this family (5)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN113742201A (zh) * | 2020-05-29 | 2021-12-03 | 中国电信股份有限公司 | 基于灰盒测试的软件缺陷检测方法和系统 |
CN113872919B (zh) * | 2020-06-30 | 2022-11-22 | 华为技术有限公司 | 一种漏洞扫描方法及装置 |
CN112363954B (zh) * | 2020-12-08 | 2021-07-30 | 南京大学 | 基于对象状态一致性的软件动态更新测试方法 |
CN113468064A (zh) * | 2021-07-19 | 2021-10-01 | 京东科技控股股份有限公司 | 灰度测试方法、装置、电子设备与存储介质 |
CN114153462A (zh) * | 2021-12-14 | 2022-03-08 | 北京字节跳动网络技术有限公司 | 客户端源码处理方法、装置、存储介质及电子设备 |
Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103530233A (zh) * | 2013-10-31 | 2014-01-22 | 广州菁英信息技术有限公司 | 移动浏览器的自动化测试方法、测试服务器及系统 |
CN105260312A (zh) * | 2015-10-26 | 2016-01-20 | 北京航空航天大学 | 一种多核实时系统应用数据竞争错误的调试方法 |
US9367415B1 (en) * | 2014-01-20 | 2016-06-14 | Google Inc. | System for testing markup language applications on a device |
CN110348216A (zh) * | 2019-05-24 | 2019-10-18 | 中国科学院信息工程研究所 | 一种针对云计算系统虚拟设备的模糊测试方法及系统 |
Family Cites Families (1)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
US10382386B2 (en) * | 2016-10-27 | 2019-08-13 | Ranorex GmbH | Functional webpage testing tool |
-
2019
- 2019-11-06 CN CN201911076694.6A patent/CN110837472B/zh active Active
Patent Citations (4)
Publication number | Priority date | Publication date | Assignee | Title |
---|---|---|---|---|
CN103530233A (zh) * | 2013-10-31 | 2014-01-22 | 广州菁英信息技术有限公司 | 移动浏览器的自动化测试方法、测试服务器及系统 |
US9367415B1 (en) * | 2014-01-20 | 2016-06-14 | Google Inc. | System for testing markup language applications on a device |
CN105260312A (zh) * | 2015-10-26 | 2016-01-20 | 北京航空航天大学 | 一种多核实时系统应用数据竞争错误的调试方法 |
CN110348216A (zh) * | 2019-05-24 | 2019-10-18 | 中国科学院信息工程研究所 | 一种针对云计算系统虚拟设备的模糊测试方法及系统 |
Non-Patent Citations (2)
Title |
---|
"AFL模糊测试系统的优化方法研究";赵斌;《中国优秀硕士学位论文全文数据库电子期刊 信息科技辑》;20190315;正文第1-61页 * |
"Fuzzing测试技术综述";史记;《理论研究》;20140331(第3期);第1-5页 * |
Also Published As
Publication number | Publication date |
---|---|
CN110837472A (zh) | 2020-02-25 |
Similar Documents
Publication | Publication Date | Title |
---|---|---|
CN110837472B (zh) | 一种浏览器测试方法、装置及计算机设备 | |
Amalfitano et al. | A general framework for comparing automatic testing techniques of Android mobile apps | |
CN102667730B (zh) | 设计时调试 | |
Patra et al. | Conflictjs: finding and understanding conflicts between javascript libraries | |
Sahar et al. | Towards energy aware object-oriented development of android applications | |
Kashyap et al. | Automated customized bug-benchmark generation | |
Arnatovich et al. | Achieving high code coverage in android UI testing via automated widget exercising | |
Ocariza Jr et al. | Automatic fault localization for client‐side JavaScript | |
Barboni et al. | Sumo: A mutation testing strategy for solidity smart contracts | |
Xu et al. | Guider: Gui structure and vision co-guided test script repair for android apps | |
Fell | A review of fuzzing tools and methods | |
Arnatovich et al. | Mobolic: An automated approach to exercising mobile application GUIs using symbiosis of online testing technique and customated input generation | |
Zeller | Search-based testing and system testing: a marriage in heaven | |
Schoofs et al. | Ampyfier: Test amplification in python | |
Aljamaan et al. | Specifying trace directives for UML attributes and state machines | |
Mirshokraie et al. | Atrina: Inferring unit oracles from GUI test cases | |
Aichernig et al. | Automata learning for symbolic execution | |
US7996798B2 (en) | Representing binary code as a circuit | |
Ghosh et al. | Bytecode fault injection for Java software | |
Ahmed et al. | An automated testing framework for smart tv apps based on model separation | |
Saieva et al. | Update with care: Testing candidate bug fixes and integrating selective updates through binary rewriting | |
Xiao et al. | Advances on improving automation in developer testing | |
Kejstová | Model checking with system call traces | |
Callan et al. | Multi-Objective Improvement of Android Applications | |
Sinhabahu | Visualizing Security Vulnerability Evolution of Software Systems |
Legal Events
Date | Code | Title | Description |
---|---|---|---|
PB01 | Publication | ||
PB01 | Publication | ||
REG | Reference to a national code |
Ref country code: HK Ref legal event code: DE Ref document number: 40022657 Country of ref document: HK |
|
SE01 | Entry into force of request for substantive examination | ||
SE01 | Entry into force of request for substantive examination | ||
GR01 | Patent grant | ||
GR01 | Patent grant |