mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-24 06:42:42 +00:00
375 lines
7.6 KiB
C
375 lines
7.6 KiB
C
#include <errno.h>
|
|
#include <fcntl.h>
|
|
#include <unistd.h>
|
|
#include <sys/types.h>
|
|
|
|
#ifdef __APPLE__
|
|
#include <mach/mach.h>
|
|
#include <mach-o/dyld_images.h>
|
|
#include <crt_externs.h>
|
|
#else
|
|
#include <sys/wait.h>
|
|
#include <sys/personality.h>
|
|
#endif
|
|
|
|
#include "frida-gumjs.h"
|
|
|
|
#include "config.h"
|
|
|
|
#include "entry.h"
|
|
#include "instrument.h"
|
|
#include "intercept.h"
|
|
#include "js.h"
|
|
#include "lib.h"
|
|
#include "module.h"
|
|
#include "output.h"
|
|
#include "persistent.h"
|
|
#include "prefetch.h"
|
|
#include "ranges.h"
|
|
#include "seccomp.h"
|
|
#include "stalker.h"
|
|
#include "stats.h"
|
|
#include "util.h"
|
|
|
|
#define PROC_MAX 65536
|
|
|
|
#ifdef __APPLE__
|
|
extern mach_port_t mach_task_self();
|
|
extern GumAddress gum_darwin_find_entrypoint(mach_port_t task);
|
|
#elif defined(__ANDROID__)
|
|
typedef struct {
|
|
|
|
void (**preinit_array)(void);
|
|
void (**init_array)(void);
|
|
void (**fini_array)(void);
|
|
|
|
} structors_array_t;
|
|
|
|
extern void __libc_init(void *raw_args, void (*onexit)(void) __unused,
|
|
int (*slingshot)(int, char **, char **),
|
|
structors_array_t const *const structors);
|
|
#else
|
|
extern int __libc_start_main(int (*main)(int, char **, char **), int argc,
|
|
char **ubp_av, void (*init)(void),
|
|
void (*fini)(void), void (*rtld_fini)(void),
|
|
void(*stack_end));
|
|
#endif
|
|
|
|
typedef int (*main_fn_t)(int argc, char **argv, char **envp);
|
|
|
|
static main_fn_t main_fn = NULL;
|
|
|
|
#ifdef __APPLE__
|
|
static void on_main_os(int argc, char **argv, char **envp) {
|
|
|
|
UNUSED_PARAMETER(argc);
|
|
UNUSED_PARAMETER(argv);
|
|
UNUSED_PARAMETER(envp);
|
|
|
|
}
|
|
|
|
#else
|
|
static void on_main_os(int argc, char **argv, char **envp) {
|
|
|
|
UNUSED_PARAMETER(argc);
|
|
/* Personality doesn't affect the current process, it only takes effect on
|
|
* evec */
|
|
int persona = personality(ADDR_NO_RANDOMIZE);
|
|
if (persona == -1) { FWARNF("Failed to set ADDR_NO_RANDOMIZE: %d", errno); }
|
|
if ((persona & ADDR_NO_RANDOMIZE) == 0) { execvpe(argv[0], argv, envp); }
|
|
|
|
GumInterceptor *interceptor = gum_interceptor_obtain();
|
|
|
|
gum_interceptor_begin_transaction(interceptor);
|
|
#if defined(__ANDROID__)
|
|
gum_interceptor_revert(interceptor, __libc_init);
|
|
#else
|
|
gum_interceptor_revert(interceptor, __libc_start_main);
|
|
#endif
|
|
gum_interceptor_end_transaction(interceptor);
|
|
gum_interceptor_flush(interceptor);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
static void embedded_init(void) {
|
|
|
|
static gboolean initialized = false;
|
|
if (!initialized) {
|
|
|
|
gum_init_embedded();
|
|
initialized = true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
static void afl_print_cmdline(void) {
|
|
|
|
#if defined(__linux__)
|
|
char *buffer = g_malloc0(PROC_MAX);
|
|
gchar *fname = g_strdup_printf("/proc/%d/cmdline", getppid());
|
|
int fd = open(fname, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
|
|
|
FWARNF("Failed to open /proc/self/cmdline, errno: (%d)", errno);
|
|
return;
|
|
|
|
}
|
|
|
|
ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
|
|
if (bytes_read < 0) {
|
|
|
|
FFATAL("Failed to read /proc/self/cmdline, errno: (%d)", errno);
|
|
|
|
}
|
|
|
|
int idx = 0;
|
|
|
|
FVERBOSE("Command Line");
|
|
|
|
for (ssize_t i = 0; i < bytes_read; i++) {
|
|
|
|
if (i == 0 || buffer[i - 1] == '\0') {
|
|
|
|
FVERBOSE("\targv[%d] = %s", idx++, &buffer[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
g_free(fname);
|
|
g_free(buffer);
|
|
#elif defined(__APPLE__)
|
|
int idx;
|
|
char **argv = *_NSGetArgv();
|
|
int nargv = *_NSGetArgc();
|
|
|
|
for (idx = 0; idx < nargv; idx++) {
|
|
|
|
FVERBOSE("\targv[%d] = %s", idx, argv[idx]);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
static void afl_print_env(void) {
|
|
|
|
char *buffer = g_malloc0(PROC_MAX);
|
|
gchar *fname = g_strdup_printf("/proc/%d/environ", getppid());
|
|
int fd = open(fname, O_RDONLY);
|
|
|
|
if (fd < 0) {
|
|
|
|
FWARNF("Failed to open /proc/self/environ, errno: (%d)", errno);
|
|
return;
|
|
|
|
}
|
|
|
|
ssize_t bytes_read = read(fd, buffer, PROC_MAX - 1);
|
|
if (bytes_read < 0) {
|
|
|
|
FFATAL("Failed to read /proc/self/environ, errno: (%d)", errno);
|
|
|
|
}
|
|
|
|
int idx = 0;
|
|
|
|
FVERBOSE("ENVIRONMENT");
|
|
for (ssize_t i = 0; i < bytes_read; i++) {
|
|
|
|
if (i == 0 || buffer[i - 1] == '\0') {
|
|
|
|
FVERBOSE("\t%3d: %s", idx++, &buffer[i]);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
close(fd);
|
|
g_free(fname);
|
|
g_free(buffer);
|
|
|
|
}
|
|
|
|
void afl_frida_config(void) {
|
|
|
|
FOKF(cRED "**********************");
|
|
FOKF(cRED "* " cYEL "******************" cRED " *");
|
|
FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
|
|
FOKF(cRED "* " cYEL "* " cGRN "* FRIDA MODE *" cYEL " *" cRED " *");
|
|
FOKF(cRED "* " cYEL "* " cGRN "**************" cYEL " *" cRED " *");
|
|
FOKF(cRED "* " cYEL "******************" cRED " *");
|
|
FOKF(cRED "**********************");
|
|
afl_print_cmdline();
|
|
afl_print_env();
|
|
|
|
/* Configure */
|
|
entry_config();
|
|
instrument_config();
|
|
js_config();
|
|
lib_config();
|
|
module_config();
|
|
output_config();
|
|
persistent_config();
|
|
prefetch_config();
|
|
ranges_config();
|
|
seccomp_config();
|
|
stalker_config();
|
|
stats_config();
|
|
|
|
js_start();
|
|
|
|
output_init();
|
|
embedded_init();
|
|
entry_init();
|
|
instrument_init();
|
|
lib_init();
|
|
module_init();
|
|
persistent_init();
|
|
prefetch_init();
|
|
seccomp_init();
|
|
stalker_init();
|
|
ranges_init();
|
|
stats_init();
|
|
|
|
}
|
|
|
|
void afl_frida_run(void) {
|
|
|
|
stalker_start();
|
|
entry_start();
|
|
|
|
}
|
|
|
|
__attribute__((visibility("default"))) void afl_frida_start(void) {
|
|
|
|
afl_frida_config();
|
|
afl_frida_run();
|
|
|
|
}
|
|
|
|
typedef void *(*entry_func_t)(size_t a1, size_t a2, size_t a3, size_t a4,
|
|
size_t a5, size_t a6);
|
|
|
|
static void *on_entry(size_t a1, size_t a2, size_t a3, size_t a4, size_t a5,
|
|
size_t a6) {
|
|
|
|
intercept_unhook(GSIZE_TO_POINTER(entry_point));
|
|
afl_frida_run();
|
|
entry_func_t entry = (entry_func_t)entry_point;
|
|
return entry(a1, a2, a3, a4, a5, a6);
|
|
|
|
}
|
|
|
|
static int on_main(int argc, char **argv, char **envp) {
|
|
|
|
int ret;
|
|
|
|
on_main_os(argc, argv, envp);
|
|
|
|
intercept_unhook_self();
|
|
|
|
afl_frida_config();
|
|
|
|
if (entry_point == 0) {
|
|
|
|
afl_frida_run();
|
|
|
|
} else {
|
|
|
|
intercept_hook(GSIZE_TO_POINTER(entry_point), on_entry, NULL);
|
|
|
|
}
|
|
|
|
if (js_main_hook != NULL) {
|
|
|
|
ret = js_main_hook(argc, argv, envp);
|
|
|
|
} else {
|
|
|
|
ret = main_fn(argc, argv, envp);
|
|
|
|
}
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
#if defined(EMBEDDED)
|
|
extern int main(int argc, char **argv, char **envp);
|
|
|
|
static void intercept_main(void) {
|
|
|
|
main_fn = main;
|
|
intercept_hook(main, on_main, NULL);
|
|
|
|
}
|
|
|
|
#elif defined(__APPLE__)
|
|
static void intercept_main(void) {
|
|
|
|
mach_port_t task = mach_task_self();
|
|
FVERBOSE("Task Id: %u", task);
|
|
GumAddress entry = gum_darwin_find_entrypoint(task);
|
|
FVERBOSE("Entry Point: 0x%016" G_GINT64_MODIFIER "x", entry);
|
|
void *main = GSIZE_TO_POINTER(entry);
|
|
main_fn = main;
|
|
intercept_hook(main, on_main, NULL);
|
|
|
|
}
|
|
|
|
#elif defined(__ANDROID__)
|
|
static void on_libc_init(void *raw_args, void (*onexit)(void) __unused,
|
|
int (*slingshot)(int, char **, char **),
|
|
structors_array_t const *const structors) {
|
|
|
|
main_fn = slingshot;
|
|
intercept_unhook_self();
|
|
intercept_hook(slingshot, on_main, NULL);
|
|
return __libc_init(raw_args, onexit, slingshot, structors);
|
|
|
|
}
|
|
|
|
static void intercept_main(void) {
|
|
|
|
intercept_hook(__libc_init, on_libc_init, NULL);
|
|
|
|
}
|
|
|
|
#else
|
|
static int on_libc_start_main(int (*main)(int, char **, char **), int argc,
|
|
char **ubp_av, void (*init)(void),
|
|
void (*fini)(void), void (*rtld_fini)(void),
|
|
void(*stack_end)) {
|
|
|
|
main_fn = main;
|
|
intercept_unhook_self();
|
|
intercept_hook(main, on_main, NULL);
|
|
return __libc_start_main(main, argc, ubp_av, init, fini, rtld_fini,
|
|
stack_end);
|
|
|
|
}
|
|
|
|
static void intercept_main(void) {
|
|
|
|
intercept_hook(__libc_start_main, on_libc_start_main, NULL);
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
__attribute__((constructor)) static void init(void) {
|
|
|
|
embedded_init();
|
|
|
|
intercept_main();
|
|
|
|
}
|
|
|