Chrome v8 pwn 前置
字数 1668 2025-08-20 18:18:05
V8 JavaScript 引擎深入解析与PWN前置知识
1. V8引擎概述
V8是Google用C++开发的开源JavaScript引擎,用于Chromium和Node.js等项目中执行JavaScript代码。V8的主要特点包括:
- 采用Just-in-time (JIT)编译技术
- 将JS代码编译为机器码执行以提高性能
- 编译后的二进制名称为d8而非v8
V8处理流程
- 解析(Parser):将JS代码转换为抽象语法树(AST)
- 解释(Ignition):将AST转换为字节码并在VM中执行
- 非优化编译(Sparkplug):对频繁执行的代码生成简单机器码
- 优化编译(TurboFan):对热点代码进行深度优化
2. 环境搭建
系统要求
推荐使用Ubuntu 20.04,18.04可能存在兼容性问题
依赖安装
sudo apt install bison cdbs curl flex g++ git python vim pkg-config
工具链安装
- 获取depot_tools:
git clone https://chromium.googlesource.com/chromium/tools/depot_tools.git
echo 'export PATH=$PATH:"/path/to/depot_tools"' >> ~/.bashrc
cd depot_tools
git reset --hard 138bff28
export DEPOT_TOOLS_UPDATE=0
- 安装ninja:
git clone https://github.com/ninja-build/ninja.git
cd ninja && ./configure.py --bootstrap && cd ..
echo 'export PATH=$PATH:"/path/to/ninja"' >> ~/.bashrc
V8源码获取与编译
fetch v8 # 或fetch --force v8
cd v8
gclient sync -D
git checkout 7.6.303.28 # 指定版本
./build/install-build-deps.sh # 添加--no-chromeos-fonts参数避免字体问题
编译选项
- 生成配置:
./tools/dev/v8gen.py x64.release # 推荐release版本
# 或
./tools/dev/v8gen.py x64.debug
- 编译:
ninja -C out.gn/x64.release
# 或使用预设选项
./tools/dev/gm.py x64.release
3. 调试工具与技巧
调试准备
在~/.gdbinit中添加:
source /path/to/v8/tools/gdbinit
source /path/to/v8/tools/gdb-v8-support.py
调试命令
gdb ./d8
set args --allow-natives-syntax ./exp.js
调试函数
%DebugPrint():显示对象详细信息%DebugPrintPtr():显示指针指向的对象%SystemBreak():设置断点
调试示例
var a = [1, 2, 3, 1.1];
%DebugPrint(a);
%SystemBreak();
4. V8对象模型
JSObject结构
V8中的对象由以下几部分组成:
- Map (HiddenClass):描述对象形状
- Properties:指向命名属性存储
- Elements:指向编号属性存储
- In-Object Properties:初始化时定义的命名属性
Hidden Class
- 位于对象的前8字节(64位)或4字节(32位)
- 包含对象类型信息、属性描述等
- 相同Map的对象具有相同类型
属性存储方式
1. 快速属性(Fast Properties)
- In-object properties:直接存储在对象中
- Descriptor Array:通过Map Transition机制动态维护
2. 慢速属性(Dictionary Mode)
- 使用哈希表存储属性
- 适用于频繁删除属性的对象
编号属性(Elements)
- 存储在连续内存中
- 类型包括:
- SMI_ELEMENTS:小整数
- DOUBLE_ELEMENTS:浮点数
- ELEMENTS:其他类型
- 类型转换是单向的
5. 常用类型结构
Smi (小整数)
- 32位架构:31位值 + 0标志位
- 64位架构(旧版):32位值 + 32位0填充
指针
- 最低位为1表示指针
- 倒数第二位表示强弱引用
浮点数
- 64位存储
- 纯浮点数数组使用FixedDoubleArray优化
指针压缩
- 较新版本使用32位偏移+基址寄存器
- 减少内存使用
6. 函数调用栈
新版栈帧结构(从底到顶):
- 函数参数(按顺序压入)
- 参数个数(Argc)
- 返回地址
- 上一个栈帧指针
- JSFunction对象指针
- Context上下文指针
- BytecodeArray函数字节码指针
- BytecodeOffset(当前字节码偏移量)
- 局部变量("寄存器")
7. WASM特性
- 可以在JS引擎地址空间中导入可读可写可执行的内存页
- 示例:
let wasm_code = new Uint8Array([...]);
let wasm_mod = new WebAssembly.Instance(new WebAssembly.Module(wasm_code), {});
let f = wasm_mod.exports.main;
%SystemBreak();
8. 优化分析与Turbolizer
编译标志
--trace-turbo:生成优化过程信息--trace-turbo-path:指定输出路径--trace-opt:打印编译优化信息--trace-deopt--print-opt-code
Turbolizer使用
- 安装Node.js:
curl -fsSL https://deb.nodesource.com/setup_lts.x | sudo -E bash -
sudo apt-get install -y nodejs
- 启动Turbolizer:
cd v8/tools/turbolizer
npm install
npm run-script build
python -m SimpleHTTPServer
- 生成分析数据:
./d8 exp.js --allow-natives-syntax --trace-turbo --trace-turbo-path=/path/to/output
9. 示例代码分析
优化示例
function add(x, y) {
return x + y;
}
for (let i = 0; i < 10000; i++) {
add(i, i + 1);
}
%OptimizeFunctionOnNextCall(add);
console.log(add(1, 2));
对象结构分析
const obj = {name: "John", age: 30, hobbies: ["reading", "swimming"], 1: 111};
obj.city = "New York";
%DebugPrint(obj);
%SystemBreak();
10. 关键数据结构
ArrayBuffer
- 表示原始二进制数据缓冲区
- 示例:
let buffer = new ArrayBuffer(16);
let int32View = new Int32Array(buffer);
int32View[0] = 123456;
DataView
- 提供灵活的数据访问接口
- 示例:
let buffer = new ArrayBuffer(8);
let dataView = new DataView(buffer);
dataView.setInt16(0, 12345);
dataView.setFloat32(2, 3.1415);
总结
本文详细介绍了V8引擎的内部结构和工作原理,包括环境搭建、调试技巧、对象模型、类型系统、函数调用等核心概念,为深入理解V8漏洞利用和PWN技术奠定了坚实基础。