dmg_cracker/
dmg.rs

1use random_string::generate;
2use std::io::Write;
3use std::process::{Command, Stdio};
4
5const BASE_MOUNT_PATH: &str = "/tmp/";
6
7pub struct Dmg {
8    pub dmg_path: String,
9    pub mount_path: String,
10}
11
12impl Dmg {
13    pub fn new(dmg_path: &str) -> Self {
14        Self {
15            dmg_path: dmg_path.to_string(),
16            mount_path: generate_random_string(),
17        }
18    }
19
20    pub fn attempt_password(&self, password: &str) -> bool {
21        self.attempt_attach(password)
22    }
23
24    fn attempt_attach(&self, password: &str) -> bool {
25        let mut child = match Command::new("hdiutil")
26            .arg("verify")
27            .arg("-stdinpass")
28            .arg("-quiet")
29            .arg(&self.dmg_path)
30            .stdin(Stdio::piped())
31            .stdout(Stdio::null())
32            .stderr(Stdio::null())
33            .spawn()
34        {
35            Ok(child) => child,
36            Err(e) => {
37                eprintln!("❌ Error: Failed to execute hdiutil command: {e}");
38                eprintln!("💡 Please ensure:");
39                eprintln!("   - You're running on macOS (hdiutil is required)");
40                eprintln!("   - You have permission to access the DMG file");
41                eprintln!("   - The DMG file exists and is not corrupted");
42                return false;
43            }
44        };
45
46        if let Some(stdin) = child.stdin.as_mut() {
47            if let Err(e) = stdin.write_all(password.as_bytes()) {
48                eprintln!("❌ Error: Failed to write password to hdiutil: {e}");
49                return false;
50            }
51        } else {
52            eprintln!("❌ Error: Failed to get stdin handle for hdiutil");
53            return false;
54        }
55
56        match child.wait_with_output() {
57            Ok(output) => output.status.success(),
58            Err(e) => {
59                eprintln!("❌ Error: Failed to wait for hdiutil process: {e}");
60                false
61            }
62        }
63    }
64}
65
66pub fn generate_random_string() -> String {
67    format!(
68        "{}{}",
69        BASE_MOUNT_PATH,
70        generate(6, "abcdefghijklmnopqrstuvwxyz")
71    )
72}