5个版本 (3个破坏性版本)

0.4.2 2024年2月21日
0.3.0 2023年7月1日
0.2.3 2024年2月21日
0.2.1 2022年10月4日
0.1.0 2021年10月20日

#78 in 硬件支持

每月下载量:36

Apache-2.0

620KB
12K SLoC

Rust 6K SLoC // 0.0% comments C 4.5K SLoC // 0.1% comments Visual Studio Project 1K SLoC

bddisasm x86/x64指令解码器

no_stdbddisasm x86/x64解码库提供的Rust绑定,构建在 bddisasm-sys 之上。

它支持所有现有的16位、32位和64位指令,并为每个指令提供广泛的信息,包括

  • 隐式操作数
  • 显式操作数
  • 每个操作数的访问模式
  • CPUID功能标志
  • 指令有效的CPU模式

用法

bddisasm 添加到您的 Cargo.toml

[dependencies]
bddisasm = "0.4"

示例

解码一条指令

使用 DecodedInstruction::decode 从代码块中解码指令。

use bddisasm::{DecodedInstruction, DecodeMode, Mnemonic};

let code = vec![0x31, 0xc0];
match DecodedInstruction::decode(&code, DecodeMode::Bits32) {
    Ok(ins) => {
        assert_eq!(ins.mnemonic(), Mnemonic::XOR);
        println!("{}", ins);
    },
    Err(err) => println!("Unable to decode: {}", err),
}

解码多条指令

使用 Decoder 从代码块中解码多条指令。

use bddisasm::{Decoder, DecodeMode};

let code = [
    // ENCLS
    0x0f, 0x01, 0xcf,
    // MOV       rax, qword ptr [rbx+rcx*4+0x1234]
    0x48, 0x8b, 0x84, 0x8b, 0x34, 0x12, 0x00, 0x00,
    // Not a valid instruction
    0x0f,
    // WRMSR
    0x0f, 0x30,
];
let decoder = Decoder::new(&code, DecodeMode::Bits64, 0x1234);

for ins in decoder {
    match ins {
        Ok(ins) => println!("{}", ins),
        Err(e) => println!("{}", e),
    }
}

这将打印

ENCLS
MOV       rax, qword ptr [rbx+rcx*4+0x1234]
the provided input buffer is too small
WRMSR

使用 Decoder::decode_next_with_info 获取关于在代码块中解码指令的位置的信息。

use bddisasm::{Decoder, DecodeMode};

let code = [
    // ENCLS
    0x0f, 0x01, 0xcf,
    // MOV       rax, qword ptr [rbx+rcx*4+0x1234]
    0x48, 0x8b, 0x84, 0x8b, 0x34, 0x12, 0x00, 0x00,
    // Not a valid instruction
    0x0f,
    // WRMSR
    0x0f, 0x30,
];
let mut decoder = Decoder::new(&code, DecodeMode::Bits64, 0x1234);


// Keep decoding until there's nothing left to decode
while let Some((result, offset, _)) = decoder.decode_next_with_info() {
    match result {
        Ok(ins) => println!("{:#x} {}", offset, ins),
        Err(e) => println!("Error: `{}` at offset {:#x}", e, offset),
    }
}

这将打印

0x0 ENCLS
0x3 MOV       rax, qword ptr [rbx+rcx*4+0x1234]
Error `the provided input buffer is too small` at offset 0xb
0xc WRMSR

处理指令操作数

可以使用 operand 模块分析指令操作数。为每种操作数类型提供丰富信息。以下是一个查看内存操作数的最小示例。

use bddisasm::{DecodedInstruction, DecodeMode, OpInfo};

// ` MOV       rax, qword ptr [rcx+r15*2]`
let code = b"\x4a\x8b\x04\x79";
let ins = DecodedInstruction::decode(code, DecodeMode::Bits64).unwrap();

// Get the operands
let operands = ins.operands();

// Get the second operand which is the source (`[rcx+r15*2]`)
let src = operands[1];

println!("Source operand type: {}", src.info);
match src.info {
    OpInfo::Mem(mem) => {
        if let Some(base) = mem.base {
            println!("Base register: {}", base);
        } else {
            println!("No base register");
        }

        if let Some(index) = mem.index {
            println!("Index register: {}", index);
        } else {
            println!("No index register");
        }

        if let Some(scale) = mem.scale {
            println!("Scale: {}", scale);
        } else {
            println!("No scale");
        }

        if let Some(displacement) = mem.disp {
            println!("Displacement: {}", displacement);
        } else {
            println!("No displacement");
        }
    },
    _ => unreachable!(),
}

将打印

Source operand type: memory
Base register: 1
Index register: 15
Scale: 2
No displacement

访问原始绑定

原始的 bddisasm_sys 绑定可通过 ffi 重新导出访问。

功能标志

  • std - 添加一个 std 依赖项 - 做这件事时唯一的可见区别是 DecodeError 实现了 Error 特性

依赖项

~0-2MB
~41K SLoC