Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
/target
/bin
/.idea
Cargo.lock
47 changes: 3 additions & 44 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,47 +1,6 @@
[package]
name = "crackers"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[bin]]
name = "crackers"
required-features = ["bin"]

[[example]]
name = "crackers_gpt"
required-features = ["gpt"]

[features]
default = ["toml"]
bin = ["dep:tracing-subscriber", "toml", "dep:clap", "dep:anyhow", "dep:tracing-indicatif"]
gpt = ["dep:tracing-subscriber", "dep:cc", "dep:anyhow", "dep:tempfile", "dep:tokio", "dep:async-openai", "dep:clap"]

toml = ["dep:toml_edit"]
bundled = ["z3/bundled"]
[workspace]
resolver = "2"
members = ["crackers", "crackers_python"]

[profile.dev]
opt-level = 3

[dependencies]
jingle = { git = "https://github.com/toolCHAINZ/jingle", branch = "main", features = ["gimli"] }
z3 = { git = "https://github.com/toolCHAINZ/z3.rs.git", branch = "patch-1" }
serde = { version = "1.0.203", features = ["derive"] }
thiserror = "1.0.58"
rmp-serde = "1.1.2"
tracing = "0.1.40"
colored = "2.1.0"
tracing-subscriber = { version = "0.3.18", optional = true, features = ["env-filter"] }
toml_edit = { version = "0.22.12", optional = true, features = ["serde"] }
object = "0.36.7"
clap = { version = "4.0.32", optional = true , features = ["derive"]}
rand = "0.8.5"
derive_builder = "0.20.0"
# gpt example deps
async-openai = { version = "0.23.4", optional = true }
cc = { version = "1.1.10", optional = true }
anyhow = { version = "1.0.86", optional = true }
tempfile = { version = "3.12.0", optional = true }
tokio = { version = "1.39.2", optional = true, features = ["rt", "rt-multi-thread", "macros"] }
tracing-indicatif = { version = "0.3.6", optional = true }
34 changes: 34 additions & 0 deletions crackers/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
[package]
name = "crackers"
version = "0.1.0"
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[[bin]]
name = "crackers"
required-features = ["bin"]

[features]
default = ["toml"]
bin = ["dep:tracing-subscriber", "toml", "dep:clap", "dep:anyhow", "dep:tracing-indicatif"]
pyo3 = ["dep:pyo3", "jingle/pyo3"]
toml = ["dep:toml_edit"]
bundled = ["z3/bundled"]

[dependencies]
jingle = { git = "https://github.com/toolCHAINZ/jingle", branch = "main", features = ["gimli"] }
z3 = { git = "https://github.com/toolCHAINZ/z3.rs.git", branch = "patch-1" }
serde = { version = "1.0.203", features = ["derive"] }
thiserror = "2.0"
tracing = "0.1"
colored = "3.0"
tracing-subscriber = { version = "0.3", optional = true, features = ["env-filter"] }
toml_edit = { version = "0.22", optional = true, features = ["serde"] }
object = "0.36"
clap = { version = "4.0", optional = true , features = ["derive"]}
rand = "0.8"
derive_builder = "0.20"
anyhow = { version = "1.0", optional = true }
tracing-indicatif = { version = "0.3", optional = true }
pyo3 = { version = "0.24", optional = true }
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ use z3::{Config, Context};

