Files
2023-12-21 23:48:43 +08:00

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();
}