Skip to content

Commit

Permalink
use sha256 as function encrypt key
Browse files Browse the repository at this point in the history
  • Loading branch information
lapla-cogito committed Aug 24, 2024
1 parent 1e3d057 commit bd54089
Show file tree
Hide file tree
Showing 4 changed files with 148 additions and 71 deletions.
78 changes: 78 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,5 @@ anyhow = "1.0.86"
clap = { version = "4.5.3", features = ["derive"] }
memmap2 = "0.9.4"
rust-crypto = "0.2.36"
sha2 = "0.10.8"
thiserror = "1.0.63"
112 changes: 56 additions & 56 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -123,53 +123,51 @@ fn main() -> crate::error::Result<()> {

fn exec_obfus(input_path: &str, output_path: &str, args: &Args) -> crate::error::Result<()> {
let loader = obfus::Obfuscator::open(input_path, output_path);
let mut obfuscator = loader.unwrap();
let mut obfuscator = match loader {
Ok(obfuscator) => obfuscator,
Err(e) => return Err(e),
};

match obfuscator.is_elf() {
true => {
println!("start obfuscating {}...", input_path);
println!("start obfuscating {}...", input_path);

if args.class {
obfuscator.change_class();
}
if args.endian {
obfuscator.change_endian();
}
if args.sechdr {
obfuscator.nullify_sec_hdr();
}
if args.symbol {
obfuscator.nullify_section(".strtab")?;
}
if args.comment {
obfuscator.nullify_section(".comment")?;
}
if !args.section.is_empty() {
obfuscator.nullify_section(&args.section)?;
}
if args.got {
if args.got_l.is_empty() || args.got_f.is_empty() {
return Err(crate::error::Error::InvalidOption(
"both library and function names are required",
));
}

obfuscator.got_overwrite(&args.got_l, &args.got_f)?;
}
if args.encrypt {
if args.encrypt_f.is_empty() || args.encrypt_key.is_empty() {
return Err(crate::error::Error::InvalidOption(
"target function name and encryption key is required",
));
}

obfuscator.encrypt_function_name(&args.encrypt_f, &args.encrypt_key)?;
}
if args.class {
obfuscator.change_class();
}
if args.endian {
obfuscator.change_endian();
}
if args.sechdr {
obfuscator.nullify_sec_hdr();
}
if args.symbol {
obfuscator.nullify_section(".strtab")?;
}
if args.comment {
obfuscator.nullify_section(".comment")?;
}
if !args.section.is_empty() {
obfuscator.nullify_section(&args.section)?;
}
if args.got {
if args.got_l.is_empty() || args.got_f.is_empty() {
return Err(crate::error::Error::InvalidOption(
"both library and function names are required",
));
}

Ok(())
obfuscator.got_overwrite(&args.got_l, &args.got_f)?;
}
if args.encrypt {
if args.encrypt_f.is_empty() || args.encrypt_key.is_empty() {
return Err(crate::error::Error::InvalidOption(
"target function name and encryption key is required",
));
}
false => Err(crate::error::Error::InvalidMagic),

obfuscator.encrypt_function_name(&args.encrypt_f, &args.encrypt_key)?;
}

Ok(())
}

#[cfg(test)]
Expand All @@ -178,8 +176,8 @@ mod tests {

#[test]
fn not_elf() {
let file = std::fs::File::open("src/main.rs").unwrap();
assert!(unsafe { memmap2::Mmap::map(&file).unwrap()[0..4] != crate::obfus::HEADER_MAGIC });
let loader = crate::obfus::Obfuscator::open("src/main.rs", "foo");
assert!(matches!(loader, Err(crate::error::Error::InvalidMagic)));
}

#[test]
Expand Down Expand Up @@ -298,7 +296,7 @@ mod tests {
permissions.set_mode(0o755);
std::fs::set_permissions("bin/res_got", permissions).unwrap();
}

std::thread::sleep(std::time::Duration::from_millis(100));
let output = std::process::Command::new("./bin/res_got")
.output()
.expect("failed to execute res_got");
Expand All @@ -311,20 +309,22 @@ mod tests {

#[test]
fn encrypt_function_name() {
let loader = crate::obfus::Obfuscator::open("bin/test_64bit", "bin/res_encrypt");
let mut obfuscator = loader.unwrap();
obfuscator.encrypt_function_name("fac", "foo").unwrap();
{
let loader = crate::obfus::Obfuscator::open("bin/test_64bit", "bin/res_encrypt");
let mut obfuscator = loader.unwrap();
obfuscator.encrypt_function_name("fac", "foo").unwrap();
}

let output = std::process::Command::new("readelf")
.args(["-s", "bin/test_64bit"])
let output = std::process::Command::new("nm")
.args(["bin/test_64bit"])
.output()
.expect("failed to execute readelf");
assert!(String::from_utf8(output.stdout).is_ok());
.expect("failed to execute nm");
assert!(output.stdout.windows(3).any(|w| w == b"fac"));

let output = std::process::Command::new("readelf")
.args(["-s", "bin/res_encrypt"])
let output = std::process::Command::new("nm")
.args(["bin/res_encrypt"])
.output()
.expect("failed to execute readelf");
assert!(String::from_utf8(output.stdout).is_err());
.expect("failed to execute nm");
assert!(!output.stdout.windows(3).any(|w| w == b"fac"));
}
}
28 changes: 13 additions & 15 deletions src/obfus.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::io::Read as _;
use std::io::Write as _;

pub const HEADER_MAGIC: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46];
const HEADER_MAGIC: [u8; 4] = [0x7f, 0x45, 0x4c, 0x46];

#[repr(C, packed)]
#[derive(Debug)]
Expand Down Expand Up @@ -43,6 +43,11 @@ impl Obfuscator {
}
};

let input = unsafe { memmap2::Mmap::map(&file).map_err(crate::error::Error::Mmap)? };
if !Self::is_elf(&input) {
return Err(crate::error::Error::InvalidMagic);
}

let mut output_file = match std::fs::OpenOptions::new()
.read(true)
.write(true)
Expand All @@ -66,7 +71,6 @@ impl Obfuscator {
.write_all(&input_contents)
.map_err(crate::error::Error::Io)?;

let input = unsafe { memmap2::Mmap::map(&file).map_err(crate::error::Error::Mmap)? };
let output =
unsafe { memmap2::MmapMut::map_mut(&output_file).map_err(crate::error::Error::Mmap)? };

Expand Down Expand Up @@ -139,11 +143,11 @@ impl Obfuscator {
Ok(obfus)
}

pub fn is_elf(&self) -> bool {
self.input[0..4] == HEADER_MAGIC
fn is_elf(mmap: &memmap2::Mmap) -> bool {
mmap[0..4] == HEADER_MAGIC
}

pub fn is_64bit(&self) -> bool {
fn is_64bit(&self) -> bool {
self.input[4] == 2
}

Expand Down Expand Up @@ -323,16 +327,10 @@ impl Obfuscator {
}

pub fn encrypt_function_name(&mut self, function: &str, key: &str) -> crate::error::Result<()> {
let mut key_bytes = [0; 32];
if key.len() > 32 {
return Err(crate::error::Error::InvalidOption(
"key length must be less than 32",
));
}
for (i, byte) in key.bytes().enumerate() {
key_bytes[i] = byte;
}
let encryptor = crypto::aessafe::AesSafe256Encryptor::new(&key_bytes);
use sha2::digest::Digest as _;

let hash = sha2::Sha256::digest(key.as_bytes());
let encryptor = crypto::aessafe::AesSafe256Encryptor::new(&hash);

let tmp_file = std::fs::OpenOptions::new()
.read(true)
Expand Down

0 comments on commit bd54089

Please sign in to comment.