Beispiel #1
0
int
RSIM_Simulator::exec(int argc, char **argv)
{
    assert(argc>0);

    create_process();

    SgAsmGenericHeader *fhdr = process->load(argv[0]);
    entry_va = fhdr->get_base_va() + fhdr->get_entry_rva();

    RSIM_Thread *main_thread = process->get_thread(getpid());
    assert(main_thread!=NULL);
    process->initialize_stack(fhdr, argc, argv);

    process->binary_trace_start();

    if ((process->get_tracing_flags() & tracingFacilityBit(TRACE_MMAP))) {
        fprintf(process->get_tracing_file(), "memory map after program load:\n");
        process->get_memory()->dump(process->get_tracing_file(), "  ");
    }

    main_thread->tracing(TRACE_STATE)->mesg("Initial state:\n");
    main_thread->policy.dump_registers(main_thread->tracing(TRACE_STATE));

    return 0;
}
std::string btorTranslate(BtorTranslationPolicy& policy, SgProject* proj, FILE* outfile, bool initialConditionsAreUnknown, bool bogusIpIsError) {
  std::vector<SgNode*> headers = NodeQuery::querySubTree(proj, V_SgAsmGenericHeader);
  ROSE_ASSERT (headers.size() == 1);
  SgAsmGenericHeader* header = isSgAsmGenericHeader(headers[0]);
  rose_addr_t entryPoint = header->get_entry_rva() + header->get_base_va();
  X86InstructionSemantics<BtorTranslationPolicy, BtorWordType> t(policy);
  std::vector<SgNode*> instructions = NodeQuery::querySubTree(proj, V_SgAsmX86Instruction);
  for (size_t i = 0; i < instructions.size(); ++i) {
    SgAsmX86Instruction* insn = isSgAsmX86Instruction(instructions[i]);
    ROSE_ASSERT (insn);
    try {
        t.processInstruction(insn);
    } catch (const X86InstructionSemantics<BtorTranslationPolicy, BtorWordType>::Exception &e) {
        fprintf(stderr, "%s: %s\n", e.mesg.c_str(), unparseInstructionWithAddress(e.insn).c_str());
    }
  }
  policy.setInitialState(entryPoint, initialConditionsAreUnknown);
  // Add "bogus IP" error
  policy.newRegisterMap.errorFlag[bmc_error_bogus_ip] =
    policy.invert(policy.isValidIp);
  for (size_t i = 0; i < numBmcErrors; ++i) {
    if (i == bmc_error_bogus_ip && !bogusIpIsError) continue; // For testing
    policy.problem.computations.push_back(policy.problem.build_op_root(policy.problem.build_op_and(policy.errorsEnabled, policy.newRegisterMap.errorFlag[i])));
  }
  policy.addNexts();
  return policy.problem.unparse();
}
Beispiel #3
0
BinaryLoader::MappingContribution
BinaryLoader::align_values(SgAsmGenericSection *section, MemoryMap *map,
                           rose_addr_t *malign_lo_p, rose_addr_t *malign_hi_p,
                           rose_addr_t *va_p, rose_addr_t *mem_size_p,
                           rose_addr_t *offset_p, rose_addr_t *file_size_p, bool *map_private_p,
                           rose_addr_t *va_offset_p, bool *anon_lo_p, bool *anon_hi_p, 
                           ConflictResolution *resolve_p)
{
    ASSERT_not_null(section);
    ASSERT_require2(section->is_mapped(), "section must be mapped to virtual memory");
    SgAsmGenericHeader *header = isSgAsmGenericHeader(section);
    if (!header) header = section->get_header();
    ASSERT_not_null(header);
    
    /* Initial guesses */
    rose_addr_t malign_lo = std::max(section->get_mapped_alignment(), (rose_addr_t)1);
    rose_addr_t malign_hi = std::min(std::max(section->get_mapped_alignment(), (rose_addr_t)1), (rose_addr_t)4096);
    rose_addr_t va        = header->get_base_va() + section->get_mapped_preferred_rva();
    rose_addr_t mem_size  = section->get_mapped_size();
    rose_addr_t falign_lo = std::max(section->get_file_alignment(), (rose_addr_t)1);
    rose_addr_t offset    = section->get_offset();
    rose_addr_t file_size = section->get_size();

    /* Align lower end of mapped region to satisfy both memory and file alignment constraints. */
    rose_addr_t va_offset = bialign(va, malign_lo, offset, falign_lo);
    if (va_offset>va || va_offset>offset) {
        mlog[TRACE] <<"      Adjustment " <<va_offset <<" exceeds va or offset (va=" <<va
                    <<", offset=" <<offset <<")\n";
        throw Exception("no solutions to memory/file alignment constraints");
    }
    ASSERT_require((va - va_offset) % malign_lo == 0);
    ASSERT_require((offset - va_offset) % falign_lo == 0);
    va -= va_offset;
    mem_size += va_offset;
    offset -= va_offset;
    file_size += va_offset;

    /* Extend mapped region to satisfy high alignment; but do not extend the file region */
    if ((va + mem_size) % malign_hi != 0) {
        uint64_t extend_by = alignUp(va+mem_size, malign_hi) - (va+mem_size);
        mem_size += extend_by;
    }

    /* Return values */
    *malign_lo_p = malign_lo;
    *malign_hi_p = malign_hi;
    *va_p = va;
    *mem_size_p = mem_size;
    *offset_p = offset;
    *file_size_p = file_size;
    *map_private_p = false;
    *va_offset_p = va_offset;
    *anon_lo_p = true;
    *anon_hi_p = true;
    *resolve_p = RESOLVE_THROW;
    return CONTRIBUTE_ADD;
}
Beispiel #4
0
/** Returns base virtual address for a section, or zero if the section is not associated with a header. */
rose_addr_t
SgAsmGenericSection::get_base_va() const
{
    ROSE_ASSERT(this != NULL);

    if (isSgAsmGenericHeader(this))
        return isSgAsmGenericHeader(this)->get_base_va();

    SgAsmGenericHeader *hdr = get_header();
    return hdr ? hdr->get_base_va() : 0;
}
Beispiel #5
0
/* This algorithm was implemented based on an e-mail from Cory Cohen at CERT and inspection of PE::ConvertRvaToFilePosition()
 * as defined in "PE.cpp 2738 2009-06-05 15:09:11Z murawski_dev". [RPM 2009-08-17] */
