Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>
This commit is contained in:
WorksButNotTested
2021-04-29 08:06:14 +01:00
committed by GitHub
parent aeb6883532
commit 26b84e3521
17 changed files with 354 additions and 50 deletions

View File

@ -10,16 +10,29 @@ OBJS:=$(foreach src,$(SOURCES),$(OBJ_DIR)$(notdir $(patsubst %.c, %.o, $(src))))
CFLAGS+=-fPIC \
-D_GNU_SOURCE \
-D_FORTIFY_SOURCE=2 \
-Wno-pointer-arith \
-g \
-O3 \
-funroll-loops \
RT_CFLAGS:=-Wno-unused-parameter \
-Wno-sign-compare \
-Wno-unused-function \
-Wno-unused-result \
LDFLAGS+=-shared \
-lpthread \
-lresolv \
-ldl \
ifdef DEBUG
CFLAGS+=-Werror \
-Wall \
-Wextra \
-Wpointer-arith
else
CFLAGS+=-Wno-pointer-arith
endif
FRIDA_BUILD_DIR:=$(BUILD_DIR)frida/
FRIDA_TRACE:=$(BUILD_DIR)afl-frida-trace.so
FRIDA_TRACE_EMBEDDED:=$(BUILD_DIR)afl-frida-trace-embedded
@ -31,7 +44,11 @@ endif
ifeq "$(shell uname)" "Darwin"
OS:=macos
CFLAGS:=$(CFLAGS) -Wno-deprecated-declarations
RT_CFLAGS:=$(RT_CFLAGS) -Wno-deprecated-declarations
else
ifdef DEBUG
RT_CFLAGS:=$(RT_CFLAGS) -Wno-prio-ctor-dtor
endif
endif
ifeq "$(shell uname)" "Linux"
@ -81,17 +98,14 @@ $(GUM_DEVIT_HEADER): | $(GUM_DEVKIT_TARBALL)
$(AFL_COMPILER_RT_OBJ): $(AFL_COMPILER_RT_SRC)
$(CC) \
$(CFLAGS) \
$(RT_CFLAGS) \
-I $(ROOT) \
-I $(ROOT)include \
-Wno-unused-parameter \
-Wno-sign-compare \
-Wno-unused-function \
-Wno-unused-result \
-o $@ \
-c $<
define BUILD_SOURCE =
define BUILD_SOURCE
$(2): $(1) GNUmakefile | $(OBJ_DIR)
$(CC) \
$(CFLAGS) \

View File

@ -36,8 +36,9 @@ void complog_init(void) {
for (guint i = 0; i < complog_ranges->len; i++) {
GumMemoryRange *range = &g_array_index(complog_ranges, GumMemoryRange, i);
OKF("CompLog Range - 0x%016lX - 0x%016lX", range->base_address,
range->base_address + range->size);
OKF("CompLog Range - 0x%016" G_GINT64_MODIFIER
"X - 0x%016" G_GINT64_MODIFIER "X",
range->base_address, range->base_address + range->size);
}

View File

@ -3,10 +3,14 @@
#include "debug.h"
#include "complog.h"
#include "util.h"
#if defined(__arm64__)
#if defined(__arm__)
void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(iterator);
if (__afl_cmp_map == NULL) { return; }
FATAL("Complog mode not supported on this architecture");
}

View File

@ -3,10 +3,14 @@
#include "debug.h"
#include "complog.h"
#include "util.h"
#if defined(__i386__)
#if defined(__aarch64__)
void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(iterator);
if (__afl_cmp_map == NULL) { return; }
FATAL("Complog mode not supported on this architecture");
}

View File

@ -3,10 +3,14 @@
#include "debug.h"
#include "complog.h"
#include "util.h"
#if defined(__arm__)
#if defined(__i386__)
void complog_instrument(const cs_insn *instr, GumStalkerIterator *iterator) {
UNUSED_PARAMETER(instr);
UNUSED_PARAMETER(iterator);
if (__afl_cmp_map == NULL) { return; }
FATAL("Complog mode not supported on this architecture");
}

BIN
frida_mode/src/lib/lib Executable file

Binary file not shown.

View File

