Skip to content

Commit b997244

Browse files
authored
pyo3 bindings (#21)
Initial cut at python API
1 parent 1eff062 commit b997244

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

70 files changed

+915
-857
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
11
/target
22
/bin
33
/.idea
4+
Cargo.lock

Cargo.toml

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,6 @@
1-
[package]
2-
name = "crackers"
3-
version = "0.1.0"
4-
edition = "2021"
5-
6-
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7-
8-
[[bin]]
9-
name = "crackers"
10-
required-features = ["bin"]
11-
12-
[[example]]
13-
name = "crackers_gpt"
14-
required-features = ["gpt"]
15-
16-
[features]
17-
default = ["toml"]
18-
bin = ["dep:tracing-subscriber", "toml", "dep:clap", "dep:anyhow", "dep:tracing-indicatif"]
19-
gpt = ["dep:tracing-subscriber", "dep:cc", "dep:anyhow", "dep:tempfile", "dep:tokio", "dep:async-openai", "dep:clap"]
20-
21-
toml = ["dep:toml_edit"]
22-
bundled = ["z3/bundled"]
1+
[workspace]
2+
resolver = "2"
3+
members = ["crackers", "crackers_python"]
234

245
[profile.dev]
256
opt-level = 3
26-
27-
[dependencies]
28-
jingle = { git = "https://github.com/toolCHAINZ/jingle", branch = "main", features = ["gimli"] }
29-
z3 = { git = "https://github.com/toolCHAINZ/z3.rs.git", branch = "patch-1" }
30-
serde = { version = "1.0.203", features = ["derive"] }
31-
thiserror = "1.0.58"
32-
rmp-serde = "1.1.2"
33-
tracing = "0.1.40"
34-
colored = "2.1.0"
35-
tracing-subscriber = { version = "0.3.18", optional = true, features = ["env-filter"] }
36-
toml_edit = { version = "0.22.12", optional = true, features = ["serde"] }
37-
object = "0.36.7"
38-
clap = { version = "4.0.32", optional = true , features = ["derive"]}
39-
rand = "0.8.5"
40-
derive_builder = "0.20.0"
41-
# gpt example deps
42-
async-openai = { version = "0.23.4", optional = true }
43-
cc = { version = "1.1.10", optional = true }
44-
anyhow = { version = "1.0.86", optional = true }
45-
tempfile = { version = "3.12.0", optional = true }
46-
tokio = { version = "1.39.2", optional = true, features = ["rt", "rt-multi-thread", "macros"] }
47-
tracing-indicatif = { version = "0.3.6", optional = true }

crackers/Cargo.toml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
[package]
2+
name = "crackers"
3+
version = "0.1.0"
4+
edition = "2021"
5+
6+
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
7+
8+
[[bin]]
9+
name = "crackers"
10+
required-features = ["bin"]
11+
12+
[features]
13+
default = ["toml"]
14+
bin = ["dep:tracing-subscriber", "toml", "dep:clap", "dep:anyhow", "dep:tracing-indicatif"]
15+
pyo3 = ["dep:pyo3", "jingle/pyo3"]
16+
toml = ["dep:toml_edit"]
17+
bundled = ["z3/bundled"]
18+
19+
[dependencies]
20+
jingle = { git = "https://github.com/toolCHAINZ/jingle", branch = "main", features = ["gimli"] }
21+
z3 = { git = "https://github.com/toolCHAINZ/z3.rs.git", branch = "patch-1" }
22+
serde = { version = "1.0.203", features = ["derive"] }
23+
thiserror = "2.0"
24+
tracing = "0.1"
25+
colored = "3.0"
26+
tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter"] }
27+
toml_edit = { version = "0.22", optional = true, features = ["serde"] }
28+
object = "0.36"
29+
clap = { version = "4.0", optional = true , features = ["derive"]}
30+
rand = "0.8"
31+
derive_builder = "0.20"
32+
anyhow = { version = "1.0", optional = true }
33+
tracing-indicatif = { version = "0.3", optional = true }
34+
pyo3 = { version = "0.24", optional = true }
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use z3::{Config, Context};
1414

1515
use crackers::bench::{bench, BenchCommand};
1616
use crackers::config::constraint::{
17-
Constraint, MemoryEqualityConstraint, PointerRange, PointerRangeConstraints,
17+
ConstraintConfig, MemoryEqualityConstraint, PointerRange, PointerRangeConstraints,
1818
StateEqualityConstraint,
1919
};
2020
use crackers::config::sleigh::SleighConfig;
@@ -64,7 +64,7 @@ fn new(path: PathBuf) -> anyhow::Result<()> {
6464
sleigh: SleighConfig {
6565
ghidra_path: "/Applications/ghidra".to_string(),
6666
},
67-
constraint: Some(Constraint {
67+
constraint: Some(ConstraintConfig {
6868
precondition: Some(StateEqualityConstraint {
6969
register: Some(HashMap::from([("ABC".to_string(), 123)])),
7070
memory: Some(MemoryEqualityConstraint {
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,21 +4,24 @@ use jingle::modeling::{ModeledBlock, ModelingContext, State};
44
use jingle::sleigh::{ArchInfoProvider, VarNode};
55
use jingle::varnode::{ResolvedIndirectVarNode, ResolvedVarnode};
66
use jingle::JingleContext;
7+
#[cfg(feature = "pyo3")]
8+
use pyo3::pyclass;
79
use serde::{Deserialize, Serialize};
810
use std::collections::HashMap;
911
use std::ops::Add;
1012
use std::sync::Arc;
1113
use tracing::{event, Level};
1214
use z3::ast::{Ast, Bool, BV};
1315

14-
#[derive(Clone, Debug, Deserialize, Serialize)]
15-
pub struct Constraint {
16+
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
17+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
18+
pub struct ConstraintConfig {
1619
pub precondition: Option<StateEqualityConstraint>,
1720
pub postcondition: Option<StateEqualityConstraint>,
1821
pub pointer: Option<PointerRangeConstraints>,
1922
}
2023

21-
impl Constraint {
24+
impl ConstraintConfig {
2225
pub fn get_preconditions<'a, T: ArchInfoProvider>(
2326
&'a self,
2427
sleigh: &'a T,
@@ -45,6 +48,7 @@ impl Constraint {
4548
}
4649

4750
#[derive(Clone, Debug, Deserialize, Serialize)]
51+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
4852
pub struct StateEqualityConstraint {
4953
pub register: Option<HashMap<String, i64>>,
5054
pub pointer: Option<HashMap<String, String>>,
@@ -94,14 +98,16 @@ impl StateEqualityConstraint {
9498
}
9599

96100
#[derive(Clone, Debug, Deserialize, Serialize)]
101+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
97102
pub struct MemoryEqualityConstraint {
98103
pub space: String,
99104
pub address: u64,
100105
pub size: usize,
101106
pub value: u8,
102107
}
103108

104-
#[derive(Clone, Debug, Deserialize, Serialize)]
109+
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
110+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
105111
pub struct PointerRangeConstraints {
106112
pub read: Option<Vec<PointerRange>>,
107113
pub write: Option<Vec<PointerRange>>,
@@ -113,6 +119,7 @@ impl PointerRangeConstraints {
113119
}
114120
}
115121
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
122+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
116123
pub struct PointerRange {
117124
pub min: u64,
118125
pub max: u64,
Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ use thiserror::Error;
44

55
#[derive(Debug, Error)]
66
pub enum CrackersConfigError {
7+
#[error("Invalid log level")]
8+
InvalidLogLevel,
79
#[error("An error reading a file referenced from the config")]
810
Io(#[from] std::io::Error),
911
#[error("An error parsing a file with gimli object: {0}")]
Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,13 @@
1+
#[cfg(feature = "pyo3")]
2+
use pyo3::pyclass;
13
use rand::random;
24
use serde::{Deserialize, Serialize};
35
use tracing::Level;
46

57
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
68
#[serde(rename_all = "UPPERCASE")]
9+
#[cfg_attr(feature = "pyo3", pyclass)]
710
pub enum CrackersLogLevel {
8-
#[serde(rename = "TRACE")]
911
Trace,
1012
Debug,
1113
Warn,
@@ -26,6 +28,7 @@ impl From<CrackersLogLevel> for Level {
2628
}
2729

2830
#[derive(Clone, Debug, Deserialize, Serialize)]
31+
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
2932
pub struct MetaConfig {
3033
#[serde(default = "random")]
3134
pub seed: i64,
Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
1-
use serde::{Deserialize, Serialize};
2-
3-
use crate::config::constraint::Constraint;
1+
use crate::config::constraint::ConstraintConfig;
42
use crate::config::meta::MetaConfig;
53
use crate::config::sleigh::SleighConfig;
64
use crate::config::specification::SpecificationConfig;
75
use crate::config::synthesis::SynthesisConfig;
86
use crate::error::CrackersError;
9-
use crate::gadget::library::builder::GadgetLibraryParams;
7+
use crate::gadget::library::builder::GadgetLibraryConfig;
108
use crate::synthesis::builder::{SynthesisParams, SynthesisParamsBuilder};
9+
use serde::{Deserialize, Serialize};
1110

1211
pub mod constraint;
1312
pub mod error;
@@ -18,14 +17,18 @@ pub mod specification;
1817
pub mod synthesis;
1918

2019
#[derive(Clone, Debug, Deserialize, Serialize)]
20+
/// This struct represents the serializable configuration found
21+
/// in a crackers .toml file. Once parsed from a file or constructed
22+
/// programmatically, it can be used to produce a [crate::synthesis::builder::SynthesisParams]
23+
/// struct, which can run the actual algorithm
2124
pub struct CrackersConfig {
2225
#[serde(default)]
2326
pub meta: MetaConfig,
2427
pub specification: SpecificationConfig,
25-
pub library: GadgetLibraryParams,
28+
pub library: GadgetLibraryConfig,
2629
pub sleigh: SleighConfig,
2730
pub synthesis: SynthesisConfig,
28-
pub constraint: Option<Constraint>,
31+
pub constraint: Option<ConstraintConfig>,
2932
}
3033

3134
impl CrackersConfig {

0 commit comments

Comments
 (0)