int main(int argc, char *argv[], char *envp[]) { RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); InsnStats insn_stats; SyscallStats call_stats; sim.install_callback(&insn_stats); sim.install_callback(&call_stats); sim.install_callback(new RSIM_Tools::UnhandledInstruction); sim.exec(argc-n, argv+n); sim.activate(); sim.main_loop(); sim.deactivate(); #if 0 std::cerr <<"Number of instructions executed: " <<insn_stats.total_insns() <<" (" <<insn_stats.unique_insns() <<" unique)\n"; std::cerr <<"Number of system calls: " <<call_stats.total_calls() <<" (" <<call_stats.unique_calls() <<" unique)\n"; #else std::cerr <<insn_stats <<call_stats; #endif return 0; }
// Main program is almost standard RSIM boilerplate. The only thing we add is the instantiation and installation of the // SymbolicBombDetector callback. int main(int argc, char *argv[], char *envp[]) { RSIM_Linux32 sim; sim.install_callback(new RSIM_Tools::UnhandledInstruction); int n = sim.configure(argc, argv, envp); sim.exec(argc-n, argv+n); sim.install_callback(new RSIM_Tools::UnhandledInstruction); // needed for some versions of ld-linux.so sim.install_callback(new SymbolicAnalysis(sim.get_process()->get_ep_start_va()), RSIM_Callbacks::BEFORE, true); sim.main_loop(); sim.describe_termination(stderr); sim.terminate_self(); return 0; }
int main(int argc, char *argv[], char *envp[]) { std::ios::sync_with_stdio(); // Our instruction callback. We can't set its trigger address until after we load the specimen, but we want to register // the callback with the simulator before we create the first thread. Trigger clone_detection_trigger; // All of this is standard boilerplate and documented in the first page of the simulator doxygen. RSIM_Linux32 sim; sim.install_callback(new RSIM_Tools::UnhandledInstruction); // needed by some versions of ld-linux.so sim.install_callback(&clone_detection_trigger); // it mustn't be destroyed while the simulator's running int n = sim.configure(argc, argv, envp); sim.exec(argc-n, argv+n); // Now that we've loaded the specimen into memory and created its first thread, figure out its original entry point (OEP) // and arm the clone_detection_trigger so that it triggers clone detection when the OEP is reached. This will allow the // specimen's dynamic linker to run. rose_addr_t trigger_va = sim.get_process()->get_ep_orig_va(); clone_detection_trigger.arm(trigger_va); // Allow the specimen to run until it reaches the clone detection trigger point, at which time a CloneDetector object is // thrown for that thread that reaches it first. try { sim.main_loop(); } catch (CloneDetector *clone_detector) { clone_detector->analyze(); } return 0; }
int main(int argc, char *argv[], char *envp[]) { std::ios::sync_with_stdio(); // Parse command-line switches understood by MultiWithConversion and leave the rest for the simulator. rose_addr_t target_va = 0; // analysis address (i.e., the "arbitrary offset"). Zero implies the program's OEP for (int i=1; i<argc; ++i) { if (!strcmp(argv[i], "--help") || !strcmp(argv[i], "-h") || !strcmp(argv[i], "-?")) { std::cout <<"usage: " <<argv[0] <<" [--target=ADDRESS] [SIMULATOR_SWITCHES] SPECIMEN [SPECIMEN_ARGS...]\n"; exit(0); } else if (!strncmp(argv[i], "--target=", 9)) { target_va = strtoull(argv[i]+9, NULL, 0); memmove(argv+i, argv+i+1, (argc-- -i)*sizeof(*argv)); // argv has argc+1 elements --i; } else { break; } } // Our instruction callback. We can't set its trigger address until after we load the specimen, but we want to register // the callback with the simulator before we create the first thread. SemanticController semantic_controller; // All of this (except the part where we register our SemanticController) is standard boilerplate and documented in // the first page of doxygen. RSIM_Linux32 sim; sim.install_callback(new RSIM_Tools::UnhandledInstruction); // needed by some versions of ld-linux.so sim.install_callback(&semantic_controller); // it mustn't be destroyed while the simulator's running int n = sim.configure(argc, argv, envp); sim.exec(argc-n, argv+n); // Register our instruction callback and tell it to trigger at the specimen's original entry point (OEP). This will cause // our analysis to run as soon as the dynamic linker is finished. We don't know the OEP until after the sim.exec() call // that loads the specimen into memory, so by time we can register our callback, the RSIM_Process has copied rose_addr_t trigger_va = sim.get_process()->get_ep_orig_va(); semantic_controller.arm(trigger_va, 0==target_va ? trigger_va : target_va); //sim.activate(); sim.main_loop(); //sim.deactivate(); sim.describe_termination(stderr); sim.terminate_self(); // probably doesn't return return 0; }
int main(int argc, char *argv[], char *envp[]) { /* Configure the simulator by parsing command-line switches. The return value is the index of the executable name in argv. */ RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); /* Parse the ELF container so we can get to the symbol table. */ char *rose_argv[4]; int rose_argc=0; rose_argv[rose_argc++] = argv[0]; rose_argv[rose_argc++] = strdup("-rose:read_executable_file_format_only"); rose_argv[rose_argc++] = argv[n]; rose_argv[rose_argc] = NULL; SgProject *project = frontend(rose_argc, rose_argv); /* Find the address of "main" and "payload" functions. */ rose_addr_t main_addr = RSIM_Tools::FunctionFinder().address(project, "main"); assert(main_addr!=0); rose_addr_t payload_addr = RSIM_Tools::FunctionFinder().address(project, "payload"); assert(payload_addr!=0); /* Register the analysis callback. */ Analysis analysis(main_addr, payload_addr); sim.install_callback(&analysis); /* Create the initial process object by loading a program and initializing the stack. This also creates the main thread, * but does not start executing it. */ sim.exec(argc-n, argv+n); /* Get ready to execute by making the specified simulator active. This sets up signal handlers, etc. We probably don't * really need it for this demo since the specimen doesn't do anything with signals. In fact, if we're using the Yices * executable (rather than its library), ROSE will generate spurious SIGCHLD which the simulator will forward to the * specimen. Of course, in that case, the analysis could temporarily deactivate the simulator. */ sim.activate(); /* Allow executor threads to run and return when the simulated process terminates. */ try { sim.main_loop(); } catch (Analysis*) { } /* Not really necessary since we're not doing anything else. */ sim.deactivate(); return 0; }
int main(int argc, char *argv[], char *envp[]) { RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); // Parse the ELF container so we can get to the symbol table. This is normal ROSE static analysis. char *rose_argv[4]; int rose_argc=0; rose_argv[rose_argc++] = argv[0]; rose_argv[rose_argc++] = strdup("-rose:read_executable_file_format_only"); rose_argv[rose_argc++] = argv[n]; rose_argv[rose_argc] = NULL; SgProject *project = frontend(rose_argc, rose_argv); // Find the address of "main" and "updcrc" functions. rose_addr_t main_va = RSIM_Tools::FunctionFinder().address(project, "main"); assert(main_va!=0); rose_addr_t updcrc_va = RSIM_Tools::FunctionFinder().address(project, "updcrc"); assert(updcrc_va!=0); // Register the analysis callback. Analysis analysis(main_va, updcrc_va); sim.install_callback(&analysis); // The rest is normal boiler plate to run the simulator, except we'll catch the Analysis to terminate the simulation early // if desired. sim.install_callback(new RSIM_Tools::UnhandledInstruction); sim.exec(argc-n, argv+n); sim.activate(); try { sim.main_loop(); } catch (Analysis*) { } sim.deactivate(); return 0; }
int main(int argc, char *argv[], char *envp[]) { rose_addr_t trigger_va = 0; // address at which disassembly is triggered std::string trigger_func = "oep"; // name of function at which disassembly is triggered (oep=original entry point) AsmUnparser::Organization org = AsmUnparser::ORGANIZED_BY_AST; // Parse arguments that we need for ourself. for (int i=1; i<argc; i++) { if (!strncmp(argv[i], "--trigger=", 10)) { // Address (or name of function) that will trigger the disassembly. When the EIP register contains this value then // disassembly will run and the specimen will be terminated. char *rest; trigger_func = ""; trigger_va = strtoull(argv[i]+10, &rest, 0); if (*rest) { trigger_va = 0; trigger_func = argv[i]+10; } memmove(argv+i, argv+i+1, (argc-- - i)*sizeof(*argv)); --i; } else if (!strcmp(argv[i], "--linear")) { org = AsmUnparser::ORGANIZED_BY_ADDRESS; memmove(argv+i, argv+i+1, (argc-- - i)*sizeof(*argv)); --i; } } // Initialize the simulator RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); sim.install_callback(new RSIM_Tools::UnhandledInstruction); sim.exec(argc-n, argv+n); RSIM_Process *process = sim.get_process(); RSIM_Thread *main_thread = process->get_main_thread(); // Find the trigger address if (0==trigger_va) { if (trigger_func.empty() || !trigger_func.compare("oep")) { trigger_va = process->get_ep_orig_va(); } else if (0==(trigger_va = RSIM_Tools::FunctionFinder().address(process->headers(), trigger_func))) { std::cerr <<argv[0] <<": unable to locate address of function: " <<trigger_func <<"\n"; exit(1); } } // Install our disassembler callback to the main thread. We don't use RSIM_Tools::MemoryDisassembler because we want to // cancel the specimen once we disassemble. main_thread->install_callback(new MyDisassembler(trigger_va, org)); // Allow the specimen to run until the disassembly is triggered bool disassembled = false; sim.activate(); try { sim.main_loop(); } catch (MyDisassembler*) { disassembled = true; } if (!disassembled) { std::cerr <<argv[0] <<": specimen ran to completion without triggering a disassembly.\n"; exit(1); } return 0; }
int main(int argc, char *argv[], char *envp[]) { RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); sim.install_callback(new RSIM_Tools::UnhandledInstruction); /************************************************************************************************************************** * Debugging callbacks... **************************************************************************************************************************/ #if 0 /* Parse the ELF container so we can get to the symbol table. */ char *rose_argv[4]; rose_argv[0] = argv[0]; rose_argv[1] = strdup("-rose:read_executable_file_format_only"); rose_argv[2] = argv[n]; rose_argv[3] = NULL; SgProject *project = frontend(3, rose_argv); /* Disassemble when we hit main() */ rose_addr_t disassemble_va = RSIM_Tools::FunctionFinder().address(project, "main"); assert(disassemble_va>0); sim.install_callback(new RSIM_Tools::MemoryDisassembler(disassemble_va)); /* Print a stack trace and memory dump for every system call */ struct SyscallStackTrace: public RSIM_Callbacks::SyscallCallback { virtual SyscallStackTrace *clone() { return this; } virtual bool operator()(bool enabled, const Args &args) { if (enabled) { RTS_Message *trace = args.thread->tracing(TRACE_SYSCALL); args.thread->report_stack_frames(trace, "Stack frames for following system call:"); args.thread->get_process()->mem_showmap(trace, "Memory map for following system call:", " "); } return enabled; } }; sim.get_callbacks().add_syscall_callback(RSIM_Callbacks::BEFORE, new SyscallStackTrace); #endif /*************************************************************************************************************************** * The main program... ***************************************************************************************************************************/ sim.exec(argc-n, argv+n); sim.install_callback(new MemoryTransactionTester(sim.get_process()->get_ep_orig_va()), RSIM_Callbacks::BEFORE, true); // sim.activate(); sim.main_loop(); // sim.deactivate(); sim.describe_termination(stderr); sim.terminate_self(); // probably doesn't return return 0; }
int main(int argc, char *argv[], char *envp[]) { // Parse (and remove) switches intended for the analysis. std::string trigger_func, analysis_func; rose_addr_t trigger_va=0, analysis_va=0; std::vector<bool> take_branch; for (int i=1; i<argc; i++) { if (!strncmp(argv[i], "--trigger=", 10)) { // name or address of function triggering analysis char *rest; trigger_va = strtoull(argv[i]+10, &rest, 0); if (*rest) { trigger_va = 0; trigger_func = argv[i]+10; } memmove(argv+i, argv+i+1, (argc-- - i)*sizeof(*argv)); --i; } else if (!strncmp(argv[i], "--analysis-func=", 16)) { // name or address of function to analyze char *rest; analysis_va = strtoull(argv[i]+16, &rest, 0); if (*rest) { analysis_va = 0; analysis_func = argv[i]+16; } memmove(argv+i, argv+i+1, (argc-- - i)*sizeof(*argv)); --i; } else if (!strncmp(argv[i], "--take-branch=", 14)) { // --take-branch=STRING. The STRING is a series of boolean values (t/f or 1/0 or y/n) that say what to do when the // analysis hits a conditional branch instruction and cannot decide whether the branch should be taken or not // taken. Whatever choice the user specifies here causes the analysis to add a new constraint to the solver. for (size_t j=14; argv[i][j]; j++) take_branch.push_back(NULL!=strchr("t1y", argv[i][j])); memmove(argv+i, argv+i+1, (argc-- -i)*sizeof(*argv)); --i; } } if (trigger_func.empty() && 0==trigger_va) { std::cerr <<argv[0] <<": --trigger-func=NAME_OR_ADDR is required\n"; return 1; } if (analysis_func.empty() && 0==analysis_va) { std::cerr <<argv[0] <<": --analysis-func=NAME_OR_ADDR is required\n"; return 1; } // Parse switches intended for the simulator. RSIM_Linux32 sim; int n = sim.configure(argc, argv, envp); // Parse the ELF container so we can get to the symbol table. This is normal ROSE static analysis. char *rose_argv[4]; int rose_argc=0; rose_argv[rose_argc++] = argv[0]; rose_argv[rose_argc++] = strdup("-rose:read_executable_file_format_only"); rose_argv[rose_argc++] = argv[n]; rose_argv[rose_argc] = NULL; SgProject *project = frontend(rose_argc, rose_argv); // Find the address of "main" and analysis functions. if (!trigger_func.empty()) trigger_va = RSIM_Tools::FunctionFinder().address(project, trigger_func); assert(trigger_va!=0); if (!analysis_func.empty()) analysis_va = RSIM_Tools::FunctionFinder().address(project, analysis_func); assert(analysis_va!=0); // Register the analysis callback. Analysis analysis(trigger_va, analysis_va, take_branch); sim.install_callback(&analysis); // The rest is normal boiler plate to run the simulator, except we'll catch the Analysis to terminate the simulation early // if desired. sim.install_callback(new RSIM_Tools::UnhandledInstruction); sim.exec(argc-n, argv+n); sim.activate(); try { sim.main_loop(); } catch (Analysis*) { } sim.deactivate(); return 0; }