crackers 0.9.0

A tool for synthesizing Code Reuse Attacks (ROP chains) using Ghidra's p-code and Z3
Documentation
use std::collections::HashSet;
use std::fmt::{Debug, Display, Formatter};

use jingle::sleigh::OpCode;

use crate::config::error::CrackersConfigError;
use crate::config::sleigh::SleighConfig;
use crate::config::specification::SpecificationConfig;
use crate::reference_program::step::Step;
use crate::reference_program::valuation::MemoryValuation;

pub(crate) mod binary;
pub(crate) mod parsed_pcode;
pub(crate) mod step;
pub(crate) mod valuation;

#[derive(Debug, Clone, Default)]
pub struct ReferenceProgram {
    steps: Vec<Step>,
    initial_memory: MemoryValuation,
}

impl Display for ReferenceProgram {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        for (index, step) in self.steps.iter().enumerate() {
            writeln!(f, "Step {index}:")?;
            for x in step.instructions() {
                writeln!(f, "  {}", x.disassembly)?;
            }
        }
        Ok(())
    }
}

impl ReferenceProgram {
    pub fn try_load(
        spec: &SpecificationConfig,
        sleigh_config: &SleighConfig,
        blacklist: &HashSet<OpCode>,
        lang_id: &str,
    ) -> Result<Self, CrackersConfigError> {
        match spec {
            SpecificationConfig::BinaryFile(binary_file_specification) => {
                ReferenceProgram::try_load_binary(
                    binary_file_specification,
                    sleigh_config,
                    blacklist,
                )
            }
            SpecificationConfig::RawPcode(s) => {
                let sleigh = sleigh_config.context_builder()?.build(lang_id)?;
                ReferenceProgram::try_load_parsed_pcode(&sleigh, s)
            }
        }
    }
}