use crackers::bench::{bench, BenchCommand};
use crackers::config::constraint::{
Constraint, MemoryEqualityConstraint, PointerRange, PointerRangeConstraints,
ConstraintConfig, MemoryEqualityConstraint, PointerRange, PointerRangeConstraints,
StateEqualityConstraint,
};
use crackers::config::sleigh::SleighConfig;
Expand Down Expand Up @@ -64,7 +64,7 @@ fn new(path: PathBuf) -> anyhow::Result<()> {
sleigh: SleighConfig {
ghidra_path: "/Applications/ghidra".to_string(),
},
constraint: Some(Constraint {
constraint: Some(ConstraintConfig {
precondition: Some(StateEqualityConstraint {
register: Some(HashMap::from([("ABC".to_string(), 123)])),
memory: Some(MemoryEqualityConstraint {
Expand Down
15 changes: 11 additions & 4 deletions src/config/constraint.rs → crackers/src/config/constraint.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,21 +4,24 @@ use jingle::modeling::{ModeledBlock, ModelingContext, State};
use jingle::sleigh::{ArchInfoProvider, VarNode};
use jingle::varnode::{ResolvedIndirectVarNode, ResolvedVarnode};
use jingle::JingleContext;
#[cfg(feature = "pyo3")]
use pyo3::pyclass;
use serde::{Deserialize, Serialize};
use std::collections::HashMap;
use std::ops::Add;
use std::sync::Arc;
use tracing::{event, Level};
use z3::ast::{Ast, Bool, BV};

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Constraint {
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct ConstraintConfig {
pub precondition: Option<StateEqualityConstraint>,
pub postcondition: Option<StateEqualityConstraint>,
pub pointer: Option<PointerRangeConstraints>,
}

impl Constraint {
impl ConstraintConfig {
pub fn get_preconditions<'a, T: ArchInfoProvider>(
&'a self,
sleigh: &'a T,
Expand All @@ -45,6 +48,7 @@ impl Constraint {
}

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

#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct MemoryEqualityConstraint {
pub space: String,
pub address: u64,
pub size: usize,
pub value: u8,
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[derive(Clone, Debug, Deserialize, Serialize, Default)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct PointerRangeConstraints {
pub read: Option<Vec<PointerRange>>,
pub write: Option<Vec<PointerRange>>,
Expand All @@ -113,6 +119,7 @@ impl PointerRangeConstraints {
}
}
#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct PointerRange {
pub min: u64,
pub max: u64,
Expand Down
2 changes: 2 additions & 0 deletions src/config/error.rs → crackers/src/config/error.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ use thiserror::Error;

#[derive(Debug, Error)]
pub enum CrackersConfigError {
#[error("Invalid log level")]
InvalidLogLevel,
#[error("An error reading a file referenced from the config")]
Io(#[from] std::io::Error),
#[error("An error parsing a file with gimli object: {0}")]
Expand Down
5 changes: 4 additions & 1 deletion src/config/meta.rs → crackers/src/config/meta.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
#[cfg(feature = "pyo3")]
use pyo3::pyclass;
use rand::random;
use serde::{Deserialize, Serialize};
use tracing::Level;

#[derive(Copy, Clone, Debug, Deserialize, Serialize)]
#[serde(rename_all = "UPPERCASE")]
#[cfg_attr(feature = "pyo3", pyclass)]
pub enum CrackersLogLevel {
#[serde(rename = "TRACE")]
Trace,
Debug,
Warn,
Expand All @@ -26,6 +28,7 @@ impl From<CrackersLogLevel> for Level {
}

#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct MetaConfig {
#[serde(default = "random")]
pub seed: i64,
Expand Down
15 changes: 9 additions & 6 deletions src/config/mod.rs → crackers/src/config/mod.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
use serde::{Deserialize, Serialize};

use crate::config::constraint::Constraint;
use crate::config::constraint::ConstraintConfig;
use crate::config::meta::MetaConfig;
use crate::config::sleigh::SleighConfig;
use crate::config::specification::SpecificationConfig;
use crate::config::synthesis::SynthesisConfig;
use crate::error::CrackersError;
use crate::gadget::library::builder::GadgetLibraryParams;
use crate::gadget::library::builder::GadgetLibraryConfig;
use crate::synthesis::builder::{SynthesisParams, SynthesisParamsBuilder};
use serde::{Deserialize, Serialize};

pub mod constraint;
pub mod error;
Expand All @@ -18,14 +17,18 @@ pub mod specification;
pub mod synthesis;

#[derive(Clone, Debug, Deserialize, Serialize)]
/// This struct represents the serializable configuration found
/// in a crackers .toml file. Once parsed from a file or constructed
/// programmatically, it can be used to produce a [crate::synthesis::builder::SynthesisParams]
/// struct, which can run the actual algorithm
pub struct CrackersConfig {
#[serde(default)]
pub meta: MetaConfig,
pub specification: SpecificationConfig,
pub library: GadgetLibraryParams,
pub library: GadgetLibraryConfig,
pub sleigh: SleighConfig,
pub synthesis: SynthesisConfig,
pub constraint: Option<Constraint>,
pub constraint: Option<ConstraintConfig>,
}

impl CrackersConfig {
Expand Down
File renamed without changes.
38 changes: 38 additions & 0 deletions crackers/src/config/sleigh.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
use jingle::sleigh::context::SleighContextBuilder;
#[cfg(feature = "pyo3")]
use pyo3::{pyclass, pymethods};
use serde::{Deserialize, Serialize};

use crate::config::error::CrackersConfigError;

#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct SleighConfig {
pub ghidra_path: String,
}

impl SleighConfig {
pub fn context_builder(&self) -> Result<SleighContextBuilder, CrackersConfigError> {
let b = SleighContextBuilder::load_ghidra_installation(&self.ghidra_path)?;
Ok(b)
}
}

#[cfg(feature = "pyo3")]
#[pymethods]
impl SleighConfig {
#[new]
fn new(ghidra_path: String) -> Self {
SleighConfig { ghidra_path }
}

#[getter]
fn ghidra_path(&self) -> String {
self.ghidra_path.clone()
}

#[setter]
fn set_ghidra_path(&mut self, ghidra_path: String) {
self.ghidra_path = ghidra_path;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ use std::fs;
use jingle::sleigh::context::loaded::LoadedSleighContext;
use jingle::sleigh::Instruction;
use object::{File, Object, ObjectSymbol};
#[cfg(feature = "pyo3")]
use pyo3::{pyclass, pymethods};
use serde::{Deserialize, Serialize};

use crate::config::error::CrackersConfigError;
Expand All @@ -11,12 +13,56 @@ use crate::config::object::load_sleigh_spec;
use crate::config::sleigh::SleighConfig;

#[derive(Clone, Debug, Deserialize, Serialize)]
#[cfg_attr(feature = "pyo3", pyclass(get_all, set_all))]
pub struct SpecificationConfig {
pub path: String,
pub max_instructions: usize,
pub base_address: Option<u64>,
}

#[cfg(feature = "pyo3")]
#[pymethods]
impl SpecificationConfig {
#[new]
fn new(path: String, max_instructions: usize, base_address: Option<u64>) -> Self {
Self {
path,
max_instructions,
base_address,
}
}

#[getter]
fn get_path(&self) -> String {
self.path.clone()
}

#[setter]
fn set_path(&mut self, path: String) {
self.path = path;
}

#[getter]
fn get_max_instructions(&self) -> usize {
self.max_instructions
}

#[setter]
fn set_max_instructions(&mut self, max_instructions: usize) {
self.max_instructions = max_instructions;
}

#[getter]
fn get_base_address(&self) -> Option<u64> {
self.base_address
}

#[setter]
fn set_base_address(&mut self, address: u64) {
self.base_address = Some(address);
}
}

impl SpecificationConfig {
fn load_sleigh<'a>(
&self,
Expand Down
Loading