25 #include <sys/ptrace.h>
64 struct probe *trigger,
struct probe *base) {
76 "RESULT:: (i:%d) cfi (2) CFIViolation \"CFI violation!\""
78 " depth=%d,violations=%d,stack=%s) ::RESULT\n",
112 while (g_hash_table_iter_next(&iter,&key,(gpointer *)&cts)) {
116 "RESULT:: (f:%d) cfi (2) CFIViolation \"CFI violation!\""
118 " depth=%d,violations=%d,stack=%s) ::RESULT\n",
119 ++i,(
int)(uintptr_t)key,
128 "RESULT:: (f:%d) cfi (3) CFIStackRemainingViolation \"CFI violation -- inferred due to remaining shadow stack items!\""
129 " (tid=%d,depth=%d,violations=%d,stack=%s) ::RESULT\n",
130 ++i,(
int)(uintptr_t)key,
137 "RESULT:: (f:%d) cfi (0) CFIClean \"CFI clean!\""
138 " (tid=%d,violations=%d) ::RESULT\n",
157 {
"overlay",
'V',
"<name_or_id>:<spec_opts>",0,
"Lookup name or id as an overlay target once the main target is instantiated, and try to open it. All spec_opts (normal target/dwdebug opts) then apply to the overlay target.",0 },
158 {
"mode",
'M',
"dynamic|static",0,
"Set the CFI mode (only dynamic now).",-3 },
159 {
"no-autofollow",
'N',NULL,0,
160 "Do not add functions to the CFI checked set.",-3 },
161 {
"no-singlestep-unknown",
'S',NULL,0,
162 "Don't singlestep unknown areas in the target.",-3 },
163 {
"fix-stack",
'f',NULL,0,
164 "Fix the stack before a RET that would violate CFI.",-3 },
181 return ARGP_ERR_UNKNOWN;
184 if (state->quoted > 0)
185 opts->
argc = state->quoted - state->next;
187 opts->
argc = state->argc - state->next;
188 if (opts->
argc > 0) {
190 memcpy(opts->
argv,&state->argv[state->next],opts->
argc*
sizeof(
char *));
191 state->next += opts->
argc;
198 case ARGP_KEY_NO_ARGS:
199 case ARGP_KEY_SUCCESS:
211 argptr = index(arg,
':');
213 verror(
"bad overlay spec!\n");
216 argv_list = array_list_create(32);
217 array_list_append(argv_list,
"dumptarget_overlay");
223 while (*argptr ==
' ')
231 while (*argptr !=
'\0') {
232 if (*argptr ==
'\\') {
251 else if (inquote && *argptr == quotechar) {
258 else if (*argptr ==
'\'' || *argptr ==
'"') {
264 else if (!inquote && *argptr ==
' ') {
265 *nargptr = *argptr =
'\0';
267 array_list_append(argv_list,vargptr);
288 array_list_append(argv_list,vargptr);
291 array_list_append(argv_list,NULL);
294 array_list_len(argv_list) - 1,
295 (
char **)argv_list->
list,
298 verror(
"could not parse overlay spec!\n");
299 array_list_free(argv_list);
303 array_list_free(argv_list);
307 return ARGP_ERR_UNKNOWN;
317 int main(
int argc,
char **argv) {
325 struct target *rtarget;
345 verror(
"could not parse target arguments!\n");
351 verror(
"could not instantiate target!\n");
357 fprintf(stderr,
"could not open %s!\n",targetstr);
374 verror(
"could not find overlay thread '%s', exiting!\n",
382 verror(
"could not instantiate overlay target '%s'!\n",
390 fprintf(stderr,
"could not open overlay target!\n");
402 root_function_list = array_list_create(
opts.
argc);
403 root_addr_list = array_list_create(
opts.
argc);
410 fprintf(stderr,
"Could not convert %s to address!\n",
423 array_list_append(root_function_list,
function);
425 array_list_append(root_addr_list,(
void *)(uintptr_t)addr);
429 root_function_list = array_list_create(1);
430 root_addr_list = array_list_create(0);
435 vwarn(
"could not lookup symbol main; trying __libc_start_main!\n");
439 verror(
"could not lookup symbol __libc_start_main;"
446 array_list_append(root_function_list,
function);
449 array_list_append(root_function_list,
function);
454 root_function_list,root_addr_list,
457 verror(
"could not instantiate the CFI meta-probe; aborting!\n");
469 fprintf(stdout,
"Starting CFI monitoring!\n");
481 verror(
"could not resume target\n");
491 fprintf(stdout,
"target %s exiting, printing final results...\n",
496 fprintf(stdout,
"target %s exiting, removing probes safely...\n",
504 verror(
"could not resume target!\n");
514 fprintf(stdout,
"target %s exited, printing final results...\n",
523 fprintf(stdout,
"target %s exited, cleaning up.\n",targetstr);
535 " -- bad status (%d), printing final results...\n",
547 " -- bad status (%d), exiting\n",
struct target * target_instantiate_overlay(struct target *target, tid_t tid, struct target_spec *spec)
tid_t target_lookup_overlay_thread_by_name(struct target *target, char *name)
struct probe * probe_cfi(struct target *target, tid_t tid, cfi_mode_t mode, cfi_flags_t flags, struct array_list *root_functions, struct array_list *root_addrs, probe_handler_t pre_handler, probe_handler_t post_handler, void *handler_data)
void * target_argp_driver_state(struct argp_state *state)
GHashTable * thread_status
tid_t target_lookup_overlay_thread_by_id(struct target *target, int id)
struct target_spec * tspec
static uint64_t unsigned int i
struct bsymbol * target_lookup_sym(struct target *target, const char *name, const char *delim, char *srcfile, symbol_type_flag_t ftype)
int target_resume(struct target *target)
struct cc_argp_state opts
int target_pause(struct target *target)
result_t cfi_handler(struct probe *probe, tid_t tid, void *data, struct probe *trigger, struct probe *base)
void cleanup_probes(void)
char * cfi_thread_backtrace(struct cfi_data *cfi, struct cfi_thread_status *cts, char *sep)
char * overlay_name_or_id
struct argp_option cc_argp_opts[]
#define verror(format,...)
int target_install_default_sighandlers(void(*sighandler)(int signo, siginfo_t *siginfo, void *x))
#define vwarn(format,...)
struct array_list * shadow_stack
int target_snprintf(struct target *target, char *buf, int bufsiz)
void target_default_cleanup()
int probe_free(struct probe *probe, int force)
void * probe_summarize_tid(struct probe *probe, tid_t tid)
void * probe_priv(struct probe *probe)
REGVAL target_read_creg(struct target *target, tid_t tid, common_reg_t reg)
void * calloc(size_t nmemb, size_t size)
void cfi_check_print_final_results(struct probe *probe)
struct target_spec * overlay_spec
int target_open(struct target *target)
target_status_t target_monitor(struct target *target)
void sigh_cleanup_probes(int signo, siginfo_t *siginfo, void *x)
error_t cc_argp_parse_opt(int key, char *arg, struct argp_state *state)
struct target_spec * target_argp_driver_parse_one(struct argp *driver_parser, void *driver_state, int argc, char **argv, target_type_t target_types, int filter_quoted)
struct target * target_instantiate(struct target_spec *spec, struct evloop *evloop)
int main(int argc, char **argv)
void target_driver_argp_init_children(struct argp_state *state)