Exemple #1
0
/* Destructor must remove section/header link */
SgAsmGenericSection::~SgAsmGenericSection()
{
    SgAsmGenericFile* ef = get_file();
    SgAsmGenericHeader *hdr = get_header();

    /* See constructor comment. This deletes both halves of the header/section link. */
    if (hdr) {
        hdr->remove_section(this);
        set_header(NULL);
    }

    /* See comment in ROSETTA/src/binaryInstruction.C.  We need to explicitly delete the section name. */
    if (p_name) {
        SageInterface::deleteAST(p_name);
        p_name = NULL;
    }
    
    /* FIXME: holes should probably be their own class, which would make the file/hole bidirectional linking more like the
     *        header/section bidirectional links (RPM 2008-09-02) */
    ef->remove_hole(this);

    /* Delete children */
    p_file   = NULL; // deleted by SageInterface::deleteAST()

    /* If the section has allocated its own local pool for the p_data member (rather than pointing into the SgAsmGenericFile)
     * then free that now. */
    if (local_data_pool!=NULL) {
        free(local_data_pool);
        local_data_pool = NULL;
    }
}
Exemple #2
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();
}
Exemple #4
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;
}
Exemple #5
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;
}
Exemple #6
0
/* once called loadInterpLibraries */
void
BinaryLoader::link(SgAsmInterpretation* interp)
{
    ASSERT_not_null(interp);
    SgBinaryComposite *composite = SageInterface::getEnclosingNode<SgBinaryComposite>(interp);
    ASSERT_not_null(composite);

    /* Make sure the pre-load objects are parsed and linked into the AST. */
    for (std::vector<std::string>::const_iterator pi=preloads.begin(); pi!=preloads.end(); ++pi) {
        mlog[TRACE] <<"preload object " <<*pi <<"\n";
        std::string filename = find_so_file(*pi);
        if (is_linked(composite, filename)) {
            mlog[TRACE] <<filename <<" is already parsed.\n";
        } else {
            Stream m1(mlog[TRACE] <<"parsing " <<filename);
            createAsmAST(composite, filename);
            m1 <<"... done.\n";
        }
    }

    /* Bootstrap */
    std::list<SgAsmGenericHeader*> unresolved_hdrs;
    unresolved_hdrs.insert(unresolved_hdrs.end(),
                           interp->get_headers()->get_headers().begin(),
                           interp->get_headers()->get_headers().end());

    /* Process unresolved headers from the beginning of the queue and push new ones onto the end. */
    while (!unresolved_hdrs.empty()) {
        SgAsmGenericHeader *header = unresolved_hdrs.front();
        unresolved_hdrs.pop_front();
        std::string header_name = header->get_file()->get_name();
        std::vector<std::string> deps = dependencies(header);
        for (std::vector<std::string>::iterator di=deps.begin(); di!=deps.end(); ++di) {
            mlog[TRACE] <<"library " <<*di <<" needed by " <<header_name <<"\n";
            std::string filename = find_so_file(*di);
            if (is_linked(composite, filename)) {
                mlog[TRACE] <<filename <<" is already parsed.\n";
            } else {
                Stream m1(mlog[TRACE] <<"parsing " <<filename);
                SgAsmGenericFile *new_file = createAsmAST(composite, filename);
                m1 <<"... done.\n";
                ASSERT_not_null2(new_file, "createAsmAST failed");
                SgAsmGenericHeaderPtrList new_hdrs = findSimilarHeaders(header, new_file->get_headers()->get_headers());
                unresolved_hdrs.insert(unresolved_hdrs.end(), new_hdrs.begin(), new_hdrs.end());
            }
        }
    }
}
Exemple #7
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;
}
Exemple #8
0
/* class method */
SgAsmGenericFile* 
BinaryLoader::createAsmAST(SgBinaryComposite* binaryFile, std::string filePath)
{
    ASSERT_forbid(filePath.empty());
  
    SgAsmGenericFile* file = SgAsmExecutableFileFormat::parseBinaryFormat(filePath.c_str());
    ASSERT_not_null(file);
  
    // TODO do I need to attach here - or can I do after return
    binaryFile->get_genericFileList()->get_files().push_back(file);
    file->set_parent(binaryFile->get_genericFileList());

    /* Add a new interpretation to the SgBinaryComposite object for each header of the newly parsed
     * SgAsmGenericFile for which a suitable interpretation does not already exist. */
    const SgAsmGenericHeaderPtrList &headers = file->get_headers()->get_headers();
    SgAsmInterpretationPtrList &interps = binaryFile->get_interpretations()->get_interpretations();
    for (size_t i = 0; i < headers.size(); ++i) {
        SgAsmGenericHeader* header = headers[i];
        SgAsmInterpretation* interp = NULL;
        for (size_t j = 0; j < interps.size(); ++j) {
            ASSERT_forbid(interps[j]->get_headers()->get_headers().empty());
            SgAsmGenericHeader* interpHeader = interps[j]->get_headers()->get_headers().front();
            if (isHeaderSimilar(header, interpHeader)) {
                interp = interps[j];
                break;
            }
        }
        if (!interp) {
            interp = new SgAsmInterpretation();
            interps.push_back(interp);
            interp->set_parent(binaryFile->get_interpretations());
            if (const RegisterDictionary *registers = RegisterDictionary::dictionary_for_isa(header->get_isa()))
                interp->set_registers(registers);
        }
        interp->get_headers()->get_headers().push_back(header);
    }

#if USE_ROSE_DWARF_SUPPORT
    /* Parse Dwarf info and add it to the SgAsmGenericFile. */
    readDwarf(file); 
#endif
  
  return file;
}
Exemple #9
0
void
VirtualTableSection::printOutVirtualFunctionTableInformation ( VirtualFunctionTableAddress vTableAddress )
{
    ROSE_ASSERT(virtualFunctionTable != NULL);
    size_t section_address_base  = virtualFunctionTable->get_mapped_preferred_rva();
    size_t offset                = vTableAddress - section_address_base;
    size_t size                  = virtualFunctionTable->get_size();

    ROSE_ASSERT(offset < size);

    printf ("In printOutVirtualFunctionTableInformation(%p): offset = %p (size = %p) \n",(void*)vTableAddress,(void*)offset,(void*)size);

    printf ("START -- Virtual function table: \n");

    SgAsmGenericHeader *hdr = virtualFunctionTable->get_header();
    SgAsmGenericFormat::ByteOrder sex = hdr->get_sex();
    size_t wordsize = hdr->get_word_size();
    size_t virtualTableSize = (size-offset) / wordsize;
    printf ("size = %zu offset = %zu wordsize = %zu virtualTableSize = %zu \n",size,offset,wordsize,virtualTableSize);
    for (size_t i=0; i < virtualTableSize; i++)
    {
        uint64_t functionPointer; /*type must support 64-bit specimen pointers in a 32-bit ROSE library*/
        // printf ("i = %zu \n",i);
        switch (wordsize)
        {
        case 4:
        {
            uint32_t ptr_disk;
            // virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            // virtualFunctionTable->read_content_local(i*wordsize, &ptr_disk, sizeof ptr_disk);
            virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            functionPointer = SgAsmExecutableFileFormat::disk_to_host(sex, ptr_disk);
            break;
        }
        case 8:
        {
            uint64_t ptr_disk;
            // virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            // virtualFunctionTable->read_content_local(i*wordsize, &ptr_disk, sizeof ptr_disk);
            virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            functionPointer = SgAsmExecutableFileFormat::disk_to_host(sex, ptr_disk);
            break;
        }
        default:
            ROSE_ASSERT(!"unsupported word size");
        }

        string sectionName;
        SgAsmElfSection* asmElfSection = getSection(project,functionPointer);
        if (asmElfSection != NULL)
        {
            sectionName = asmElfSection->get_name()->get_string();
        }
        else
        {
            sectionName = "NOT CONTAINED IN EXECUTABLE";

            // At the first sign of a pointer that is not in the executable then quit, this should be the end of the table.
            // Alternatively it appears that the end of the table has a code  0x4231 (for the first table).
            break;
        }

        printf ("Pointer 0x%"PRIx64" is to data in the %s section \n",functionPointer,sectionName.c_str());
    }

    printf ("END -- Virtual function table: \n");
}
Exemple #10
0
// Constructor
VirtualFunctionTable::VirtualFunctionTable ( SgProject* project, SgAsmElfSection* virtualFunctionTable, size_t vTableAddress )
    : virtualFunctionTablePosition(vTableAddress)
{
    printf ("Building virtual function table for position %p \n",(void*)virtualFunctionTablePosition);

    // Get the boundaries of the section where the virtual function tables are located.
    ROSE_ASSERT(virtualFunctionTable != NULL);
    size_t section_address_base  = virtualFunctionTable->get_mapped_preferred_rva();

    // Compute the offset for the input virtual function table into the section.
    size_t offset                = vTableAddress - section_address_base;

    // This is the upper bound on the size of the table (stay within the section)
    size_t size                  = virtualFunctionTable->get_size();

    ROSE_ASSERT(offset < size);

    printf ("In printOutVirtualFunctionTableInformation(%p): offset = %p (size = %p) \n",(void*)vTableAddress,(void*)offset,(void*)size);

    printf ("START -- Virtual function table: \n");

    // Get the architecture specifici information required to the raw data in the section.
    SgAsmGenericHeader *hdr = virtualFunctionTable->get_header();
    SgAsmGenericFormat::ByteOrder sex = hdr->get_sex();
    size_t wordsize = hdr->get_word_size();
    size_t virtualTableSize = (size-offset) / wordsize;
    printf ("size = %zu offset = %zu wordsize = %zu virtualTableSize = %zu \n",size,offset,wordsize,virtualTableSize);

    for (size_t i=0; i < virtualTableSize; i++)
    {
        uint64_t functionPointer; /*type must support 64-bit specimen pointers in a 32-bit ROSE library*/
        // printf ("i = %zu \n",i);
        switch (wordsize)
        {
        case 4:
        {
            uint32_t ptr_disk;
            // virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            // virtualFunctionTable->read_content_local(i*wordsize, &ptr_disk, sizeof ptr_disk);
            virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            functionPointer = SgAsmExecutableFileFormat::disk_to_host(sex, ptr_disk);
            break;
        }

        case 8:
        {
            uint64_t ptr_disk;
            // virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            // virtualFunctionTable->read_content_local(i*wordsize, &ptr_disk, sizeof ptr_disk);
            virtualFunctionTable->read_content_local(offset+i*wordsize, &ptr_disk, sizeof ptr_disk);
            functionPointer = SgAsmExecutableFileFormat::disk_to_host(sex, ptr_disk);
            break;
        }

        default:
            ROSE_ASSERT(!"unsupported word size");
        }

        string sectionName;
        SgAsmElfSection* asmElfSection = getSection(project,functionPointer);
        if (asmElfSection != NULL)
        {
            sectionName = asmElfSection->get_name()->get_string();
        }
        else
        {
            sectionName = "NOT CONTAINED IN EXECUTABLE";

            // At the first sign of a pointer that is not in the executable then quit, this should be the end of the table.
            // Alternatively it appears that the end of the table has a code  0x4231 (for the first table).
            break;
        }

        printf ("Pointer 0x%"PRIx64" is to data in the %s section \n",functionPointer,sectionName.c_str());

        string name = "virtual_function_" + StringUtility::numberToString(i);

        VirtualFunction* virtualFunction = new VirtualFunction(name,functionPointer);
        ROSE_ASSERT(virtualFunction != NULL);
        virtualFunctionList.push_back(virtualFunction);
    }

    printf ("END -- Virtual function table: \n");

#if 0
    printf ("Exiting in VirtualFunctionTable constructor \n");
    ROSE_ASSERT(false);
#endif
}
Exemple #11
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;
}