From 929f013713362044d3876ad6e10c15679da447f2 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Sat, 21 Oct 2023 11:39:04 +0200 Subject: [PATCH 01/20] copy from mitmproxy_rs macos-proc branch --- mitmproxy-rs/src/util.rs | 4 +-- src/{macos.rs => macos/certificates.rs} | 0 src/macos/mod.rs | 2 ++ src/macos/processes.rs | 42 +++++++++++++++++++++++++ 4 files changed, 46 insertions(+), 2 deletions(-) rename src/{macos.rs => macos/certificates.rs} (100%) create mode 100644 src/macos/mod.rs create mode 100644 src/macos/processes.rs diff --git a/mitmproxy-rs/src/util.rs b/mitmproxy-rs/src/util.rs index c403556d..55798f22 100644 --- a/mitmproxy-rs/src/util.rs +++ b/mitmproxy-rs/src/util.rs @@ -90,7 +90,7 @@ pub fn add_cert(py: Python<'_>, pem: String) -> PyResult<()> { return Err(anyhow!("{} does not exist", executable_path.display()).into()); } let der = BASE64.decode(pem_body.as_bytes()).unwrap(); - match macos::add_cert(der, executable_path.to_str().unwrap()) { + match macos::certificates::add_cert(der, executable_path.to_str().unwrap()) { Ok(_) => Ok(()), Err(e) => Err(PyErr::new::(format!( "Failed to add certificate: {:?}", @@ -109,7 +109,7 @@ pub fn add_cert(py: Python<'_>, pem: String) -> PyResult<()> { pub fn remove_cert() -> PyResult<()> { #[cfg(target_os = "macos")] { - match macos::remove_cert() { + match macos::certificates::remove_cert() { Ok(_) => Ok(()), Err(e) => Err(PyErr::new::(format!( "Failed to remove certificate: {:?}", diff --git a/src/macos.rs b/src/macos/certificates.rs similarity index 100% rename from src/macos.rs rename to src/macos/certificates.rs diff --git a/src/macos/mod.rs b/src/macos/mod.rs new file mode 100644 index 00000000..42004f34 --- /dev/null +++ b/src/macos/mod.rs @@ -0,0 +1,2 @@ +pub mod certificates; +// pub mod processes; diff --git a/src/macos/processes.rs b/src/macos/processes.rs new file mode 100644 index 00000000..67b0db54 --- /dev/null +++ b/src/macos/processes.rs @@ -0,0 +1,42 @@ +use anyhow::Result; +use objc2::ffi::id; +use objc2::msg_send; +use objc2::class; +use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt}; +use crate::processes::ProcessList; + +pub fn active_executables() -> Result { + + let mut sys = System::new(); + sys.refresh_processes_specifics(ProcessRefreshKind::new()); + for proc in sys.processes() { + dbg!(proc); + + let int_value = proc.0.as_u32(); + let pid: i32 = msg_send![pid, intValue]; + let p: id = msg_send![ + class!(NSRunningApplication), + runningApplicationWithProcessIdentifier: proc.0.as_u32() + ]; + + + } + + Ok(vec![]) +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn process_list() { + let lst = active_executables().unwrap(); + assert!(!lst.is_empty()); + + for proc in &lst { + dbg!(proc); + } + dbg!(lst.len()); + } +} From f9054e34471fe5b81a4595771538b4ba8ae3cd4a Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Sat, 21 Oct 2023 11:40:02 +0200 Subject: [PATCH 02/20] gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5bbe27c8..b7c19106 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,4 @@ /docs/ __pycache__/ *.xcuserstate +*.DS_Store From a1679d31396e42ac3b9b79c8bd2852b2948bc48c Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Sun, 22 Oct 2023 07:15:25 +0200 Subject: [PATCH 03/20] icrate --- Cargo.lock | 78 ++++++++++++++++++++++++++++++++++++++++++ Cargo.toml | 4 +++ src/macos/mod.rs | 2 +- src/macos/processes.rs | 50 +++++++++++++++++++++++---- 4 files changed, 127 insertions(+), 7 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index fe5f1e15..703f7e3d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -248,6 +248,25 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-sys" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" +dependencies = [ + "objc-sys", +] + +[[package]] +name = "block2" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" +dependencies = [ + "block-sys", + "objc2", +] + [[package]] name = "boringtun" version = "0.6.0" @@ -1074,6 +1093,16 @@ dependencies = [ "tokio-io-timeout", ] +[[package]] +name = "icrate" +version = "0.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" +dependencies = [ + "block2", + "objc2", +] + [[package]] name = "image" version = "0.24.7" @@ -1352,15 +1381,18 @@ dependencies = [ "criterion", "env_logger", "futures-util", + "icrate", "image", "log", "nix 0.27.1", + "objc2", "once_cell", "pretty-hex", "prost", "rand", "rand_core", "smoltcp", + "sysinfo", "tokio", "tokio-util", "windows 0.51.1", @@ -1420,6 +1452,15 @@ dependencies = [ "minimal-lexical", ] +[[package]] +name = "ntapi" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8a3895c6391c39d7fe7ebc444a87eb2991b2a0bc718fdabd071eec617fc68e4" +dependencies = [ + "winapi", +] + [[package]] name = "num-integer" version = "0.1.45" @@ -1460,6 +1501,28 @@ dependencies = [ "libc", ] +[[package]] +name = "objc-sys" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845" + +[[package]] +name = "objc2" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +dependencies = [ + "objc-sys", + "objc2-encode", +] + +[[package]] +name = "objc2-encode" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" + [[package]] name = "object" version = "0.32.1" @@ -2126,6 +2189,21 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2047c6ded9c721764247e62cd3b03c09ffc529b2ba5b10ec482ae507a4a70160" +[[package]] +name = "sysinfo" +version = "0.29.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0a18d114d420ada3a891e6bc8e96a2023402203296a47cdd65083377dad18ba5" +dependencies = [ + "cfg-if", + "core-foundation-sys", + "libc", + "ntapi", + "once_cell", + "rayon", + "winapi", +] + [[package]] name = "tar" version = "0.4.40" diff --git a/Cargo.toml b/Cargo.toml index 682f2b00..5dd8a69e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,6 +45,10 @@ prost = "0.12.0" tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } +objc2 = "0.4.1" +sysinfo = "0.29.10" +icrate = {version = "0.0.4", features = ["AppKit"]} + # [patch.crates-io] # tokio = { path = "../tokio/tokio" } # smoltcp = { git = 'https://github.com/mhils/smoltcp', rev = 'f65351adfa92db5193f368368cb668bac721fe43' } diff --git a/src/macos/mod.rs b/src/macos/mod.rs index 42004f34..3e9436df 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -1,2 +1,2 @@ pub mod certificates; -// pub mod processes; +pub mod processes; diff --git a/src/macos/processes.rs b/src/macos/processes.rs index 67b0db54..eb812d6a 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,11 +1,47 @@ use anyhow::Result; +use objc2::runtime::NSObject; +use objc2::runtime::NSObjectProtocol; use objc2::ffi::id; use objc2::msg_send; use objc2::class; use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt}; use crate::processes::ProcessList; +use objc2::{extern_class, msg_send_id, mutability, ClassType}; +use icrate::AppKit::NSRunningApplication; +// extern_class!( +// #[derive(Debug, PartialEq, Eq, Hash)] +// #[cfg(feature = "AppKit_NSRunningApplication")] +// pub struct NSRunningApplication; +// +// #[cfg(feature = "AppKit_NSRunningApplication")] +// unsafe impl ClassType for NSRunningApplication { +// type Super = NSObject; +// type Mutability = InteriorMutable; +// } +// ); +// extern_class!( +// /// An example description. +// #[derive(PartialEq, Eq, Hash)] // Uses the superclass' implementation +// // Specify the class and struct name to be used +// pub struct NSRunningApplication; +// +// // Specify the superclass, in this case `NSObject` +// unsafe impl ClassType for NSRunningApplication { +// type Super = NSObject; +// type Mutability = mutability::InteriorMutable; +// // Optionally, specify the name of the class, if it differs from +// // the struct name. +// // const NAME: &'static str = "NSFormatter"; +// } +// ); +// unsafe impl NSObjectProtocol for NSRunningApplication {} + // pub executable: PathBuf, + // pub display_name: String, + // pub is_visible: bool, + // pub is_system: bool, pub fn active_executables() -> Result { + dbg!("active_executables"); let mut sys = System::new(); sys.refresh_processes_specifics(ProcessRefreshKind::new()); @@ -13,12 +49,14 @@ pub fn active_executables() -> Result { dbg!(proc); let int_value = proc.0.as_u32(); - let pid: i32 = msg_send![pid, intValue]; - let p: id = msg_send![ - class!(NSRunningApplication), - runningApplicationWithProcessIdentifier: proc.0.as_u32() - ]; - + // let cls = NSRunningApplication::class(); + unsafe{ + let p: i32 = msg_send![ + class!(NSRunningApplication), + runningApplicationWithProcessIdentifier: int_value + ]; + dbg!(p); + }; } From 54034d83a0a7450ecdf45dbe7934bf8bc291e080 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Mon, 23 Oct 2023 20:25:41 +0200 Subject: [PATCH 04/20] test with objc and cocoa --- Cargo.lock | 150 ++++++++++++++++++++++++++++------------- Cargo.toml | 5 +- src/macos/processes.rs | 46 +++++++++---- 3 files changed, 136 insertions(+), 65 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 703f7e3d..421b53bb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,6 +239,12 @@ dependencies = [ "digest", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -248,25 +254,6 @@ dependencies = [ "generic-array", ] -[[package]] -name = "block-sys" -version = "0.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2dd7cf50912cddc06dc5ea7c08c5e81c1b2c842a70d19def1848d54c586fed92" -dependencies = [ - "objc-sys", -] - -[[package]] -name = "block2" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b55663a85f33501257357e6421bb33e769d5c9ffb5ba0921c975a123e35e68" -dependencies = [ - "block-sys", - "objc2", -] - [[package]] name = "boringtun" version = "0.6.0" @@ -423,6 +410,36 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -482,6 +499,30 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -795,6 +836,33 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "futures" version = "0.3.28" @@ -1093,16 +1161,6 @@ dependencies = [ "tokio-io-timeout", ] -[[package]] -name = "icrate" -version = "0.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99d3aaff8a54577104bafdf686ff18565c3b6903ca5782a2026ef06e2c7aa319" -dependencies = [ - "block2", - "objc2", -] - [[package]] name = "image" version = "0.24.7" @@ -1289,6 +1347,15 @@ dependencies = [ "apple-security-framework", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "managed" version = "0.8.0" @@ -1377,15 +1444,15 @@ dependencies = [ "apple-security-framework", "async-trait", "boringtun", + "cocoa", "console-subscriber", "criterion", "env_logger", "futures-util", - "icrate", "image", "log", "nix 0.27.1", - "objc2", + "objc", "once_cell", "pretty-hex", "prost", @@ -1502,27 +1569,14 @@ dependencies = [ ] [[package]] -name = "objc-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "99e1d07c6eab1ce8b6382b8e3c7246fe117ff3f8b34be065f5ebace6749fe845" - -[[package]] -name = "objc2" -version = "0.4.1" +name = "objc" +version = "0.2.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "559c5a40fdd30eb5e344fbceacf7595a81e242529fb4e21cf5f43fb4f11ff98d" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" dependencies = [ - "objc-sys", - "objc2-encode", + "malloc_buf", ] -[[package]] -name = "objc2-encode" -version = "3.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d079845b37af429bfe5dfa76e6d087d788031045b25cfc6fd898486fd9847666" - [[package]] name = "object" version = "0.32.1" diff --git a/Cargo.toml b/Cargo.toml index 5dd8a69e..50229f8d 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,10 +45,9 @@ prost = "0.12.0" tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } -objc2 = "0.4.1" +objc = "0.2" sysinfo = "0.29.10" -icrate = {version = "0.0.4", features = ["AppKit"]} - +cocoa = "0.25.0" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } # smoltcp = { git = 'https://github.com/mhils/smoltcp', rev = 'f65351adfa92db5193f368368cb668bac721fe43' } diff --git a/src/macos/processes.rs b/src/macos/processes.rs index eb812d6a..a6fbc96a 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,13 +1,15 @@ use anyhow::Result; -use objc2::runtime::NSObject; -use objc2::runtime::NSObjectProtocol; -use objc2::ffi::id; -use objc2::msg_send; -use objc2::class; +//use objc::runtime::AnyClass; use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt}; use crate::processes::ProcessList; -use objc2::{extern_class, msg_send_id, mutability, ClassType}; -use icrate::AppKit::NSRunningApplication; + +use cocoa::appkit::NSRunningApplication; + +use cocoa::{ + base::{id, nil}, +}; +use objc::{sel, msg_send, class}; + // extern_class!( // #[derive(Debug, PartialEq, Eq, Hash)] // #[cfg(feature = "AppKit_NSRunningApplication")] @@ -47,15 +49,31 @@ pub fn active_executables() -> Result { sys.refresh_processes_specifics(ProcessRefreshKind::new()); for proc in sys.processes() { dbg!(proc); - - let int_value = proc.0.as_u32(); + //dbg!(AnyClass::classes_count()); + pub type pid_t = i32; + let int_value: pid_t = proc.0.as_u32() as i32; // let cls = NSRunningApplication::class(); + //let nsrunning = class!(NSRunningApplication); unsafe{ - let p: i32 = msg_send![ - class!(NSRunningApplication), - runningApplicationWithProcessIdentifier: int_value - ]; - dbg!(p); + //let current_app = NSRunningApplication::runningApplicationWithProcessIdentifier(nil, int_value); + let app_class = class!(NSRunningApplication); + let app: id = msg_send![app_class, currentApplication]; + let app_name: id = msg_send![app, localizedName]; + //let app_name: id = msg_send![current_app, localizedName]; + dbg!(app_name); + //current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps); + // let superclass = class!(NSObject); + // let mut decl = objc2::declare::ClassBuilder::new("NSRunningApplication", superclass).unwrap(); + // decl.register(); + //dbg!(AnyClass::get("NSRunningApplication")); + // let app_class = class!(NSRunningApplication); + // let app_with_process_id: *mut Object = msg_send![ + // app_class, + // runningApplicationWithProcessIdentifier: process_id as i64 + // ]; + //let app_class = class!(NSRunningApplication); + //let p: i32 = msg_send![ app_class, runningApplicationWithProcessIdentifier: int_value ]; + //dbg!(p); }; } From 96e56cd3a1048ad227089d24c4801521d0a02d49 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Tue, 24 Oct 2023 20:30:46 +0200 Subject: [PATCH 05/20] tst --- Cargo.lock | 108 +---------------------------------------- Cargo.toml | 5 +- src/macos/processes.rs | 79 ++++++++++++++++++++++++------ 3 files changed, 67 insertions(+), 125 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 421b53bb..92dcbe8f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -239,12 +239,6 @@ dependencies = [ "digest", ] -[[package]] -name = "block" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" - [[package]] name = "block-buffer" version = "0.10.4" @@ -410,36 +404,6 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" -[[package]] -name = "cocoa" -version = "0.25.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" -dependencies = [ - "bitflags 1.3.2", - "block", - "cocoa-foundation", - "core-foundation", - "core-graphics", - "foreign-types", - "libc", - "objc", -] - -[[package]] -name = "cocoa-foundation" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" -dependencies = [ - "bitflags 1.3.2", - "block", - "core-foundation", - "core-graphics-types", - "libc", - "objc", -] - [[package]] name = "color_quant" version = "1.1.0" @@ -499,30 +463,6 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" -[[package]] -name = "core-graphics" -version = "0.23.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "core-graphics-types", - "foreign-types", - "libc", -] - -[[package]] -name = "core-graphics-types" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" -dependencies = [ - "bitflags 1.3.2", - "core-foundation", - "libc", -] - [[package]] name = "cpufeatures" version = "0.2.9" @@ -836,33 +776,6 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" -[[package]] -name = "foreign-types" -version = "0.5.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" -dependencies = [ - "foreign-types-macros", - "foreign-types-shared", -] - -[[package]] -name = "foreign-types-macros" -version = "0.2.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.37", -] - -[[package]] -name = "foreign-types-shared" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" - [[package]] name = "futures" version = "0.3.28" @@ -1347,15 +1260,6 @@ dependencies = [ "apple-security-framework", ] -[[package]] -name = "malloc_buf" -version = "0.0.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" -dependencies = [ - "libc", -] - [[package]] name = "managed" version = "0.8.0" @@ -1444,15 +1348,14 @@ dependencies = [ "apple-security-framework", "async-trait", "boringtun", - "cocoa", "console-subscriber", "criterion", "env_logger", "futures-util", "image", + "libc", "log", "nix 0.27.1", - "objc", "once_cell", "pretty-hex", "prost", @@ -1568,15 +1471,6 @@ dependencies = [ "libc", ] -[[package]] -name = "objc" -version = "0.2.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" -dependencies = [ - "malloc_buf", -] - [[package]] name = "object" version = "0.32.1" diff --git a/Cargo.toml b/Cargo.toml index 50229f8d..43d49894 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -45,9 +45,10 @@ prost = "0.12.0" tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } -objc = "0.2" sysinfo = "0.29.10" -cocoa = "0.25.0" +# cacao = "0.3.2" +# objc = "0.2" +libc = "0.2" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } # smoltcp = { git = 'https://github.com/mhils/smoltcp', rev = 'f65351adfa92db5193f368368cb668bac721fe43' } diff --git a/src/macos/processes.rs b/src/macos/processes.rs index a6fbc96a..2d9ee8e5 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -3,13 +3,13 @@ use anyhow::Result; use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt}; use crate::processes::ProcessList; -use cocoa::appkit::NSRunningApplication; - -use cocoa::{ - base::{id, nil}, -}; -use objc::{sel, msg_send, class}; +//use cocoa::appkit::NSRunningApplication; +// use cacao::foundation::{id, nil, NSString, NSURL, BOOL}; +// use objc::{sel, sel_impl, msg_send, class}; +use std::ptr; +use std::os::raw::{c_char, c_int}; +use libc::{proc_pidpath, proc_name,PROC_PIDPATHINFO_MAXSIZE, c_void, PROC_PIDTBSDINFO, proc_pidinfo, proc_bsdinfo}; // extern_class!( // #[derive(Debug, PartialEq, Eq, Hash)] // #[cfg(feature = "AppKit_NSRunningApplication")] @@ -44,23 +44,70 @@ use objc::{sel, msg_send, class}; pub fn active_executables() -> Result { dbg!("active_executables"); - let mut sys = System::new(); sys.refresh_processes_specifics(ProcessRefreshKind::new()); for proc in sys.processes() { - dbg!(proc); + // dbg!(proc); //dbg!(AnyClass::classes_count()); - pub type pid_t = i32; - let int_value: pid_t = proc.0.as_u32() as i32; + //let int_value: pid_t = proc.0.as_u32() as i32; // let cls = NSRunningApplication::class(); //let nsrunning = class!(NSRunningApplication); - unsafe{ + unsafe { + // let mut path_buffer: [c_char; PROC_PIDPATHINFO_MAXSIZE as usize] = [0; PROC_PIDPATHINFO_MAXSIZE as usize]; + // let mut name_buffer: [c_char; 256] = [0; 256]; + const PROC_PIDTBSDINFO_SIZE:usize = std::mem::size_of::(); + let mut bsd_info: [c_char; PROC_PIDTBSDINFO_SIZE] = [0; PROC_PIDTBSDINFO_SIZE]; + + let ret = proc_pidinfo(proc.0.as_u32() as i32, PROC_PIDTBSDINFO, 0, bsd_info.as_mut_ptr() as *mut c_void, PROC_PIDTBSDINFO_SIZE as i32); + let bsd_info_struct: proc_bsdinfo = std::mem::transmute(bsd_info); + if ret as usize == PROC_PIDTBSDINFO_SIZE { + println!("Process ID: {}", bsd_info_struct.pbi_pid); + println!("Process Name: {:?}", std::ffi::CStr::from_ptr(bsd_info_struct.pbi_comm.as_ptr())); + println!("Process status: {:?}", bsd_info_struct.pbi_status); + } else { + println!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); + println!("Error for pid {}", proc.0.as_u32()); + println!("Process ID: {}", bsd_info_struct.pbi_pid); + println!("Process Name: {:?}", std::ffi::CStr::from_ptr(bsd_info_struct.pbi_comm.as_ptr())); + println!("Process status: {:?}", bsd_info_struct.pbi_status); + println!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); + } + + // proc_pidpath(proc.0.as_u32() as i32, path_buffer.as_mut_ptr() as *mut c_void, PROC_PIDPATHINFO_MAXSIZE as u32); + // proc_name(proc.0.as_u32() as i32, name_buffer.as_mut_ptr() as *mut c_void, size_of_val); + + // let path_str = std::ffi::CStr::from_ptr(path_buffer.as_ptr()).to_str().unwrap(); + // let name_str = std::ffi::CStr::from_ptr(name_buffer.as_ptr()).to_str().unwrap(); + + // println!("Path: {}\nName: {}", path_str, name_str); + //let proces_info = class!(NSPRocessInfo); + //let app: id = msg_send![app_class, currentApplication]; + // let app: id = msg_send![app_class, runningApplicationWithProcessIdentifier: proc.0.as_u32() as i32]; + // let localized_name: id = msg_send![app, localizedName]; + // if localized_name != nil { + // let localized_name = NSString::retain(localized_name).to_string(); + // dbg!(localized_name); + // } + // + // let bundle_identifier: id = msg_send![app, bundleIdentifier]; + // if bundle_identifier != nil { + // let bundle_identifier = NSString::retain(bundle_identifier).to_string(); + // // dbg!(bundle_identifier); + // + // let hidden: BOOL = msg_send![app, isHidden]; + // // dbg!(hidden); + // } + // + // let executable: id = msg_send![app, executableURL]; + // if executable != nil { + // let executable = NSURL::retain(executable).pathbuf(); + // // dbg!(executable); + // } + + } + // unsafe{ //let current_app = NSRunningApplication::runningApplicationWithProcessIdentifier(nil, int_value); - let app_class = class!(NSRunningApplication); - let app: id = msg_send![app_class, currentApplication]; - let app_name: id = msg_send![app, localizedName]; //let app_name: id = msg_send![current_app, localizedName]; - dbg!(app_name); //current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps); // let superclass = class!(NSObject); // let mut decl = objc2::declare::ClassBuilder::new("NSRunningApplication", superclass).unwrap(); @@ -74,7 +121,7 @@ pub fn active_executables() -> Result { //let app_class = class!(NSRunningApplication); //let p: i32 = msg_send![ app_class, runningApplicationWithProcessIdentifier: int_value ]; //dbg!(p); - }; + // }; } From b239349c08ccece908524f8ae5e4d3969f836c35 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Wed, 25 Oct 2023 19:38:00 +0200 Subject: [PATCH 06/20] cacao + objc --- Cargo.toml | 5 +- src/ipc/mitmproxy_ipc.rs | 48 ++++++------- src/macos/processes.rs | 143 +++++++-------------------------------- src/processes.rs | 2 +- 4 files changed, 51 insertions(+), 147 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 43d49894..279f3c9e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,9 +46,8 @@ tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } sysinfo = "0.29.10" -# cacao = "0.3.2" -# objc = "0.2" -libc = "0.2" +cacao = "0.3.2" +objc = "0.2" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } # smoltcp = { git = 'https://github.com/mhils/smoltcp', rev = 'f65351adfa92db5193f368368cb668bac721fe43' } diff --git a/src/ipc/mitmproxy_ipc.rs b/src/ipc/mitmproxy_ipc.rs index d0e50428..7f92b185 100644 --- a/src/ipc/mitmproxy_ipc.rs +++ b/src/ipc/mitmproxy_ipc.rs @@ -8,34 +8,34 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PacketWithMeta { - #[prost(bytes="vec", tag="1")] + #[prost(bytes = "vec", tag = "1")] pub data: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TunnelInfo { - #[prost(uint32, tag="1")] + #[prost(uint32, tag = "1")] pub pid: u32, - #[prost(string, optional, tag="2")] + #[prost(string, optional, tag = "2")] pub process_name: ::core::option::Option<::prost::alloc::string::String>, } /// Packet or intercept spec (Windows pipe to redirector) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FromProxy { - #[prost(oneof="from_proxy::Message", tags="1, 2")] + #[prost(oneof = "from_proxy::Message", tags = "1, 2")] pub message: ::core::option::Option, } /// Nested message and enum types in `FromProxy`. pub mod from_proxy { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] Packet(super::Packet), - #[prost(message, tag="2")] + #[prost(message, tag = "2")] InterceptConf(super::InterceptConf), } } @@ -43,68 +43,68 @@ pub mod from_proxy { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Packet { - #[prost(bytes="vec", tag="1")] + #[prost(bytes = "vec", tag = "1")] pub data: ::prost::alloc::vec::Vec, } /// Intercept conf (macOS Control Stream) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct InterceptConf { - #[prost(uint32, repeated, tag="1")] + #[prost(uint32, repeated, tag = "1")] pub pids: ::prost::alloc::vec::Vec, - #[prost(string, repeated, tag="2")] + #[prost(string, repeated, tag = "2")] pub process_names: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(bool, tag="3")] + #[prost(bool, tag = "3")] pub invert: bool, } /// New flow (macOS TCP/UDP Stream) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NewFlow { - #[prost(oneof="new_flow::Message", tags="1, 2")] + #[prost(oneof = "new_flow::Message", tags = "1, 2")] pub message: ::core::option::Option, } /// Nested message and enum types in `NewFlow`. pub mod new_flow { #[allow(clippy::derive_partial_eq_without_eq)] -#[derive(Clone, PartialEq, ::prost::Oneof)] + #[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { - #[prost(message, tag="1")] + #[prost(message, tag = "1")] Tcp(super::TcpFlow), - #[prost(message, tag="2")] + #[prost(message, tag = "2")] Udp(super::UdpFlow), } } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TcpFlow { - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub remote_address: ::core::option::Option
, - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UdpFlow { - #[prost(message, optional, tag="1")] + #[prost(message, optional, tag = "1")] pub local_address: ::core::option::Option
, - #[prost(message, optional, tag="3")] + #[prost(message, optional, tag = "3")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UdpPacket { - #[prost(bytes="vec", tag="1")] + #[prost(bytes = "vec", tag = "1")] pub data: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag="2")] + #[prost(message, optional, tag = "2")] pub remote_address: ::core::option::Option
, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Address { - #[prost(string, tag="1")] + #[prost(string, tag = "1")] pub host: ::prost::alloc::string::String, - #[prost(uint32, tag="2")] + #[prost(uint32, tag = "2")] pub port: u32, } // @@protoc_insertion_point(module) diff --git a/src/macos/processes.rs b/src/macos/processes.rs index 2d9ee8e5..8671e50f 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,131 +1,36 @@ use anyhow::Result; -//use objc::runtime::AnyClass; -use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt}; -use crate::processes::ProcessList; - -//use cocoa::appkit::NSRunningApplication; - -// use cacao::foundation::{id, nil, NSString, NSURL, BOOL}; -// use objc::{sel, sel_impl, msg_send, class}; -use std::ptr; -use std::os::raw::{c_char, c_int}; -use libc::{proc_pidpath, proc_name,PROC_PIDPATHINFO_MAXSIZE, c_void, PROC_PIDTBSDINFO, proc_pidinfo, proc_bsdinfo}; -// extern_class!( -// #[derive(Debug, PartialEq, Eq, Hash)] -// #[cfg(feature = "AppKit_NSRunningApplication")] -// pub struct NSRunningApplication; -// -// #[cfg(feature = "AppKit_NSRunningApplication")] -// unsafe impl ClassType for NSRunningApplication { -// type Super = NSObject; -// type Mutability = InteriorMutable; -// } -// ); -// extern_class!( -// /// An example description. -// #[derive(PartialEq, Eq, Hash)] // Uses the superclass' implementation -// // Specify the class and struct name to be used -// pub struct NSRunningApplication; -// -// // Specify the superclass, in this case `NSObject` -// unsafe impl ClassType for NSRunningApplication { -// type Super = NSObject; -// type Mutability = mutability::InteriorMutable; -// // Optionally, specify the name of the class, if it differs from -// // the struct name. -// // const NAME: &'static str = "NSFormatter"; -// } -// ); -// unsafe impl NSObjectProtocol for NSRunningApplication {} - // pub executable: PathBuf, - // pub display_name: String, - // pub is_visible: bool, - // pub is_system: bool, +use crate::processes::{ProcessList, ProcessInfo}; +use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt, ProcessExt}; +use cacao::foundation::{id, NSString}; +use objc::{class, msg_send, sel, sel_impl}; pub fn active_executables() -> Result { dbg!("active_executables"); let mut sys = System::new(); + let mut list: ProcessList = vec![]; sys.refresh_processes_specifics(ProcessRefreshKind::new()); for proc in sys.processes() { - // dbg!(proc); - //dbg!(AnyClass::classes_count()); - //let int_value: pid_t = proc.0.as_u32() as i32; - // let cls = NSRunningApplication::class(); - //let nsrunning = class!(NSRunningApplication); - unsafe { - // let mut path_buffer: [c_char; PROC_PIDPATHINFO_MAXSIZE as usize] = [0; PROC_PIDPATHINFO_MAXSIZE as usize]; - // let mut name_buffer: [c_char; 256] = [0; 256]; - const PROC_PIDTBSDINFO_SIZE:usize = std::mem::size_of::(); - let mut bsd_info: [c_char; PROC_PIDTBSDINFO_SIZE] = [0; PROC_PIDTBSDINFO_SIZE]; - - let ret = proc_pidinfo(proc.0.as_u32() as i32, PROC_PIDTBSDINFO, 0, bsd_info.as_mut_ptr() as *mut c_void, PROC_PIDTBSDINFO_SIZE as i32); - let bsd_info_struct: proc_bsdinfo = std::mem::transmute(bsd_info); - if ret as usize == PROC_PIDTBSDINFO_SIZE { - println!("Process ID: {}", bsd_info_struct.pbi_pid); - println!("Process Name: {:?}", std::ffi::CStr::from_ptr(bsd_info_struct.pbi_comm.as_ptr())); - println!("Process status: {:?}", bsd_info_struct.pbi_status); - } else { - println!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); - println!("Error for pid {}", proc.0.as_u32()); - println!("Process ID: {}", bsd_info_struct.pbi_pid); - println!("Process Name: {:?}", std::ffi::CStr::from_ptr(bsd_info_struct.pbi_comm.as_ptr())); - println!("Process status: {:?}", bsd_info_struct.pbi_status); - println!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); - } - - // proc_pidpath(proc.0.as_u32() as i32, path_buffer.as_mut_ptr() as *mut c_void, PROC_PIDPATHINFO_MAXSIZE as u32); - // proc_name(proc.0.as_u32() as i32, name_buffer.as_mut_ptr() as *mut c_void, size_of_val); - - // let path_str = std::ffi::CStr::from_ptr(path_buffer.as_ptr()).to_str().unwrap(); - // let name_str = std::ffi::CStr::from_ptr(name_buffer.as_ptr()).to_str().unwrap(); - - // println!("Path: {}\nName: {}", path_str, name_str); - //let proces_info = class!(NSPRocessInfo); - //let app: id = msg_send![app_class, currentApplication]; - // let app: id = msg_send![app_class, runningApplicationWithProcessIdentifier: proc.0.as_u32() as i32]; - // let localized_name: id = msg_send![app, localizedName]; - // if localized_name != nil { - // let localized_name = NSString::retain(localized_name).to_string(); - // dbg!(localized_name); - // } - // - // let bundle_identifier: id = msg_send![app, bundleIdentifier]; - // if bundle_identifier != nil { - // let bundle_identifier = NSString::retain(bundle_identifier).to_string(); - // // dbg!(bundle_identifier); - // - // let hidden: BOOL = msg_send![app, isHidden]; - // // dbg!(hidden); - // } - // - // let executable: id = msg_send![app, executableURL]; - // if executable != nil { - // let executable = NSURL::retain(executable).pathbuf(); - // // dbg!(executable); - // } - - } - // unsafe{ - //let current_app = NSRunningApplication::runningApplicationWithProcessIdentifier(nil, int_value); - //let app_name: id = msg_send![current_app, localizedName]; - //current_app.activateWithOptions_(NSApplicationActivateIgnoringOtherApps); - // let superclass = class!(NSObject); - // let mut decl = objc2::declare::ClassBuilder::new("NSRunningApplication", superclass).unwrap(); - // decl.register(); - //dbg!(AnyClass::get("NSRunningApplication")); - // let app_class = class!(NSRunningApplication); - // let app_with_process_id: *mut Object = msg_send![ - // app_class, - // runningApplicationWithProcessIdentifier: process_id as i64 - // ]; - //let app_class = class!(NSRunningApplication); - //let p: i32 = msg_send![ app_class, runningApplicationWithProcessIdentifier: int_value ]; - //dbg!(p); - // }; - + let app: id = unsafe{msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()]}; + let display_name = if !app.is_null() { + let localized_name: id = unsafe{msg_send![app, localizedName]}; + NSString::retain(localized_name).to_string() + } else { + proc.1.name().to_string() + }; + let executable = proc.1.exe(); + let activation_policy: u8 = unsafe {msg_send![app, activationPolicy]}; + + list.push( + ProcessInfo { + executable: executable.to_path_buf(), + display_name, + activation_policy, + is_system: executable.starts_with("/System/"), + } + ); } - Ok(vec![]) + Ok(list) } #[cfg(test)] diff --git a/src/processes.rs b/src/processes.rs index 521a3243..40dcc81f 100644 --- a/src/processes.rs +++ b/src/processes.rs @@ -5,7 +5,7 @@ use std::path::PathBuf; pub struct ProcessInfo { pub executable: PathBuf, pub display_name: String, - pub is_visible: bool, + pub activation_policy: u8, pub is_system: bool, } From 6cf5edf1f0f8df6e5a6269d6938976314bb9def0 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Wed, 25 Oct 2023 17:48:19 +0000 Subject: [PATCH 07/20] [autofix.ci] apply automated fixes --- src/ipc/mitmproxy_ipc.rs | 48 ++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/ipc/mitmproxy_ipc.rs b/src/ipc/mitmproxy_ipc.rs index 7f92b185..d0e50428 100644 --- a/src/ipc/mitmproxy_ipc.rs +++ b/src/ipc/mitmproxy_ipc.rs @@ -8,34 +8,34 @@ #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct PacketWithMeta { - #[prost(bytes = "vec", tag = "1")] + #[prost(bytes="vec", tag="1")] pub data: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "2")] + #[prost(message, optional, tag="2")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TunnelInfo { - #[prost(uint32, tag = "1")] + #[prost(uint32, tag="1")] pub pid: u32, - #[prost(string, optional, tag = "2")] + #[prost(string, optional, tag="2")] pub process_name: ::core::option::Option<::prost::alloc::string::String>, } /// Packet or intercept spec (Windows pipe to redirector) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct FromProxy { - #[prost(oneof = "from_proxy::Message", tags = "1, 2")] + #[prost(oneof="from_proxy::Message", tags="1, 2")] pub message: ::core::option::Option, } /// Nested message and enum types in `FromProxy`. pub mod from_proxy { #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] Packet(super::Packet), - #[prost(message, tag = "2")] + #[prost(message, tag="2")] InterceptConf(super::InterceptConf), } } @@ -43,68 +43,68 @@ pub mod from_proxy { #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Packet { - #[prost(bytes = "vec", tag = "1")] + #[prost(bytes="vec", tag="1")] pub data: ::prost::alloc::vec::Vec, } /// Intercept conf (macOS Control Stream) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct InterceptConf { - #[prost(uint32, repeated, tag = "1")] + #[prost(uint32, repeated, tag="1")] pub pids: ::prost::alloc::vec::Vec, - #[prost(string, repeated, tag = "2")] + #[prost(string, repeated, tag="2")] pub process_names: ::prost::alloc::vec::Vec<::prost::alloc::string::String>, - #[prost(bool, tag = "3")] + #[prost(bool, tag="3")] pub invert: bool, } /// New flow (macOS TCP/UDP Stream) #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct NewFlow { - #[prost(oneof = "new_flow::Message", tags = "1, 2")] + #[prost(oneof="new_flow::Message", tags="1, 2")] pub message: ::core::option::Option, } /// Nested message and enum types in `NewFlow`. pub mod new_flow { #[allow(clippy::derive_partial_eq_without_eq)] - #[derive(Clone, PartialEq, ::prost::Oneof)] +#[derive(Clone, PartialEq, ::prost::Oneof)] pub enum Message { - #[prost(message, tag = "1")] + #[prost(message, tag="1")] Tcp(super::TcpFlow), - #[prost(message, tag = "2")] + #[prost(message, tag="2")] Udp(super::UdpFlow), } } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct TcpFlow { - #[prost(message, optional, tag = "1")] + #[prost(message, optional, tag="1")] pub remote_address: ::core::option::Option
, - #[prost(message, optional, tag = "2")] + #[prost(message, optional, tag="2")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UdpFlow { - #[prost(message, optional, tag = "1")] + #[prost(message, optional, tag="1")] pub local_address: ::core::option::Option
, - #[prost(message, optional, tag = "3")] + #[prost(message, optional, tag="3")] pub tunnel_info: ::core::option::Option, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct UdpPacket { - #[prost(bytes = "vec", tag = "1")] + #[prost(bytes="vec", tag="1")] pub data: ::prost::alloc::vec::Vec, - #[prost(message, optional, tag = "2")] + #[prost(message, optional, tag="2")] pub remote_address: ::core::option::Option
, } #[allow(clippy::derive_partial_eq_without_eq)] #[derive(Clone, PartialEq, ::prost::Message)] pub struct Address { - #[prost(string, tag = "1")] + #[prost(string, tag="1")] pub host: ::prost::alloc::string::String, - #[prost(uint32, tag = "2")] + #[prost(uint32, tag="2")] pub port: u32, } // @@protoc_insertion_point(module) From 142b5508b685e11e49263c9448a3fe6d1324b8e1 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Thu, 26 Oct 2023 19:48:17 +0200 Subject: [PATCH 08/20] get the icon from the NSRunningApp --- Cargo.lock | 115 +++++++++++++++++++++++++++++++++++++++-- Cargo.toml | 4 +- src/macos/processes.rs | 60 ++++++++++++--------- src/processes.rs | 3 +- 4 files changed, 153 insertions(+), 29 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 92dcbe8f..ad812ce1 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -208,9 +208,9 @@ checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" [[package]] name = "base64" -version = "0.21.4" +version = "0.21.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ba43ea6f343b788c8764558649e08df62f86c6ef251fdaeb1ffd010a9ae50a2" +checksum = "35636a1494ede3b646cc98f74f8e62c773a38a659ebc777a2cf26b9b74171df9" [[package]] name = "bit_field" @@ -239,6 +239,12 @@ dependencies = [ "digest", ] +[[package]] +name = "block" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0d8c1fef690941d3e7788d328517591fecc684c084084702d6ff1641e993699a" + [[package]] name = "block-buffer" version = "0.10.4" @@ -404,6 +410,36 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cd7cc57abe963c6d3b9d8be5b06ba7c8957a930305ca90304f24ef040aa6f961" +[[package]] +name = "cocoa" +version = "0.25.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f6140449f97a6e97f9511815c5632d84c8aacf8ac271ad77c559218161a1373c" +dependencies = [ + "bitflags 1.3.2", + "block", + "cocoa-foundation", + "core-foundation", + "core-graphics", + "foreign-types", + "libc", + "objc", +] + +[[package]] +name = "cocoa-foundation" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8c6234cbb2e4c785b456c0644748b1ac416dd045799740356f8363dfe00c93f7" +dependencies = [ + "bitflags 1.3.2", + "block", + "core-foundation", + "core-graphics-types", + "libc", + "objc", +] + [[package]] name = "color_quant" version = "1.1.0" @@ -463,6 +499,30 @@ version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e496a50fda8aacccc86d7529e2c1e0892dbd0f898a6b5645b5561b89c3210efa" +[[package]] +name = "core-graphics" +version = "0.23.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "970a29baf4110c26fedbc7f82107d42c23f7e88e404c4577ed73fe99ff85a212" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "core-graphics-types", + "foreign-types", + "libc", +] + +[[package]] +name = "core-graphics-types" +version = "0.1.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2bb142d41022986c1d8ff29103a1411c8a3dfad3552f87a4f8dc50d61d4f4e33" +dependencies = [ + "bitflags 1.3.2", + "core-foundation", + "libc", +] + [[package]] name = "cpufeatures" version = "0.2.9" @@ -776,6 +836,33 @@ version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" +[[package]] +name = "foreign-types" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d737d9aa519fb7b749cbc3b962edcf310a8dd1f4b67c91c4f83975dbdd17d965" +dependencies = [ + "foreign-types-macros", + "foreign-types-shared", +] + +[[package]] +name = "foreign-types-macros" +version = "0.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a5c6c585bc94aaf2c7b51dd4c2ba22680844aba4c687be581871a6f518c5742" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.37", +] + +[[package]] +name = "foreign-types-shared" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "aa9a19cbb55df58761df49b23516a86d432839add4af60fc256da840f66ed35b" + [[package]] name = "futures" version = "0.3.28" @@ -1260,6 +1347,15 @@ dependencies = [ "apple-security-framework", ] +[[package]] +name = "malloc_buf" +version = "0.0.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "62bb907fe88d54d8d9ce32a3cceab4218ed2f6b7d35617cafe9adf84e43919cb" +dependencies = [ + "libc", +] + [[package]] name = "managed" version = "0.8.0" @@ -1347,15 +1443,17 @@ dependencies = [ "anyhow", "apple-security-framework", "async-trait", + "base64 0.21.5", "boringtun", + "cocoa", "console-subscriber", "criterion", "env_logger", "futures-util", "image", - "libc", "log", "nix 0.27.1", + "objc", "once_cell", "pretty-hex", "prost", @@ -1471,6 +1569,15 @@ dependencies = [ "libc", ] +[[package]] +name = "objc" +version = "0.2.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "915b1b472bc21c53464d6c8461c9d3af805ba1ef837e1cac254428f4a77177b1" +dependencies = [ + "malloc_buf", +] + [[package]] name = "object" version = "0.32.1" @@ -2312,7 +2419,7 @@ dependencies = [ "async-stream", "async-trait", "axum", - "base64 0.21.4", + "base64 0.21.5", "bytes", "h2", "http", diff --git a/Cargo.toml b/Cargo.toml index 279f3c9e..cf38de25 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,8 +46,10 @@ tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } sysinfo = "0.29.10" -cacao = "0.3.2" +cocoa = "0.25" objc = "0.2" +base64 = "0.21.5" + # [patch.crates-io] # tokio = { path = "../tokio/tokio" } # smoltcp = { git = 'https://github.com/mhils/smoltcp', rev = 'f65351adfa92db5193f368368cb668bac721fe43' } diff --git a/src/macos/processes.rs b/src/macos/processes.rs index 8671e50f..f6a68e1e 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,35 +1,49 @@ -use anyhow::Result; -use crate::processes::{ProcessList, ProcessInfo}; -use sysinfo::{PidExt, ProcessRefreshKind, System, SystemExt, ProcessExt}; -use cacao::foundation::{id, NSString}; +use crate::processes::{ProcessInfo, ProcessList}; +use anyhow::{bail, Result}; +use base64::engine::general_purpose; +use base64::Engine; +use cocoa::base::id; use objc::{class, msg_send, sel, sel_impl}; +use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; pub fn active_executables() -> Result { - dbg!("active_executables"); let mut sys = System::new(); let mut list: ProcessList = vec![]; sys.refresh_processes_specifics(ProcessRefreshKind::new()); for proc in sys.processes() { - let app: id = unsafe{msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()]}; - let display_name = if !app.is_null() { - let localized_name: id = unsafe{msg_send![app, localizedName]}; - NSString::retain(localized_name).to_string() - } else { - proc.1.name().to_string() - }; + let display_name = proc.1.name().to_string(); + let mut activation_policy = None; + let mut _icon: Option = None; let executable = proc.1.exe(); - let activation_policy: u8 = unsafe {msg_send![app, activationPolicy]}; - - list.push( - ProcessInfo { - executable: executable.to_path_buf(), - display_name, - activation_policy, - is_system: executable.starts_with("/System/"), + let mut icon = vec![]; + let app: id = unsafe { + msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()] + }; + if !app.is_null() { + activation_policy = Some(unsafe { msg_send![app, activationPolicy] }); + let img: id = unsafe { msg_send![app, icon] }; + let tif: id = unsafe { msg_send![img, TIFFRepresentation] }; + let bitmap: id = unsafe { msg_send![class!(NSBitmapImageRep), imageRepWithData: tif] }; + let png: id = unsafe { msg_send![bitmap, representationUsingType: 4 properties: 0] }; + let length: usize = unsafe { msg_send![png, length] }; + if let Some(len) = base64::encoded_len(length, true) { + let bytes: *const u8 = unsafe { msg_send![png, bytes] }; + let s = unsafe { std::slice::from_raw_parts(bytes, length) }.to_vec(); + icon.resize(len, 0); + match general_purpose::STANDARD.encode_slice(s, &mut icon) { + Ok(len) => icon.truncate(len), + Err(e) => bail!(e), + } } - ); + } + list.push(ProcessInfo { + executable: executable.to_path_buf(), + display_name, + activation_policy, + is_system: executable.starts_with("/System/"), + icon, + }); } - Ok(list) } @@ -43,7 +57,7 @@ mod tests { assert!(!lst.is_empty()); for proc in &lst { - dbg!(proc); + dbg!(proc); } dbg!(lst.len()); } diff --git a/src/processes.rs b/src/processes.rs index 40dcc81f..69081c95 100644 --- a/src/processes.rs +++ b/src/processes.rs @@ -5,8 +5,9 @@ use std::path::PathBuf; pub struct ProcessInfo { pub executable: PathBuf, pub display_name: String, - pub activation_policy: u8, + pub activation_policy: Option, pub is_system: bool, + pub icon: Vec, } pub type ProcessList = Vec; From f5e0e8291febe374154095516496186d3ec711f3 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Thu, 26 Oct 2023 19:52:22 +0200 Subject: [PATCH 09/20] nit --- src/macos/processes.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/macos/processes.rs b/src/macos/processes.rs index f6a68e1e..ab1ca381 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -13,7 +13,6 @@ pub fn active_executables() -> Result { for proc in sys.processes() { let display_name = proc.1.name().to_string(); let mut activation_policy = None; - let mut _icon: Option = None; let executable = proc.1.exe(); let mut icon = vec![]; let app: id = unsafe { From 278e222407d56a9ada454f16f75443f5b5e4948c Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Fri, 27 Oct 2023 14:56:29 +0200 Subject: [PATCH 10/20] readability not too much unsafe blocks --- src/macos/processes.rs | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/src/macos/processes.rs b/src/macos/processes.rs index ab1ca381..00a71c25 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -15,23 +15,23 @@ pub fn active_executables() -> Result { let mut activation_policy = None; let executable = proc.1.exe(); let mut icon = vec![]; - let app: id = unsafe { - msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()] - }; - if !app.is_null() { - activation_policy = Some(unsafe { msg_send![app, activationPolicy] }); - let img: id = unsafe { msg_send![app, icon] }; - let tif: id = unsafe { msg_send![img, TIFFRepresentation] }; - let bitmap: id = unsafe { msg_send![class!(NSBitmapImageRep), imageRepWithData: tif] }; - let png: id = unsafe { msg_send![bitmap, representationUsingType: 4 properties: 0] }; - let length: usize = unsafe { msg_send![png, length] }; - if let Some(len) = base64::encoded_len(length, true) { - let bytes: *const u8 = unsafe { msg_send![png, bytes] }; - let s = unsafe { std::slice::from_raw_parts(bytes, length) }.to_vec(); - icon.resize(len, 0); - match general_purpose::STANDARD.encode_slice(s, &mut icon) { - Ok(len) => icon.truncate(len), - Err(e) => bail!(e), + unsafe { + let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()]; + if !app.is_null() { + activation_policy = Some(msg_send![app, activationPolicy]); + let img: id = msg_send![app, icon]; + let tif: id = msg_send![img, TIFFRepresentation]; + let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; + let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; + let length: usize = msg_send![png, length]; + if let Some(len) = base64::encoded_len(length, true) { + let bytes: *const u8 = msg_send![png, bytes]; + let s = std::slice::from_raw_parts(bytes, length).to_vec(); + icon.resize(len, 0); + match general_purpose::STANDARD.encode_slice(s, &mut icon) { + Ok(len) => icon.truncate(len), + Err(e) => bail!(e), + } } } } @@ -56,7 +56,7 @@ mod tests { assert!(!lst.is_empty()); for proc in &lst { - dbg!(proc); + dbg!(&proc.display_name); } dbg!(lst.len()); } From 96d1bdd804b0cc15556bed0684002e65af9cc48a Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Wed, 1 Nov 2023 19:59:47 +0100 Subject: [PATCH 11/20] visible windows on macos implemented --- Cargo.toml | 2 + src/macos/icons.rs | 37 +++++++++++ src/macos/processes.rs | 146 ++++++++++++++++++++++++++++++++++------- src/processes.rs | 3 +- 4 files changed, 163 insertions(+), 25 deletions(-) create mode 100644 src/macos/icons.rs diff --git a/Cargo.toml b/Cargo.toml index cf38de25..b240a998 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -49,6 +49,8 @@ sysinfo = "0.29.10" cocoa = "0.25" objc = "0.2" base64 = "0.21.5" +core-graphics = "0.23" +core-foundation = "0.9" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } diff --git a/src/macos/icons.rs b/src/macos/icons.rs new file mode 100644 index 00000000..6985a9b8 --- /dev/null +++ b/src/macos/icons.rs @@ -0,0 +1,37 @@ +pub static ICON_CACHE: Lazy> = Lazy::new(|| Mutex::new(IconCache::default())); +#[derive(Default)] +pub struct IconCache { + /// executable name -> icon hash + executables: HashMap, + /// icon hash -> png bytes + icons: HashMap>, +} + +impl IconCache { + pub fn get_png(&mut self, executable: PathBuf) -> Result<&Vec> { + match self.executables.entry(executable) { + Entry::Occupied(e) => { + // Guaranteed to exist because we never clear the cache. + Ok(self.icons.get(e.get()).unwrap()) + } + Entry::Vacant(e) => { + let pixels = unsafe { + let hinst = GetModuleHandleW(None)?; + icon_for_executable(e.key(), hinst)? + }; + let pixel_hash = pixels.hash(); + e.insert(pixel_hash); + let icon = self.icons.entry(pixel_hash).or_insert_with(|| { + let mut c = Cursor::new(Vec::new()); + pixels + .to_image() + .write_to(&mut c, image::ImageOutputFormat::Png) + .unwrap(); + c.into_inner() + }); + Ok(icon) + } + } + } +} + diff --git a/src/macos/processes.rs b/src/macos/processes.rs index 00a71c25..a432e4e7 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,51 +1,133 @@ +use std::collections::{HashMap, HashSet}; +use std::collections::hash_map::Entry; use crate::processes::{ProcessInfo, ProcessList}; use anyhow::{bail, Result}; use base64::engine::general_purpose; use base64::Engine; use cocoa::base::id; +use cocoa::base::nil; +use cocoa::foundation::NSString; +use core_foundation::number::CFNumberGetValue; +use core_foundation::number::CFNumberRef; +use core_foundation::number::kCFNumberSInt32Type; +use core_foundation::string::CFStringGetCString; +use core_foundation::string::CFStringRef; +use core_foundation::string::kCFStringEncodingUTF8; +use core_graphics::display::{CFDictionaryGetValueIfPresent, CGWindowListCopyWindowInfo, CFArrayGetCount, CFArrayGetValueAtIndex, CFDictionaryRef, kCGNullWindowID, kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements}; +use std::ffi::{c_void, CStr}; use objc::{class, msg_send, sel, sel_impl}; use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; +use std::path::PathBuf; +use crate::intercept_conf::PID; +use once_cell::sync::Lazy; +use std::sync::Mutex; + +pub static DISPLAY_NAME_CACHE: Lazy> = Lazy::new(|| Mutex::new(DisplayNameCache::default())); + +#[derive(Default)] +pub struct DisplayNameCache(HashMap>); + +impl DisplayNameCache { + pub fn get(&mut self, executable: PathBuf) -> &Result { + self.0 + .entry(executable) + .or_insert_with_key(|path| get_display_name(path)) + } +} pub fn active_executables() -> Result { + let mut executables: HashMap = HashMap::new(); + let mut visible = visible_windows()?; let mut sys = System::new(); let mut list: ProcessList = vec![]; sys.refresh_processes_specifics(ProcessRefreshKind::new()); - for proc in sys.processes() { - let display_name = proc.1.name().to_string(); - let mut activation_policy = None; - let executable = proc.1.exe(); - let mut icon = vec![]; + for (pid, process) in sys.processes() { + let pid = pid.as_u32(); + let display_name = process.name().to_string(); + let executable = process.exe().to_path_buf(); + // let mut icon = vec![]; + match executables.entry(executable) { + Entry::Occupied(mut e) => { + let process_info = e.get(); + if !process_info.is_visible && visible.contains(&pid){ + let mut display_name_cache = DISPLAY_NAME_CACHE.lock().unwrap(); + if let Ok(d) = display_name_cache.get(e.key().clone()) { + e.get_mut().display_name = d.clone(); + } + e.get_mut().is_visible = true; + } + } + Entry::Vacant(e) => { + } + + } + unsafe { - let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: proc.0.as_u32()]; + let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: pid.as_u32()]; if !app.is_null() { - activation_policy = Some(msg_send![app, activationPolicy]); - let img: id = msg_send![app, icon]; - let tif: id = msg_send![img, TIFFRepresentation]; - let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; - let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; - let length: usize = msg_send![png, length]; - if let Some(len) = base64::encoded_len(length, true) { - let bytes: *const u8 = msg_send![png, bytes]; - let s = std::slice::from_raw_parts(bytes, length).to_vec(); - icon.resize(len, 0); - match general_purpose::STANDARD.encode_slice(s, &mut icon) { - Ok(len) => icon.truncate(len), - Err(e) => bail!(e), - } + let app: id = msg_send![app, delegate]; + let windows: id = msg_send![app, orderedWindows]; + dbg!(windows); + let windows_len: usize = msg_send![windows, count]; + dbg!(windows_len); + for i in 0..windows_len { + let window: id = msg_send![windows, objectAtIndex: i]; + dbg!(window); + let occlusion_state: u64 = msg_send![window, occlusionState]; + dbg!(occlusion_state); } + //is_visible = occlusion_state == 2; + // let img: id = msg_send![app, icon]; + // let tif: id = msg_send![img, TIFFRepresentation]; + // let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; + // let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; + // let length: usize = msg_send![png, length]; + // if let Some(len) = base64::encoded_len(length, true) { + // let bytes: *const u8 = msg_send![png, bytes]; + // let s = std::slice::from_raw_parts(bytes, length).to_vec(); + // icon.resize(len, 0); + // match general_purpose::STANDARD.encode_slice(s, &mut icon) { + // Ok(len) => icon.truncate(len), + // Err(e) => bail!(e), + // } + // } } } list.push(ProcessInfo { executable: executable.to_path_buf(), display_name, - activation_policy, is_system: executable.starts_with("/System/"), - icon, + is_visible, }); } Ok(list) } +pub fn visible_windows() -> Result> { + let mut pids: HashSet = HashSet::new(); + + unsafe{ + let windows_info_list = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly + kCGWindowListExcludeDesktopElements, kCGNullWindowID); + let count = CFArrayGetCount(windows_info_list); + + for i in 0..count-1 { + let dic_ref = CFArrayGetValueAtIndex(windows_info_list, i); + let key = NSString::alloc(nil).init_str("kCGWindowOwnerPID"); + let mut pid: *const c_void = std::ptr::null_mut(); + + if CFDictionaryGetValueIfPresent(dic_ref as CFDictionaryRef, key as *const c_void, &mut pid) != 0{ + let pid_cf_ref = pid as CFNumberRef; + let mut pid:i32 = 0; + if CFNumberGetValue(pid_cf_ref, kCFNumberSInt32Type, &mut pid as *mut i32 as *mut c_void) { + pids.insert(pid as u32); + } + } + } + + Ok(pids) + } +} + #[cfg(test)] mod tests { use super::*; @@ -56,7 +138,25 @@ mod tests { assert!(!lst.is_empty()); for proc in &lst { - dbg!(&proc.display_name); + // dbg!(&proc.display_name); + if !proc.is_visible { + dbg!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); + dbg!(&proc.display_name); + dbg!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); + } + } + dbg!(lst.len()); + } + + #[test] + fn visible_windows_list() { + let lst = visible_windows().unwrap(); + assert!(!lst.is_empty()); + + for pid in &lst { + dbg!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); + dbg!(&pid); + dbg!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); } dbg!(lst.len()); } diff --git a/src/processes.rs b/src/processes.rs index 69081c95..521a3243 100644 --- a/src/processes.rs +++ b/src/processes.rs @@ -5,9 +5,8 @@ use std::path::PathBuf; pub struct ProcessInfo { pub executable: PathBuf, pub display_name: String, - pub activation_policy: Option, + pub is_visible: bool, pub is_system: bool, - pub icon: Vec, } pub type ProcessList = Vec; From 39cbe5aeec6c1834b49153b5e703f6848ec710f4 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Thu, 2 Nov 2023 18:06:38 +0100 Subject: [PATCH 12/20] get_png and active_executables for MacOS completed --- Cargo.lock | 2 + mitmproxy-rs/src/process_info.rs | 18 +++--- src/macos/icons.rs | 67 ++++++++++++++++----- src/macos/mod.rs | 1 + src/macos/processes.rs | 99 ++++++-------------------------- 5 files changed, 83 insertions(+), 104 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index ad812ce1..e8e325b8 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1447,6 +1447,8 @@ dependencies = [ "boringtun", "cocoa", "console-subscriber", + "core-foundation", + "core-graphics", "criterion", "env_logger", "futures-util", diff --git a/mitmproxy-rs/src/process_info.rs b/mitmproxy-rs/src/process_info.rs index 0e4007a1..43030445 100644 --- a/mitmproxy-rs/src/process_info.rs +++ b/mitmproxy-rs/src/process_info.rs @@ -4,9 +4,11 @@ use anyhow::Result; use pyo3::prelude::*; #[allow(unused_imports)] -use mitmproxy::processes::{image, ProcessList}; +use mitmproxy::processes::image; #[cfg(windows)] -use mitmproxy::windows; +use mitmproxy::windows::{icons, processes}; +#[cfg(target_os = "macos")] +use mitmproxy::macos::{processes, icons}; #[pyclass(module = "mitmproxy_rs", frozen)] pub struct Process(mitmproxy::processes::ProcessInfo); @@ -46,13 +48,13 @@ impl Process { /// *Availability: Windows* #[pyfunction] pub fn active_executables() -> PyResult> { - #[cfg(windows)] + #[cfg(any(windows, target_os = "macos"))] { - windows::processes::active_executables() + processes::active_executables() .map(|p| p.into_iter().map(Process).collect()) .map_err(|e| pyo3::exceptions::PyRuntimeError::new_err(format!("{}", e))) } - #[cfg(not(windows))] + #[cfg(not(any(windows, target_os = "macos")))] Err(pyo3::exceptions::PyNotImplementedError::new_err( "active_executables is only available on Windows", )) @@ -61,15 +63,15 @@ pub fn active_executables() -> PyResult> { #[pyfunction] #[allow(unused_variables)] pub fn executable_icon(path: PathBuf) -> Result { - #[cfg(windows)] + #[cfg(any(windows, target_os = "macos"))] { - let mut icon_cache = windows::icons::ICON_CACHE.lock().unwrap(); + let mut icon_cache = icons::ICON_CACHE.lock().unwrap(); let png_bytes = icon_cache.get_png(path)?; Ok(Python::with_gil(|py| { pyo3::types::PyBytes::new(py, png_bytes).to_object(py) })) } - #[cfg(not(windows))] + #[cfg(not(any(windows, target_os = "macos")))] Err(pyo3::exceptions::PyNotImplementedError::new_err( "executable_icon is only available on Windows", ) diff --git a/src/macos/icons.rs b/src/macos/icons.rs index 6985a9b8..58c5e759 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -1,4 +1,17 @@ +use once_cell::sync::Lazy; +use std::{sync::Mutex, collections::hash_map::Entry}; +use cocoa::base::id; +use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; +use objc::{class, msg_send, sel, sel_impl}; +use std::path::PathBuf; +use std::path::Path; use std::collections::HashMap; +use std::collections::hash_map::DefaultHasher; +use anyhow::{bail, Result}; +use std::hash::{Hasher, Hash}; + + pub static ICON_CACHE: Lazy> = Lazy::new(|| Mutex::new(IconCache::default())); + #[derive(Default)] pub struct IconCache { /// executable name -> icon hash @@ -15,23 +28,49 @@ impl IconCache { Ok(self.icons.get(e.get()).unwrap()) } Entry::Vacant(e) => { - let pixels = unsafe { - let hinst = GetModuleHandleW(None)?; - icon_for_executable(e.key(), hinst)? - }; - let pixel_hash = pixels.hash(); - e.insert(pixel_hash); - let icon = self.icons.entry(pixel_hash).or_insert_with(|| { - let mut c = Cursor::new(Vec::new()); - pixels - .to_image() - .write_to(&mut c, image::ImageOutputFormat::Png) - .unwrap(); - c.into_inner() - }); + let icon = unsafe { png_data_for_executable(e.key())? }; + let mut hasher = DefaultHasher::new(); + icon.hash(&mut hasher); + let icon_hash = hasher.finish(); + e.insert(icon_hash); + let icon = self.icons.entry(icon_hash).or_insert(icon); Ok(icon) } } } } +unsafe fn png_data_for_executable(executable: &Path) -> Result> { + let mut sys = System::new(); + sys.refresh_processes_specifics(ProcessRefreshKind::new()); + for (pid, process) in sys.processes() { + let pid = pid.as_u32(); + if executable == process.exe().to_path_buf(){ + let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: pid]; + if !app.is_null() { + let img: id = msg_send![app, icon]; + let tif: id = msg_send![img, TIFFRepresentation]; + let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; + let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; + let length: usize = msg_send![png, length]; + let bytes: *const u8 = msg_send![png, bytes]; + let data = std::slice::from_raw_parts(bytes, length).to_vec(); + return Ok(data) + } + } + } + bail!("unable to extract icon"); +} + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn png() { + let path = PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); + let mut icon_cache = IconCache::default(); + let vec = icon_cache.get_png(path).unwrap(); + dbg!(vec.len()); + } +} diff --git a/src/macos/mod.rs b/src/macos/mod.rs index 3e9436df..401efbf2 100644 --- a/src/macos/mod.rs +++ b/src/macos/mod.rs @@ -1,2 +1,3 @@ pub mod certificates; +pub mod icons; pub mod processes; diff --git a/src/macos/processes.rs b/src/macos/processes.rs index a432e4e7..b9a7348f 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,111 +1,55 @@ use std::collections::{HashMap, HashSet}; use std::collections::hash_map::Entry; use crate::processes::{ProcessInfo, ProcessList}; -use anyhow::{bail, Result}; -use base64::engine::general_purpose; -use base64::Engine; -use cocoa::base::id; +use anyhow::Result; use cocoa::base::nil; use cocoa::foundation::NSString; use core_foundation::number::CFNumberGetValue; use core_foundation::number::CFNumberRef; use core_foundation::number::kCFNumberSInt32Type; -use core_foundation::string::CFStringGetCString; -use core_foundation::string::CFStringRef; -use core_foundation::string::kCFStringEncodingUTF8; use core_graphics::display::{CFDictionaryGetValueIfPresent, CGWindowListCopyWindowInfo, CFArrayGetCount, CFArrayGetValueAtIndex, CFDictionaryRef, kCGNullWindowID, kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements}; -use std::ffi::{c_void, CStr}; -use objc::{class, msg_send, sel, sel_impl}; +use std::ffi::c_void; use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; use std::path::PathBuf; use crate::intercept_conf::PID; -use once_cell::sync::Lazy; -use std::sync::Mutex; -pub static DISPLAY_NAME_CACHE: Lazy> = Lazy::new(|| Mutex::new(DisplayNameCache::default())); - -#[derive(Default)] -pub struct DisplayNameCache(HashMap>); - -impl DisplayNameCache { - pub fn get(&mut self, executable: PathBuf) -> &Result { - self.0 - .entry(executable) - .or_insert_with_key(|path| get_display_name(path)) - } -} pub fn active_executables() -> Result { let mut executables: HashMap = HashMap::new(); - let mut visible = visible_windows()?; + let visible = visible_windows()?; let mut sys = System::new(); - let mut list: ProcessList = vec![]; sys.refresh_processes_specifics(ProcessRefreshKind::new()); for (pid, process) in sys.processes() { let pid = pid.as_u32(); let display_name = process.name().to_string(); let executable = process.exe().to_path_buf(); + let is_system = executable.starts_with("/System/"); // let mut icon = vec![]; match executables.entry(executable) { Entry::Occupied(mut e) => { let process_info = e.get(); if !process_info.is_visible && visible.contains(&pid){ - let mut display_name_cache = DISPLAY_NAME_CACHE.lock().unwrap(); - if let Ok(d) = display_name_cache.get(e.key().clone()) { - e.get_mut().display_name = d.clone(); - } e.get_mut().is_visible = true; } } Entry::Vacant(e) => { - } - - } - - unsafe { - let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: pid.as_u32()]; - if !app.is_null() { - let app: id = msg_send![app, delegate]; - let windows: id = msg_send![app, orderedWindows]; - dbg!(windows); - let windows_len: usize = msg_send![windows, count]; - dbg!(windows_len); - for i in 0..windows_len { - let window: id = msg_send![windows, objectAtIndex: i]; - dbg!(window); - let occlusion_state: u64 = msg_send![window, occlusionState]; - dbg!(occlusion_state); - } - //is_visible = occlusion_state == 2; - // let img: id = msg_send![app, icon]; - // let tif: id = msg_send![img, TIFFRepresentation]; - // let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; - // let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; - // let length: usize = msg_send![png, length]; - // if let Some(len) = base64::encoded_len(length, true) { - // let bytes: *const u8 = msg_send![png, bytes]; - // let s = std::slice::from_raw_parts(bytes, length).to_vec(); - // icon.resize(len, 0); - // match general_purpose::STANDARD.encode_slice(s, &mut icon) { - // Ok(len) => icon.truncate(len), - // Err(e) => bail!(e), - // } - // } + let executable = e.key().clone(); + let is_visible = visible.contains(&pid); + e.insert(ProcessInfo { + executable, + display_name, + is_visible, + is_system, + }); } } - list.push(ProcessInfo { - executable: executable.to_path_buf(), - display_name, - is_system: executable.starts_with("/System/"), - is_visible, - }); } - Ok(list) + Ok(executables.into_values().collect()) } + pub fn visible_windows() -> Result> { let mut pids: HashSet = HashSet::new(); - unsafe{ let windows_info_list = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly + kCGWindowListExcludeDesktopElements, kCGNullWindowID); let count = CFArrayGetCount(windows_info_list); @@ -138,11 +82,8 @@ mod tests { assert!(!lst.is_empty()); for proc in &lst { - // dbg!(&proc.display_name); if !proc.is_visible { - dbg!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); dbg!(&proc.display_name); - dbg!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); } } dbg!(lst.len()); @@ -150,14 +91,8 @@ mod tests { #[test] fn visible_windows_list() { - let lst = visible_windows().unwrap(); - assert!(!lst.is_empty()); - - for pid in &lst { - dbg!("VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV"); - dbg!(&pid); - dbg!("^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^"); - } - dbg!(lst.len()); + let open_windows_pids = visible_windows().unwrap(); + assert!(!open_windows_pids.is_empty()); + dbg!(open_windows_pids.len()); } } From c15a97c3c214578be3e9b2877d2010a4ac545a0d Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Thu, 2 Nov 2023 18:10:24 +0100 Subject: [PATCH 13/20] macos dependecies --- Cargo.toml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index b240a998..7ee5b124 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,11 +46,7 @@ tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } sysinfo = "0.29.10" -cocoa = "0.25" -objc = "0.2" base64 = "0.21.5" -core-graphics = "0.23" -core-foundation = "0.9" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } @@ -75,6 +71,10 @@ features = [ [target.'cfg(target_os = "macos")'.dependencies] apple-security-framework = "2.9.2" nix = { version = "0.27.1", default-features = false, features = ["fs"] } +core-graphics = "0.23" +core-foundation = "0.9" +cocoa = "0.25" +objc = "0.2" [dev-dependencies] env_logger = "0.10" From 4945e93c4c55b745a1dc07c56b8d652422aa826a Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Thu, 2 Nov 2023 17:12:53 +0000 Subject: [PATCH 14/20] [autofix.ci] apply automated fixes --- mitmproxy-rs/src/process_info.rs | 4 +-- src/macos/icons.rs | 25 ++++++++++-------- src/macos/processes.rs | 44 +++++++++++++++++++++----------- 3 files changed, 45 insertions(+), 28 deletions(-) diff --git a/mitmproxy-rs/src/process_info.rs b/mitmproxy-rs/src/process_info.rs index 43030445..45354a01 100644 --- a/mitmproxy-rs/src/process_info.rs +++ b/mitmproxy-rs/src/process_info.rs @@ -3,12 +3,12 @@ use std::path::{Path, PathBuf}; use anyhow::Result; use pyo3::prelude::*; +#[cfg(target_os = "macos")] +use mitmproxy::macos::{icons, processes}; #[allow(unused_imports)] use mitmproxy::processes::image; #[cfg(windows)] use mitmproxy::windows::{icons, processes}; -#[cfg(target_os = "macos")] -use mitmproxy::macos::{processes, icons}; #[pyclass(module = "mitmproxy_rs", frozen)] pub struct Process(mitmproxy::processes::ProcessInfo); diff --git a/src/macos/icons.rs b/src/macos/icons.rs index 58c5e759..c5020ccc 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -1,14 +1,14 @@ -use once_cell::sync::Lazy; -use std::{sync::Mutex, collections::hash_map::Entry}; +use anyhow::{bail, Result}; use cocoa::base::id; -use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; use objc::{class, msg_send, sel, sel_impl}; -use std::path::PathBuf; -use std::path::Path; use std::collections::HashMap; +use once_cell::sync::Lazy; use std::collections::hash_map::DefaultHasher; -use anyhow::{bail, Result}; -use std::hash::{Hasher, Hash}; - +use std::collections::HashMap; +use std::hash::{Hash, Hasher}; +use std::path::Path; +use std::path::PathBuf; +use std::{collections::hash_map::Entry, sync::Mutex}; +use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; pub static ICON_CACHE: Lazy> = Lazy::new(|| Mutex::new(IconCache::default())); @@ -45,8 +45,11 @@ unsafe fn png_data_for_executable(executable: &Path) -> Result> { sys.refresh_processes_specifics(ProcessRefreshKind::new()); for (pid, process) in sys.processes() { let pid = pid.as_u32(); - if executable == process.exe().to_path_buf(){ - let app: id = msg_send![class!(NSRunningApplication), runningApplicationWithProcessIdentifier: pid]; + if executable == process.exe().to_path_buf() { + let app: id = msg_send![ + class!(NSRunningApplication), + runningApplicationWithProcessIdentifier: pid + ]; if !app.is_null() { let img: id = msg_send![app, icon]; let tif: id = msg_send![img, TIFFRepresentation]; @@ -55,7 +58,7 @@ unsafe fn png_data_for_executable(executable: &Path) -> Result> { let length: usize = msg_send![png, length]; let bytes: *const u8 = msg_send![png, bytes]; let data = std::slice::from_raw_parts(bytes, length).to_vec(); - return Ok(data) + return Ok(data); } } } diff --git a/src/macos/processes.rs b/src/macos/processes.rs index b9a7348f..66759791 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -1,18 +1,21 @@ -use std::collections::{HashMap, HashSet}; -use std::collections::hash_map::Entry; +use crate::intercept_conf::PID; use crate::processes::{ProcessInfo, ProcessList}; use anyhow::Result; use cocoa::base::nil; use cocoa::foundation::NSString; +use core_foundation::number::kCFNumberSInt32Type; use core_foundation::number::CFNumberGetValue; use core_foundation::number::CFNumberRef; -use core_foundation::number::kCFNumberSInt32Type; -use core_graphics::display::{CFDictionaryGetValueIfPresent, CGWindowListCopyWindowInfo, CFArrayGetCount, CFArrayGetValueAtIndex, CFDictionaryRef, kCGNullWindowID, kCGWindowListOptionOnScreenOnly, kCGWindowListExcludeDesktopElements}; +use core_graphics::display::{ + kCGNullWindowID, kCGWindowListExcludeDesktopElements, kCGWindowListOptionOnScreenOnly, + CFArrayGetCount, CFArrayGetValueAtIndex, CFDictionaryGetValueIfPresent, CFDictionaryRef, + CGWindowListCopyWindowInfo, +}; +use std::collections::hash_map::Entry; +use std::collections::{HashMap, HashSet}; use std::ffi::c_void; -use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; use std::path::PathBuf; -use crate::intercept_conf::PID; - +use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; pub fn active_executables() -> Result { let mut executables: HashMap = HashMap::new(); @@ -28,7 +31,7 @@ pub fn active_executables() -> Result { match executables.entry(executable) { Entry::Occupied(mut e) => { let process_info = e.get(); - if !process_info.is_visible && visible.contains(&pid){ + if !process_info.is_visible && visible.contains(&pid) { e.get_mut().is_visible = true; } } @@ -47,22 +50,33 @@ pub fn active_executables() -> Result { Ok(executables.into_values().collect()) } - pub fn visible_windows() -> Result> { let mut pids: HashSet = HashSet::new(); - unsafe{ - let windows_info_list = CGWindowListCopyWindowInfo( kCGWindowListOptionOnScreenOnly + kCGWindowListExcludeDesktopElements, kCGNullWindowID); + unsafe { + let windows_info_list = CGWindowListCopyWindowInfo( + kCGWindowListOptionOnScreenOnly + kCGWindowListExcludeDesktopElements, + kCGNullWindowID, + ); let count = CFArrayGetCount(windows_info_list); - for i in 0..count-1 { + for i in 0..count - 1 { let dic_ref = CFArrayGetValueAtIndex(windows_info_list, i); let key = NSString::alloc(nil).init_str("kCGWindowOwnerPID"); let mut pid: *const c_void = std::ptr::null_mut(); - if CFDictionaryGetValueIfPresent(dic_ref as CFDictionaryRef, key as *const c_void, &mut pid) != 0{ + if CFDictionaryGetValueIfPresent( + dic_ref as CFDictionaryRef, + key as *const c_void, + &mut pid, + ) != 0 + { let pid_cf_ref = pid as CFNumberRef; - let mut pid:i32 = 0; - if CFNumberGetValue(pid_cf_ref, kCFNumberSInt32Type, &mut pid as *mut i32 as *mut c_void) { + let mut pid: i32 = 0; + if CFNumberGetValue( + pid_cf_ref, + kCFNumberSInt32Type, + &mut pid as *mut i32 as *mut c_void, + ) { pids.insert(pid as u32); } } From ab57062f5f6c0342f3fe094efb601ca28d97f5bb Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Thu, 2 Nov 2023 18:57:58 +0100 Subject: [PATCH 15/20] comment removed --- src/macos/processes.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/macos/processes.rs b/src/macos/processes.rs index 66759791..181af85e 100644 --- a/src/macos/processes.rs +++ b/src/macos/processes.rs @@ -27,7 +27,6 @@ pub fn active_executables() -> Result { let display_name = process.name().to_string(); let executable = process.exe().to_path_buf(); let is_system = executable.starts_with("/System/"); - // let mut icon = vec![]; match executables.entry(executable) { Entry::Occupied(mut e) => { let process_info = e.get(); @@ -81,7 +80,6 @@ pub fn visible_windows() -> Result> { } } } - Ok(pids) } } From e9a4f9e213888e777e7df4b83ab016e5ce5883f5 Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Fri, 3 Nov 2023 20:00:29 +0100 Subject: [PATCH 16/20] tif to png conversion with image crate --- benches/process.rs | 26 ++++++++++++++++++++++++++ src/macos/icons.rs | 31 +++++++++++++++++++++++++------ 2 files changed, 51 insertions(+), 6 deletions(-) diff --git a/benches/process.rs b/benches/process.rs index 692b6b51..5ad50e39 100755 --- a/benches/process.rs +++ b/benches/process.rs @@ -1,6 +1,8 @@ use criterion::{criterion_group, criterion_main, Criterion}; #[cfg(windows)] use mitmproxy::windows::{icons, processes}; +#[cfg(target_os = "macos")] +use mitmproxy::macos::icons; #[cfg(windows)] use windows::Win32::System::LibraryLoader::GetModuleHandleW; @@ -45,6 +47,30 @@ fn criterion_benchmark(c: &mut Criterion) { b.iter(processes::active_executables) }); } + #[cfg(target_os = "macos")] + { + let test_app = std::path::PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); + + c.bench_function("get png with system", |b| { + b.iter(|| { + icons::IconCache::default() + .get_png(test_app.clone()) + .unwrap(); + }) + }); + + + let mut cache = icons::IconCache::default(); + c.bench_function("get_png with system", |b| { + b.iter(|| { + cache + .get_png(test_app.clone()) + .unwrap(); + }) + }); + + + } } criterion_group!(benches, criterion_benchmark); diff --git a/src/macos/icons.rs b/src/macos/icons.rs index c5020ccc..24a3a4b2 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -9,6 +9,7 @@ use std::path::Path; use std::path::PathBuf; use std::{collections::hash_map::Entry, sync::Mutex}; use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; +use image::ImageEncoder; pub static ICON_CACHE: Lazy> = Lazy::new(|| Mutex::new(IconCache::default())); @@ -21,6 +22,7 @@ pub struct IconCache { } impl IconCache { + pub fn get_png(&mut self, executable: PathBuf) -> Result<&Vec> { match self.executables.entry(executable) { Entry::Occupied(e) => { @@ -28,7 +30,8 @@ impl IconCache { Ok(self.icons.get(e.get()).unwrap()) } Entry::Vacant(e) => { - let icon = unsafe { png_data_for_executable(e.key())? }; + let tif = unsafe { tif_data_for_executable(e.key())? }; + let icon = tif_to_png(&tif)?; let mut hasher = DefaultHasher::new(); icon.hash(&mut hasher); let icon_hash = hasher.finish(); @@ -38,9 +41,23 @@ impl IconCache { } } } + +} + +pub fn tif_to_png(tif: &[u8]) -> Result> { + let tif_image = image::load_from_memory(tif)?; + let mut png_image: Vec = Vec::new(); + let encoder = image::codecs::png::PngEncoder::new(&mut png_image); + encoder.write_image( + tif_image.as_rgba8().unwrap(), + tif_image.width(), + tif_image.height(), + image::ColorType::Rgba8, + )?; + Ok(png_image) } -unsafe fn png_data_for_executable(executable: &Path) -> Result> { +unsafe fn tif_data_for_executable(executable: &Path) -> Result> { let mut sys = System::new(); sys.refresh_processes_specifics(ProcessRefreshKind::new()); for (pid, process) in sys.processes() { @@ -53,10 +70,8 @@ unsafe fn png_data_for_executable(executable: &Path) -> Result> { if !app.is_null() { let img: id = msg_send![app, icon]; let tif: id = msg_send![img, TIFFRepresentation]; - let bitmap: id = msg_send![class!(NSBitmapImageRep), imageRepWithData: tif]; - let png: id = msg_send![bitmap, representationUsingType: 4 properties: 0]; - let length: usize = msg_send![png, length]; - let bytes: *const u8 = msg_send![png, bytes]; + let length: usize = msg_send![tif, length]; + let bytes: *const u8 = msg_send![tif, bytes]; let data = std::slice::from_raw_parts(bytes, length).to_vec(); return Ok(data); } @@ -68,12 +83,16 @@ unsafe fn png_data_for_executable(executable: &Path) -> Result> { #[cfg(test)] mod tests { use super::*; + use base64::{engine::general_purpose, Engine as _}; #[test] fn png() { let path = PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); let mut icon_cache = IconCache::default(); let vec = icon_cache.get_png(path).unwrap(); + assert!(vec.len() > 0); dbg!(vec.len()); + let base64_png = general_purpose::STANDARD.encode(&vec); + dbg!(base64_png); } } From 8180276d39fdf3fd7afcfe33940e6bfd013e7323 Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 19:11:06 +0000 Subject: [PATCH 17/20] [autofix.ci] apply automated fixes --- benches/process.rs | 15 ++++++--------- src/macos/icons.rs | 4 +--- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/benches/process.rs b/benches/process.rs index 5ad50e39..3463fd76 100755 --- a/benches/process.rs +++ b/benches/process.rs @@ -1,8 +1,8 @@ use criterion::{criterion_group, criterion_main, Criterion}; -#[cfg(windows)] -use mitmproxy::windows::{icons, processes}; #[cfg(target_os = "macos")] use mitmproxy::macos::icons; +#[cfg(windows)] +use mitmproxy::windows::{icons, processes}; #[cfg(windows)] use windows::Win32::System::LibraryLoader::GetModuleHandleW; @@ -49,7 +49,9 @@ fn criterion_benchmark(c: &mut Criterion) { } #[cfg(target_os = "macos")] { - let test_app = std::path::PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); + let test_app = std::path::PathBuf::from( + "/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder", + ); c.bench_function("get png with system", |b| { b.iter(|| { @@ -59,17 +61,12 @@ fn criterion_benchmark(c: &mut Criterion) { }) }); - let mut cache = icons::IconCache::default(); c.bench_function("get_png with system", |b| { b.iter(|| { - cache - .get_png(test_app.clone()) - .unwrap(); + cache.get_png(test_app.clone()).unwrap(); }) }); - - } } diff --git a/src/macos/icons.rs b/src/macos/icons.rs index 24a3a4b2..319ce4b3 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -1,5 +1,6 @@ use anyhow::{bail, Result}; use cocoa::base::id; +use image::ImageEncoder; use objc::{class, msg_send, sel, sel_impl}; use once_cell::sync::Lazy; use std::collections::hash_map::DefaultHasher; @@ -9,7 +10,6 @@ use std::path::Path; use std::path::PathBuf; use std::{collections::hash_map::Entry, sync::Mutex}; use sysinfo::{PidExt, ProcessExt, ProcessRefreshKind, System, SystemExt}; -use image::ImageEncoder; pub static ICON_CACHE: Lazy> = Lazy::new(|| Mutex::new(IconCache::default())); @@ -22,7 +22,6 @@ pub struct IconCache { } impl IconCache { - pub fn get_png(&mut self, executable: PathBuf) -> Result<&Vec> { match self.executables.entry(executable) { Entry::Occupied(e) => { @@ -41,7 +40,6 @@ impl IconCache { } } } - } pub fn tif_to_png(tif: &[u8]) -> Result> { From 8e22c06028c511000bdda01c66b2dfdcda35433f Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Fri, 3 Nov 2023 19:12:53 +0000 Subject: [PATCH 18/20] [autofix.ci] apply automated fixes (attempt 2/3) --- src/macos/icons.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/macos/icons.rs b/src/macos/icons.rs index 319ce4b3..c378e022 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -88,9 +88,9 @@ mod tests { let path = PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); let mut icon_cache = IconCache::default(); let vec = icon_cache.get_png(path).unwrap(); - assert!(vec.len() > 0); + assert!(!vec.is_empty()); dbg!(vec.len()); - let base64_png = general_purpose::STANDARD.encode(&vec); + let base64_png = general_purpose::STANDARD.encode(vec); dbg!(base64_png); } } From cb36109f3a885766d141487f69d925363c2b14ec Mon Sep 17 00:00:00 2001 From: emanuele-em Date: Mon, 6 Nov 2023 16:08:29 +0100 Subject: [PATCH 19/20] memory_leak test and fix icons hashmap --- Cargo.lock | 2 +- Cargo.toml | 2 +- benches/process.rs | 4 ++-- src/macos/icons.rs | 48 ++++++++++++++++++++++++++++------------------ 4 files changed, 33 insertions(+), 23 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index e8e325b8..98c69168 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1443,13 +1443,13 @@ dependencies = [ "anyhow", "apple-security-framework", "async-trait", - "base64 0.21.5", "boringtun", "cocoa", "console-subscriber", "core-foundation", "core-graphics", "criterion", + "data-encoding", "env_logger", "futures-util", "image", diff --git a/Cargo.toml b/Cargo.toml index 7ee5b124..e78638d5 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -46,7 +46,7 @@ tokio-util = { version = "0.7.8", features = ["codec"] } futures-util = { version = "0.3.28", features = ["sink"] } sysinfo = "0.29.10" -base64 = "0.21.5" +data-encoding = "2.4.0" # [patch.crates-io] # tokio = { path = "../tokio/tokio" } diff --git a/benches/process.rs b/benches/process.rs index 3463fd76..0f8a6dd2 100755 --- a/benches/process.rs +++ b/benches/process.rs @@ -53,7 +53,7 @@ fn criterion_benchmark(c: &mut Criterion) { "/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder", ); - c.bench_function("get png with system", |b| { + c.bench_function("get_png", |b| { b.iter(|| { icons::IconCache::default() .get_png(test_app.clone()) @@ -62,7 +62,7 @@ fn criterion_benchmark(c: &mut Criterion) { }); let mut cache = icons::IconCache::default(); - c.bench_function("get_png with system", |b| { + c.bench_function("get_png (cached)", |b| { b.iter(|| { cache.get_png(test_app.clone()).unwrap(); }) diff --git a/src/macos/icons.rs b/src/macos/icons.rs index c378e022..0542fcca 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -29,33 +29,33 @@ impl IconCache { Ok(self.icons.get(e.get()).unwrap()) } Entry::Vacant(e) => { - let tif = unsafe { tif_data_for_executable(e.key())? }; - let icon = tif_to_png(&tif)?; + let tiff = unsafe { tiff_data_for_executable(e.key())? }; let mut hasher = DefaultHasher::new(); - icon.hash(&mut hasher); - let icon_hash = hasher.finish(); - e.insert(icon_hash); - let icon = self.icons.entry(icon_hash).or_insert(icon); + tiff.hash(&mut hasher); + let tiff_hash = hasher.finish(); + let icon = self.icons.entry(tiff_hash).or_insert_with(|| + tiff_to_png(&tiff) + ); Ok(icon) } } } } -pub fn tif_to_png(tif: &[u8]) -> Result> { - let tif_image = image::load_from_memory(tif)?; +pub fn tiff_to_png(tiff: &[u8]) -> Vec { + let tiff_image = image::load_from_memory(tiff).unwrap(); let mut png_image: Vec = Vec::new(); let encoder = image::codecs::png::PngEncoder::new(&mut png_image); encoder.write_image( - tif_image.as_rgba8().unwrap(), - tif_image.width(), - tif_image.height(), + tiff_image.as_rgba8().unwrap(), + tiff_image.width(), + tiff_image.height(), image::ColorType::Rgba8, - )?; - Ok(png_image) + ).unwrap(); + png_image } -unsafe fn tif_data_for_executable(executable: &Path) -> Result> { +unsafe fn tiff_data_for_executable(executable: &Path) -> Result> { let mut sys = System::new(); sys.refresh_processes_specifics(ProcessRefreshKind::new()); for (pid, process) in sys.processes() { @@ -67,9 +67,9 @@ unsafe fn tif_data_for_executable(executable: &Path) -> Result> { ]; if !app.is_null() { let img: id = msg_send![app, icon]; - let tif: id = msg_send![img, TIFFRepresentation]; - let length: usize = msg_send![tif, length]; - let bytes: *const u8 = msg_send![tif, bytes]; + let tiff: id = msg_send![img, TIFFRepresentation]; + let length: usize = msg_send![tiff, length]; + let bytes: *const u8 = msg_send![tiff, bytes]; let data = std::slice::from_raw_parts(bytes, length).to_vec(); return Ok(data); } @@ -81,7 +81,7 @@ unsafe fn tif_data_for_executable(executable: &Path) -> Result> { #[cfg(test)] mod tests { use super::*; - use base64::{engine::general_purpose, Engine as _}; + use data_encoding::BASE64; #[test] fn png() { @@ -90,7 +90,17 @@ mod tests { let vec = icon_cache.get_png(path).unwrap(); assert!(!vec.is_empty()); dbg!(vec.len()); - let base64_png = general_purpose::STANDARD.encode(vec); + let base64_png = BASE64.encode(vec); dbg!(base64_png); } + + #[ignore] + #[test] + fn memory_leak() { + let path = PathBuf::from("/System/Library/CoreServices/Finder.app/Contents/MacOS/Finder"); + for _ in 0..500 { + _ = unsafe { &tiff_data_for_executable(&path) }; + } + } + } From a48ee8801a4ec459ec55ad0a02ed8e8eab2d94cb Mon Sep 17 00:00:00 2001 From: "autofix-ci[bot]" <114827586+autofix-ci[bot]@users.noreply.github.com> Date: Mon, 6 Nov 2023 15:13:14 +0000 Subject: [PATCH 20/20] [autofix.ci] apply automated fixes --- src/macos/icons.rs | 22 ++++++++++++---------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/src/macos/icons.rs b/src/macos/icons.rs index 0542fcca..2811ba9a 100644 --- a/src/macos/icons.rs +++ b/src/macos/icons.rs @@ -33,9 +33,10 @@ impl IconCache { let mut hasher = DefaultHasher::new(); tiff.hash(&mut hasher); let tiff_hash = hasher.finish(); - let icon = self.icons.entry(tiff_hash).or_insert_with(|| - tiff_to_png(&tiff) - ); + let icon = self + .icons + .entry(tiff_hash) + .or_insert_with(|| tiff_to_png(&tiff)); Ok(icon) } } @@ -46,12 +47,14 @@ pub fn tiff_to_png(tiff: &[u8]) -> Vec { let tiff_image = image::load_from_memory(tiff).unwrap(); let mut png_image: Vec = Vec::new(); let encoder = image::codecs::png::PngEncoder::new(&mut png_image); - encoder.write_image( - tiff_image.as_rgba8().unwrap(), - tiff_image.width(), - tiff_image.height(), - image::ColorType::Rgba8, - ).unwrap(); + encoder + .write_image( + tiff_image.as_rgba8().unwrap(), + tiff_image.width(), + tiff_image.height(), + image::ColorType::Rgba8, + ) + .unwrap(); png_image } @@ -102,5 +105,4 @@ mod tests { _ = unsafe { &tiff_data_for_executable(&path) }; } } - }