void klee_make_symbolic(void *addr, size_t nbytes, const char *name) { /* XXX remove model version code once new tests gen'd */ if (obj_index >= input->numObjects) { if (strcmp("model_version", name) == 0) { assert(nbytes == 4); *((int*) addr) = 0; } else { __emit_error("ran out of appropriate inputs"); } } else { KTestObject *boo = &input->objects[obj_index]; if (strcmp("model_version", name) == 0 && strcmp("model_version", boo->name) != 0) { assert(nbytes == 4); *((int*) addr) = 0; } else { if (boo->numBytes != nbytes) { fprintf(stderr, "make_symbolic mismatch, different sizes: " "%d in input file, %lu in code\n", boo->numBytes, (unsigned long)nbytes); exit(1); } else { memcpy(addr, boo->bytes, nbytes); obj_index++; } } } }
/* Helper function that converts a string to an integer, and terminates the program with an error message is the string is not a proper number */ static long int __str_to_int(char *s, const char *error_msg) { long int res = 0; char c; if (!*s) __emit_error(error_msg); while ((c = *s++)) { if (c == '\0') { break; } else if (c>='0' && c<='9') { res = res*10 + (c - '0'); } else { __emit_error(error_msg); } } return res; }
static void __add_arg(int *argc, char **argv, char *arg, int argcMax) { if (*argc==argcMax) { __emit_error("too many arguments for klee_init_env"); } else { argv[*argc] = arg; (*argc)++; } }
void klee_report_error(const char *file, int line, const char *message, const char *suffix) { __emit_error(message); }
static void __s2e_init_env(int *argcPtr, char ***argvPtr) { int argc = *argcPtr; char** argv = *argvPtr; int new_argc = 0, n_args; char* new_argv[1024]; unsigned max_len, min_argvs, max_argvs; char** final_argv; char sym_arg_name[5] = "arg"; unsigned sym_arg_num = 0; int k=0, i; int concolic_mode = 0; sym_arg_name[4] = '\0'; // Load the process map and get the info about the current process procmap_entry_t* proc_map = load_process_map(); display_process_map(proc_map); register_module(proc_map, argv[0]); register_module(proc_map, "init_env.so"); #ifndef DEBUG_NATIVE s2e_codeselector_select_module("init_env.so"); #endif // Recognize --help when it is the sole argument. if (argc == 2 && __streq(argv[1], "--help")) { __emit_error("s2e_init_env\n\n" "usage: (s2e_init_env) [options] [program arguments]\n" "\n" " -select-process - Enable forking in the current process only\n" " -select-process-userspace - Enable forking in userspace-code of the\n" " current process only\n" " -select-process-code - Enable forking in the code section of the current binary only\n" " -concolic - Augment existing concrete arguments with symbolic values\n" " -sym-arg <N> - Replace by a symbolic argument of length N\n" " -sym-args <MIN> <MAX> <N> - Replace by at least MIN arguments and at most\n" " MAX arguments, each with maximum length N\n\n"); } #ifndef DEBUG_NATIVE s2e_enable_forking(); #endif while (k < argc) { if (__streq(argv[k], "--concolic") || __streq(argv[k], "-concolic")) { concolic_mode = 1; ++k; } else if (__streq(argv[k], "--sym-arg") || __streq(argv[k], "-sym-arg")) { const char *msg = "--sym-arg expects an integer argument <max-len>"; if (++k == argc) __emit_error(msg); max_len = __str_to_int(argv[k++], msg); sym_arg_name[3] = '0' + sym_arg_num++; __add_arg(&new_argc, new_argv, __get_sym_str(max_len, sym_arg_name), 1024); } else if (__streq(argv[k], "--sym-args") || __streq(argv[k], "-sym-args")) { const char *msg = "--sym-args expects three integer arguments <min-argvs> <max-argvs> <max-len>"; if (k+3 >= argc) __emit_error(msg); k++; min_argvs = __str_to_int(argv[k++], msg); max_argvs = __str_to_int(argv[k++], msg); max_len = __str_to_int(argv[k++], msg); n_args = s2e_range(min_argvs, max_argvs+1, "n_args"); for (i=0; i < n_args; i++) { sym_arg_name[3] = '0' + sym_arg_num++; __add_arg(&new_argc, new_argv, __get_sym_str(max_len, sym_arg_name), 1024); } } else if (__streq(argv[k], "--select-process") || __streq(argv[k], "-select-process")) { k++; myprintf("Forks will be restricted to the current address space\n"); s2e_codeselector_enable_address_space(0); } else if (__streq(argv[k], "--select-process-userspace") || __streq(argv[k], "-select-process-userspace")) { k++; myprintf("Forks will be restricted to the user-mode portion of the current address space\n"); s2e_codeselector_enable_address_space(1); } else if (__streq(argv[k], "--select-process-code") || __streq(argv[k], "-select-process-code")) { k++; const char *process_base_name = __base_name(argv[0]); myprintf("Forks will be restricted to %s\n", process_base_name); s2e_codeselector_select_module(process_base_name); } else { /* simply copy arguments */ if (concolic_mode) { sym_arg_name[3] = '0' + k; s2e_make_concolic(argv[k], strlen(argv[k]), sym_arg_name); } __add_arg(&new_argc, new_argv, argv[k++], 1024); } } final_argv = (char**) malloc((new_argc+1) * sizeof(*final_argv)); memcpy(final_argv, new_argv, new_argc * sizeof(*final_argv)); final_argv[new_argc] = 0; *argcPtr = new_argc; *argvPtr = final_argv; }