From e3af8ef5065077a366cf2af460153f2ca804f698 Mon Sep 17 00:00:00 2001 From: maitrecraft1234 Date: Mon, 9 Sep 2024 23:40:45 +0200 Subject: [PATCH] hopefully boolean obfuscation is here making deadcode entrypoints a little more hidden --- src/main.rs | 1 + src/obfuscator/boolean.rs | 66 +++++++++++++++++++ src/obfuscator/dead_code_entry_points.rs | 6 +- .../{obfuscator_struct.rs => init.rs} | 23 ++++--- src/obfuscator/intergers.rs | 13 ++-- src/obfuscator/mod.rs | 11 +++- 6 files changed, 102 insertions(+), 18 deletions(-) create mode 100644 src/obfuscator/boolean.rs rename src/obfuscator/{obfuscator_struct.rs => init.rs} (66%) diff --git a/src/main.rs b/src/main.rs index bb49184..4d2c424 100644 --- a/src/main.rs +++ b/src/main.rs @@ -16,6 +16,7 @@ fn main() { let mut obfuscator = Obfuscator::new(code); obfuscator.instert_dead_branches(); + obfuscator.obfuscate_booleans(); obfuscator.obfuscate_strings(); obfuscator.obfuctate_functions(); obfuscator.obfuscate_integers(); diff --git a/src/obfuscator/boolean.rs b/src/obfuscator/boolean.rs new file mode 100644 index 0000000..721ec59 --- /dev/null +++ b/src/obfuscator/boolean.rs @@ -0,0 +1,66 @@ +use rand::thread_rng; +use rand::Rng; +use tree_sitter::{Tree, TreeCursor}; +use super::Shiftable; +use super::Obfuscator; + +fn get_bools(tree: &Tree) -> Vec> { + fn go(cursor: &mut TreeCursor, bools: &mut Vec>) { + let node = cursor.node(); + if node.kind() == "true" || node.kind() == "false" { + bools.push(node.start_byte()..node.end_byte()); + } + if cursor.goto_first_child() { + go(cursor, bools); + cursor.goto_parent(); + } + while cursor.goto_next_sibling() { + go(cursor, bools); + } + } + let mut bools = Vec::new(); + + go(&mut tree.walk(), &mut bools); + + bools +} + +fn random_args() -> String { + let mut rng = thread_rng(); + let args = rng.gen_range(1..10); + (0..args).map(|_| { + let arg : i32 = rng.gen(); + if rng.gen_bool(0.5) { + arg.to_string() + } else { + format!("\"{}\"", arg) + } + }).collect::>().join(", ") +} + +fn obfuctated_boolean(val: &str) -> String { + let val = match val { + "True" => format!("thruthy({})", random_args()), + "False" => format!("falsy({})", random_args()), + _ => {dbg!(val); panic!()},//unreachable!(), + }; + return format!("({} {})","not not ".repeat(thread_rng().gen_range(0..2)), val); +} + +impl Obfuscator { + pub fn obfuscate_booleans(&mut self) { + let bools = get_bools(&self.tree); + let mut shift = 0; + + bools.into_iter().for_each(|boolean| { + let boolean = boolean.shift(shift); + let val = &self.code[boolean.clone()]; + shift -= val.len() as i32; + let encoded = obfuctated_boolean(val); + + self.code.replace_range(boolean, &encoded); + shift += encoded.len() as i32; + }); + self.reparse(); + } +} diff --git a/src/obfuscator/dead_code_entry_points.rs b/src/obfuscator/dead_code_entry_points.rs index 0288aef..7139ba6 100644 --- a/src/obfuscator/dead_code_entry_points.rs +++ b/src/obfuscator/dead_code_entry_points.rs @@ -1,3 +1,5 @@ +use crate::obfuscator::init; + use super::Obfuscator; use rand::Rng; @@ -11,7 +13,7 @@ const RANDOM_USELESS_CODE: [&str; 5] = [ const DEAD_CODE_ENTRY_POINT: [&str; 6] = [ "if False:", - "if !True:", + "if not True:", "if 0 == 1:", "if 1 == 0:", "if 1 != 1:", @@ -38,7 +40,7 @@ impl Obfuscator { let iterations = rng.gen_range(1..lines / 3); for _ in 0..iterations { - let line = rng.gen_range(8..lines); // skip the helper function + let line = rng.gen_range(init::OBFUSCATOR_HELPER_FUNCTIONS.lines().count()..lines); // skip the helper function let code = self.code.clone(); self.code = code diff --git a/src/obfuscator/obfuscator_struct.rs b/src/obfuscator/init.rs similarity index 66% rename from src/obfuscator/obfuscator_struct.rs rename to src/obfuscator/init.rs index 10aff2b..6677d49 100644 --- a/src/obfuscator/obfuscator_struct.rs +++ b/src/obfuscator/init.rs @@ -1,12 +1,7 @@ -use tree_sitter::{Parser, Tree}; +use tree_sitter::Parser; +use super::Obfuscator; -pub struct Obfuscator { - pub code: String, - pub parser: Parser, - pub tree: Tree, -} - -const STRING_OBFUSCATOR_HELPER: &str = r#" +pub const OBFUSCATOR_HELPER_FUNCTIONS: &str = r#" def string_decode(string): string = list(string) if string == []: @@ -15,13 +10,23 @@ def string_decode(string): if ord(string[i]) >= 35 and ord(string[i]) <= 125: string[i] = chr(ord(string[i]) - 1) return ''.join(string) + +def useless(*args, **kwargs): + return + +def thruthy(*args, **kwargs): + return useless(args, kwargs) or 1 == int(float("01.0342671")) + +def falsy(*args, **kwargs): + return thruthy(args, value="awae", iteration=2) and str(2) == "the_number_two" + "#; impl Obfuscator { pub fn new(mut code: String) -> Self { let mut parser = Parser::new(); - code.insert_str(0, STRING_OBFUSCATOR_HELPER); + code.insert_str(0, OBFUSCATOR_HELPER_FUNCTIONS); parser .set_language(&tree_sitter_python::language()) .expect("error setting language"); diff --git a/src/obfuscator/intergers.rs b/src/obfuscator/intergers.rs index 6aabf76..e3853c1 100644 --- a/src/obfuscator/intergers.rs +++ b/src/obfuscator/intergers.rs @@ -26,14 +26,17 @@ fn get_ints(tree: &Tree) -> Vec> { } fn encode_int(int: &str) -> String { - let int = int.parse::().expect("int where fake ints =("); - let shift_key: i128 = thread_rng().gen_range(1..16); - let xor_key: i128 = thread_rng().gen_range(1..u32::MAX as i128); + let int = int.parse::().expect("int litteral might be too big =("); + let mut rng = thread_rng(); + let shift_key: i128 = rng.gen_range(1..16); + let xor_key: i128 = rng.gen_range(1..u32::MAX as i128); + let shift_mult: i128 = rng.gen_range(1..u32::MAX as i128); let encoded = int ^ (xor_key); let xor_key = xor_key << shift_key; + let shift_key = shift_key * shift_mult; - format!("({encoded}) ^ (({xor_key} ) >> {shift_key})") + format!("({encoded} ^ (({xor_key} ) >> ({shift_key} // {shift_mult})))") } impl Obfuscator { @@ -41,7 +44,7 @@ impl Obfuscator { let ints = get_ints(&self.tree); let mut shift = 0; - ints.into_iter().skip(3).for_each(|int| { + ints.into_iter().for_each(|int| { let int = int.shift(shift); let val = &self.code[int.clone()]; shift -= val.len() as i32; diff --git a/src/obfuscator/mod.rs b/src/obfuscator/mod.rs index e60af33..0be6f59 100644 --- a/src/obfuscator/mod.rs +++ b/src/obfuscator/mod.rs @@ -1,13 +1,20 @@ mod strings; mod print; mod functions; -mod obfuscator_struct; +mod init; mod intergers; mod boolean; mod dead_code_entry_points; -pub use obfuscator_struct::Obfuscator; mod random_identifiers; +use tree_sitter::{Parser, Tree}; + +pub struct Obfuscator { + code: String, + parser: Parser, + tree: Tree, +} + trait Shiftable { fn shift(&self, shift: i32) -> Self where