Fixing Frida ASAN tests on Windows (#2299)

* libafl_frida unit tests passing with ASAN

* Clippy+fmt

* Clippy

* Setup VS environment before building
This commit is contained in:
mkravchik 2024-06-11 04:22:46 -07:00 committed by GitHub
parent df40db5ae8
commit 03d8d2eb08
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 140 additions and 28 deletions

View File

@ -478,6 +478,7 @@ jobs:
profile: minimal profile: minimal
toolchain: stable toolchain: stable
- uses: actions/checkout@v3 - uses: actions/checkout@v3
- uses: ./.github/workflows/windows-tester-prepare
- uses: Swatinem/rust-cache@v2 - uses: Swatinem/rust-cache@v2
- name: Run real clippy, not the fake one - name: Run real clippy, not the fake one
shell: pwsh shell: pwsh

View File

@ -87,7 +87,7 @@ backtrace = { version = "0.3", default-features = false, features = [
"serde", "serde",
] } ] }
num-traits = "0.2" num-traits = "0.2"
ahash = "0.8" ahash = "^0.8" # fetch the latest
paste = "1.0" paste = "1.0"
log = "0.4.20" log = "0.4.20"
mmap-rs = "0.6.0" mmap-rs = "0.6.0"
@ -104,3 +104,5 @@ winsafe = {version = "0.0.21", features = ["kernel"]}
serial_test = { version = "3", default-features = false, features = ["logging"] } serial_test = { version = "3", default-features = false, features = ["logging"] }
clap = {version = "4.5", features = ["derive"]} clap = {version = "4.5", features = ["derive"]}
libloading = "0.8" libloading = "0.8"
mimalloc = { version = "*", default-features = false }
dlmalloc ={version = "0.2.6", features = ["global"]}

View File

