Пример #1
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;
}
Пример #2
0
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;
}
Пример #3
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;
}
Пример #4
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 IntervalAnalysis(sim.get_process()->get_ep_start_va()), RSIM_Callbacks::BEFORE, true);
    sim.main_loop();
    sim.describe_termination(stderr);
    sim.terminate_self();
    return 0;
}
Пример #5
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;
}
Пример #6
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;
}
Пример #7
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;
}
Пример #8
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;
}
Пример #9
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;
}