BinaryLoader::MappingContribution
BinaryLoaderPe::align_values(SgAsmGenericSection *section, MemoryMap *map,
                             rose_addr_t *malign_lo_p, rose_addr_t *malign_hi_p,
                             rose_addr_t *va_p, rose_addr_t *mem_size_p,
                             rose_addr_t *offset_p, rose_addr_t *file_size_p, bool *map_private_p,
                             rose_addr_t *va_offset_p, bool *anon_lo_p, bool *anon_hi_p,
                             ConflictResolution *resolve_p)
{
    SgAsmGenericHeader *header = isSgAsmPEFileHeader(section);
    if (!header) header = section->get_header();
    ROSE_ASSERT(header!=NULL);

    if (!section->is_mapped())
        return CONTRIBUTE_NONE;

    /* File and memory alignment must be between 1 and 0x200 (512), inclusive */
    rose_addr_t file_alignment = section->get_file_alignment();
    if (file_alignment>0x200 || 0==file_alignment)
        file_alignment = 0x200;
    rose_addr_t mapped_alignment = section->get_mapped_alignment();
    if (0==mapped_alignment)
        mapped_alignment = 0x200;

    /* Align file size upward even before we align the file offset downward. */
    rose_addr_t file_size = ALIGN_UP(section->get_size(), file_alignment);

    /* Map the entire section's file content (aligned) or the requested map size, whichever is larger. */
    rose_addr_t mapped_size = std::max(section->get_mapped_size(), file_size);

    /* Align file offset downward but do not adjust file size. */
    rose_addr_t file_offset = ALIGN_DN(section->get_offset(), file_alignment);

    /* Align the preferred relative virtual address downward without regard for the base virtual address, and do not adjust
     * mapped size. */
    rose_addr_t mapped_va = header->get_base_va() + ALIGN_DN(section->get_mapped_preferred_rva(), mapped_alignment);

    *malign_lo_p = mapped_alignment;
    *malign_hi_p = 1;
    *va_p = mapped_va;
    *mem_size_p = mapped_size;
    *offset_p = file_offset;
    *file_size_p = file_size;
    *map_private_p = false;
    *va_offset_p = 0;
    *anon_lo_p = *anon_hi_p = true;
    *resolve_p = RESOLVE_OVERMAP;
    return CONTRIBUTE_ADD;
}
Beispiel #6
0
int
main(int argc, char *argv[])
{
    SgProject *project = frontend(argc, argv);
    SgAsmInterpretation *interp = SageInterface::querySubTree<SgAsmInterpretation>(project).back();
    AllInstructions insns(interp);
    SgAsmGenericHeader *header = interp->get_headers()->get_headers().front();
    rose_addr_t start_va = header->get_base_va() + header->get_entry_rva();

#if SEMANTIC_API == OLD_API
    MyPolicy operators;
    X86InstructionSemantics<MyPolicy, MyValueType> dispatcher(operators);
#else
    BaseSemantics::RiscOperatorsPtr operators = make_ops();
    BaseSemantics::DispatcherPtr dispatcher = DispatcherX86::instance(operators);
#endif

    struct sigaction sa;
    sa.sa_handler = alarm_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGALRM, &sa, NULL);
    alarm(timeout);
    struct timeval start_time;
    std::cout <<"test starting...\n";
    gettimeofday(&start_time, NULL);

    size_t ninsns = 0;
    while (!had_alarm) {
        rose_addr_t va = start_va;
        while (SgAsmInstruction *insn = insns.fetch(va)) {
            //std::cerr <<unparseInstructionWithAddress(insn) <<"\n";
#if SEMANTIC_API == OLD_API
            dispatcher.processInstruction(isSgAsmx86Instruction(insn));
            ++ninsns;
#if SEMANTIC_DOMAIN == MULTI_DOMAIN
            // multi-semantics ValueType has no is_known() or get_known(). We need to invoke it on a specific subpolicy.
            PartialSymbolicSemantics::ValueType<32> ip = operators.readRegister<32>("eip")
                                                         .get_subvalue(MyMultiSemanticsClass::SP0());
#else
            MyValueType<32> ip = operators.readRegister<32>("eip");
#endif
            if (!ip.is_known())
                break;
            va = ip.known_value();
#else
            dispatcher->processInstruction(insn);
            ++ninsns;
            BaseSemantics::SValuePtr ip = operators->readRegister(dispatcher->findRegister("eip"));
            if (!ip->is_number())
                break;
            va = ip->get_number();
#endif
            if (had_alarm)
                break;
        }
    }

