Example #1
0
File: simulate.C Project: 8l/rose
int main(int argc, char *argv[]) {
    Diagnostics::initialize();
    ::mlog = Diagnostics::Facility("tool", Diagnostics::destination);
    Diagnostics::mfacilities.insertAndAdjust(::mlog);

    // Parse the command-line
    Partitioner2::Engine engine;
    std::vector<std::string> specimenNames = parseCommandLine(argc, argv, engine);
    if (specimenNames.empty())
        throw std::runtime_error("no specimen specified; see --help");

    // Load specimen into memory
    MemoryMap map = engine.loadSpecimens(specimenNames);

    // Configure instruction semantics
    Partitioner2::Partitioner partitioner = engine.createPartitioner();
    Disassembler *disassembler = engine.obtainDisassembler();
    const RegisterDictionary *regdict = disassembler->get_registers();
    if (disassembler->dispatcher() == NULL)
        throw std::runtime_error("no instruction semantics for this architecture");    
    BaseSemantics::RiscOperatorsPtr ops = InstructionSemantics2::ConcreteSemantics::RiscOperators::instance(regdict);
    BaseSemantics::DispatcherPtr cpu = disassembler->dispatcher()->create(ops);
    ConcreteSemantics::MemoryState::promote(ops->currentState()->memoryState())->memoryMap(map);

    // Find starting address
    rose_addr_t va = 0;
    if (settings.startVa) {
        va = *settings.startVa;
    } else if (engine.isaName() == "coldfire") {
        // Use the interrupt vector to initialize the stack pointer and instruction pointer.
        uint32_t sp, ip;
        if (4 != map.at(0).limit(4).read((uint8_t*)&sp).size())
            throw std::runtime_error("cannot read stack pointer at address 0x00000000");
        ops->writeRegister(disassembler->stackPointerRegister(), ops->number_(32, ByteOrder::be_to_host(sp)));
        if (4 != map.at(4).limit(4).read((uint8_t*)&ip).size())
            throw std::runtime_error("cannot read instruction pointer at address 0x00000004");
        va = ByteOrder::be_to_host(ip);
    } else if (!map.atOrAfter(0).require(MemoryMap::EXECUTABLE).next().assignTo(va)) {
        throw std::runtime_error("no starting address specified and none marked executable");
    }
    ops->writeRegister(disassembler->instructionPointerRegister(), ops->number_(32, va));

    // Execute
    map.dump(::mlog[INFO]);
    while (1) {
        va = ops->readRegister(disassembler->instructionPointerRegister())->get_number();
        SgAsmInstruction *insn = partitioner.instructionProvider()[va];
        SAWYER_MESG(::mlog[TRACE]) <<unparseInstructionWithAddress(insn, NULL, regdict) <<"\n";
        try {
            cpu->processInstruction(insn);
        } catch (const BaseSemantics::Exception &e) {
            ::mlog[WARN] <<e <<"\n";
        }
    }

    // std::cout <<"Final state:\n";
    // std::cout <<*ops->currentState();
}
Example #2
0
static void
listInstructions(const InstructionProvider::Ptr &insns, const MemoryMap &map,
                 const FunctionByAddress &code1, FunctionByAddress &code2) {
    std::ostream &out = std::cout;
    static const size_t insnWidth = 110;
    rose_addr_t va1 = code1.hull().least();
    rose_addr_t va2 = code2.hull().least();
    rose_addr_t va = std::min(va1, va2);
    rose_addr_t expectedVa = va;
    AsmUnparser unparser;

    while (va<=code1.hull().greatest() || va<=code2.hull().greatest()) {
        // Address and contents
        if (va != expectedVa)
            out <<"\n";                                 // visual cue that addresses are not sequential here
        std::ostringstream ss;
        size_t size;
        if (!map.at(va).require(MemoryMap::EXECUTABLE).exists()) {
            ss <<StringUtility::addrToString(va) <<": " <<(map.at(va).exists() ? "not executable" : "not mapped");
            size = 1;
        } else if (SgAsmInstruction *insn = (*insns)[va]) {
            unparser.unparse(ss, insn);
            size = insn->get_size();
        } else {
            ss <<StringUtility::addrToString(va) <<": bad instruction";
            size = 1;
        }
        std::vector<std::string> lines = StringUtility::split('\n', ss.str());
        while (lines.size()>0 && lines[lines.size()-1]=="")
            lines.pop_back();
        for (size_t i=0; i<lines.size(); ++i) {
            if (i+1 < lines.size()) {
                out <<lines[i] <<"\n";
            } else {
                out <<std::setw(insnWidth) <<std::left <<lines[i];
            }
        }
        
        // Functions owning
        Sawyer::Optional<rose_addr_t> f1 = code1.getOptional(va);
        Sawyer::Optional<rose_addr_t> f2 = code2.getOptional(va);
        out <<"\t" <<std::setw(10) <<std::left <<(f1 ? StringUtility::addrToString(*f1) : std::string("none"));
        out <<"\t" <<std::setw(10) <<std::left <<(f2 ? StringUtility::addrToString(*f2) : std::string("none"));
        out <<" " <<(f1.isEqual(f2) ? "" : "<---") <<"\n";

        // Advance address pointer
        rose_addr_t next = va + size;
        expectedVa = next;
        FunctionByAddress::ConstIntervalIterator i1 = code1.upperBound(va);
        if (i1!=code1.nodes().end() && i1->least() < next)
            next = i1->least();
        FunctionByAddress::ConstIntervalIterator i2 = code2.upperBound(va);
        if (i2!=code2.nodes().end() && i2->least() < next)
            next = i2->least();
        if (!map.atOrAfter(next).next().assignTo(va))
            break;
    }
}
Example #3
0
int
main(int argc, char *argv[]) {
    Diagnostics::initialize();

    BinaryAnalysis::Partitioner2::Engine engine;
    Settings settings;
    std::vector<std::string> specimenNames = parseCommandLine(argc, argv, engine, settings /*in,out*/);

    BinaryAnalysis::MagicNumber analyzer;
    analyzer.maxBytesToCheck(settings.maxBytes);

    MemoryMap map = engine.loadSpecimens(specimenNames);
    map.dump(mlog[INFO]);

    size_t step = std::max(size_t(1), settings.step);
    AddressInterval limits = settings.limits.isEmpty() ? map.hull() : (settings.limits & map.hull());
    Sawyer::Container::IntervalSet<AddressInterval> addresses(map);
    addresses.intersect(limits);
    size_t nPositions = addresses.size() / step;
    mlog[INFO] <<"approximately " <<StringUtility::plural(nPositions, "positions") <<" to check\n";

    {
        Sawyer::ProgressBar<size_t> progress(nPositions, mlog[INFO], "positions");
        for (rose_addr_t va=limits.least();
             va<=limits.greatest() && map.atOrAfter(va).next().assignTo(va);
             va+=step, ++progress) {
            std::string magicString = analyzer.identify(map, va);
            if (magicString!="data") {                  // runs home to Momma when it gets confused
                uint8_t buf[8];
                size_t nBytes = map.at(va).limit(sizeof buf).read(buf).size();
                std::cout <<StringUtility::addrToString(va) <<" |" <<leadingBytes(buf, nBytes) <<" | " <<magicString <<"\n";
            }
            if (va==limits.greatest())
                break;                                  // prevent overflow at top of address space
        }
    }
}
Example #4
0
// class method
size_t
SRecord::dump(const MemoryMap &map, std::ostream &out, size_t addrSize) {
    ASSERT_require(2==addrSize || 3==addrSize || 4==addrSize);
    SRecord::Type type = SREC_NONE;
    switch (addrSize) {
        case 2: type = SREC_DATA16; break;
        case 3: type = SREC_DATA24; break;
        case 4: type = SREC_DATA32; break;
    }

    size_t nRecords = 0;
    rose_addr_t va = 0;
    static const size_t maxBytesPerRecord = 28;         // common value so each S-Record fits on an 80-character screen
    uint8_t buffer[maxBytesPerRecord];
    while (map.atOrAfter(va).next().assignTo(va)) {
        size_t nread = map.at(va).limit(maxBytesPerRecord).read(buffer).size();
        ASSERT_require(nread>0);                        // since map.next() returned true
        SRecord srec(type, va, buffer, nread);
        out <<srec <<"\n";
        va += nread;
        ++nRecords;
    }
    return nRecords;
}