codedefender_config/
lib.rs

1//! `codedefender-config` provides the Rust data structures used for serializing and deserializing
2//! CodeDefender YAML configuration files and analysis results. These structures are used by both
3//! the CodeDefender CLI and its backend services.
4//!
5//! This crate is intended to be consumed by tools that integrate with or generate CodeDefender config files.
6
7use serde::{Deserialize, Serialize};
8
9/// Current supported YAML config version.
10pub const YAML_CONFIG_VERSION: &str = "1.0.0";
11
12/// Available SIMD extension types used by mutation engines.
13#[derive(Debug, Serialize, Deserialize, Clone)]
14pub enum MutationEngineExtension {
15    /// Generic (no special SIMD usage)
16    Generic,
17    /// SSE-enabled
18    SSE,
19}
20
21/// Supported PE environments.
22#[derive(Debug, Clone, Copy, Eq, PartialEq, PartialOrd, Ord, Serialize, Deserialize)]
23pub enum PeEnvironment {
24    /// User-mode PE (exe, dll)
25    UserMode,
26    /// Kernel-mode PE (sys)
27    KernelMode,
28    /// UEFI firmware image
29    UEFI,
30}
31
32/// Configuration settings for lifting x86 instructions into IR.
33#[derive(Debug, Serialize, Deserialize, Clone)]
34pub struct LifterSettings {
35    /// Whether to lift calls into IR.
36    pub lift_calls: bool,
37    /// Max stack copy size in bytes when lifting.
38    pub max_stack_copy_size: u32,
39    /// Fallback: split on calls if lifting fails.
40    pub split_on_calls_fallback: bool,
41}
42
43/// IR optimization settings.
44#[derive(Debug, Serialize, Deserialize, Clone)]
45pub struct OptimizationSettings {
46    /// Enable constant propagation.
47    pub constant_propagation: bool,
48    /// Enable instruction combining.
49    pub instruction_combine: bool,
50    /// Enable dead code elimination.
51    pub dead_code_elim: bool,
52    /// Enable pruning of unused block parameters.
53    pub prune_useless_block_params: bool,
54    /// Number of optimization iterations to run.
55    pub iterations: u32,
56}
57
58/// Assembler-level codegen settings.
59#[derive(Debug, Serialize, Deserialize, Clone)]
60pub struct AssemblerSettings {
61    /// Whether to shuffle basic blocks.
62    pub shuffle_basic_blocks: bool,
63    /// Instruction prefix to prepend to emitted instructions.
64    pub instruction_prefix: String,
65    /// Chance of randomly applying the prefix.
66    pub random_prefix_chance: f64,
67}
68
69/// Compiler configuration (IR + codegen) for a profile.
70#[derive(Debug, Serialize, Deserialize, Clone)]
71pub struct CDCompilerSettings {
72    /// Assembler settings.
73    pub assembler_settings: AssemblerSettings,
74    /// Optimization settings.
75    pub optimization_settings: OptimizationSettings,
76    /// IR lifter settings.
77    pub lifter_settings: LifterSettings,
78}
79
80/// Fake PDB string settings to confuse debuggers.
81#[derive(Debug, Serialize, Deserialize)]
82pub struct FakePdbString {
83    /// Whether the fake PDB string is enabled.
84    pub enabled: bool,
85    /// Value to emit as the fake PDB string.
86    pub value: String,
87}
88
89/// Custom `.text` section name override.
90#[derive(Debug, Serialize, Deserialize)]
91pub struct CustomSectionName {
92    /// Whether this feature is enabled.
93    pub enabled: bool,
94    /// Custom section name value.
95    pub value: String,
96}
97
98/// Global obfuscation settings for the module.
99#[derive(Debug, Serialize, Deserialize)]
100pub struct CDModuleSettings {
101    /// Whether to crash the IDA decompiler intentionally.
102    pub ida_crasher: bool,
103    /// Whether to enable IAT/Import protection.
104    pub import_protection: bool,
105    /// Fake PDB string settings.
106    pub fake_pdb_string: FakePdbString,
107    /// Custom PE section name settings.
108    pub custom_section_name: CustomSectionName,
109}
110
111/// Instruction-level semantics used in transformations.
112#[derive(Debug, Serialize, Deserialize, Clone)]
113pub struct Semantics {
114    pub add: bool,
115    pub sub: bool,
116    pub and: bool,
117    pub xor: bool,
118    pub or: bool,
119    pub not: bool,
120    pub neg: bool,
121}
122
123/// Bit widths to apply transformations to.
124#[derive(Debug, Serialize, Deserialize, Clone)]
125pub struct BitWidths {
126    pub bit8: bool,
127    pub bit16: bool,
128    pub bit32: bool,
129    pub bit64: bool,
130}
131
132/// Configuration for the Loop Encode Semantics pass.
133#[derive(Debug, Serialize, Deserialize, Clone)]
134pub struct LoopEncodeSemantics {
135    /// Number of times to attempt transformation.
136    pub iterations: u32,
137    /// Percent chance to apply transformation (0–100).
138    pub probability: u32,
139    /// Instruction semantics to consider.
140    pub semantics: Semantics,
141    /// Bit widths to target.
142    pub bitwidths: BitWidths,
143}
144
145/// Configuration for Mixed Boolean Arithmetic pass.
146#[derive(Debug, Serialize, Deserialize, Clone)]
147pub struct MixedBooleanArithmetic {
148    pub iterations: u32,
149    pub probability: u32,
150    pub semantics: Semantics,
151    pub bitwidths: BitWidths,
152}
153
154/// Configuration for Mutation Engine pass.
155#[derive(Debug, Serialize, Deserialize, Clone)]
156pub struct MutationEngine {
157    pub iterations: u32,
158    pub probability: u32,
159    pub extension: MutationEngineExtension,
160    pub semantics: Semantics,
161    pub bitwidths: BitWidths,
162}
163
164/// Pass that crashes IDA’s decompiler.
165#[derive(Debug, Serialize, Deserialize, Clone)]
166pub struct IDADecompilerCrasher;
167
168/// Constant obfuscation pass.
169#[derive(Debug, Serialize, Deserialize, Clone)]
170pub struct ObscureConstants;
171
172/// Memory reference obfuscation pass.
173#[derive(Debug, Serialize, Deserialize, Clone)]
174pub struct ObscureReferences;
175
176/// Control-flow obfuscation pass.
177#[derive(Debug, Serialize, Deserialize, Clone)]
178pub struct ObscureControlFlow;
179
180/// All possible obfuscation passes.
181#[derive(Debug, Serialize, Deserialize, Clone)]
182#[serde(tag = "type")]
183pub enum ObfuscationPass {
184    LoopEncodeSemantics(LoopEncodeSemantics),
185    MixedBooleanArithmetic(MixedBooleanArithmetic),
186    MutationEngine(MutationEngine),
187    IDADecompilerCrasher,
188    ObscureConstants,
189    ObscureReferences,
190    ObscureControlFlow,
191}
192
193/// Profile definition used to apply passes to symbols.
194#[derive(Debug, Serialize, Deserialize)]
195pub struct CDProfile {
196    /// Name of the profile.
197    pub name: String,
198    /// Obfuscation passes for this profile.
199    pub passes: Vec<ObfuscationPass>,
200    /// Compiler settings for this profile.
201    pub compiler_settings: CDCompilerSettings,
202    /// List of symbol RVAs this profile targets.
203    pub symbols: Vec<u64>,
204}
205
206/// Top-level config file structure.
207#[derive(Debug, Serialize, Deserialize)]
208pub struct CDConfig {
209    /// Module-wide settings.
210    pub module_settings: CDModuleSettings,
211    /// All profiles to apply during obfuscation.
212    pub profiles: Vec<CDProfile>,
213}
214
215/// Information about a single function found during analysis.
216#[derive(Deserialize, Serialize, Clone, Debug)]
217pub struct AnalysisFunction {
218    /// RVA of the function.
219    pub rva: u64,
220    /// Function name.
221    pub symbol: String,
222    /// Number of references to this function.
223    pub ref_count: usize,
224}
225
226/// Reason why a function was rejected from analysis.
227#[derive(Deserialize, Serialize, Clone, Debug)]
228pub struct AnalysisReject {
229    /// RVA of the rejected function.
230    pub rva: u64,
231    /// Symbol name.
232    pub symbol: String,
233    /// Mnemonic reason string (e.g., internal enum).
234    pub ty: String,
235    /// Stringified reason (human-readable).
236    pub reason: String,
237}
238
239/// Grouping of functions under a named macro profile.
240#[derive(Deserialize, Serialize, Clone, Debug)]
241pub struct AnalysisMacroProfile {
242    /// Name of the macro profile.
243    pub name: String,
244    /// List of function RVAs in this macro.
245    pub rvas: Vec<u64>,
246}
247
248/// Results from binary analysis, returned to the frontend.
249#[derive(Deserialize, Serialize, Clone, Debug)]
250pub struct AnalysisResult {
251    /// Environment type (UserMode, KernelMode, UEFI).
252    pub environment: PeEnvironment,
253    /// Functions found during analysis.
254    pub functions: Vec<AnalysisFunction>,
255    /// Rejected functions and reasons.
256    pub rejects: Vec<AnalysisReject>,
257    /// Macro profiles generated from analysis.
258    pub macros: Vec<AnalysisMacroProfile>,
259}
260
261/// Symbol representation used in YAML: either name or RVA.
262#[derive(Debug, Serialize, Deserialize)]
263pub enum YamlSymbol {
264    /// Symbol name
265    Name(String),
266    /// Symbol RVA.
267    Rva(u64),
268}
269
270/// Obfuscation profile for YAML configuration.
271#[derive(Debug, Serialize, Deserialize)]
272pub struct YamlProfile {
273    /// Profile name (referenced by source macros).
274    pub name: String,
275    /// Passes to apply to this profile.
276    pub passes: Vec<ObfuscationPass>,
277    /// Compiler configuration for this profile.
278    pub compiler_settings: CDCompilerSettings,
279    /// Symbols targeted by this profile.
280    pub symbols: Vec<YamlSymbol>,
281    /// Only used by the SaaS UI. Not used by the CLI.
282    pub color: Option<String>,
283}
284
285/// Root YAML config structure.
286#[derive(Debug, Serialize, Deserialize)]
287pub struct YamlConfig {
288    /// Version of the config file format.
289    pub version: String,
290    /// Global module-wide obfuscation settings.
291    pub module_settings: CDModuleSettings,
292    /// Obfuscation profiles to apply.
293    pub profiles: Vec<YamlProfile>,
294}