@ -8,6 +8,7 @@ fn main() {
} }
let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap(); let target_family = std::env::var("CARGO_CFG_TARGET_FAMILY").unwrap();
// Force linking against libc++ // Force linking against libc++
if target_family == "unix" { if target_family == "unix" {
println!("cargo:rustc-link-lib=dylib=c++"); println!("cargo:rustc-link-lib=dylib=c++");
@ -23,7 +24,7 @@ fn main() {
if target_family == "windows" { if target_family == "windows" {
let compiler = cc::Build::new() let compiler = cc::Build::new()
.cpp(true) .cpp(true)
.file("test_harness.a") .file("test_harness.cpp")
.get_compiler(); .get_compiler();
let mut cmd = std::process::Command::new(compiler.path()); let mut cmd = std::process::Command::new(compiler.path());
let cmd = cmd let cmd = cmd
@ -46,7 +47,20 @@ fn main() {
std::env::var("HOME").unwrap() std::env::var("HOME").unwrap()
)); ));
cmd.arg("/dll").arg("/OUT:test_harness.dll"); cmd.arg("/dll").arg("/OUT:test_harness.dll");
cmd.status().expect("Failed to link test_harness.dll"); let output = cmd.output().expect("Failed to link test_harness.dll");
let output_str = format!(
"{:?}\nstatus: {}\nstdout: {}\nstderr: {}",
cmd,
output.status,
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
// std::fs::write("compiler_output.txt", output_str.clone()).expect("Unable to write file");
assert!(output.status.success(),
"Failed to link test_harness.dll\n {:?}",
output_str.as_str()
);
} else { } else {
let compiler = cc::Build::new() let compiler = cc::Build::new()
.cpp(true) .cpp(true)

View File

@ -158,6 +158,7 @@ impl Allocator {
#[must_use] #[must_use]
#[allow(clippy::missing_safety_doc)] #[allow(clippy::missing_safety_doc)]
pub unsafe fn alloc(&mut self, size: usize, _alignment: usize) -> *mut c_void { pub unsafe fn alloc(&mut self, size: usize, _alignment: usize) -> *mut c_void {
log::trace!("alloc");
let mut is_malloc_zero = false; let mut is_malloc_zero = false;
let size = if size == 0 { let size = if size == 0 {
is_malloc_zero = true; is_malloc_zero = true;
@ -242,6 +243,7 @@ impl Allocator {
/// Releases the allocation at the given address. /// Releases the allocation at the given address.
#[allow(clippy::missing_safety_doc)] #[allow(clippy::missing_safety_doc)]
pub unsafe fn release(&mut self, ptr: *mut c_void) { pub unsafe fn release(&mut self, ptr: *mut c_void) {
log::trace!("release {:?}", ptr);
let Some(metadata) = self.allocations.get_mut(&(ptr as usize)) else { let Some(metadata) = self.allocations.get_mut(&(ptr as usize)) else {
if !ptr.is_null() { if !ptr.is_null() {
AsanErrors::get_mut_blocking() AsanErrors::get_mut_blocking()
@ -375,9 +377,14 @@ impl Allocator {
unpoison: bool, unpoison: bool,
) -> (usize, usize) { ) -> (usize, usize) {
let shadow_mapping_start = map_to_shadow!(self, start); let shadow_mapping_start = map_to_shadow!(self, start);
log::trace!("map_shadow_for_region: {:x}, {:x}", start, end);
let shadow_start = self.round_down_to_page(shadow_mapping_start); let shadow_start = self.round_down_to_page(shadow_mapping_start);
let shadow_end = self.round_up_to_page((end - start) / 8 + self.page_size + shadow_start); let shadow_end = self.round_up_to_page((end - start) / 8 + self.page_size + shadow_start);
log::trace!(
"map_shadow_for_region: shadow_start {:x}, shadow_end {:x}",
shadow_start,
shadow_end
);
if self.using_pre_allocated_shadow_mapping { if self.using_pre_allocated_shadow_mapping {
let mut newly_committed_regions = Vec::new(); let mut newly_committed_regions = Vec::new();
for gap in self.shadow_pages.gaps(&(shadow_start..shadow_end)) { for gap in self.shadow_pages.gaps(&(shadow_start..shadow_end)) {
@ -406,6 +413,11 @@ impl Allocator {
} }
} }
for newly_committed_region in newly_committed_regions { for newly_committed_region in newly_committed_regions {
log::trace!(
"committed shadow pages: start {:x}, end {:x}",
newly_committed_region.start(),
newly_committed_region.end()
);
self.shadow_pages self.shadow_pages
.insert(newly_committed_region.start()..newly_committed_region.end()); .insert(newly_committed_region.start()..newly_committed_region.end());
self.mappings self.mappings
@ -549,21 +561,20 @@ impl Allocator {
} }
} }
/// Unpoison all the memory that is currently mapped with read/write permissions. /// Unpoison all the memory that is currently mapped with read permissions.
pub fn unpoison_all_existing_memory(&mut self) { pub fn unpoison_all_existing_memory(&mut self) {
RangeDetails::enumerate_with_prot( RangeDetails::enumerate_with_prot(
PageProtection::Read, PageProtection::Read,
&mut |range: &RangeDetails| -> bool { &mut |range: &RangeDetails| -> bool {
let start = range.memory_range().base_address().0 as usize; let start = range.memory_range().base_address().0 as usize;
let end = start + range.memory_range().size(); let end = start + range.memory_range().size();
//the shadow region should be the highest valid userspace region, so don't continue after
if self.is_managed(start as *mut c_void) { if self.is_managed(start as *mut c_void) {
false log::trace!("Not unpoisoning: {:#x}-{:#x}, is_managed", start, end);
} else { } else {
log::trace!("Unpoisoning: {:#x}-{:#x}", start, end); log::trace!("Unpoisoning: {:#x}-{:#x}", start, end);
self.map_shadow_for_region(start, end, true); self.map_shadow_for_region(start, end, true);
true
} }
true
}, },
); );
} }
@ -672,6 +683,11 @@ impl Allocator {
shadow_bit = (try_shadow_bit).try_into().unwrap(); shadow_bit = (try_shadow_bit).try_into().unwrap();
log::warn!("shadow_bit {shadow_bit:} is suitable"); log::warn!("shadow_bit {shadow_bit:} is suitable");
log::trace!(
"shadow area from {:x} to {:x} pre-allocated",
addr,
addr + (1 << (try_shadow_bit + 1))
);
self.pre_allocated_shadow_mappings.push(mapping); self.pre_allocated_shadow_mappings.push(mapping);
self.using_pre_allocated_shadow_mapping = true; self.using_pre_allocated_shadow_mapping = true;
break; break;
@ -734,6 +750,7 @@ impl Default for Allocator {
} }
#[test] #[test]
#[cfg(not(windows))] // not working yet
fn check_shadow() { fn check_shadow() {
let mut allocator = Allocator::default(); let mut allocator = Allocator::default();
allocator.init(); allocator.init();

View File

@ -1722,11 +1722,11 @@ impl AsanRuntime {
; .arch x64 ; .arch x64
// ; int3 // ; int3
; mov rdx, 1 ; mov rdx, 1
; shl rdx, shadow_bit as i8 //rcx now contains the mask ; shl rdx, shadow_bit as i8 //rdx = shadow_base
; mov rcx, rdi //copy address into rdx ; mov rcx, rdi //copy address into rcx
; and rcx, 7 //rsi now contains the offset for unaligned accesses ; and rcx, 7 //remainder
; shr rdi, 3 //rdi now contains the shadow byte offset ; shr rdi, 3 //start >> 3
; add rdi, rdx //add rdx and rdi to get the address of the shadow byte. rdi now contains the shadow address ; add rdi, rdx //shadow_base + (start >> 3)
; mov edx, [rdi] //load 4 shadow bytes. We load 4 just in case of an unaligned access ; mov edx, [rdi] //load 4 shadow bytes. We load 4 just in case of an unaligned access
; bswap edx //bswap to get it into an acceptable form ; bswap edx //bswap to get it into an acceptable form
; shl edx, cl //this shifts by the unaligned access offset. why does x86 require cl... ; shl edx, cl //this shifts by the unaligned access offset. why does x86 require cl...
@ -2259,7 +2259,7 @@ impl AsanRuntime {
#[allow(clippy::result_unit_err)] #[allow(clippy::result_unit_err)]
pub fn asan_is_interesting_instruction( pub fn asan_is_interesting_instruction(
decoder: InstDecoder, decoder: InstDecoder,
_address: u64, address: u64,
instr: &Insn, instr: &Insn,
) -> Option<(u8, X86Register, X86Register, u8, i32)> { ) -> Option<(u8, X86Register, X86Register, u8, i32)> {
let result = frida_to_cs(decoder, instr); let result = frida_to_cs(decoder, instr);
@ -2291,6 +2291,8 @@ impl AsanRuntime {
return None; return None;
} }
log::trace!("{:#x} {:#?} {:#?}", address, cs_instr, cs_instr.to_string());
for operand in operands { for operand in operands {
if operand.is_memory() { if operand.is_memory() {
// log::trace!("{:#?}", operand); // log::trace!("{:#?}", operand);
@ -2298,12 +2300,17 @@ impl AsanRuntime {
// because in x64 there's no mem to mem inst, just return the first memory operand // because in x64 there's no mem to mem inst, just return the first memory operand
if let Some((basereg, indexreg, scale, disp)) = operand_details(&operand) { if let Some((basereg, indexreg, scale, disp)) = operand_details(&operand) {
let memsz = cs_instr.mem_size().unwrap().bytes_size().unwrap(); // this won't fail if it is mem access inst // if the base register is rip, then it is a pc-relative access
// and does not deal with dynamically allocated memory
if basereg != X86Register::Rip {
let memsz = cs_instr.mem_size().unwrap().bytes_size().unwrap(); // this won't fail if it is mem access inst
// println!("{:#?} {:#?} {:#?}", cs_instr, cs_instr.to_string(), operand); // println!("{:#?} {:#?} {:#?}", cs_instr, cs_instr.to_string(), operand);
// println!("{:#?}", (memsz, basereg, indexreg, scale, disp)); // println!("{:#?}", (memsz, basereg, indexreg, scale, disp));
log::trace!("ASAN Interesting operand {:#?}", operand);
return Some((memsz, basereg, indexreg, scale, disp)); log::trace!("{:#?}", (memsz, basereg, indexreg, scale, disp));
return Some((memsz, basereg, indexreg, scale, disp));
}
} // else {} // perhaps avx instructions? } // else {} // perhaps avx instructions?
} }
} }

View File

@ -1,4 +1,6 @@
use core::fmt::{self, Debug, Formatter}; use core::fmt::{self, Debug, Formatter};
#[cfg(all(windows, not(test)))]
use std::process::abort;
use std::{ffi::c_void, marker::PhantomData}; use std::{ffi::c_void, marker::PhantomData};
use frida_gum::{ use frida_gum::{
@ -110,7 +112,7 @@ where
log::error!("Crashing target as it had ASan errors"); log::error!("Crashing target as it had ASan errors");
libc::raise(libc::SIGABRT); libc::raise(libc::SIGABRT);
#[cfg(windows)] #[cfg(windows)]
std::process::abort(); abort();
} }
} }
self.helper.post_exec(input)?; self.helper.post_exec(input)?;

View File

@ -183,7 +183,7 @@ impl FridaInstrumentationHelperBuilder {
/// # Example /// # Example
/// Instrument all modules in `/usr/lib` as well as `libfoo.so`: /// Instrument all modules in `/usr/lib` as well as `libfoo.so`:
/// ``` /// ```
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder; ///# use libafl_frida::helper::FridaInstrumentationHelper;
/// let builder = FridaInstrumentationHelper::builder() /// let builder = FridaInstrumentationHelper::builder()
/// .instrument_module_if(|module| module.name() == "libfoo.so") /// .instrument_module_if(|module| module.name() == "libfoo.so")
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib")); /// .instrument_module_if(|module| module.path().starts_with("/usr/lib"));
@ -212,7 +212,7 @@ impl FridaInstrumentationHelperBuilder {
/// Instrument all modules in `/usr/lib`, but exclude `libfoo.so`. /// Instrument all modules in `/usr/lib`, but exclude `libfoo.so`.
/// ///
/// ``` /// ```
///# use libafl_frida::helper::FridaInstrumentationHelperBuilder; ///# use libafl_frida::helper::FridaInstrumentationHelper;
/// let builder = FridaInstrumentationHelper::builder() /// let builder = FridaInstrumentationHelper::builder()
/// .instrument_module_if(|module| module.path().starts_with("/usr/lib")) /// .instrument_module_if(|module| module.path().starts_with("/usr/lib"))
/// .skip_module_if(|module| module.name() == "libfoo.so"); /// .skip_module_if(|module| module.name() == "libfoo.so");
@ -464,6 +464,7 @@ where
}) })
} }
#[allow(clippy::too_many_lines)]
fn transform( fn transform(
basic_block: StalkerIterator, basic_block: StalkerIterator,
output: &StalkerOutput, output: &StalkerOutput,
@ -484,13 +485,20 @@ where
let mut runtimes = (*runtimes_unborrowed).borrow_mut(); let mut runtimes = (*runtimes_unborrowed).borrow_mut();
if first { if first {
first = false; first = false;
// log::info!( log::trace!(
// "block @ {:x} transformed to {:x}", "block @ {:x} transformed to {:x}",
// address, address,
// output.writer().pc() output.writer().pc()
// ); );
if let Some(rt) = runtimes.match_first_type_mut::<CoverageRuntime>() { if let Some(rt) = runtimes.match_first_type_mut::<CoverageRuntime>() {
let start = output.writer().pc();
rt.emit_coverage_mapping(address, output); rt.emit_coverage_mapping(address, output);
log::trace!(
"emitted coverage info mapping for {:x} at {:x}-{:x}",
address,
start,
output.writer().pc()
);
} }
if let Some(_rt) = runtimes.match_first_type_mut::<DrCovRuntime>() { if let Some(_rt) = runtimes.match_first_type_mut::<DrCovRuntime>() {
basic_block_start = address; basic_block_start = address;
@ -506,6 +514,7 @@ where
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
if let Some(details) = res { if let Some(details) = res {
if let Some(rt) = runtimes.match_first_type_mut::<AsanRuntime>() { if let Some(rt) = runtimes.match_first_type_mut::<AsanRuntime>() {
let start = output.writer().pc();
rt.emit_shadow_check( rt.emit_shadow_check(
address, address,
output, output,
@ -516,6 +525,12 @@ where
details.3, details.3,
details.4, details.4,
); );
log::trace!(
"emitted shadow_check for {:x} at {:x}-{:x}",
address,
start,
output.writer().pc()
);
} }
} }

View File

@ -365,6 +365,8 @@ mod tests {
use libafl_bolts::{ use libafl_bolts::{
cli::FuzzerOptions, rands::StdRand, tuples::tuple_list, AsSlice, SimpleStdoutLogger, cli::FuzzerOptions, rands::StdRand, tuples::tuple_list, AsSlice, SimpleStdoutLogger,
}; };
#[cfg(unix)]
use mimalloc::MiMalloc;
use crate::{ use crate::{
asan::{ asan::{
@ -375,6 +377,14 @@ mod tests {
executor::FridaInProcessExecutor, executor::FridaInProcessExecutor,
helper::FridaInstrumentationHelper, helper::FridaInstrumentationHelper,
}; };
#[cfg(unix)]
#[global_allocator]
static GLOBAL: MiMalloc = MiMalloc;
#[cfg(windows)]
use dlmalloc::GlobalDlmalloc;
#[cfg(windows)]
#[global_allocator]
static GLOBAL: GlobalDlmalloc = GlobalDlmalloc;
static GUM: OnceLock<Gum> = OnceLock::new(); static GUM: OnceLock<Gum> = OnceLock::new();

View File

@ -7,16 +7,21 @@
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call,
LPVOID lpReserved) { LPVOID lpReserved) {
(void)hModule;
(void)lpReserved;
(void)ul_reason_for_call;
return TRUE; return TRUE;
} }
#define EXTERN __declspec(dllexport) extern "C" #define EXTERN extern "C" __declspec(dllexport)
#else #else
#define EXTERN #define EXTERN
extern "C" { extern "C" {
#endif #endif
EXTERN int heap_uaf_read(const uint8_t *_data, size_t _size) { EXTERN int heap_uaf_read(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = new int[100]; int *array = new int[100];
delete[] array; delete[] array;
fprintf(stdout, "%d\n", array[5]); fprintf(stdout, "%d\n", array[5]);
@ -24,13 +29,26 @@ EXTERN int heap_uaf_read(const uint8_t *_data, size_t _size) {
} }
EXTERN int heap_uaf_write(const uint8_t *_data, size_t _size) { EXTERN int heap_uaf_write(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = new int[100]; int *array = new int[100];
delete[] array; delete[] array;
array[5] = 1; array[5] = 1;
return 0; return 0;
} }
#include <winnt.h>
#include <winternl.h>
static volatile bool stop = false;
EXTERN int heap_oob_read(const uint8_t *_data, size_t _size) { EXTERN int heap_oob_read(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
// while(!stop);
// OutputDebugStringA("heap_oob_read\n");
int *array = new int[100]; int *array = new int[100];
fprintf(stdout, "%d\n", array[100]); fprintf(stdout, "%d\n", array[100]);
delete[] array; delete[] array;
@ -38,12 +56,16 @@ EXTERN int heap_oob_read(const uint8_t *_data, size_t _size) {
} }
EXTERN int heap_oob_write(const uint8_t *_data, size_t _size) { EXTERN int heap_oob_write(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = new int[100]; int *array = new int[100];
array[100] = 1; array[100] = 1;
delete[] array; delete[] array;
return 0; return 0;
} }
EXTERN int malloc_heap_uaf_read(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_uaf_read(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = static_cast<int *>(malloc(100 * sizeof(int))); int *array = static_cast<int *>(malloc(100 * sizeof(int)));
free(array); free(array);
fprintf(stdout, "%d\n", array[5]); fprintf(stdout, "%d\n", array[5]);
@ -51,6 +73,8 @@ EXTERN int malloc_heap_uaf_read(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_uaf_write(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_uaf_write(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = static_cast<int *>(malloc(100 * sizeof(int))); int *array = static_cast<int *>(malloc(100 * sizeof(int)));
free(array); free(array);
array[5] = 1; array[5] = 1;
@ -58,6 +82,8 @@ EXTERN int malloc_heap_uaf_write(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_oob_read(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_oob_read(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = static_cast<int *>(malloc(100 * sizeof(int))); int *array = static_cast<int *>(malloc(100 * sizeof(int)));
fprintf(stdout, "%d\n", array[100]); fprintf(stdout, "%d\n", array[100]);
free(array); free(array);
@ -65,6 +91,8 @@ EXTERN int malloc_heap_oob_read(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_oob_write(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_oob_write(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
int *array = static_cast<int *>(malloc(100 * sizeof(int))); int *array = static_cast<int *>(malloc(100 * sizeof(int)));
array[100] = 1; array[100] = 1;
free(array); free(array);
@ -72,6 +100,8 @@ EXTERN int malloc_heap_oob_write(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_oob_write_0x12(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_oob_write_0x12(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x12)); char *array = static_cast<char *>(malloc(0x12));
array[0x12] = 1; array[0x12] = 1;
free(array); free(array);
@ -79,6 +109,8 @@ EXTERN int malloc_heap_oob_write_0x12(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_oob_write_0x14(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_oob_write_0x14(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x14)); char *array = static_cast<char *>(malloc(0x14));
array[0x14] = 1; array[0x14] = 1;
free(array); free(array);
@ -86,6 +118,8 @@ EXTERN int malloc_heap_oob_write_0x14(const uint8_t *_data, size_t _size) {
} }
EXTERN int malloc_heap_oob_write_0x17(const uint8_t *_data, size_t _size) { EXTERN int malloc_heap_oob_write_0x17(const uint8_t *_data, size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x17)); char *array = static_cast<char *>(malloc(0x17));
array[0x17] = 1; array[0x17] = 1;
free(array); free(array);
@ -94,6 +128,8 @@ EXTERN int malloc_heap_oob_write_0x17(const uint8_t *_data, size_t _size) {
EXTERN int malloc_heap_oob_write_0x17_int_at_0x16(const uint8_t *_data, EXTERN int malloc_heap_oob_write_0x17_int_at_0x16(const uint8_t *_data,
size_t _size) { size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x17)); char *array = static_cast<char *>(malloc(0x17));
*(int *)(&array[0x16]) = 1; *(int *)(&array[0x16]) = 1;
free(array); free(array);
@ -102,6 +138,8 @@ EXTERN int malloc_heap_oob_write_0x17_int_at_0x16(const uint8_t *_data,
EXTERN int malloc_heap_oob_write_0x17_int_at_0x15(const uint8_t *_data, EXTERN int malloc_heap_oob_write_0x17_int_at_0x15(const uint8_t *_data,
size_t _size) { size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x17)); char *array = static_cast<char *>(malloc(0x17));
*(int *)(&array[0x15]) = 1; *(int *)(&array[0x15]) = 1;
free(array); free(array);
@ -109,6 +147,8 @@ EXTERN int malloc_heap_oob_write_0x17_int_at_0x15(const uint8_t *_data,
} }
EXTERN int malloc_heap_oob_write_0x17_int_at_0x14(const uint8_t *_data, EXTERN int malloc_heap_oob_write_0x17_int_at_0x14(const uint8_t *_data,
size_t _size) { size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x17)); char *array = static_cast<char *>(malloc(0x17));
*(int *)(&array[0x14]) = 1; *(int *)(&array[0x14]) = 1;
free(array); free(array);
@ -117,6 +157,8 @@ EXTERN int malloc_heap_oob_write_0x17_int_at_0x14(const uint8_t *_data,
EXTERN int malloc_heap_oob_write_0x17_int_at_0x13(const uint8_t *_data, EXTERN int malloc_heap_oob_write_0x17_int_at_0x13(const uint8_t *_data,
size_t _size) { size_t _size) {
(void)_data;
(void)_size;
char *array = static_cast<char *>(malloc(0x17)); char *array = static_cast<char *>(malloc(0x17));
*(int *)(&array[0x13]) = 1; *(int *)(&array[0x13]) = 1;
free(array); free(array);
@ -125,6 +167,8 @@ EXTERN int malloc_heap_oob_write_0x17_int_at_0x13(const uint8_t *_data,
EXTERN int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) { EXTERN int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// abort(); // abort();
(void)data;
(void)size;
return 0; return 0;
} }