首页
论坛
专栏
课程

分享:
# 认识Chakra 在IE浏览器时代,在渲染引擎中负责解析执行javascript代码的引擎是jscript.dll和jscript9.dll,其中jscript9是在IE9之后使用的。 在微软放弃IE系列浏览器并启用全新的Microsoft Edge系列之后,就放弃了原有的mshtml.dll和jscript9.dll转而采用了全新的页面渲染引擎edgehtml.dll和脚本解析引擎Chakra.dll。虽然根据微软的说法这两者是全新开发的,但是根据反汇编的结果来看其实也有部分代码是fork自以前的。但是Chakra带来的最显著的变化是微软开源了这个项目,这个开源版本被称为ChakraCore。严格来说Chakra与ChakraCore并不完全相同,因为ChakraCore不包含Chakra所具有的一些接口代码,微软没有开源这部分出来,但是为了方便使用转而设计并开源了另一套接口。 ![](https://github.com/Microsoft/ChakraCore/wiki/images/chakracore_componentization.png) 由于针对脚本解析的核心代码是一致的,因此在实际的Edge浏览器中存在的漏洞,在ChakraCore中同样可以触发。因此对于研究内存破坏类漏洞而言,开源的ChakraCore提供给我们很大的便利。 ChakraCore项目在Github的地址是:https://github.com/Microsoft/ChakraCore ChakraCore支持两个比较重要的特性,一个是基于标记清除法的垃圾回收器(Mark-Sweep GC),一个是为了效率考虑的运行时编译技术(Just-In-Time Compiler)。ChakraCore的文档中对此给出了简单的介绍,大家可以先浏览一下:https://github.com/Microsoft/ChakraCore/wiki/Architecture-Overview 在介绍具体特性之前,首先借用一篇文章给大家介绍一下指令虚拟机的大概执行方式,因为Chakra本质上其实也是一个JavaScript的指令虚拟机。 大家在平时应该接触过许多的程序开发语言,这些语言大概可以分为两类一类是C这种经过编译链接执行机器码的语言。另一类比如脚本语言Python、Java等,这些脚本语言在执行的时候会依赖一种指令虚拟机来解释执行。 假设要解析执行javascript中`i = a + b * c;`这样的一条指令,那么首先会进行词法分析和语法分析。 这里的词法分析和语法分析,如果了解过编译原理的同学应该不陌生,这一般也是被称为编译器前端所做的工作。 首先进行词法分析会生成供语法分析使用的标记序列 ``` "i", "=", "a", "+", "b", "*", "c"; ``` 之后进行语法分析生成抽象语法树,也就是一般所说的AST。比如i = a + b * c;经过了词法分析和语法分析会生成如下的抽象语法树(AST) ![](http://djt.qq.com/upload/public/common/2013/05/images/07111550619.gif) 每次执行这条语句,都要进行一次遍历树的过程,这种方式存在着很大的性能缺陷,因此Javascript引擎转向使用字节码的方式。 所谓的字节码方式是指在遍历语法树后,生成对应的逆波兰式操作序列,然后在执行时,直接解释执行这个后缀记法的操作序列。这种操作序列就是字节码(bytecode),这种执行方式就是字节码解释方式(bytecode interpreter)。 ![](http://djt.qq.com/upload/public/common/2013/05/images/07111632296.gif) 这里的字节码就相当于编译器的中间代码也就是中间语言IL,接触过VMP这类虚拟机保护壳的同学应该对这种中间语言虚拟机不陌生。 一个比较简单的bytecode执行方式是针对每种bytecode进行分发,来进行对应的行为处理。 ![](http://djt.qq.com/upload/public/common/2013/05/images/07111920725.jpg) 解析字节码的方式与遍历语法树相比在性能上有很大的提升,并且中间代码可以进行进一步的优化从而进一步提升效率。 为了进一步提升性能,chakra引入了JIT引擎。JIT会在运行时将源代码翻译成机器码,下次在执行同一代码段时就无需再翻译了。但是JIT引擎并不是直接就会执行的,否则就跟直接编译成机器码没有区别了,而直接编译成机器码的性能开销会很大。在Chakra中只有当目标函数或者循环语句被频繁调用时才会启用JIT编译,JIT编译后生成了相应的机器指令,下一次调用到这个语句或是函数时就会直接执行机器指令。一旦JIT代码准备就绪,ChakraCore就会替换函数或循环的入口点,以便随后对函数或循环调用执行更快的JIT代码,而不是通过解释器继续执行字节代码。 ![](https://github.com/Microsoft/ChakraCore/wiki/images/chakracore_pipeline.png) ## Reference http://djt.qq.com/article/view/489

上一篇 :
下一篇 :
讨论 (0)
沪ICP备16048531号-1
沪公网安备 31011502006611号