From c8bfe76c437f33b60b38a04bc7ef78fab78442ab Mon Sep 17 00:00:00 2001 From: s1341 Date: Thu, 1 Apr 2021 15:39:11 +0300 Subject: [PATCH] Fix android and optimize frida (#44) * fix_android_and_optimize_frida: Fix build and run for android; optimize frida maybe_log functions * fix_android_and_optimize_frida: Get rid of the HasFd trait; cleanup warnings * fix_android_and_optimize_frida: fmt --- fuzzers/frida_libpng/build.rs | 13 ++-- fuzzers/frida_libpng/src/fuzzer.rs | 107 ++++++++++++++--------------- libafl/src/bolts/llmp.rs | 38 +++------- libafl/src/bolts/shmem.rs | 15 +--- libafl/src/events/llmp.rs | 8 +-- 5 files changed, 73 insertions(+), 108 deletions(-) diff --git a/fuzzers/frida_libpng/build.rs b/fuzzers/frida_libpng/build.rs index cfe52fdf7a..63c8ae17ee 100644 --- a/fuzzers/frida_libpng/build.rs +++ b/fuzzers/frida_libpng/build.rs @@ -29,8 +29,13 @@ fn main() { let libpng_tar = format!("{}/libpng-1.6.37.tar.xz", &cwd); // Enforce clang for its -fsanitize-coverage support. - std::env::set_var("CC", "clang"); - std::env::set_var("CXX", "clang++"); + let clang = match env::var("CLANG_PATH") { + Ok(path) => path, + Err(_) => "clang".to_string(), + }; + let clangpp = format!("{}++", &clang); + std::env::set_var("CC", &clang); + std::env::set_var("CXX", &clangpp); let ldflags = match env::var("LDFLAGS") { Ok(val) => val, Err(_) => "".to_string(), @@ -61,8 +66,8 @@ fn main() { "--disable-shared", &format!("--host={}", env::var("TARGET").unwrap())[..], ]) - .env("CC", "clang") - .env("CXX", "clang++") + .env("CC", &clang) + .env("CXX", &clangpp) .env( "CFLAGS", "-O3 -g -D_DEFAULT_SOURCE -fPIC -fno-omit-frame-pointer", diff --git a/fuzzers/frida_libpng/src/fuzzer.rs b/fuzzers/frida_libpng/src/fuzzer.rs index 885a62279f..b9cc649bbc 100644 --- a/fuzzers/frida_libpng/src/fuzzer.rs +++ b/fuzzers/frida_libpng/src/fuzzer.rs @@ -77,69 +77,56 @@ pub fn get_module_size(module_name: &str) -> usize { /// every time we need a copy that is within a direct branch of the start of the transformed basic /// block. #[cfg(target_arch = "x86_64")] -const MAYBE_LOG_CODE: [u8; 69] = [ - 0x9c, // pushfq - 0x50, // push rax - 0x51, // push rcx - 0x52, // push rdx - 0x56, // push rsi - 0x89, 0xf8, // mov eax, edi - 0xc1, 0xe0, 0x08, // shl eax, 8 - 0xc1, 0xef, 0x04, // shr edi, 4 - 0x31, 0xc7, // xor edi, eax - 0x0f, 0xb7, 0xc7, // movzx eax, di - 0x48, 0x8d, 0x0d, 0x34, 0x00, 0x00, 0x00, // lea rcx, sym._afl_area_ptr_ptr - 0x48, 0x8b, 0x09, // mov rcx, qword [rcx] - 0x48, 0x8d, 0x15, 0x22, 0x00, 0x00, 0x00, // lea rdx, sym._afl_prev_loc_ptr - 0x48, 0x8b, 0x32, // mov rsi, qword [rdx] - 0x48, 0x8b, 0x36, // mov rsi, qword [rsi] - 0x48, 0x31, 0xc6, // xor rsi, rax - 0x48, 0x81, 0xe6, 0xff, 0x1f, 0x00, - 0x00, // and rsi, 0x1fff (8 * 1024 - 1) TODO: make this variable - 0xfe, 0x04, 0x31, // inc byte [rcx + rsi] - 0x48, 0xd1, 0xe8, // shr rax, 1 - 0x48, 0x8b, 0x0a, // mov rcx, qword [rdx] - 0x48, 0x89, 0x01, // mov qword [rcx], rax - 0x5e, // pop rsi - 0x5a, // pop rdx - 0x59, // pop rcx - 0x58, // pop rax - 0x9d, // popfq - 0xc3, // ret - // Read-only data goes here: - // uint64_t* afl_prev_loc_ptr - // uint8_t** afl_area_ptr_ptr - // unsigned int afl_instr_rms +const MAYBE_LOG_CODE: [u8; 47] = [ + 0x9c, /* pushfq */ + 0x50, /* push rax */ + 0x51, /* push rcx */ + 0x52, /* push rdx */ + 0x48, 0x8d, 0x05, 0x24, 0x00, 0x00, 0x00, /* lea rax, sym._afl_area_ptr_ptr */ + 0x48, 0x8b, 0x00, /* mov rax, qword [rax] */ + 0x48, 0x8d, 0x0d, 0x22, 0x00, 0x00, 0x00, /* lea rcx, sym.previous_pc */ + 0x48, 0x8b, 0x11, /* mov rdx, qword [rcx] */ + 0x48, 0x8b, 0x12, /* mov rdx, qword [rdx] */ + 0x48, 0x31, 0xfa, /* xor rdx, rdi */ + 0xfe, 0x04, 0x10, /* inc byte [rax + rdx] */ + 0x48, 0xd1, 0xef, /* shr rdi, 1 */ + 0x48, 0x8b, 0x01, /* mov rax, qword [rcx] */ + 0x48, 0x89, 0x38, /* mov qword [rax], rdi */ + 0x5a, /* pop rdx */ + 0x59, /* pop rcx */ + 0x58, /* pop rax */ + 0x9d, /* popfq */ + 0xc3, /* ret */ + + /* Read-only data goes here: */ + /* uint8_t* afl_area_ptr */ + /* uint64_t* afl_prev_loc_ptr */ ]; #[cfg(target_arch = "aarch64")] -const MAYBE_LOG_CODE: [u8; 104] = [ +const MAYBE_LOG_CODE: [u8; 56] = [ + // __afl_area_ptr[current_pc ^ previous_pc]++; + // previous_pc = current_pc >> 1; 0xE1, 0x0B, 0xBF, 0xA9, // stp x1, x2, [sp, -0x10]! 0xE3, 0x13, 0xBF, 0xA9, // stp x3, x4, [sp, -0x10]! - 0xE1, 0x03, 0x00, 0xAA, // mov x1, x0 - 0x00, 0xDC, 0x78, 0xD3, // lsl x0, x0, #8 - 0x21, 0xFC, 0x44, 0xD3, // lsr x1, x1, #4 - 0x00, 0x00, 0x01, 0xCA, // eor x0, x0, x1 - 0x00, 0x3C, 0x00, 0x53, // uxth w0, w0 - 0xa1, 0x02, 0x00, 0x58, // ldr x1, =area_ptr - 0x42, 0x02, 0x00, 0x58, // ldr x2, =pc_ptr - 0x43, 0x00, 0x40, 0xF9, // ldr x3, [x2] - 0x63, 0x00, 0x00, 0xCA, // eor x3, x3, x0 - 0x63, 0x40, 0x40, 0x92, // and x3, x3, #0x1ffff - 0x21, 0x00, 0x03, 0x8B, // add x1, x1, x3 - 0x24, 0x00, 0x40, 0x39, // ldrb w4, [x1, #0 - 0x84, 0x04, 0x00, 0x91, // add x4, x4, #1 - 0x24, 0x00, 0x00, 0x39, // strb w4, [x1, #0] - 0x00, 0xFC, 0x41, 0xD3, // lsr x0, x0, #1 - 0x40, 0x00, 0x00, 0xF9, // str x0, [x2] + // x0 = current_pc + 0x81, 0x01, 0x00, 0x58, // ldr x1, #0x30, =__afl_area_ptr + 0xa2, 0x01, 0x00, 0x58, // ldr x2, #0x38, =&previous_pc + 0x44, 0x00, 0x40, 0xf9, // ldr x4, [x2] (=previous_pc) + // __afl_area_ptr[current_pc ^ previous_pc]++; + 0x84, 0x00, 0x00, 0xca, // eor x4, x4, x0 + 0x23, 0x68, 0x64, 0xf8, // ldr x3, [x1, x4] + 0x63, 0x04, 0x00, 0x91, // add x3, x3, #1 + 0x23, 0x68, 0x24, 0xf8, // str x3, [x1, x2] + // previous_pc = current_pc >> 1; + 0xe0, 0x07, 0x40, 0x8b, // add x0, xzr, x0, LSR #1 + 0x40, 0x00, 0x00, 0xf9, // str x0, [x2] 0xE3, 0x13, 0xc1, 0xA8, // ldp x3, x4, [sp], #0x10 0xE1, 0x0B, 0xc1, 0xA8, // ldp x1, x2, [sp], #0x10 0xC0, 0x03, 0x5F, 0xD6, // ret - 0x1f, 0x20, 0x03, 0xD5, // nop - 0x1f, 0x20, 0x03, 0xD5, // nop - 0x1f, 0x20, 0x03, 0xD5, // nop - 0x1f, 0x20, 0x03, 0xD5, // nop - 0x1f, 0x20, 0x03, 0xD5, // nop + + // &afl_area_ptr + // &afl_prev_loc_ptr ]; /// The implementation of the FridaEdgeCoverageHelper @@ -198,7 +185,10 @@ impl<'a> FridaEdgeCoverageHelper<'a> { -(frida_gum_sys::GUM_RED_ZONE_SIZE as i32), ); writer.put_push_reg(X86Register::Rdi); - writer.put_mov_reg_address(X86Register::Rdi, address); + writer.put_mov_reg_address( + X86Register::Rdi, + ((address >> 4) ^ (address << 8)) & (MAP_SIZE - 1) as u64, + ); writer.put_call_address(helper.current_log_impl); writer.put_pop_reg(X86Register::Rdi); writer.put_lea_reg_reg_offset( @@ -216,7 +206,10 @@ impl<'a> FridaEdgeCoverageHelper<'a> { -(16 + frida_gum_sys::GUM_RED_ZONE_SIZE as i32) as i64, IndexMode::PreAdjust, ); - writer.put_ldr_reg_u64(Aarch64Register::X0, address); + writer.put_ldr_reg_u64( + Aarch64Register::X0, + ((address >> 4) ^ (address << 8)) & (MAP_SIZE - 1) as u64, + ); writer.put_bl_imm(helper.current_log_impl); writer.put_ldp_reg_reg_reg_offset( Aarch64Register::Lr, diff --git a/libafl/src/bolts/llmp.rs b/libafl/src/bolts/llmp.rs index 9d896c7b8a..479e9b943d 100644 --- a/libafl/src/bolts/llmp.rs +++ b/libafl/src/bolts/llmp.rs @@ -80,18 +80,12 @@ use nix::{ }; #[cfg(all(feature = "std", unix))] -use std::{ - ffi::CStr, - os::unix::{ - self, - net::{UnixListener, UnixStream}, - {io::AsRawFd, prelude::RawFd}, - }, +use std::os::unix::{ + self, + net::{UnixListener, UnixStream}, + {io::AsRawFd, prelude::RawFd}, }; -#[cfg(all(unix, feature = "std"))] -use libc::c_char; - #[cfg(all(unix, feature = "std"))] use uds::{UnixListenerExt, UnixSocketAddr, UnixStreamExt}; @@ -102,9 +96,6 @@ use crate::{ Error, }; -#[cfg(all(unix, feature = "std"))] -use super::shmem::HasFd; - /// We'll start off with 256 megabyte maps per fuzzer client #[cfg(not(feature = "llmp_small_maps"))] const LLMP_CFG_INITIAL_MAP_SIZE: usize = 1 << 28; @@ -454,7 +445,7 @@ where #[cfg(all(unix, feature = "std"))] impl LlmpConnection where - SH: ShMem + HasFd, + SH: ShMem, { #[cfg(all(feature = "std", unix))] pub fn on_domain_socket(filename: &str) -> Result { @@ -1438,6 +1429,7 @@ where let client_out_map_mem = &self.llmp_out.out_maps.first().unwrap().shmem; let broadcast_map_description = postcard::to_allocvec(&client_out_map_mem.description())?; + let client_out_map_mem_fd: i32 = client_out_map_mem.shm_str().parse().unwrap(); let mut incoming_map_description_serialized = vec![0u8; broadcast_map_description.len()]; @@ -1504,17 +1496,7 @@ where ListenerStream::Unix(stream, addr) => unsafe { dbg!("New connection", addr); - let broadcast_fd_initial: i32 = - CStr::from_ptr(broadcast_map_description.as_ptr() as *const c_char) - .to_string_lossy() - .into_owned() - .parse() - .unwrap_or_else(|_| { - panic!( - "ShmId is not a valid int file descriptor: {:?}", - broadcast_map_description - ) - }); + let broadcast_fd_initial: i32 = client_out_map_mem_fd; match sendmsg( stream.as_raw_fd(), @@ -1893,7 +1875,7 @@ where #[cfg(all(unix, feature = "std"))] impl LlmpClient where - SH: ShMem + HasFd, + SH: ShMem, { #[cfg(all(unix, feature = "std"))] /// Create a LlmpClient, getting the ID from a given filename @@ -1936,7 +1918,9 @@ where .first() .unwrap() .shmem - .shm_id()])], + .shm_str() + .parse() + .unwrap()])], MsgFlags::empty(), None, ) { diff --git a/libafl/src/bolts/shmem.rs b/libafl/src/bolts/shmem.rs index 3c704be519..84cf07e5b3 100644 --- a/libafl/src/bolts/shmem.rs +++ b/libafl/src/bolts/shmem.rs @@ -101,13 +101,6 @@ pub trait ShMem: Sized + Debug { } } -/// shared maps that have an id can use this trait -//#[cfg(all(unix, feature = "std"))] -pub trait HasFd { - /// Retrieve the id of this shared map - fn shm_id(&self) -> i32; -} - #[cfg(all(unix, feature = "std"))] pub mod unix_shmem { @@ -121,7 +114,7 @@ pub mod unix_shmem { use crate::Error; - use super::{HasFd, ShMem}; + use super::ShMem; #[cfg(unix)] extern "C" { @@ -313,12 +306,6 @@ pub mod unix_shmem { } } - impl HasFd for UnixShMem { - fn shm_id(&self) -> i32 { - self.shm_id - } - } - /// Deinit sharedmaps on drop impl Drop for UnixShMem { fn drop(&mut self) { diff --git a/libafl/src/events/llmp.rs b/libafl/src/events/llmp.rs index e8ec17ffc0..cbd113ef30 100644 --- a/libafl/src/events/llmp.rs +++ b/libafl/src/events/llmp.rs @@ -17,9 +17,6 @@ use crate::utils::{fork, ForkResult}; #[cfg(all(feature = "std", unix))] use crate::bolts::shmem::UnixShMem; -#[cfg(all(feature = "std", unix))] -use crate::bolts::shmem::HasFd; - use crate::{ bolts::{ llmp::{self, LlmpClient, LlmpClientDescription, LlmpSender, Tag}, @@ -313,7 +310,7 @@ impl LlmpEventManager where I: Input, S: IfInteresting, - SH: ShMem + HasFd, + SH: ShMem, ST: Stats, { #[cfg(all(feature = "std", unix))] @@ -516,7 +513,7 @@ pub fn setup_restarting_mgr( where I: Input, S: DeserializeOwned + IfInteresting, - SH: ShMem, // Todo: HasFd is only needed for Android + SH: ShMem, ST: Stats, { let mut mgr; @@ -525,7 +522,6 @@ where let (sender, mut receiver) = if std::env::var(_ENV_FUZZER_SENDER).is_err() { #[cfg(target_os = "android")] { - let path = std::env::current_dir()?; mgr = LlmpEventManager::::new_on_domain_socket(stats, "\x00llmp_socket")?; }; #[cfg(not(target_os = "android"))]