Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion crates/extendify-native/src/unix/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use crate::cef::{
_cef_browser_settings_t, _cef_browser_view_delegate_t, _cef_browser_view_t, _cef_client_t,
_cef_dictionary_value_t, _cef_request_context_t, cef_string_t,
};
use crate::vtable_hooks::GET_REQ_HANDLER_OG;
use crate::{log, vtable_hooks};

#[macro_use]
Expand All @@ -22,7 +23,7 @@ extern_c_overrides! {

let view = real_cef_browser_view_create(client, url, settings, extra_info, request_context, delegate);

vtable_hooks::GET_REQ_HANDLER_OG = (*client).get_request_handler;
*GET_REQ_HANDLER_OG.lock().unwrap() = (*client).get_request_handler;
(*client).get_request_handler = Some(vtable_hooks::get_req_handler_hook);

view
Expand Down
106 changes: 54 additions & 52 deletions crates/extendify-native/src/vtable_hooks.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,21 @@ use crate::cef::{
};
use crate::{callbacks, log};
use std::ffi::c_int;
use std::sync::Mutex;

const ENTRYPOINTS: &[&str] = &["/xpui.js", "/xpui-snapshot.js"];

#[allow(unused)]
pub static mut ON_CONTEXT_CREATED_OG: Option<
unsafe extern "C" fn(
*mut _cef_render_process_handler_t,
*mut _cef_browser_t,
*mut _cef_frame_t,
*mut _cef_v8_context_t,
),
> = None;
pub static ON_CONTEXT_CREATED_OG: Mutex<
Option<
unsafe extern "C" fn(
*mut _cef_render_process_handler_t,
*mut _cef_browser_t,
*mut _cef_frame_t,
*mut _cef_v8_context_t,
),
>,
> = Mutex::new(None);
#[allow(unused)]
pub unsafe extern "C" fn on_context_created_hook(
self_: *mut _cef_render_process_handler_t,
Expand All @@ -29,27 +32,27 @@ pub unsafe extern "C" fn on_context_created_hook(

callbacks::on_frame(frame);

unsafe {
if let Some(func) = ON_CONTEXT_CREATED_OG {
return func(self_, browser, frame, context);
}
if let Some(func) = ON_CONTEXT_CREATED_OG.lock().ok().and_then(|g| *g) {
unsafe { func(self_, browser, frame, context) };
}

log("Couldn't call original on_context_created");
log(format!("Couldn't call original {}", stringify!($mutex)));
}

pub static mut RES_HANDLER_OG: Option<
unsafe extern "C" fn(
*mut _cef_request_handler_t,
*mut _cef_browser_t,
*mut _cef_frame_t,
*mut _cef_request_t,
c_int,
c_int,
*const cef_string_t,
*mut c_int,
) -> *mut _cef_resource_request_handler_t,
> = None;
pub static RES_HANDLER_OG: Mutex<
Option<
unsafe extern "C" fn(
*mut _cef_request_handler_t,
*mut _cef_browser_t,
*mut _cef_frame_t,
*mut _cef_request_t,
c_int,
c_int,
*const cef_string_t,
*mut c_int,
) -> *mut _cef_resource_request_handler_t,
>,
> = Mutex::new(None);
pub unsafe extern "C" fn res_handler_hook(
self_: *mut _cef_request_handler_t,
browser: *mut _cef_browser_t,
Expand All @@ -60,24 +63,24 @@ pub unsafe extern "C" fn res_handler_hook(
initiator: *const cef_string_t,
disable_default_handling: *mut c_int,
) -> *mut _cef_resource_request_handler_t {
unsafe {
callbacks::on_frame(frame);
callbacks::on_frame(frame);

let url = ctos((*request).get_url.unwrap()(request));
if ENTRYPOINTS
.iter()
.any(|entrypoint| url.ends_with(entrypoint))
{
let header = (*request).get_header_by_name.unwrap()(request, stoc("extendify"));
if header.is_null() {
log("Blocked entrypoint");
let url = unsafe { ctos((*request).get_url.unwrap()(request)) };
if ENTRYPOINTS
.iter()
.any(|entrypoint| url.ends_with(entrypoint))
{
let header = unsafe { (*request).get_header_by_name.unwrap()(request, stoc("extendify")) };
if header.is_null() {
log("Blocked entrypoint");

return std::ptr::null_mut();
}
return std::ptr::null_mut();
}
}

if let Some(func) = RES_HANDLER_OG {
return func(
if let Some(func) = RES_HANDLER_OG.lock().ok().and_then(|g| *g) {
return unsafe {
func(
self_,
browser,
frame,
Expand All @@ -86,33 +89,32 @@ pub unsafe extern "C" fn res_handler_hook(
is_download,
initiator,
disable_default_handling,
);
}
)
};
}

log("Couldn't call original res handler");
std::ptr::null_mut()
}

#[allow(unused)]
pub static mut GET_REQ_HANDLER_OG: Option<
unsafe extern "C" fn(*mut _cef_client_t) -> *mut _cef_request_handler_t,
> = None;
pub static GET_REQ_HANDLER_OG: Mutex<
Option<unsafe extern "C" fn(*mut _cef_client_t) -> *mut _cef_request_handler_t>,
> = Mutex::new(None);
#[allow(unused)]
pub unsafe extern "C" fn get_req_handler_hook(
self_: *mut _cef_client_t,
) -> *mut _cef_request_handler_t {
unsafe {
if let Some(func) = GET_REQ_HANDLER_OG {
let handler = func(self_);
if let Some(func) = GET_REQ_HANDLER_OG.lock().ok().and_then(|g| *g) {
let handler = unsafe { func(self_) };

if !handler.is_null() {
RES_HANDLER_OG = (*handler).get_resource_request_handler;
if !handler.is_null() {
unsafe {
*RES_HANDLER_OG.lock().unwrap() = (*handler).get_resource_request_handler;
(*handler).get_resource_request_handler = Some(res_handler_hook);
}

return handler;
}

return handler;
}

log("Couldn't call original req handler");
Expand Down
63 changes: 35 additions & 28 deletions crates/extendify-native/src/win/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ use slim_detours_sys::{
SlimDetoursAttach, SlimDetoursTransactionBegin, SlimDetoursTransactionCommit,
};
use std::ffi::{CString, c_int, c_void};
use std::sync::Mutex;
use windows_sys::Win32::Foundation::HINSTANCE;
use windows_sys::Win32::System::LibraryLoader::{GetModuleHandleW, GetProcAddress, LoadLibraryW};
use windows_sys::Win32::System::SystemServices::DLL_PROCESS_ATTACH;
Expand Down Expand Up @@ -60,10 +61,11 @@ macro_rules! define_hook {

let symbol_c = CString::new($symbol).unwrap();
if let Some(target) = GetProcAddress(module, symbol_c.as_ptr() as _) {
$original = Some(std::mem::transmute(target));
let mut guard = $original.lock().unwrap();
*guard = Some(std::mem::transmute(target));

SlimDetoursTransactionBegin();
SlimDetoursAttach(std::ptr::addr_of_mut!($original) as _, $hook as _);
SlimDetoursAttach(guard.as_mut().unwrap() as *mut _ as _, $hook as _);
let status = SlimDetoursTransactionCommit();

if status >= 0 {
Expand All @@ -80,10 +82,11 @@ macro_rules! define_hook {

macro_rules! define_inline_hook {
($target: expr, $hook: expr, $original: expr) => {
$original = Some(std::mem::transmute($target));
let mut guard = $original.lock().unwrap();
*guard = Some(std::mem::transmute($target));

SlimDetoursTransactionBegin();
SlimDetoursAttach(std::ptr::addr_of_mut!($original) as _, $hook as _);
SlimDetoursAttach(guard.as_mut().unwrap() as *mut _ as _, $hook as _);
let status = SlimDetoursTransactionCommit();

if status >= 0 {
Expand All @@ -106,14 +109,16 @@ fn init_hooks() {
define_hook!("cef_browser_view_create", cef_view_hook, CEF_VIEW_OG);
}

static mut CEF_INITIALIZE_OG: Option<
unsafe extern "C" fn(
*const _cef_main_args_t,
*mut _cef_settings_t,
*mut _cef_app_t,
*mut c_void,
) -> c_int,
> = None;
static CEF_INITIALIZE_OG: Mutex<
Option<
unsafe extern "C" fn(
*const _cef_main_args_t,
*mut _cef_settings_t,
*mut _cef_app_t,
*mut c_void,
) -> c_int,
>,
> = Mutex::new(None);
unsafe extern "C" fn cef_initialize_hook(
args: *const _cef_main_args_t,
settings: *mut _cef_settings_t,
Expand All @@ -123,7 +128,7 @@ unsafe extern "C" fn cef_initialize_hook(
log(format!("CEF init call on PID {}", std::process::id()));

unsafe {
if let Some(func) = CEF_INITIALIZE_OG {
if let Some(func) = CEF_INITIALIZE_OG.lock().ok().and_then(|g| *g) {
return func(args, settings, app, std::ptr::null_mut());
}
}
Expand All @@ -132,9 +137,9 @@ unsafe extern "C" fn cef_initialize_hook(
0
}

static mut CEF_PROCESS_OG: Option<
unsafe extern "C" fn(*const _cef_main_args_t, *mut _cef_app_t, *mut c_void) -> c_int,
> = None;
static CEF_PROCESS_OG: Mutex<
Option<unsafe extern "C" fn(*const _cef_main_args_t, *mut _cef_app_t, *mut c_void) -> c_int>,
> = Mutex::new(None);
unsafe extern "C" fn cef_process_hook(
args: *const _cef_main_args_t,
app: *mut _cef_app_t,
Expand All @@ -156,7 +161,7 @@ unsafe extern "C" fn cef_process_hook(
}
}

if let Some(func) = CEF_PROCESS_OG {
if let Some(func) = CEF_PROCESS_OG.lock().ok().and_then(|g| *g) {
return func(args, app, std::ptr::null_mut());
}
}
Expand All @@ -165,16 +170,18 @@ unsafe extern "C" fn cef_process_hook(
0
}

static mut CEF_VIEW_OG: Option<
unsafe extern "C" fn(
*mut _cef_client_t,
*const cef_string_t,
*const _cef_browser_settings_t,
*mut _cef_dictionary_value_t,
*mut _cef_request_context_t,
*mut _cef_browser_view_delegate_t,
) -> *mut _cef_browser_view_t,
> = None;
static CEF_VIEW_OG: Mutex<
Option<
unsafe extern "C" fn(
*mut _cef_client_t,
*const cef_string_t,
*const _cef_browser_settings_t,
*mut _cef_dictionary_value_t,
*mut _cef_request_context_t,
*mut _cef_browser_view_delegate_t,
) -> *mut _cef_browser_view_t,
>,
> = Mutex::new(None);
unsafe extern "C" fn cef_view_hook(
client: *mut _cef_client_t,
url: *const cef_string_t,
Expand All @@ -193,7 +200,7 @@ unsafe extern "C" fn cef_view_hook(
vtable_hooks::RES_HANDLER_OG
);

if let Some(func) = CEF_VIEW_OG {
if let Some(func) = CEF_VIEW_OG.lock().ok().and_then(|g| *g) {
return func(client, url, settings, extra_info, request_context, delegate);
}
}
Expand Down
Loading