From 36beaa454a5f21b737efbdf4d626de79ed1bec5e Mon Sep 17 00:00:00 2001 From: abba23 Date: Wed, 5 May 2021 11:01:06 +0200 Subject: [PATCH] Remove redhook dependency --- Cargo.toml | 4 +-- src/lib.rs | 86 +++++++++++++++++++++++++++++++++--------------------- 2 files changed, 55 insertions(+), 35 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index e3909d6..cb2c9bf 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,15 +8,15 @@ edition = "2018" [dependencies] lazy_static = "*" libc = "*" -redhook = "*" regex = "*" serde = { version = "*", features = ["derive"] } toml = "*" [lib] name = "spotifyadblock" -crate_type = ["dylib"] +crate_type = ["cdylib"] [profile.release] lto = true +opt-level = 3 panic = "abort" diff --git a/src/lib.rs b/src/lib.rs index 39f2b40..5a0d7bd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -4,17 +4,37 @@ use cef::{ _cef_request_context_t, _cef_request_t, _cef_urlrequest_client_t, cef_string_userfree_utf16_free, cef_urlrequest_t, }; use lazy_static::lazy_static; -use libc::{addrinfo, c_char, EAI_FAIL}; -use redhook::{hook, real}; +use libc::{addrinfo, c_char, dlsym, EAI_FAIL, RTLD_NEXT}; use regex::Regex; use serde::Deserialize; use std::ffi::CStr; use std::fs::read_to_string; +use std::mem; use std::path::PathBuf; use std::ptr::null; use std::slice::from_raw_parts; use std::string::String; +macro_rules! hook { + ($function_name:ident($($parameter_name:ident: $parameter_type:ty),*) -> $return_type:ty => $new_function_name:ident $body:block) => { + lazy_static! { + static ref $new_function_name: fn($($parameter_type),*) -> $return_type = unsafe { + let function_name = CStr::from_bytes_with_nul(concat!(stringify!($function_name), "\0").as_bytes()).unwrap(); + let function_pointer = dlsym(RTLD_NEXT, function_name.as_ptr()); + if function_pointer.is_null() { + panic!("[*] Error: Unable to find function \"{}\"", stringify!($function_name)); + } + mem::transmute(function_pointer) + }; + } + + #[no_mangle] + pub unsafe extern "C" fn $function_name($($parameter_name: $parameter_type),*) -> $return_type { + $body + } + } +} + #[derive(Deserialize)] struct Config { allowlist: Vec, @@ -55,6 +75,37 @@ lazy_static! { }; } +hook! { + getaddrinfo(node: *const c_char, service: *const c_char, hints: *const addrinfo, res: *const *const addrinfo) -> i32 => REAL_GETADDRINFO { + let domain = CStr::from_ptr(node).to_str().unwrap(); + + if listed(domain, &CONFIG.allowlist) { + println!("[+] getaddrinfo:\t\t {}", domain); + REAL_GETADDRINFO(node, service, hints, res) + } else { + println!("[-] getaddrinfo:\t\t {}", domain); + EAI_FAIL + } + } +} + +hook! { + cef_urlrequest_create(request: *mut _cef_request_t, client: *const _cef_urlrequest_client_t, request_context: *const _cef_request_context_t) -> *const cef_urlrequest_t => REAL_CEF_URLREQUEST_CREATE { + let url_cef = (*request).get_url.unwrap()(request); + let url_utf16 = from_raw_parts((*url_cef).str_, (*url_cef).length as usize); + let url = String::from_utf16(url_utf16).unwrap(); + cef_string_userfree_utf16_free(url_cef); + + if listed(&url, &CONFIG.denylist) { + println!("[-] cef_urlrequest_create:\t {}", url); + null() + } else { + println!("[+] cef_urlrequest_create:\t {}", url); + REAL_CEF_URLREQUEST_CREATE(request, client, request_context) + } + } +} + fn listed(element: &str, regex_list: &Vec) -> bool { for regex_string in regex_list { // TODO: only generate each regex once outside of loop @@ -71,34 +122,3 @@ fn listed(element: &str, regex_list: &Vec) -> bool { } false } - -hook! { - unsafe fn getaddrinfo(node: *const c_char, service: *const c_char, hints: *const addrinfo, res: *const *const addrinfo) -> i32 => _getaddrinfo { - let domain = CStr::from_ptr(node).to_str().unwrap(); - - if listed(domain, &CONFIG.allowlist) { - println!("[+] getaddrinfo:\t\t {}", domain); - real!(getaddrinfo)(node, service, hints, res) - } else { - println!("[-] getaddrinfo:\t\t {}", domain); - EAI_FAIL - } - } -} - -hook! { - unsafe fn cef_urlrequest_create(request: *mut _cef_request_t, client: *const _cef_urlrequest_client_t, request_context: *const _cef_request_context_t) -> *const cef_urlrequest_t => _cef_urlrequest_create { - let url_cef = (*request).get_url.unwrap()(request); - let url_utf16 = from_raw_parts((*url_cef).str_, (*url_cef).length as usize); - let url = String::from_utf16(url_utf16).unwrap(); - cef_string_userfree_utf16_free(url_cef); - - if listed(&url, &CONFIG.denylist) { - println!("[-] cef_urlrequest_create:\t {}", url); - null() - } else { - println!("[+] cef_urlrequest_create:\t {}", url); - real!(cef_urlrequest_create)(request, client, request_context) - } - } -}