V8 escape环境搭建(一)
Jsjsj Lv2

以后想准备深入研究v8,这里先把环境搭建下和一些看到v8类型的题如何处理的过程,

环境搭建

虚拟机版本为 ubuntu 18.04

1.编译 v8

先下载chrom开发工具depot_tools,它用来进行v8编译,类似gcc

1
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git

然后把它添加到环境变量里

1
export PATH=$PATH:<path to depot_tools>

然后挂代理(不挂代理的话后面fetch v8和依赖会被墙毕竟是google),

安装ninja报错,将版本调到138bff28,将DEPOT_TOOLS_UPDATE设置为0,然后gclient

这个一定要执行,不然后面ninja报错导致环境搭建不起来(一定要执行!!,做题的时候,在拉去版本之前也要执行)

1
2
3
git reset --hard 138bff28
export DEPOT_TOOLS_UPDATE=0
gclient

下一步下载v8

1
2
fetch v8
或者fetch --force v8

然后进入到v8目录下,如果在比赛中这里会根据题目给的版本进行git checkout 版本,第二步gclient sync -D 下载相关依赖,-D 会删除不需要的依赖

1
2
3
cd v8
git checkout 7.6.303.28
gclient sync -D

报错的话就执行这句:gclient config https://chromium.googlesource.com/v8/v8

下面来介绍题目方法导入

如果比赛给了一个Chrome浏览器,我🚪可以在浏览器里输入chrome://version 查看版本

然后打开 github 的 chrome 项目,搜索版本号并切换至相应版本。

image

然后在项目根目录下的 DEPS 文件中查看 V8 版本:

image

如果题目给了 diff 文件需要将 patch 到项目中。

1
git apply ./oob.diff

diff文件patch项目里在v8目录下,然后安装相关依赖(如果遇到下载字体未响应问题需要添加 --no-chromeos-fonts 参数),每次运行不同版本都要安装依赖(也就是不同题版本会不一样),这样gdb使用调试的时候就不会报错了

1
2
./build/install-build-deps.sh
或者./build/install-build-deps.sh --no-chromeos-fonts

下面开始编译v8,选择release版本,因为debug版本在进行漏洞调试会有检测,一般都是用release

编译v8:

1
./tools/dev/gm.py x64.release

编译生成的 d8./out/x64.release/d8 中。

题目拉取方法,以2019 oob为例

1
2
3
4
5
6
7
8
9
10
git reset --hard 138bff28
export DEPOT_TOOLS_UPDATE=0
gclient
fetch v8 之前fetch就执行fetch --force v8
cd v8
git reset --hard 6dc88c191f5ecc5389dc26efa3ca0907faef3598 #设置v8分支
gclient sync
git apply ../oob.diff
./build/install-build-deps.sh --no-chromeos-fonts
tools/dev/gm.py x64.release

调试 v8

~/.gdbinit 添加 v8 的调试插件:

1
2
source /path/to/v8/tools/gdbinit
source /path/to/v8/gdb-v8-support.py

/path/to/是自己到达v8目录的一些路径

常见参数:

–allow-natives-syntax 开启原生API (用的比较多)
–trace-turbo 跟踪生成TurboFan IR
–print-bytecode 打印生成的bytecode
–shell 运行脚本后切入交互模式
更多参数可以参考 –help
调试 js 脚本时可以采用如下命令:

1
2
gdb ./d8
r --allow-natives-syntax --shell ./exp.js

js中常见的⼀些调试技巧:

在js中写⼊断点:**%SystemBreak();** ,如果不在调试模式的话, 程序直接中断, 如果在调试器中, 会被调试器识别到
并且断下来。
打印出对象的地址和对应的信息: %DebugPrint(var_name);
调试时输入 job + DebugPrint打印的对象地址 可以打印出对象的结构。

安装 turbolizer

turbolizer 是一个可视化分析 JS 优化的工具,安装命令如下:

1
2
3
4
5
6
cd /path/to/v8/tools/turbolizer
sudo npm install n -g
sudo n 16.20.0
sudo npm i
sudo npm run-script build

由于 Ubuntu18.04 默认的 node 版本过低,需要安装 16.20.0 版本。

1
sudo npm i

最后需要启动一个 web 服务器,根据需要 8000 可以换成其它端口。

1
python -m SimpleHTTPServer 8000

编写一个 js 脚本:
%OptimizeFunctionOnNextCall 内置函数可以直接触发强行触发优化。

1
2
3
4
5
6
7
8
9
10
function add(a, b) {
return a + b;
}

//%OptimizeFunctionOnNextCall(add);
for (let i = 0; i < 10000000; i++) {
add(i, i + 1);
}


运行 js 脚本并使用 --trace-turbo 参数

1
./d8 --trace-turbo --allow-natives-syntax ./test.js

在浏览器中访问 http://127.0.0.1:8000/path/to/v8/tools/turbolizer/ ,然后在其中打开该文件就可以进行分析。

先占个坑稍后来补全。。。。

 Comments