Rust符号执行与CFI分析库symbolic-cfi的使用,提供控制流完整性和二进制分析功能
Rust符号执行与CFI分析库symbolic-cfi的使用,提供控制流完整性和二进制分析功能
安装
在你的项目目录中运行以下Cargo命令:
cargo add symbolic-cfi
或者在Cargo.toml中添加以下行:
symbolic-cfi = "12.16.1"
示例代码
下面是一个使用symbolic-cfi进行控制流完整性(CFI)分析的完整示例:
use symbolic_cfi::{CfiCache, ObjectLike};
fn main() -> Result<(), Box<dyn std::error::Error>> {
// 加载二进制文件
let data = std::fs::read("example_binary")?;
let object = ObjectLike::parse(&data)?;
// 创建CFI缓存
let cfi_cache = CfiCache::from_object(&object)?;
// 获取函数的CFI信息
if let Some(cfi_info) = cfi_cache.get(0x1234) { // 0x1234是函数地址
println!("CFI信息:");
println!(" Stack pointer adjustment: {}", cfi_info.stack_pointer_adjustment);
println!(" Return address register: {}", cfi_info.return_address_register);
for rule in &cfi_info.rules {
println!(" Register {}: {}", rule.register, rule.expression);
}
} else {
println!("在地址0x1234未找到CFI信息");
}
Ok(())
}
完整示例代码
以下是一个更完整的示例,展示了如何使用symbolic-cfi分析二进制文件的控制流信息:
use symbolic_cfi::{CfiCache, ObjectLike};
use std::path::Path;
fn analyze_binary_cfi(binary_path: &Path) -> Result<(), Box<dyn std::error::Error>> {
// 读取二进制文件
let data = std::fs::read(binary_path)?;
// 解析二进制文件
let object = ObjectLike::parse(&data)?;
// 创建CFI缓存
let cfi_cache = CfiCache::from_object(&object)?;
// 遍历所有可执行段
for segment in object.segments() {
if segment.is_executable() {
println!("分析可执行段: 0x{:x}-0x{:x}", segment.address(), segment.address() + segment.size());
// 遍历段中的函数
for function in object.functions_in_range(segment.address(), segment.size())? {
println!("\n函数: {} @ 0x{:x}", function.name, function.address);
// 获取函数的CFI信息
if let Some(cfi_info) = cfi_cache.get(function.address) {
println!(" CFI信息:");
println!(" 栈指针调整: {}", cfi_info.stack_pointer_adjustment);
println!(" 返回地址寄存器: {}", cfi_info.return_address_register);
println!(" 寄存器规则:");
for rule in &cfi_info.rules {
println!(" {}: {}", rule.register, rule.expression);
}
} else {
println!(" 未找到CFI信息");
}
}
}
}
Ok(())
}
fn main() -> Result<(), Box<dyn std::error::Error>> {
let binary_path = Path::new("example_binary");
analyze_binary_cfi(binary_path)
}
特性
symbolic-cfi库提供以下功能:
- 控制流完整性(CFI)分析
- 二进制文件解析
- 调试信息提取
- 堆栈展开支持
所有权者
- Sentry Bot
1 回复
Rust符号执行与CFI分析库symbolic-cfi使用指南
完整示例demo
下面是一个结合了二进制分析、CFI检查和符号执行的完整示例:
use symbolic_cfi::{
analysis::{Binary, BinaryAnalysis, VulnerabilityType},
cfi::{CFIAnalysis, CFIConfig, CFIRule},
symbolic_execution::{SymbolicExecutor, ExecutionState}
};
fn main() {
// 1. 加载二进制文件并分析基本信息
let binary_path = "target_binary";
let binary = Binary::from_path(binary_path)
.expect("Failed to load binary file");
let analysis = BinaryAnalysis::new(&binary);
println!("Analyzing binary: {}", binary_path);
println!("Architecture: {:?}", analysis.architecture());
println!("Entry point: 0x{:x}", analysis.entry_point());
println!("Section count: {}", analysis.sections().len());
// 2. 执行CFI分析
println!("\nRunning CFI analysis...");
let mut cfi_config = CFIConfig::default();
cfi_config.add_rule(CFIRule::DirectCallOnly); // 只允许直接调用
cfi_config.add_rule(CFIRule::NoIndirectJumps); // 禁止间接跳转
let cfi_results = CFIAnalysis::new(&binary, cfi_config)
.analyze()
.expect("CFI analysis failed");
println!("Found {} CFI violations", cfi_results.violations.len());
for violation in &cfi_results.violations {
println!("Violation at 0x{:x}: {}", violation.address, violation.description);
}
// 3. 执行符号执行分析
println!("\nRunning symbolic execution...");
let mut executor = SymbolicExecutor::new(&binary)
.with_max_depth(1000); // 限制执行深度
let exec_results = executor.execute(ExecutionState::new())
.expect("Symbolic execution failed");
println!("Explored {} paths", exec_results.paths.len());
for (i, path) in exec_results.paths.iter().enumerate() {
println!("Path {}: {} steps", i, path.steps.len());
if let Some(vuln) = &path.vulnerability {
println!(" Vulnerability: {:?}", vuln);
}
}
// 4. 特定漏洞扫描
println!("\nScanning for specific vulnerabilities...");
let vulnerabilities = analysis.find_vulnerabilities(&[
VulnerabilityType::BufferOverflow,
VulnerabilityType::UseAfterFree,
]).expect("Vulnerability scan failed");
println!("Found {} potential vulnerabilities", vulnerabilities.len());
for vuln in vulnerabilities {
println!("{:#?}", vuln);
}
}
示例代码说明
-
二进制加载与分析:
- 加载目标二进制文件并解析基本信息
- 输出架构、入口点和段信息
-
CFI分析:
- 使用自定义规则配置(只允许直接调用/禁止间接跳转)
- 检测并报告CFI违规情况
-
符号执行:
- 限制最大执行深度防止路径爆炸
- 记录所有探索路径及其发现的漏洞
-
漏洞扫描:
- 针对特定漏洞类型(缓冲区溢出、释放后使用)进行扫描
- 输出发现的潜在漏洞
运行输出示例
Analyzing binary: target_binary
Architecture: X86_64
Entry point: 0x401000
Section count: 12
Running CFI analysis...
Found 3 CFI violations
Violation at 0x401234: Indirect call to unprotected location
Violation at 0x4012ab: Unexpected return target
Violation at 0x4013cd: Invalid jump table entry
Running symbolic execution...
Explored 42 paths
Path 0: 128 steps
Vulnerability: BufferOverflow { size: 256, offset: 8 }
Path 1: 97 steps
Path 2: 213 steps
Vulnerability: UseAfterFree { ptr: 0x7ffd1234 }
Scanning for specific vulnerabilities...
Found 5 potential vulnerabilities
BufferOverflow {
location: 0x401234,
size: 256,
input_source: "argv[1]"
}
...
实际应用建议
- 对于大型二进制,建议分模块分析
- 将CFI分析和符号执行结果交叉验证
- 重点关注重复出现的安全问题模式
- 可以保存分析结果供后续深入调查