#if SEMANTIC_API == OLD_API
    MyValueType<32> eax = operators.readRegister<32>("eax");
    std::cerr <<"eax = " <<eax <<"\n";
#else
    BaseSemantics::SValuePtr eax = operators->readRegister(dispatcher->findRegister("eax"));
#if SEMANTIC_DOMAIN == MULTI_DOMAIN
    // This is entirely optional, but the output looks better if it has the names of the subdomains.
    std::cerr <<"eax = " <<(*eax + MultiSemantics::RiscOperators::promote(operators)->get_formatter()) <<"\n";
#else
    std::cerr <<"eax = " <<*eax <<"\n";
#endif
#endif

    struct timeval stop_time;
    gettimeofday(&stop_time, NULL);
    double elapsed = ((double)stop_time.tv_sec-start_time.tv_sec) + 1e-6*((double)stop_time.tv_usec-start_time.tv_usec);
    if (elapsed < timeout/4.0)
        std::cout <<"warning: test did not run for a sufficiently long time; output may contain a high degree of error.\n";
    std::cout <<"number of instructions:  " <<ninsns <<"\n"
              <<"elapsed time:            " <<elapsed <<" seconds\n"
              <<"semantic execution rate: " <<(ninsns/elapsed) <<" instructions/second\n";
    return 0;
}