@ -1,29 +1,32 @@
#include <elf.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#ifndef __APPLE__
#include <elf.h>
#include <fcntl.h>
#include <limits.h>
#include <stdio.h>
#include <sys/mman.h>
#include <unistd.h>
#include "frida-gum.h"
#include "frida-gum.h"
#include "debug.h"
#include "debug.h"
#include "lib.h"
#include "lib.h"
#if defined(__arm__) || defined(__i386__)
#define ELFCLASS ELFCLASS32
#if defined(__arm__) || defined(__i386__)
#define ELFCLASS ELFCLASS32
typedef Elf32_Ehdr Elf_Ehdr;
typedef Elf32_Phdr Elf_Phdr;
typedef Elf32_Shdr Elf_Shdr;
#elif defined(__aarch64__) || defined(__x86_64__)
#define ELFCLASS ELFCLASS64
typedef Elf32_Addr Elf_Addr;
#elif defined(__aarch64__) || defined(__x86_64__)
#define ELFCLASS ELFCLASS64
typedef Elf64_Ehdr Elf_Ehdr;
typedef Elf64_Phdr Elf_Phdr;
typedef Elf64_Shdr Elf_Shdr;
#else
#error "Unsupported platform"
#endif
typedef Elf64_Addr Elf_Addr;
#else
#error "Unsupported platform"
#endif
typedef struct {
@ -50,13 +53,6 @@ static gboolean lib_find_exe(const GumModuleDetails *details,
}
static gboolean lib_is_little_endian(void) {
int probe = 1;
return *(char *)&probe;
}
static void lib_validate_hdr(Elf_Ehdr *hdr) {
if (hdr->e_ident[0] != ELFMAG0) FATAL("Invalid e_ident[0]");
@ -64,22 +60,14 @@ static void lib_validate_hdr(Elf_Ehdr *hdr) {
if (hdr->e_ident[2] != ELFMAG2) FATAL("Invalid e_ident[2]");
if (hdr->e_ident[3] != ELFMAG3) FATAL("Invalid e_ident[3]");
if (hdr->e_ident[4] != ELFCLASS) FATAL("Invalid class");
/*
if (hdr->e_ident[5] != (lib_is_little_endian() ? ELFDATA2LSB : ELFDATA2MSB))
FATAL("Invalid endian");
if (hdr->e_ident[6] != EV_CURRENT) FATAL("Invalid version");
if (hdr->e_type != ET_DYN) FATAL("Invalid type");
if (hdr->e_version != EV_CURRENT) FATAL("Invalid e_version");
if (hdr->e_phoff != sizeof(Elf_Ehdr)) FATAL("Invalid e_phoff");
if (hdr->e_ehsize != sizeof(Elf_Ehdr)) FATAL("Invalid e_ehsize");
if (hdr->e_phentsize != sizeof(Elf_Phdr)) FATAL("Invalid e_phentsize");
if (hdr->e_shentsize != sizeof(Elf_Shdr)) FATAL("Invalid e_shentsize");
*/
}
static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
Elf_Phdr *phdr;
gboolean found_preferred_base = FALSE;
Elf_Addr preferred_base;
Elf_Shdr *shdr;
Elf_Shdr *shstrtab;
char * shstr;
@ -87,6 +75,23 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
Elf_Shdr *curr;
char text_name[] = ".text";
phdr = (Elf_Phdr *)((char *)hdr + hdr->e_phoff);
for (size_t i = 0; i < hdr->e_phnum; i++) {
if (phdr[i].p_type == PT_LOAD) {
preferred_base = phdr[i].p_vaddr;
found_preferred_base = TRUE;
break;
}
}
if (!found_preferred_base) { FATAL("Failed to find preferred load address"); }
OKF("Image preferred load address 0x%016lx", preferred_base);
shdr = (Elf_Shdr *)((char *)hdr + hdr->e_shoff);
shstrtab = &shdr[hdr->e_shstrndx];
shstr = (char *)hdr + shstrtab->sh_offset;
@ -107,8 +112,8 @@ static void lib_read_text_section(lib_details_t *lib_details, Elf_Ehdr *hdr) {
if (memcmp(section_name, text_name, sizeof(text_name)) == 0 &&
text_base == 0) {
text_base = lib_details->base_address + curr->sh_addr;
text_limit = lib_details->base_address + curr->sh_addr + curr->sh_size;
text_base = lib_details->base_address + curr->sh_addr - preferred_base;
text_limit = text_base + curr->sh_size;
OKF("> text_addr: 0x%016lX", text_base);
OKF("> text_limit: 0x%016lX", text_limit);
@ -167,3 +172,5 @@ guint64 lib_get_text_limit(void) {
}
#endif

View File

@ -0,0 +1,82 @@
#ifdef __APPLE__
#include "frida-gum.h"
#include "debug.h"
#include "lib.h"
#include "util.h"
extern mach_port_t mach_task_self();
extern void gum_darwin_enumerate_modules(mach_port_t task,
GumFoundModuleFunc func,
gpointer user_data);
static guint64 text_base = 0;
static guint64 text_limit = 0;
static gboolean lib_get_main_module(const GumModuleDetails *details,
gpointer user_data) {
GumDarwinModule **ret = (GumDarwinModule **)user_data;
GumDarwinModule * module = gum_darwin_module_new_from_memory(
details->path, mach_task_self(), details->range->base_address,
GUM_DARWIN_MODULE_FLAGS_NONE, NULL);
OKF("Found main module: %s", module->name);
*ret = module;
return FALSE;
}
gboolean lib_get_text_section(const GumDarwinSectionDetails *details,
gpointer user_data) {
UNUSED_PARAMETER(user_data);
static size_t idx = 0;
char text_name[] = "__text";
OKF("Section: %2lu - base: 0x%016" G_GINT64_MODIFIER
"X size: 0x%016" G_GINT64_MODIFIER "X %s",
idx++, details->vm_address, details->vm_address + details->size,
details->section_name);
if (memcmp(details->section_name, text_name, sizeof(text_name)) == 0 &&
text_base == 0) {
text_base = details->vm_address;
text_limit = details->vm_address + details->size;
OKF("> text_addr: 0x%016" G_GINT64_MODIFIER "X", text_base);
OKF("> text_limit: 0x%016" G_GINT64_MODIFIER "X", text_limit);
}
return TRUE;
}
void lib_init(void) {
GumDarwinModule *module = NULL;
gum_darwin_enumerate_modules(mach_task_self(), lib_get_main_module, &module);
gum_darwin_module_enumerate_sections(module, lib_get_text_section, NULL);
}
guint64 lib_get_text_base(void) {
if (text_base == 0) FATAL("Lib not initialized");
return text_base;
}
guint64 lib_get_text_limit(void) {
if (text_limit == 0) FATAL("Lib not initialized");
return text_limit;
}
#endif

View File

@ -49,6 +49,10 @@ static int on_fork(void) {
#ifdef __APPLE__
static void on_main_os(int argc, char **argv, char **envp) {
UNUSED_PARAMETER(argc);
UNUSED_PARAMETER(argv);
UNUSED_PARAMETER(envp);
}
#else

View File

@ -33,9 +33,9 @@ void persistent_init(void) {
if (persistent_start != 0 && !persistent_is_supported())
FATAL("Persistent mode not supported on this architecture");
OKF("Instrumentation - persistent mode [%c] (0x%016lX)",
OKF("Instrumentation - persistent mode [%c] (0x%016" G_GINT64_MODIFIER "X)",
persistent_start == 0 ? ' ' : 'X', persistent_start);
OKF("Instrumentation - persistent count [%c] (%ld)",
OKF("Instrumentation - persistent count [%c] (%" G_GINT64_MODIFIER "d)",
persistent_start == 0 ? ' ' : 'X', persistent_count);
OKF("Instrumentation - hook [%s]", hook_name);

View File

@ -3,6 +3,7 @@
#include "debug.h"
#include "persistent.h"
#include "util.h"
#if defined(__arm__)
@ -62,6 +63,7 @@ gboolean persistent_is_supported(void) {
void persistent_prologue(GumStalkerOutput *output) {
UNUSED_PARAMETER(output);
FATAL("Persistent mode not supported on this architecture");
}

View File

@ -4,6 +4,7 @@
#include "debug.h"
#include "instrument.h"
#include "util.h"
#if defined(__aarch64__)
@ -105,6 +106,7 @@ gboolean persistent_is_supported(void) {
void persistent_prologue(GumStalkerOutput *output) {
UNUSED_PARAMETER(output);
FATAL("Persistent mode not supported on this architecture");
}

View File

@ -3,6 +3,7 @@
#include "debug.h"
#include "persistent.h"
#include "util.h"
#if defined(__i386__)
@ -45,6 +46,7 @@ gboolean persistent_is_supported(void) {
void persistent_prologue(GumStalkerOutput *output) {
UNUSED_PARAMETER(output);
FATAL("Persistent mode not supported on this architecture");
}

View File

@ -0,0 +1,50 @@
PWD:=$(shell pwd)/
ROOT:=$(shell realpath $(PWD)../../..)/
BUILD_DIR:=$(PWD)build/
TESTINSTR_DATA_DIR:=$(BUILD_DIR)in/
TESTINSTR_DATA_FILE:=$(TESTINSTR_DATA_DIR)in
TESTINSTBIN:=$(BUILD_DIR)testinstr
TESTINSTSRC:=$(PWD)testinstr.c
QEMU_OUT:=$(BUILD_DIR)qemu-out
FRIDA_OUT:=$(BUILD_DIR)frida-out
.PHONY: all clean qemu frida
all: $(TESTINSTBIN)
make -C $(ROOT)frida_mode/
$(BUILD_DIR):
mkdir -p $@
$(TESTINSTR_DATA_DIR): | $(BUILD_DIR)
mkdir -p $@
$(TESTINSTR_DATA_FILE): | $(TESTINSTR_DATA_DIR)
echo -n "000" > $@
$(TESTINSTBIN): $(TESTINSTSRC) | $(BUILD_DIR)
$(CC) -o $@ $< -no-pie
clean:
rm -rf $(BUILD_DIR)
qemu: $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
$(ROOT)afl-fuzz \
-D \
-Q \
-i $(TESTINSTR_DATA_DIR) \
-o $(QEMU_OUT) \
-- \
$(TESTINSTBIN) @@
frida: $(FRIDA_TRACE) $(TESTINSTBIN) $(TESTINSTR_DATA_FILE)
$(ROOT)afl-fuzz \
-D \
-O \
-i $(TESTINSTR_DATA_DIR) \
-o $(FRIDA_OUT) \
-- \
$(TESTINSTBIN) @@

View File

@ -0,0 +1,12 @@
all:
@echo trying to use GNU make...
@gmake all || echo please install GNUmake
clean:
@gmake clean
qemu:
@gmake qemu
frida:
@gmake frida

View File

@ -0,0 +1,112 @@
/*
american fuzzy lop++ - a trivial program to test the build
--------------------------------------------------------
Originally written by Michal Zalewski
Copyright 2014 Google Inc. All rights reserved.
Copyright 2019-2020 AFLplusplus Project. All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at:
http://www.apache.org/licenses/LICENSE-2.0
*/
#include <fcntl.h>
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#ifdef __APPLE__
#define TESTINSTR_SECTION
#else
#define TESTINSTR_SECTION __attribute__((section(".testinstr")))
#endif
void testinstr(char *buf, int len) {
if (len < 1) return;
buf[len] = 0;
// we support three input cases
if (buf[0] == '0')
printf("Looks like a zero to me!\n");
else if (buf[0] == '1')
printf("Pretty sure that is a one!\n");
else
printf("Neither one or zero? How quaint!\n");
}
TESTINSTR_SECTION int main(int argc, char **argv) {
char * file;
int fd = -1;
off_t len;
char * buf = NULL;
size_t n_read;
int result = -1;
if (argc != 2) { return 1; }
do {
file = argv[1];
dprintf(STDERR_FILENO, "Running: %s\n", file);
fd = open(file, O_RDONLY);
if (fd < 0) {
perror("open");
break;
}
len = lseek(fd, 0, SEEK_END);
if (len < 0) {
perror("lseek (SEEK_END)");
break;
}
if (lseek(fd, 0, SEEK_SET) != 0) {
perror("lseek (SEEK_SET)");
break;
}
buf = malloc(len);
if (buf == NULL) {
perror("malloc");
break;
}
n_read = read(fd, buf, len);
if (n_read != len) {
perror("read");
break;
}
dprintf(STDERR_FILENO, "Running: %s: (%zd bytes)\n", file, n_read);
testinstr(buf, len);
dprintf(STDERR_FILENO, "Done: %s: (%zd bytes)\n", file, n_read);
result = 0;
} while (false);
if (buf != NULL) { free(buf); }
if (fd != -1) { close(fd); }
return result;
}

View File

@ -21,6 +21,9 @@ PNGTEST_OBJ:=$(PNGTEST_BUILD_DIR)target.o
PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libpng-1.2.56/target.cc"
TEST_BIN:=$(BUILD_DIR)test
ifeq "$(shell uname)" "Darwin"
TEST_BIN_LDFLAGS:=-undefined dynamic_lookup
endif
TEST_DATA_DIR:=$(LIBPNG_DIR)contrib/pngsuite/
@ -80,6 +83,7 @@ $(TEST_BIN): $(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB)
-o $@ \
$(HARNESS_OBJ) $(PNGTEST_OBJ) $(LIBPNG_LIB) \
-lz \
$(TEST_BIN_LDFLAGS) \
clean:
rm -rf $(BUILD_DIR)