ok thanks you a lot , even though it didn't fix my problem at least I learned something, here is my final code :
use crate::frida_script::FRIDA_SCRIPT;
use frida::{
Device, DeviceManager, Frida, Message, MessageError, MessageLog, MessageSend, Script,
ScriptHandler, ScriptOption, Session,
};
use ouroboros::self_referencing;
use serde_json::Value;
use log::{self};
use std::sync::{Arc, Mutex};
use tauri::async_runtime::{channel, spawn, Receiver, Sender};
use tokio::sync::oneshot;
struct MyHandler {
event_sender: Arc<Sender<String>>,
test: &'static mut String,
}
impl MyHandler {
pub fn new(event_sender: Sender<String>) -> Self {
let instance = Self {
event_sender: Arc::new(event_sender),
test: Box::leak(Box::new("working?".to_string())),
};
instance
}
}
impl ScriptHandler for &MyHandler {
fn on_message(&mut self, message: &Message) {
println!("In on_message");
println!("{}", self.test);
println!("trying to acces event");
/*match Arc::strong_count(&self.event_sender) {
count if count > 0 => println!("event_sender strong count: {}", count),
_ => println!("event_sender Arc seems invalid or dropped"),
}
println!("aftter strong count");*/
println!("{:?}", self.event_sender);
match message {
Message::Send(MessageSend { payload }) => {
println!(
"Received Send message with payload result: {:?}",
payload.result
);
}
Message::Log(MessageLog { level, payload }) => {
println!(
"Received Log message with level: {:?}, payload: {}",
level, payload
);
}
Message::Error(MessageError {
description,
stack,
file_name,
line_number,
column_number,
}) => {
println!(
"Received Error message with description: {}, stack: {}, file_name: {}, line_number: {}, column_number: {}",
description, stack, file_name, line_number, column_number
);
}
Message::Other(value) => match value {
Value::Null => println!("Received Other message: null"),
Value::Bool(b) => println!("Received Other message: bool({})", b),
Value::Number(n) => println!("Received Other message: number({})", n),
Value::String(s) => println!("Received Other message: string({})", s),
Value::Array(arr) => println!("Received Other message: array({:?})", arr),
Value::Object(obj) => {
if let Some(data) = obj.get("data").unwrap().as_str() {
match serde_json::from_str::<Value>(data) {
Ok(json_value) => {
if let Some(adress) =
json_value.get("payload").and_then(|v| v.as_str())
{
println!("Received Other message: object({})", adress);
println!("before string");
let address_clones = adress.to_string();
/*println!("after string {}", address_clones);
match Arc::strong_count(&self.event_sender) {
count if count > 0 => {
println!("event_sender strong count: {}", count)
}
_ => println!("event_sender Arc seems invalid or dropped"),
}*/
println!("before clone");
// let event_sender = self.event_sender.lock().unwrap().clone();
let even_sender = self.event_sender.clone();
println!("before spawn");
spawn(async move {
println!("trying to send message");
if let Err(e) = even_sender.send(address_clones).await {
eprintln!("Failed to send message: {}", e);
}
println!("message sent");
});
println!("after spawn");
} else {
eprintln!("Failed to get payload from JSON");
}
}
Err(e) => eprintln!("Failed to parse JSON: {}", e),
}
}
}
},
}
}
}
#[self_referencing]
struct Connection<'a> {
#[borrows()]
session: Session<'a>,
#[borrows(session)]
#[not_covariant]
script: Script<'this>,
}
enum HookMessage {
IsRunning { respond_to: oneshot::Sender<bool> },
Attach { respond_to: oneshot::Sender<bool> },
}
pub struct Hook<'a> {
receiver: Receiver<HookMessage>,
_name: String,
script: String,
device: &'a Device<'static>,
script_handler: &'static MyHandler,
_connection: Option<Connection<'a>>,
}
impl<'a> Hook<'a> {
pub fn new(
_hook_message_receiver: Receiver<HookMessage>,
event_sender: Sender<String>,
) -> Self {
let frida: &'static Frida = Box::leak(Box::new(unsafe { Frida::obtain() }));
let device_manager = DeviceManager::obtain(frida);
let device_manager_boxed = Box::leak(Box::new(device_manager));
let device = Box::leak(Box::new(device_manager_boxed.get_local_device().unwrap()));
Self {
receiver: _hook_message_receiver,
_name: "myApp.exe".to_string(),
script: FRIDA_SCRIPT.to_string(),
device,
script_handler: Box::leak(Box::new(MyHandler::new(event_sender))),
_connection: None,
}
}
fn handle_message(&mut self, msg: HookMessage) {
match msg {
HookMessage::IsRunning { respond_to } => {
let _ = respond_to.send(self.is__running());
}
HookMessage::Attach { respond_to } => {
let _ = respond_to.send(self.attach());
println!(" Hooked");
}
}
}
pub fn run_my_actor(&mut self) {
while let Some(message) = self.receiver.blocking_recv() {
self.handle_message(message);
}
}
pub fn attach(&mut self) -> bool {
if !self.is__running() {
return false;
}
let _pid = self.get__pid();
let session = self.device.attach(_pid).unwrap();
self._connection = Some(
ConnectionBuilder {
session: session,
script_builder: |session| {
let mut script: Script = session
.create_script(&self.script, &mut ScriptOption::new())
.unwrap();
let _ = script.handle_message(self.script_handler);
let _ = script.load();
script
},
}
.build(),
);
log::info!("Attached to process with PID: {}", _pid);
true
}
pub fn get__pid(&self) -> u32 {
let processes = self.device.enumerate_processes();
let _process = processes
.iter()
.find(|process| process.get_name().starts_with(&self._name))
.ok_or(" process not found")
.unwrap();
_process.get_pid()
}
pub fn is__running(&self) -> bool {
let processes = self.device.enumerate_processes();
processes
.iter()
.any(|process| process.get_name() == self._name)
}
}
#[derive(Clone)]
pub struct HookHandle {
sender: Sender<HookMessage>,
}
impl HookHandle {
pub fn new(event_sender: Sender<String>) -> Self {
let (sender, receiver) = channel(8);
std::thread::spawn(move || {
let mut actor = Hook::new(receiver, event_sender);
actor.run_my_actor()
});
Self { sender }
}
pub async fn is__running(&self) -> bool {
let (send, recv) = oneshot::channel();
let msg = HookMessage::IsRunning { respond_to: send };
// Ignore send errors. If this send fails, so does the
// recv.await below. There's no reason to check for the
// same failure twice.
let _ = self.sender.send(msg).await;
match recv.await {
Ok(result) => result,
Err(e) => {
eprintln!("Failed to receive message: {}", e);
false
}
}
}
pub async fn attach(&self) -> bool {
let (send, recv) = oneshot::channel();
let msg = HookMessage::Attach { respond_to: send };
let _ = self.sender.send(msg).await;
match recv.await {
Ok(result) => result,
Err(e) => {
eprintln!("Failed to receive message: {}", e);
false
}
}
}
}
Unfortunately it didn't fix my issue and i still have :
=================================================================
==6196==ERROR: AddressSanitizer: access-violation on unknown address 0x000000000009 (pc 0x7ff66c2e98c4 bp 0x00440a1fd770 sp 0x00440a1fd6c0 T24)
==6196==The signal is caused by a READ memory access.
==6196==Hint: address points to the zero page.
#0 0x7ff66c2e98c3 in _$LT$$RF$mut$u20$T$u20$as$u20$core..fmt..Display$GT$::fmt::h1176aadaf509fdab C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\fmt\mod.rs:2644
#1 0x7ff66d3353a9 in core::fmt::rt::Argument::fmt /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\core\src\fmt\rt.rs:177
#2 0x7ff66d3353a9 in core::fmt::write::hd09721bccbef5a36 /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\core\src\fmt\mod.rs:1437
#3 0x7ff66d30d82a in std::io::Write::write_fmt /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\io\mod.rs:1887
#4 0x7ff66d30d82a in _$LT$$RF$std..io..stdio..Stdout$u20$as$u20$std..io..Write$GT$::write_fmt::haad2e52e4f8128a3 /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\io\stdio.rs:792
#5 0x7ff66d30e4d0 in std::io::stdio::impl$15::write_fmt /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\io\stdio.rs:766
#6 0x7ff66d30e4d0 in std::io::stdio::print_to /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\io\stdio.rs:1122
#7 0x7ff66d30e4d0 in std::io::stdio::_print::h394176707872073f /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\io\stdio.rs:1233
#8 0x7ff66ab0c0bb in _$LT$$RF$app_lib..hook..MyHandler$u20$as$u20$frida..script..ScriptHandler$GT$::on_message::hb1521dc7c35741a0 C:\Programmation\Projets\src-tauri\src\hook.rs:33
#9 0x7ff66aba1564 in frida::script::call_on_message::h0f776aee639d7da9 C:\Users\sauro\.cargo\registry\src\index.crates.io-6f17d22bba15001f\frida-0.15.1\src\script.rs:121
#10 0x7ff66d3ac731 in g_closure_invoke D:\a\frida\frida\deps\src\glib\gobject\gclosure.c:836
#11 0x7ff66d340261 in signal_emit_unlocked_R D:\a\frida\frida\deps\src\glib\gobject\gsignal.c:3800
#12 0x7ff66d33e6a9 in g_signal_emit_valist D:\a\frida\frida\deps\src\glib\gobject\gsignal.c:3553
#13 0x7ff66d33dfc3 in g_signal_emit D:\a\frida\frida\deps\src\glib\gobject\gsignal.c:3610
#14 0x7ff66d372b3f in frida_session_real_post_messages_co D:\a\frida\frida\build\frida.c:47029
#15 0x7ff66d3883d4 in frida_agent_message_sink_post_messages D:\a\frida\frida\build\session.c:14126
#16 0x7ff66d3799ea in _dbus_frida_agent_message_sink_post_messages D:\a\frida\frida\build\session.c:14356
#17 0x7ff66d3c0cc8 in call_in_idle_cb D:\a\frida\frida\deps\src\glib\gio\gdbusconnection.c:4998
#18 0x7ff66d3b777e in g_idle_dispatch D:\a\frida\frida\deps\src\glib\glib\gmain.c:6462
#19 0x7ff66d3b8df4 in g_main_dispatch D:\a\frida\frida\deps\src\glib\glib\gmain.c:3557
#20 0x7ff66d3b7fdf in g_main_context_dispatch D:\a\frida\frida\deps\src\glib\glib\gmain.c:4281
#21 0x7ff66d3b8306 in g_main_context_iterate D:\a\frida\frida\deps\src\glib\glib\gmain.c:4357
#22 0x7ff66d3b8fee in g_main_loop_run D:\a\frida\frida\deps\src\glib\glib\gmain.c:4557
#23 0x7ff66d344c63 in run_main_loop D:\a\frida\frida\subprojects\frida-core\src\frida-glue.c:159
#24 0x7ff66d3b74ec in g_thread_proxy D:\a\frida\frida\deps\src\glib\glib\gthread.c:1055
#25 0x7ff66d3a40da in g_thread_win32_proxy D:\a\frida\frida\deps\src\glib\glib\gthread-win32.c:494
#26 0x7ffe564d9332 (C:\Windows\System32\ucrtbase.dll+0x180029332)
#27 0x7ffd5807de2d in asan_thread_start D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win.cpp:170
#28 0x7ffe5758259c (C:\Windows\System32\KERNEL32.DLL+0x18001259c)
#29 0x7ffe58c6af37 (C:\Windows\SYSTEM32\ntdll.dll+0x18005af37)
AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: access-violation C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\fmt\mod.rs:2644 in _$LT$$RF$mut$u20$T$u20$as$u20$core..fmt..Display$GT$::fmt::h1176aadaf509fdab
Thread T24 created by T23 here:
#0 0x7ffd5807e237 in CreateThread D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win.cpp:223
#1 0x7ffe564d83ad (C:\Windows\System32\ucrtbase.dll+0x1800283ad)
#2 0x7ff66d3a3c66 in g_system_thread_new D:\a\frida\frida\deps\src\glib\glib\gthread-win32.c:539
#3 0x7ff66d3b7316 in g_thread_new_internal D:\a\frida\frida\deps\src\glib\glib\gthread.c:1162
#4 0x7ff66d3b72b7 in g_thread_new D:\a\frida\frida\deps\src\glib\glib\gthread.c:1112
#5 0x7ff66d344b48 in frida_init_with_runtime D:\a\frida\frida\subprojects\frida-core\src\frida-glue.c:47
#6 0x7ff66c0d94e8 in frida::Frida::obtain::h1c8de11d8b6a5b03 C:\Users\sauro\.cargo\registry\src\index.crates.io-6f17d22bba15001f\frida-0.15.1\src\lib.rs:51
#7 0x7ff66ab0dcdd in app_lib::hook::Hook::new::h88decbf6d87bcc02 C:\Programmation\Projets\src-tauri\src\hook.rs:142
#8 0x7ff66b9fc781 in app_lib::hook::HookHandle::new::_$u7b$$u7b$closure$u7d$$u7d$::h080a1736b4ca15a9 C:\Programmation\Projets\src-tauri\src\hook.rs:255
#9 0x7ff66b3ecc42 in std::sys::backtrace::__rust_begin_short_backtrace::h366b478b3b1b2187 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys\backtrace.rs:152
#10 0x7ff66a9b13fd in std::thread::Builder::spawn_unchecked_::_$u7b$$u7b$closure$u7d$$u7d$::_$u7b$$u7b$closure$u7d$$u7d$::h7f4e9de15281129c C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:561
#11 0x7ff66bb5b777 in _$LT$core..panic..unwind_safe..AssertUnwindSafe$LT$F$GT$$u20$as$u20$core..ops..function..FnOnce$LT$$LP$$RP$$GT$$GT$::call_once::h447b09500d277125 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\panic\unwind_safe.rs:272
#12 0x7ff66b41f1fc in std::panicking::try::do_call::h85f65ddc4c4d443a C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:573
#13 0x7ff66a9b1e42 in _$LT$std..thread..Packet$LT$T$GT$$u20$as$u20$core..ops..drop..Drop$GT$::drop::_$u7b$$u7b$closure$u7d$$u7d$::haaa54579984ab298 (C:\Programmation\Projets\src-tauri\target\x86_64-pc-windows-msvc\debug.exe+0x1400e1e42)
#14 0x7ff66a9af605 in std::panicking::try C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panicking.rs:536
#15 0x7ff66a9af605 in std::panic::catch_unwind C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\panic.rs:358
#16 0x7ff66a9af605 in std::thread::Builder::spawn_unchecked_::_$u7b$$u7b$closure$u7d$$u7d$::h6fdd3a7c2e2abd90 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:559
#17 0x7ff66a9d814d in core::ops::function::FnOnce::call_once$u7b$$u7b$vtable.shim$u7d$$u7d$::h591dfcfa4c69a80e C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
#18 0x7ff66d3229cc in alloc::boxed::impl$28::call_once /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\alloc\src\boxed.rs:1970
#19 0x7ff66d3229cc in alloc::boxed::impl$28::call_once /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\alloc\src\boxed.rs:1970
#20 0x7ff66d3229cc in std::sys::pal::windows::thread::impl$0::new::thread_start /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\sys\pal\windows\thread.rs:55
#21 0x7ffd5807de2d in asan_thread_start D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win.cpp:170
#22 0x7ffe5758259c (C:\Windows\System32\KERNEL32.DLL+0x18001259c)
#23 0x7ffe58c6af37 (C:\Windows\SYSTEM32\ntdll.dll+0x18005af37)
Thread T23 created by T0 here:
#0 0x7ffd5807e237 in CreateThread D:\a\_work\1\s\src\vctools\asan\llvm\compiler-rt\lib\asan\asan_win.cpp:223
#1 0x7ff66d322860 in std::sys::pal::windows::thread::Thread::new::h017280e5c552294c /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\sys\pal\windows\thread.rs:30
#2 0x7ff66a9aba94 in std::thread::Builder::spawn_unchecked_::h23616de7f9648ee4 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:600
#3 0x7ff66a9a9387 in std::thread::Builder::spawn_unchecked::hfebf73570bf90fde C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:467
#4 0x7ff66a9a8935 in std::thread::Builder::new C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:400
#5 0x7ff66a9a8935 in std::thread::spawn::h95479ba6bb736495 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\thread\mod.rs:730
#6 0x7ff66ab10391 in app_lib::hook::HookHandle::new::h09add5cfa9f2380c C:\Programmation\Projets\src-tauri\src\hook.rs:254
#7 0x7ff66a8d4cf6 in app_lib::bot::Bot::new::hd04a96350e501073 C:\Programmation\Projets\src-tauri\src\bot.rs:21
#8 0x7ff66a8d1d39 in app_lib::run::hb45281bcd6215cd9 C:\Programmation\Projets\src-tauri\src\lib.rs:16
#9 0x7ff66a8d1048 in::main C:\Programmation\Projets\src-tauri\src\main.rs:5
#10 0x7ff66a8d129a in core::ops::function::FnOnce::call_once::hdf3489fdcfff43ad C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\core\src\ops\function.rs:250
#11 0x7ff66a8d100d in std::sys::backtrace::__rust_begin_short_backtrace::hccf684203473f78a C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\sys\backtrace.rs:152
#12 0x7ff66a8d1563 in std::rt::lang_start::_$u7b$$u7b$closure$u7d$$u7d$::h519e6d06634b26f5 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:195
#13 0x7ff66d3086bb in core::ops::function::impls::impl$2::call_once /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\core\src\ops\function.rs:284
#14 0x7ff66d3086bb in std::panicking::try::do_call /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panicking.rs:573
#15 0x7ff66d3086bb in std::panicking::try /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panicking.rs:536
#16 0x7ff66d3086bb in std::panic::catch_unwind /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panic.rs:358
#17 0x7ff66d3086bb in std::rt::lang_start_internal::closure$1 /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\rt.rs:174
#18 0x7ff66d3086bb in std::panicking::try::do_call /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panicking.rs:573
#19 0x7ff66d3086bb in std::panicking::try /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panicking.rs:536
#20 0x7ff66d3086bb in std::panic::catch_unwind /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\panic.rs:358
#21 0x7ff66d3086bb in std::rt::lang_start_internal::h9709fc44ae8f04d9 /rustc/a224f3807e58afc9353510f1d556c607d367545d/library\std\src\rt.rs:174
#22 0x7ff66a8d13e9 in std::rt::lang_start::h1f1d1d8c1fd35049 C:\Users\sauro\.rustup\toolchains\nightly-x86_64-pc-windows-msvc\lib\rustlib\src\rust\library\std\src\rt.rs:194
#23 0x7ff66a8d1068 in main (C:\Programmation\Projets\src-tauri\target\x86_64-pc-windows-msvc\debug.exe+0x140001068)
#24 0x7ff66d91900f in invoke_main D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:78
#25 0x7ff66d91900f in __scrt_common_main_seh D:\a\_work\1\s\src\vctools\crt\vcstartup\src\startup\exe_common.inl:288
#26 0x7ffe5758259c (C:\Windows\System32\KERNEL32.DLL+0x18001259c)
#27 0x7ffe58c6af37 (C:\Windows\SYSTEM32\ntdll.dll+0x18005af37)
==6196==ABORTING
From what i understand the issue is in the frida runtime created by Frida::obtain()
when it execute frida::script::call_on_message
and i tries to print my String. So probably my structure MyHandler
is not correctly shared ? If it would be freed the function on_message
could not be executed right ? The structure is static because of Box::leak(Box::new())
so it's is not that the variable doesn't exist anymore when it is used but probably that the pointers to his fields are corrupted/wrong ?