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.3";
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    /// Calling convention used for lifting, only `WindowsAbi`, and `Conservative` are supported.
38    pub calling_convention: String,
39    /// Max stack copy size in bytes when lifting.
40    pub max_stack_copy_size: u32,
41    /// Fallback: split on calls if lifting fails.
42    pub split_on_calls_fallback: bool,
43}
44
45/// IR optimization settings.
46#[derive(Debug, Serialize, Deserialize, Clone)]
47pub struct OptimizationSettings {
48    /// Enable constant propagation.
49    pub constant_propagation: bool,
50    /// Enable instruction combining.
51    pub instruction_combine: bool,
52    /// Enable dead code elimination.
53    pub dead_code_elim: bool,
54    /// Enable pruning of unused block parameters.
55    pub prune_useless_block_params: bool,
56    /// Number of optimization iterations to run.
57    pub iterations: u32,
58}
59
60/// Assembler-level codegen settings.
61#[derive(Debug, Serialize, Deserialize, Clone)]
62pub struct AssemblerSettings {
63    /// Whether to shuffle basic blocks.
64    pub shuffle_basic_blocks: bool,
65    /// Instruction prefix to prepend to emitted instructions.
66    pub instruction_prefix: String,
67    /// Chance of randomly applying the prefix.
68    pub random_prefix_chance: f64,
69}
70
71/// Compiler configuration (IR + codegen) for a profile.
72#[derive(Debug, Serialize, Deserialize, Clone)]
73pub struct CDCompilerSettings {
74    /// Assembler settings.
75    pub assembler_settings: AssemblerSettings,
76    /// Optimization settings.
77    pub optimization_settings: OptimizationSettings,
78    /// IR lifter settings.
79    pub lifter_settings: LifterSettings,
80}
81
82/// Fake PDB string settings to confuse debuggers.
83#[derive(Default, Debug, Serialize, Deserialize)]
84pub struct FakePdbString {
85    /// Whether the fake PDB string is enabled.
86    pub enabled: bool,
87    /// Value to emit as the fake PDB string.
88    pub value: String,
89}
90
91/// Custom `.text` section name override.
92#[derive(Default, Debug, Serialize, Deserialize)]
93pub struct CustomSectionName {
94    /// Whether this feature is enabled.
95    pub enabled: bool,
96    /// Custom section name value.
97    pub value: String,
98}
99
100/// Global obfuscation settings for the module.
101#[derive(Debug, Serialize, Deserialize)]
102pub struct CDModuleSettings {
103    /// Whether to crash the IDA decompiler intentionally.
104    #[serde(default)]
105    pub ida_crasher: bool,
106    /// Whether to enable IAT/Import protection.
107    #[serde(default)]
108    pub import_protection: bool,
109    /// Obscure the entry point of the module with anti tamper and anti debug tactics
110    #[serde(default)]
111    pub obscure_entry_point: bool,
112    /// Clear unwind information. makes it harder for attackers to locate functions, however
113    /// structured exception handling will not work.
114    #[serde(default)]
115    pub clear_unwind_info: bool,
116    /// Fake PDB string settings.
117    #[serde(default)]
118    pub fake_pdb_string: FakePdbString,
119    /// Custom PE section name settings.
120    #[serde(default)]
121    pub custom_section_name: CustomSectionName,
122}
123
124/// Instruction-level semantics used in transformations.
125#[derive(Debug, Serialize, Deserialize, Clone)]
126pub struct Semantics {
127    #[serde(default)]
128    pub add: bool,
129    #[serde(default)]
130    pub sub: bool,
131    #[serde(default)]
132    pub and: bool,
133    #[serde(default)]
134    pub xor: bool,
135    #[serde(default)]
136    pub or: bool,
137    #[serde(default)]
138    pub not: bool,
139    #[serde(default)]
140    pub neg: bool,
141}
142
143/// Bit widths to apply transformations to.
144#[derive(Debug, Serialize, Deserialize, Clone)]
145pub struct BitWidths {
146    #[serde(default)]
147    pub bit8: bool,
148    #[serde(default)]
149    pub bit16: bool,
150    #[serde(default)]
151    pub bit32: bool,
152    #[serde(default)]
153    pub bit64: bool,
154}
155
156/// Configuration for the Loop Encode Semantics pass.
157#[derive(Debug, Serialize, Deserialize, Clone)]
158pub struct LoopEncodeSemantics {
159    /// Number of times to attempt transformation.
160    pub iterations: u32,
161    /// Percent chance to apply transformation (0–100).
162    pub probability: u32,
163    /// Instruction semantics to consider.
164    pub semantics: Semantics,
165    /// Bit widths to target.
166    pub bitwidths: BitWidths,
167}
168
169/// Configuration for Mixed Boolean Arithmetic pass.
170#[derive(Debug, Serialize, Deserialize, Clone)]
171pub struct MixedBooleanArithmetic {
172    pub iterations: u32,
173    pub probability: u32,
174    pub semantics: Semantics,
175    pub bitwidths: BitWidths,
176}
177
178/// Configuration for Mutation Engine pass.
179#[derive(Debug, Serialize, Deserialize, Clone)]
180pub struct MutationEngine {
181    pub iterations: u32,
182    pub probability: u32,
183    pub extension: MutationEngineExtension,
184    pub semantics: Semantics,
185    pub bitwidths: BitWidths,
186}
187
188/// Pass that crashes IDA’s decompiler.
189#[derive(Debug, Serialize, Deserialize, Clone)]
190pub struct IDADecompilerCrasher;
191
192/// Constant obfuscation pass.
193#[derive(Debug, Serialize, Deserialize, Clone)]
194pub struct ObscureConstants;
195
196/// Memory reference obfuscation pass.
197#[derive(Debug, Serialize, Deserialize, Clone)]
198pub struct ObscureReferences;
199
200/// Control-flow obfuscation pass.
201#[derive(Debug, Serialize, Deserialize, Clone)]
202pub struct ObscureControlFlow {
203    pub probability: u32,
204}
205
206/// Tether extraction pass.
207#[derive(Debug, Serialize, Deserialize, Clone)]
208pub struct TetherExtraction {
209    /// Min length of a sequence of instructions that should be extracted.
210    /// Its a bad idea for this to be 1 usually because its easy to synthesize
211    pub min_extract_len: usize,
212    /// Tether server endpoint
213    pub endpoint: String,
214    /// Tether server port
215    pub port: u16,
216    /// Hex string of the servers public key. This is used for public key pinning.
217    /// This needs to be length 64...
218    pub server_public_key: String,
219}
220
221/// Opaque block duplication pass.
222#[derive(Debug, Serialize, Deserialize, Clone)]
223pub struct OpaqueBlockDuplication {
224    /// Number of iterations to attempt transformation.
225    pub iterations: u32,
226    /// Percent chance to apply transformation (0–100).
227    pub probability: u32,
228}
229
230/// All possible obfuscation passes.
231#[derive(Debug, Serialize, Deserialize, Clone)]
232#[serde(tag = "type")]
233pub enum ObfuscationPass {
234    LoopEncodeSemantics(LoopEncodeSemantics),
235    MixedBooleanArithmetic(MixedBooleanArithmetic),
236    MutationEngine(MutationEngine),
237    TetherExtraction(TetherExtraction),
238    IDADecompilerCrasher,
239    ObscureConstants,
240    ObscureReferences,
241    AntiEmulator,
242    OpaqueBlockDuplication(OpaqueBlockDuplication),
243    ObscureControlFlow(ObscureControlFlow),
244}
245
246/// Profile definition used to apply passes to symbols.
247#[derive(Debug, Serialize, Deserialize)]
248pub struct CDProfile {
249    /// Name of the profile.
250    pub name: String,
251    /// Obfuscation passes for this profile.
252    pub passes: Vec<ObfuscationPass>,
253    /// Compiler settings for this profile.
254    pub compiler_settings: CDCompilerSettings,
255    /// List of symbol RVAs this profile targets.
256    pub symbols: Vec<u64>,
257}
258
259/// Top-level config file structure.
260#[derive(Debug, Serialize, Deserialize)]
261pub struct CDConfig {
262    /// Module-wide settings.
263    pub module_settings: CDModuleSettings,
264    /// All profiles to apply during obfuscation.
265    pub profiles: Vec<CDProfile>,
266}
267
268/// Information about a single function found during analysis.
269#[derive(Deserialize, Serialize, Clone, Debug)]
270pub struct AnalysisFunction {
271    /// RVA of the function.
272    pub rva: u64,
273    /// Function name.
274    pub symbol: String,
275    /// Number of references to this function.
276    pub ref_count: usize,
277}
278
279/// Reason why a function was rejected from analysis.
280#[derive(Deserialize, Serialize, Clone, Debug)]
281pub struct AnalysisReject {
282    /// RVA of the rejected function.
283    pub rva: u64,
284    /// Symbol name.
285    pub symbol: String,
286    /// Mnemonic reason string (e.g., internal enum).
287    pub ty: String,
288    /// Stringified reason (human-readable).
289    pub reason: String,
290}
291
292/// Grouping of functions under a named macro profile.
293#[derive(Deserialize, Serialize, Clone, Debug)]
294pub struct AnalysisMacroProfile {
295    /// Name of the macro profile.
296    pub name: String,
297    /// List of function RVAs in this macro.
298    pub rvas: Vec<u64>,
299}
300
301/// Results from binary analysis, returned to the frontend.
302#[derive(Deserialize, Serialize, Clone, Debug)]
303pub struct AnalysisResult {
304    /// Environment type (UserMode, KernelMode, UEFI).
305    pub environment: PeEnvironment,
306    /// Functions found during analysis.
307    pub functions: Vec<AnalysisFunction>,
308    /// Rejected functions and reasons.
309    pub rejects: Vec<AnalysisReject>,
310    /// Macro profiles generated from analysis.
311    pub macros: Vec<AnalysisMacroProfile>,
312}
313
314/// Symbol representation used in YAML: either name or RVA.
315#[derive(Debug, Serialize, Deserialize)]
316pub enum YamlSymbol {
317    /// Symbol name
318    Name(String),
319    /// Symbol RVA.
320    Rva(u64),
321}
322
323/// Obfuscation profile for YAML configuration.
324#[derive(Debug, Serialize, Deserialize)]
325pub struct YamlProfile {
326    /// Profile name (referenced by source macros).
327    pub name: String,
328    /// Passes to apply to this profile.
329    pub passes: Vec<ObfuscationPass>,
330    /// Compiler configuration for this profile.
331    pub compiler_settings: CDCompilerSettings,
332    /// Symbols targeted by this profile.
333    pub symbols: Vec<YamlSymbol>,
334    /// Only used by the SaaS UI. Not used by the CLI.
335    pub color: Option<String>,
336}
337
338/// Root YAML config structure.
339#[derive(Debug, Serialize, Deserialize)]
340pub struct YamlConfig {
341    /// Version of the config file format.
342    pub version: String,
343    /// Global module-wide obfuscation settings.
344    pub module_settings: CDModuleSettings,
345    /// Obfuscation profiles to apply.
346    pub profiles: Vec<YamlProfile>,
347}