Skip to content

Commit

Permalink
Updates Rust binding to the latest version.
Browse files Browse the repository at this point in the history
Fixed build in disasmtool_lix.
  • Loading branch information
vlutas committed Jan 5, 2022
1 parent fe6a937 commit 70db095
Show file tree
Hide file tree
Showing 27 changed files with 1,888 additions and 724 deletions.
7 changes: 7 additions & 0 deletions bindings/rsbddisasm/bddisasm-sys/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
# bddisasm-sys changelog

## Unreleased

### Changed

- the crate is now a `no_std` crate (this adds a dependency on [cty](https://crates.io/crates/cty))
5 changes: 3 additions & 2 deletions bindings/rsbddisasm/bddisasm-sys/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bddisasm-sys"
version = "0.1.0"
version = "0.1.1"
authors = ["Cristi Anichitei <ianichitei@bitdefender.com>"]
edition = "2018"
links = "bddisasm"
Expand All @@ -12,14 +12,15 @@ documentation = "https://docs.rs/bddisasm-sys"
description = """
Bindings to bddisasm instruction decoder library
"""
categories = ["external-ffi-bindings", "hardware-support"]
categories = ["external-ffi-bindings", "hardware-support", "no_std"]
keywords = ["disassembler", "decoder", "x86", "amd64", "x86_64"]

[lib]
name = "bddisasm_sys"
path = "src/lib.rs"

[dependencies]
cty = "0.2.2"

[build-dependencies]
bindgen = "0.59.1"
Expand Down
6 changes: 5 additions & 1 deletion bindings/rsbddisasm/bddisasm-sys/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
# bddisasm-sys

Rust bindings for [bddisasm](https://github.com/bitdefender/bddisasm).
`no_std` Rust bindings for [bddisasm](https://github.com/bitdefender/bddisasm).

See [bddisasm](https://crates.io/crates/bddisasm) if you're looking for a Rust wrapper for these bindings.

## Requirements

[bindgen](https://crates.io/crates/bindgen) is used to generate the bindings at build time. Because of this, users need to have `clang` installed. Check the [bindgen documentation](https://rust-lang.github.io/rust-bindgen/requirements.html) for more information.

## Notes

While this crate is `no_std`, the `bddisasm` library it links against depends on a C library because it needs `vsnprintf` and `memset`. It is possible to [work around this limitation](https://github.com/bitdefender/bddisasm#nd_vsnprintf_s-and-nd_memset), but this is not currently done for these bindings.
3 changes: 3 additions & 0 deletions bindings/rsbddisasm/bddisasm-sys/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ fn main() {
cc::Build::new()
.file("csrc/bddisasm/bddisasm.c")
.file("csrc/bddisasm/bdformat.c")
.file("csrc/bddisasm/bdhelpers.c")
.file("csrc/bddisasm/crt.c")
.include("csrc/bddisasm/include")
.include("csrc/inc")
Expand All @@ -24,6 +25,8 @@ fn main() {
.allowlist_type("ND.*")
.allowlist_var("ND.*")
.rustified_enum(".*")
.ctypes_prefix("cty")
.use_core()
.impl_debug(true)
.generate_comments(false)
.parse_callbacks(Box::new(bindgen::CargoCallbacks))
Expand Down
1 change: 1 addition & 0 deletions bindings/rsbddisasm/bddisasm-sys/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
//! [bindgen](https://crates.io/crates/bindgen) is used to generate the bindings at build time. Because of this, users
//! need to have `clang` installed.
//! Check the [bindgen documentation](https://rust-lang.github.io/rust-bindgen/requirements.html) for more information.
#![cfg_attr(not(test), no_std)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(non_upper_case_globals)]
Expand Down
17 changes: 17 additions & 0 deletions bindings/rsbddisasm/bddisasm/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# bddisasm changelog

## Unreleased

### Added

- implement `Decoder::decode_next_with_offset`
- implement ``Decoder::decode_next_with_ip`
- `OperandLookup` struct which makes working with operands easier
- re-export `bddisasm_sys` as `ffi`
- re-export commonly used items
- Implement `as_*` and `is_*` accessors for the `OpInfo` enum

### Changed

- the crate is now a `no_std` crate
- public types no longer implement `From` and no longer `panic!` when an unexpected value is encountered
12 changes: 11 additions & 1 deletion bindings/rsbddisasm/bddisasm/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "bddisasm"
version = "0.1.0"
version = "0.1.2"
authors = ["Cristi Anichitei <ianichitei@bitdefender.com>"]
edition = "2018"
license = "Apache-2.0"
Expand All @@ -15,3 +15,13 @@ keywords = ["disassembler", "decoder", "x86", "amd64", "x86_64"]

[dependencies]
bddisasm-sys = { version = "0.1.0", path = "../bddisasm-sys" }

[features]
std = []

[package.metadata."docs.rs"]
all-features = true

[dev-dependencies]
anyhow = "1.0"
clap = "2.34.0"
86 changes: 67 additions & 19 deletions bindings/rsbddisasm/bddisasm/README.md
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
# bddisasm
# bddisasm x86/x64 instruction decoder

Rust bindings for the [bddisasm](https://github.com/bitdefender/bddisasm) x86/x64 decoder library, built on top
of [bddisasm-sys](https://crates.io/crates/bddisasm-sys).
`no_std` Rust bindings for the [bddisasm](https://github.com/bitdefender/bddisasm) x86/x64 decoder library, built
on top of [bddisasm-sys](https://crates.io/crates/bddisasm-sys).

It supports all existing x86 instruction, offering a wide range of information about each one, including:
It supports all existing 16-bit, 32-bit and 64-bit instructions, offering a wide range of information about each one,
including:

- operands (implicit and explicit)
- implicit operands
- explicit operands
- access mode for each operand
- CPUID feature flags
- CPU modes in which an instruction is valid
Expand All @@ -23,8 +25,11 @@ bddisasm = "0.1.0"

### Decoding one instruction

```rust
use bddisasm::decoded_instruction::{DecodedInstruction, DecodeMode, Mnemonic};
Use [`DecodedInstruction::decode`](https://docs.rs/bddisasm/latest/bddisasm/decoded_instruction/struct.DecodedInstruction.html#method.decode)
to decode an instruction from a chunk of code.

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

let code = vec![0x31, 0xc0];
match DecodedInstruction::decode(&code, DecodeMode::Bits32) {
Expand All @@ -38,8 +43,11 @@ match DecodedInstruction::decode(&code, DecodeMode::Bits32) {

### Decoding multiple instructions

```rust
use bddisasm::decoder::{Decoder, DecodeMode};
Use [`Decoder`](https://docs.rs/bddisasm/latest/bddisasm/decoder/struct.Decoder.html) to decode multiple instructions
from a chunk of code.

```Rust
use bddisasm::{Decoder, DecodeMode};

let code = [
// ENCLS
Expand Down Expand Up @@ -70,21 +78,58 @@ the provided input buffer is too small
WRMSR
```

Use [`Decoder::decode_next_with_info`](https://docs.rs/bddisasm/latest/bddisasm/decoder/struct.Decoder.html#method.decode_next_with_info)
to get information about the offset inside the code chunk at which an instruction was decoded from.

```Rust
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),
}
}
```

This will print:

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

### Working with instruction operands

Rich informaion is offered for each type of operand. Bellow is a minimal example that looks at a memory operand.
Instruction operands can be analyzed using the [operand](https://docs.rs/bddisasm/latest/bddisasm/operand/index.html)
module. Rich informaion is offered for each type of operand. Bellow is a minimal example that looks at a memory operand.

```rust
# use bddisasm::decode_error::DecodeError;
# fn test() -> Result<(), DecodeError> {
use bddisasm::decoded_instruction::{DecodedInstruction, DecodeMode};
use bddisasm::operand::OpInfo;
```Rust
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];

Expand Down Expand Up @@ -117,8 +162,6 @@ match src.info {
},
_ => unreachable!(),
}
# Ok(())
# }
```

Will print:
Expand All @@ -131,6 +174,11 @@ Scale: 2
No displacement
```

## Requirements
## Accessing the raw bindings

The raw `bddisasm_sys` bindings are available via the `ffi` re-export.

## Feature Flags

Because [bddisasm-sys](https://crates.io/crates/bddisasm-sys) uses [bindgen](https://crates.io/crates/bindgen) to generate the bindings at build time, users need to have `clang` installed. Check the [bindgen documentation](https://rust-lang.github.io/rust-bindgen/requirements.html) for more information.
- `std` - adds a `std` dependency - the only visible difference when doing this is that [`DecodeError`] implements
the `Error` trait
Loading

0 comments on commit 70db095

Please sign in to comment.