Пример #1
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;
}
Пример #2
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;
}
Пример #3
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;
}
Пример #4
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;
}