Skip to content

CutieDeng/rustc-pa

Repository files navigation

rustc-pa:私有字段可观测的 rustc wrapper

它是什么

  • 一个基于 rustc_driver 的编译器 wrapper,命名为 rustc-pa
  • 通过宏占位 + MIR 重写,在不修改上游 rustc 的前提下访问结构体私有字段。
  • 提供两种能力:
    • priv_access!:只读访问私有字段(字段需实现 Copy)。
    • priv_field_ptr!:获取字段的裸指针(可读写,保持可变性语义)。

适用场景

  • 调试、性能剖析、运行时观测、二进制插桩、ABI 研究等需要窥视内部状态的场景。
  • 需要避免手算 offset、兼容字段重排,或需要在不改动上游源码的前提下观测 std / 第三方库内部。

工作原理(简述)

  1. 宏展开为占位函数调用,携带父类型与字段名哈希(FNV-1a)。
  2. rustc-pa 覆写 mir_built,扫描占位调用并解析字段。
  3. 将调用重写为字段投影:
    • priv_access!Copy 读取字段。
    • priv_field_ptr! → 生成裸指针,保持 & / &mut 可变性。
  4. 未被 wrapper 处理时,占位函数会 panic,暴露配置错误。

特点与优势

  • 零 rustc 源码改动:独立二进制,直接通过 RUSTC_WRAPPER 注入。
  • 布局自适应:基于真实布局生成字段投影,无硬编码 offset。
  • 受控风险:只读访问要求字段 Copy;指针路径显式 unsafe
  • 清晰报错:类型非 struct、字段缺失/冲突、字段非 Copy 均在编译期报错。

快速上手

# 构建 wrapper(当前依赖 nightly,因为 rustc_private 仅在 nightly 提供)
cargo build -p priv_access_driver

# 使用时设置 RUSTC_WRAPPER
env RUSTC_WRAPPER=target/debug/priv_access_driver \
    RUSTUP_TOOLCHAIN=nightly \
    cargo test -p example --manifest-path tests/fixtures/priv_access_example/Cargo.toml

示例测试将读取/写入私有字段,验证 wrapper 生效。

发布与分发(GitHub)

  • 不上 crates.io,直接在 GitHub 发布构建好的 rustc-pa 二进制。
  • 建议流程:
    • cargo build -p priv_access_driver --release,产物位于 target/release/priv_access_driver
    • 在 Git 标签对应的 Release 附带各平台构建产物(可重命名为 rustc-pa 便于使用)。
    • 文档示例统一使用 RUSTC_WRAPPER=/path/to/rustc-pa,避免用户额外配置。

代码示例:跨模块越权读取与指针写入

// src/private_types.rs (被访问方,独立模块)
pub struct PrivateBox { value: i32 }
pub struct Pair { pub left: i32, right: i32 }
impl PrivateBox { pub fn new(v: i32) -> Self { Self { value: v } } }
impl Pair { pub fn new(l: i32, r: i32) -> Self { Self { left: l, right: r } } }

// src/lib.rs (访问方,非同一模块)
use priv_access::{priv_access, priv_field_ptr};
use crate::private_types::{Pair, PrivateBox};

fn demo_read(boxed: &PrivateBox) -> i32 {
    // 越权读取私有字段 value(字段需 Copy)
    unsafe { priv_access!(boxed, crate::private_types::PrivateBox, value) }
}

fn demo_write(pair: &mut Pair) {
    // 获取私有字段 right 的裸指针并写入
    let ptr: *mut i32 = unsafe { priv_field_ptr!(pair, crate::private_types::Pair, right) };
    unsafe { *ptr = 42 };
}

未来计划

  • 提供与 stable 版本对齐的预编译 rustc-pa 二进制,减少 nightly 依赖。
  • 丰富 UI/运行时测试,覆盖更多标准库内部场景。

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages