Esempio n. 1
0
    TEST_FIXTURE(MemoryMapTestFixture, CreateWriteRead)
    {
        if (!fileName.isEmpty()) {

            fs::remove(fileName.getString());

            {
                vector<uint8_t> data(length);
                for (size_t i = 0; i < length; ++i) {
                    data[i] = uint8_t(i%256);
                }
            
                File fwrite(fileName.getString(), File::Write|File::Create);
                CHECK(fwrite.isOk());
                CHECK(fwrite.write(&data[0], length));
            }
        
            {
                File file(fileName.getString(), File::Read);
                MemoryMap mread;
                CHECK(mread.map(file.getDescriptor(), length, MemoryMap::Read, MemoryMap::Private));
                uint8_t *data = static_cast<uint8_t *>(mread.getMemory());
                for (size_t i = 0; i < length; ++i) {
                    CHECK_EQUAL(uint8_t(i%256), data[i]);
                }
            }
        }
    }
Esempio n. 2
0
Partitioner::RegionStats *
Partitioner::region_statistics()
{
    MemoryMap mymap = *map;
    mymap.prune(MemoryMap::MM_PROT_EXEC);
    return region_statistics(mymap.va_extents());
}
Esempio n. 3
0
int main(int argc, char *argv[]) {
    Diagnostics::initialize();
    mlog = Sawyer::Message::Facility("tool", Diagnostics::destination);
    Diagnostics::mfacilities.insertAndAdjust(mlog);

    // Parse command line
    Settings settings;
    std::vector<std::string> args = parseCommandLine(argc, argv, settings).unreachedArgs();
    if (args.size()!=2)
        throw std::runtime_error("invalid usage; see --help");

    // Load the CSV files
    FunctionByAddress code1, data1, code2, data2;
    readCsvFile(args[0], code1 /*out*/, data1 /*out*/);
    readCsvFile(args[1], code2 /*out*/, data2 /*out*/);

    showStats(FileSystem::Path(args[0]).filename().string(), code1, data1,
              FileSystem::Path(args[1]).filename().string(), code2, data2);
    std::cout <<"\n";

    // Parse the specimen
    if (!settings.specimenName.empty()) {
        P2::Engine engine;
        MemoryMap map = engine.loadSpecimens(settings.specimenName);
        InstructionProvider::Ptr insns = InstructionProvider::instance(engine.obtainDisassembler(), map);
        map.dump(std::cout);
        listInstructions(insns, map, code1, code2);
    }
}
Esempio n. 4
0
File: simulate.C Progetto: 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();
}
Esempio n. 5
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;
    }
}
Esempio n. 6
0
int
main(int argc, char *argv[])
{
    // Parse command-line
    int argno=1;
    for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) {
        if (!strcmp(argv[argno], "--")) {
            ++argno;
            break;
        } else {
            std::cerr <<argv[0] <<": unrecognized switch: " <<argv[argno] <<"\n";
            exit(1);
        }
    }
    if (argno+1!=argc) {
        std::cerr <<"usage: " <<argv[0] <<" [SWITCHES] [--] SPECIMEN\n";
        exit(1);
    }
    std::string specimen_name = argv[argno++];

    // Open the file
    rose_addr_t start_va = 0;
    MemoryMap map;
    size_t file_size = map.insertFile(specimen_name, start_va);
    map.at(start_va).limit(file_size).changeAccess(MemoryMap::EXECUTABLE, 0);

    // Try to disassemble every byte, and print the CALL/FARCALL targets
    InstructionMap insns;
    size_t nerrors=0;
    Disassembler *disassembler = new DisassemblerX86(4);
    for (rose_addr_t offset=0; offset<file_size; ++offset) {
        try {
            rose_addr_t insn_va = start_va + offset;
            if (SgAsmX86Instruction *insn = isSgAsmX86Instruction(disassembler->disassembleOne(&map, insn_va)))
                insns[insn_va] = insn;
        } catch (const Disassembler::Exception &e) {
            ++nerrors;
        }
    }

    // Partition those instructions into basic blocks and functions
    Partitioner partitioner;
    SgAsmBlock *gblock = partitioner.partition(NULL, insns, &map);

    // Print addresses of functions
    struct T1: AstSimpleProcessing {
        void visit(SgNode *node) {
            if (SgAsmFunction *func = isSgAsmFunction(node))
                std::cout <<StringUtility::addrToString(func->get_entry_va()) <<"\n";
        }
    };
    T1().traverse(gblock, preorder);

    std::cerr <<specimen_name <<": " <<insns.size() <<" instructions; " <<nerrors <<" errors\n";
    return 0;
}
Esempio n. 7
0
TEST(MemoryMap, Values)
{
    const size_t NUM_BANKS = 11;
    const size_t BANK_SIZE = 17;
    MemoryMap<uint8_t> memMap;
    for (size_t ii = 0; ii < NUM_BANKS; ++ii)
    {
        std::shared_ptr<RAM<uint8_t> > bank(new RAM<uint8_t>(BANK_SIZE));
        memMap.setMemoryBank(ii * BANK_SIZE, bank);
    }
    memMap.lockLookUpTable();

    for (size_t ii = 0; ii < NUM_BANKS * BANK_SIZE; ++ii)
    {
        memMap.writeWord(ii, ii);
    }

    for (size_t ii = 0; ii < NUM_BANKS * BANK_SIZE; ++ii)
    {
        EXPECT_EQ(ii, memMap.readWord(ii));
    }

    // Test a few long values
    EXPECT_EQ(static_cast<uint16_t>(0x0201), memMap.readLong(1));
    EXPECT_EQ(static_cast<uint16_t>(0x0302), memMap.readLong(2));
    EXPECT_EQ(static_cast<uint16_t>(0x0908), memMap.readLong(8));
    EXPECT_EQ(static_cast<uint16_t>(0x0B0A), memMap.readLong(10));
    EXPECT_EQ(static_cast<uint16_t>(0x0C0B), memMap.readLong(11));
    EXPECT_EQ(static_cast<uint16_t>(0x0D0C), memMap.readLong(12));
    EXPECT_EQ(static_cast<uint16_t>(0x0E0D), memMap.readLong(13));
}
Esempio n. 8
0
// class method
rose_addr_t
SRecord::load(const std::vector<SRecord> &srecs, MemoryMap &map, bool createSegments, unsigned accessPerms)
{
    if (createSegments) {
        // We want to minimize the number of buffers in the map, so the first step is to discover what addresses are covered by
        // the data S-records
        Sawyer::Container::IntervalSet<AddressInterval> addressesUsed;
        BOOST_FOREACH (const SRecord &srec, srecs) {
            switch (srec.type()) {
                case SREC_DATA16:
                case SREC_DATA24:
                case SREC_DATA32:
                    addressesUsed.insert(AddressInterval::baseSize(srec.address(), srec.data().size()));
                    break;
                default:
                    break;
            }
        }

        // Create buffers for the data and insert them into the memory map
        BOOST_FOREACH (const AddressInterval &interval, addressesUsed.intervals()) {
            ASSERT_forbid(interval.isWhole());              // not practically possible since S-Record file would be >2^65 bytes
            map.insert(interval, MemoryMap::Segment::anonymousInstance(interval.size(), accessPerms, "S-Records"));
        }
    }

    // Populate the map by writing the S-Record data into it.
    rose_addr_t startingAddr = 0;
    BOOST_FOREACH (const SRecord &srec, srecs) {
        switch (srec.type()) {
            case SREC_DATA16:
            case SREC_DATA24:
            case SREC_DATA32: {
                if (!srec.data().empty()) {
                    size_t nwritten = map.at(srec.address()).write(srec.data()).size();
                    if (nwritten != srec.data().size())
                        throw MemoryMap::NotMapped("S-Record destination is not mapped for " +
                                                   StringUtility::plural(srec.data().size(), "bytes"),
                                                   &map, srec.address());
                }
                break;
            }
            case SREC_START16:
            case SREC_START24:
            case SREC_START32:
                startingAddr = srec.address();
                break;
            default:
                break;
        }
    }
    return startingAddr;
}
Esempio n. 9
0
VirtualAddressRange
findFreeVirtualAddressInRange(VirtualAddressRange range,
                              uint32_t size,
                              uint32_t align)
{
   return sMemoryMap.findFreeVirtualAddressInRange(range, size, align);
}
Esempio n. 10
0
std::string
MagicNumber::identify(const MemoryMap &map, rose_addr_t va) const {
    uint8_t buf[256];
    size_t nBytes = map.at(va).limit(std::min(maxBytes_, sizeof buf)).read(buf).size();
    if (0==nBytes)
        return "empty";
#ifdef ROSE_HAVE_LIBMAGIC
    return magic_buffer(details_->cookie, buf, nBytes);
#elif defined(BOOST_WINDOWS)
    throw std::runtime_error("magic number identification is not supported on Microsoft Windows");
#elif BOOST_FILESYSTEM_VERSION == 2
    throw std::runtime_error("MagicNumber::identify must have either libmagic or boost::filesystem version 3");
#else
    // We can maybe still do it, but this will be much, much slower.  We copy some specimen memory into a temporary file, then
    // run the unix file(1) command on it, then delete the temp file.
    static int ncalls = 0;
    if (1 == ++ncalls)
        mlog[WARN] <<"libmagic is not available on this system; using slow method instead\n";
    FileSystem::Path tmpFile = boost::filesystem::unique_path("/tmp/ROSE-%%%%-%%%%-%%%%-%%%%");
    std::ofstream(tmpFile.c_str()).write((const char*)buf, nBytes);
    std::string cmd = "file " + tmpFile.string();
    std::string magic;
    if (FILE *f = popen(cmd.c_str(), "r")) {
        char line[1024];
        if (fgets(line, sizeof line, f))
            magic = boost::trim_right_copy(std::string(line).substr(tmpFile.string().size()+2)); // filename + ": "
        pclose(f);
    } else {
        boost::filesystem::remove(tmpFile);
        throw std::runtime_error("command file: " + tmpFile.string());
    }
    boost::filesystem::remove(tmpFile);
    return magic;
#endif
}
Esempio n. 11
0
	virtual void populateCache(const Fingerprint &fileId, const DenseDataPtr &respondData) {
		{
			MemoryMap::write_iterator writer(mData);
			if (mData.alloc(respondData->length(), writer)) {
				bool newentry = writer.insert(fileId, respondData->length());
				if (newentry) {
					SILOG(transfer,debug,fileId << " created " << *respondData);
					CacheData *cdata = new CacheData;
					*writer = cdata;
					cdata->mSparse.addValidData(respondData);
					writer.use();
				} else {
					CacheData *cdata = static_cast<CacheData*>(*writer);
					cdata->mSparse.addValidData(respondData);
                    if (SILOGP(transfer,debug)) {
                        SILOGNOCR(transfer,debug,fileId << " already exists: ");
                        std::stringstream rangeListStream;
                        Range::printRangeList(rangeListStream,cdata->mSparse, (Range)(*respondData));
                        SILOGNOCR(transfer,debug,rangeListStream.str());
                    }
					writer.update(cdata->mSparse.getSpaceUsed());
				}

			}
		}
		CacheLayer::populateParentCaches(fileId, respondData);
	}
Esempio n. 12
0
int
main(int argc, char *argv[])
{
    // Parse command-line
    int argno=1;
    for (/*void*/; argno<argc && '-'==argv[argno][0]; ++argno) {
        if (!strcmp(argv[argno], "--")) {
            ++argno;
            break;
        } else {
            std::cerr <<argv[0] <<": unrecognized switch: " <<argv[argno] <<"\n";
            exit(1);
        }
    }
    if (argno+1!=argc) {
        std::cerr <<"usage: " <<argv[0] <<" [SWITCHES] [--] SPECIMEN\n";
        exit(1);
    }
    std::string specimen_name = argv[argno++];
            
    // Open the file
    rose_addr_t start_va = 0;
    MemoryMap map;
    size_t file_size = map.insertFile(specimen_name, start_va);
    map.at(start_va).limit(file_size).changeAccess(MemoryMap::EXECUTABLE, 0);

    // Try to disassemble every byte, and print the CALL/FARCALL targets
    size_t ninsns=0, nerrors=0;
    Disassembler *disassembler = new DisassemblerX86(4);
    for (rose_addr_t offset=0; offset<file_size; ++offset) {
        try {
            rose_addr_t insn_va = start_va + offset;
            SgAsmX86Instruction *insn = isSgAsmX86Instruction(disassembler->disassembleOne(&map, insn_va));
            if (insn && (x86_call==insn->get_kind() || x86_farcall==insn->get_kind())) {
                ++ninsns;
                rose_addr_t target_va;
                if (insn->getBranchTarget(&target_va))
                    std::cout <<StringUtility::addrToString(insn_va) <<": " <<StringUtility::addrToString(target_va) <<"\n";
            }
        } catch (const Disassembler::Exception &e) {
            ++nerrors;
        }
    }

    std::cerr <<specimen_name <<": " <<ninsns <<" instructions; " <<nerrors <<" errors\n";
    return 0;
}
Esempio n. 13
0
bool
mapMemory(VirtualAddress virtualAddress,
          PhysicalAddress physicalAddress,
          uint32_t size,
          MapPermission permission)
{
   return sMemoryMap.mapMemory(virtualAddress, physicalAddress, size, permission);
}
Esempio n. 14
0
    // Get all the functions defined for this process image.  We do this by disassembling the entire process executable memory
    // and using CFG analysis to figure out where the functions are located.
    Functions find_functions(RTS_Message *m, RSIM_Process *proc) {
        m->mesg("%s triggered; disassembling entire specimen image...\n", name);
        MemoryMap *map = disassembly_map(proc);
        std::ostringstream ss;
        map->dump(ss, "  ");
        m->mesg("%s: using this memory map for disassembly:\n%s", name, ss.str().c_str());
        SgAsmBlock *gblk = proc->disassemble(false/*take no shortcuts*/, map);
        delete map; map=NULL;
        std::vector<SgAsmFunction*> functions = SageInterface::querySubTree<SgAsmFunction>(gblk);
#if 0 /*DEBUGGING [Robb P. Matzke 2013-02-12]*/
        // Prune the function list to contain only what we want.
        for (std::vector<SgAsmFunction*>::iterator fi=functions.begin(); fi!=functions.end(); ++fi) {
            if ((*fi)->get_name().compare("_Z1fRi")!=0)
                *fi = NULL;
        }
        functions.erase(std::remove(functions.begin(), functions.end(), (SgAsmFunction*)NULL), functions.end());
#endif
        return Functions(functions.begin(), functions.end());
    }
int
main(int argc, char *argv[]) {
    ROSE_INITIALIZE;
    Diagnostics::initAndRegister(mlog, "tool");
    Sawyer::ProgressBarSettings::minimumUpdateInterval(0.2); // more fluid spinner

    // Parse command-line
    P2::Engine engine;
    Settings settings;
    std::vector<std::string> args = parseCommandLine(argc, argv, engine, settings);
    ASSERT_always_require2(args.size() >= 2, "incorrect usage; see --help");

    // Parse file containing instruction addresses
    std::string addrFileName = args[0];
    std::set<rose_addr_t> knownVas = parseAddressFile(addrFileName);
    mlog[INFO] <<"parsed " <<plural(knownVas.size(), "unique addresses") <<"\n";

    // Load specimen natively and attach debugger
    std::vector<std::string> specimen_cmd(args.begin()+1, args.end());
    BinaryDebugger debugger(specimen_cmd);
    debugger.setBreakpoint(AddressInterval::whole());
    ASSERT_always_require(debugger.isAttached());
    ASSERT_always_forbid(debugger.isTerminated());
    pid_t pid = debugger.isAttached();
    mlog[INFO] <<"child PID " <<pid <<"\n";

    // Get memory map.
    MemoryMap map;
    if (MAP_ROSE==settings.mapSource) {
        map = engine.loadSpecimens(specimen_cmd[0]);
    } else {
        map.insertProcess(":noattach:" + numberToString(pid));
    }
    map.dump(mlog[INFO]);

    // The addresses specified in the instruction address file must all be in memory that is mapped.
    BOOST_FOREACH (rose_addr_t va, knownVas) {
        ASSERT_always_require2(map.at(va).require(MemoryMap::EXECUTABLE).exists(),
                               "given address " + addrToString(va) + " is not mapped or lacks execute permission");
    }
Esempio n. 16
0
int
main(int argc, char *argv[]) {
    //! [commandline]
    ROSE_INITIALIZE;                                    // see rose::initialize
    std::string purpose = "finds static strings in a binary specimen";
    std::string description =
        "This tool disassembles a binary specimen and then scans the "
        "read-only parts of memory to find static strings. It looks for "
        "C-style NUL-termianted printable ASCII strings, zero-terminated "
        "UTF-16 little-endian strings, two-byte little-endian length-encoded "
        "ASCII strings, and some other common formats.";

    Partitioner2::Engine engine;
    std::vector<std::string> specimen =
        engine.parseCommandLine(argc, argv, purpose, description).unreachedArgs();
    //! [commandline]

    //! [load]
    MemoryMap map = engine.loadSpecimens(specimen);
    ByteOrder::Endianness sex = engine.obtainDisassembler()->get_sex();
    //! [load]

    //! [analysis]
    Strings::StringFinder finder;       // the string analyzer
    finder.settings().minLength = 5;    // no strings shorter than 5 characters
    finder.settings().maxLength = 8192; // no strings longer than 8k characters
    finder.insertCommonEncoders(sex);   // match common encodings of strings
    finder.find(map.require(MemoryMap::READABLE).prohibit(MemoryMap::WRITABLE));
    //! [analysis]

    //! [output]
    // Output, or just do "std::cout <<finder" if you're not picky.
    BOOST_FOREACH (const Strings::EncodedString &string, finder.strings()) {
        std::cout <<"string at " <<string.address() <<" for " <<string.size() <<" bytes\n";
        std::cout <<"encoding: " <<string.encoder()->name() <<"\n";
        std::cout <<"narrow value: \"" <<StringUtility::cEscape(string.narrow()) <<"\"\n";
    }
    //! [output]
}
Esempio n. 17
0
MMPainter::FStreamRecorder::FStreamRecorder( const char* fname, const MemoryMap& mm )
#ifdef MEMMON_DEBUG
: _fname( fname )
, _count( 0 )
#endif
{
	_buf.open( fname, std::ios_base::out | std::ios_base::binary );

	if( !_buf.is_open() )
		throw MemMon::ConstructorFailure< FStreamRecorder >();

	std::streambuf* bufptr = &_buf;
	mm.Write( bufptr );
}
Esempio n. 18
0
    // Obtain a memory map for disassembly
    MemoryMap *disassembly_map(RSIM_Process *proc) {
        MemoryMap *map = new MemoryMap(proc->get_memory(), MemoryMap::COPY_SHALLOW);
        map->prune(MemoryMap::MM_PROT_READ); // don't let the disassembler read unreadable memory, else it will segfault

        // Removes execute permission for any segment whose debug name does not contain the name of the executable. When
        // comparing two different executables for clones, we probably don't need to compare code that came from dynamically
        // linked libraries since they will be identical in both executables.
        struct Pruner: MemoryMap::Visitor {
            std::string exename;
            Pruner(const std::string &exename): exename(exename) {}
            virtual bool operator()(const MemoryMap*, const Extent&, const MemoryMap::Segment &segment_) {
                MemoryMap::Segment *segment = const_cast<MemoryMap::Segment*>(&segment_);
                if (segment->get_name().find(exename)==std::string::npos) {
                    unsigned p = segment->get_mapperms();
                    p &= ~MemoryMap::MM_PROT_EXEC;
                    segment->set_mapperms(p);
                }
                return true;
            }
        } pruner(proc->get_exename());
        map->traverse(pruner);
        return map;
    }
Esempio n. 19
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
        }
    }
}
Esempio n. 20
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;
}
Esempio n. 21
0
void GenomeSequence::sanityCheck(MemoryMap &fasta) const
{
    unsigned int i;

    unsigned int genomeIndex = 0;
    for (i=0; i<fasta.length(); i++)
    {
        switch (fasta[i])
        {
            case '>':
                while (fasta[i]!='\n' && fasta[i]!='\r') i++;
                break;
            case '\n':
            case '\r':
                break;
            default:
                assert(BaseAsciiMap::base2int[(int)(*this)[genomeIndex]] == 
                       BaseAsciiMap::base2int[(int) fasta[i]]);
                genomeIndex++;
                break;
        }
    }
}
Esempio n. 22
0
/* Looks at the RVA/Size pairs in the PE header and creates an SgAsmGenericSection object for each one.  This must be done
 * after we build the mapping from virtual addresses to file offsets. */
void
SgAsmPEFileHeader::create_table_sections()
{

    /* First, only create the sections. */
    for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) {
        SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i];
        if (0==pair->get_e_size())
            continue;

        /* Table names come from PE file specification and are hard coded by RVA/Size pair index */
        const char *tabname_short;
        std::string tabname = rvasize_pair_name((PairPurpose)i, &tabname_short);

        /* Find the starting offset in the file.
         * FIXME: We have a potential problem here in that ROSE sections are always contiguous in the file but a section created
         *        from an RVA/Size pair is not necessarily contiguous in the file.  Normally such sections are in fact
         *        contiguous and we'll just ignore this for now.  In any case, as long as these sections only ever read their
         *        data via the same MemoryMap that we use here, everything should be fine. [RPM 2009-08-17] */
        MemoryMap *map = get_loader_map();
        ROSE_ASSERT(map!=NULL);
        const MemoryMap::MapElement *elmt = map->find(get_base_va() + pair->get_e_rva());
        if (!elmt) {
            fprintf(stderr, "SgAsmPEFileHeader::create_table_sections: warning: pair-%zu, rva=0x%08"PRIx64", size=%"PRIu64
                    " bytes \"%s\": unable to find a mapping for the virtual address (skipping)\n",
                    i, pair->get_e_rva().get_rva(), pair->get_e_size(), tabname.c_str());
            continue;
        }
        rose_addr_t file_offset = elmt->is_anonymous() ? 0 : elmt->get_va_offset(get_base_va() + pair->get_e_rva(), 1);

        /* Create the new section */
        SgAsmGenericSection *tabsec = NULL;
        switch (i) {
            case 0: {
                /* Sometimes export sections are represented by a ".edata" section, and sometimes they're represented by an
                 * RVA/Size pair, and sometimes both point to the same part of the file. We don't want the exports duplicated
                 * in the AST, so we only create this table as exports if we haven't already seen some other export section. */
                SgAsmGenericSectionPtrList &sections = get_sections()->get_sections();
                bool seen_exports = false;
                for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_exports && si!=sections.end(); ++si)
                    seen_exports = isSgAsmPEExportSection(*si);
                if (seen_exports) {
                    tabsec = new SgAsmGenericSection(get_file(), this);
                } else {
                    tabsec = new SgAsmPEExportSection(this);
                }
                break;
            }
            case 1: {
                /* Sometimes import sections are represented by a ".idata" section, and sometimes they're represented by an
                 * RVA/Size pair, and sometimes both point to the same part of the file.  We don't want the imports duplicated
                 * in the AST, so we only create this table as imports if we haven't already seen some other import section. */
                SgAsmGenericSectionPtrList &sections = get_sections()->get_sections();
                bool seen_imports = false;
                for (SgAsmGenericSectionPtrList::iterator si=sections.begin(); !seen_imports && si!=sections.end(); ++si)
                    seen_imports = isSgAsmPEImportSection(*si);
                if (seen_imports) {
                    tabsec = new SgAsmGenericSection(get_file(), this);
                } else {
                    tabsec = new SgAsmPEImportSection(this);
                }
                break;
            }
            default: {
                tabsec = new SgAsmGenericSection(get_file(), this);
                break;
            }
        }
        tabsec->set_name(new SgAsmBasicString(tabname));
        tabsec->set_short_name(tabname_short);
        tabsec->set_synthesized(true);
        tabsec->set_purpose(SP_HEADER);

        tabsec->set_offset(file_offset);
        tabsec->set_size(pair->get_e_size());
        tabsec->set_file_alignment(1);

        tabsec->set_mapped_alignment(1);
        tabsec->set_mapped_preferred_rva(pair->get_e_rva().get_rva());
        tabsec->set_mapped_actual_va(pair->get_e_rva().get_rva()+get_base_va()); /*FIXME: not sure this is correct. [RPM 2009-09-11]*/
        tabsec->set_mapped_size(pair->get_e_size());
        tabsec->set_mapped_rperm(true);
        tabsec->set_mapped_wperm(false);
        tabsec->set_mapped_xperm(false);
        pair->set_section(tabsec);
        pair->set_e_rva(pair->get_e_rva().set_section(tabsec));
    }

    /* Now parse the sections */
    for (size_t i=0; i<p_rvasize_pairs->get_pairs().size(); i++) {
        SgAsmPERVASizePair *pair = p_rvasize_pairs->get_pairs()[i];
        SgAsmGenericSection *tabsec = pair->get_section();
        if (tabsec)
            tabsec->parse();
    }
}
Esempio n. 23
0
bool
virtualToPhysicalAddress(VirtualAddress virtualAddress,
                         PhysicalAddress &out)
{
   return sMemoryMap.virtualToPhysicalAddress(virtualAddress, out);
}
Esempio n. 24
0
bool
initialiseMemory()
{
   return sMemoryMap.reserve();
}
Esempio n. 25
0
static void ProcessMultibootInfo(multiboot_info const * const mbi)
{
    // Add multiboot data header
    g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, (uintptr_t)mbi, sizeof(*mbi));

    if (mbi->flags & MULTIBOOT_MEMORY_INFO)
    {
        // Add memory map itself
        g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, mbi->mmap_addr, mbi->mmap_length);

        const multiboot_mmap_entry* entry = (multiboot_mmap_entry*)mbi->mmap_addr;
        const multiboot_mmap_entry* end = (multiboot_mmap_entry*)(mbi->mmap_addr + mbi->mmap_length);

        while (entry < end)
        {
            MemoryType type;
            uint32_t flags;

            switch (entry->type)
            {
            case MULTIBOOT_MEMORY_AVAILABLE:
                type = MemoryType_Available;
                flags = 0;
                break;

            case MULTIBOOT_MEMORY_ACPI_RECLAIMABLE:
                type = MemoryType_AcpiReclaimable;
                flags = 0;
                break;

            case MULTIBOOT_MEMORY_NVS:
                type = MemoryType_AcpiNvs;
                flags = 0;
                break;

            case MULTIBOOT_MEMORY_BADRAM:
                type = MemoryType_Unusable;
                flags = 0;
                break;

            case MULTIBOOT_MEMORY_RESERVED:
            default:
                type = MemoryType_Reserved;
                flags = 0;
                break;
            }

            g_memoryMap.AddBytes(type, flags, entry->addr, entry->len);

            // Go to next entry
            entry = (multiboot_mmap_entry*) ((uintptr_t)entry + entry->size + sizeof(entry->size));
        }
    }
    else if (mbi->flags & MULTIBOOT_INFO_MEMORY)
    {
        g_memoryMap.AddBytes(MemoryType_Available, 0, 0, (uint64_t)mbi->mem_lower * 1024);
        g_memoryMap.AddBytes(MemoryType_Available, 0, 1024*1024, (uint64_t)mbi->mem_upper * 1024);
    }

    if (mbi->flags & MULTIBOOT_INFO_MODS)
    {
        const multiboot_module* modules = (multiboot_module*)mbi->mods_addr;

        for (uint32_t i = 0; i != mbi->mods_count; ++i)
        {
            const multiboot_module* module = &modules[i];

            if (strcmp(module->string, "initrd")==0)
            {
                g_bootInfo.initrdAddress = module->mod_start;
                g_bootInfo.initrdSize = module->mod_end - module->mod_start;
            }

            g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, module->mod_start, module->mod_end - module->mod_start);
        }
    }

    if (mbi->flags & MULTIBOOT_INFO_FRAMEBUFFER_INFO)
    {
        switch (mbi->framebuffer_type)
        {
        case MULTIBOOT_FRAMEBUFFER_TYPE_RGB:
            {
                const auto redMask = ((1 << mbi->framebuffer_red_mask_size) - 1) << mbi->framebuffer_red_field_position;
                const auto greenMask = ((1 << mbi->framebuffer_green_mask_size) - 1) << mbi->framebuffer_green_field_position;
                const auto blueMask = ((1 << mbi->framebuffer_blue_mask_size) - 1) << mbi->framebuffer_blue_field_position;
                const auto pixelMask = mbi->framebuffer_bpp < 32 ? (1 << mbi->framebuffer_bpp) - 1 : -1;
                const auto reservedMask = pixelMask ^ redMask ^ greenMask ^ blueMask;

                g_frameBuffer.width = mbi->framebuffer_width;
                g_frameBuffer.height = mbi->framebuffer_height;
                g_frameBuffer.pitch = mbi->framebuffer_pitch;
                g_frameBuffer.pixels = (void*)mbi->framebuffer_addr;
                g_frameBuffer.format = DeterminePixelFormat(redMask, greenMask, blueMask, reservedMask);
            }
            break;

        case MULTIBOOT_FRAMEBUFFER_TYPE_EGA_TEXT:
            {
                // OK to initialize VgaConsole here since it doesn't allocate any memory
                // g_vgaConsole.Initialize((void*)mbi->framebuffer_addr, mbi->framebuffer_width, mbi->framebuffer_height);
                // g_console = &g_vgaConsole;
            }
            break;
        }
    }
}
Esempio n. 26
0
void* AllocatePages(size_t pageCount, physaddr_t maxAddress)
{
    const physaddr_t memory = g_memoryMap.AllocatePages(MemoryType_Bootloader, pageCount, maxAddress);
    return memory == MEMORY_ALLOC_FAILED ? nullptr : (void*)memory;
}
Esempio n. 27
0
extern "C" void multiboot_main(unsigned int magic, void* mbi)
{
    // 0x00000000 - 0x000003FF - Interrupt Vector Table
    // 0x00000400 - 0x000004FF - BIOS Data Area (BDA)
    // 0x00000500 - 0x000005FF - ROM BASIC (still used / reclaimed by some BIOS)
    g_memoryMap.AddBytes(MemoryType_Bootloader, 0, 0, 0x600);

    // Process multiboot info
    bool gotMultibootInfo = false;

    // Add bootloader (ourself) to memory map
    extern const char ImageBase[];
    extern const char ImageEnd[];
    const physaddr_t start = (physaddr_t)&ImageBase;
    const physaddr_t end = (physaddr_t)&ImageEnd;
    g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, start, end - start);

    if (magic == MULTIBOOT_BOOTLOADER_MAGIC && mbi)
    {
        ProcessMultibootInfo(static_cast<multiboot_info*>(mbi));
        gotMultibootInfo = true;
    }
    else if (magic== MULTIBOOT2_BOOTLOADER_MAGIC && mbi)
    {
        ProcessMultibootInfo(static_cast<multiboot2_info*>(mbi));
        gotMultibootInfo = true;
    }

    // Now that the memory allocator is initialized, we can create GraphicsConsole
    if (gotMultibootInfo)
    {
        if (g_frameBuffer.format != PIXFMT_UNKNOWN)
        {
            g_graphicsConsole.Initialize(&g_frameBuffer);
            g_console = &g_graphicsConsole;

            Framebuffer* fb = &g_bootInfo.framebuffers[g_bootInfo.framebufferCount];

            fb->width = g_frameBuffer.width;
            fb->height = g_frameBuffer.height;
            fb->pitch = g_frameBuffer.pitch;
            fb->format = g_frameBuffer.format;
            fb->pixels = (uintptr_t)g_frameBuffer.pixels;

            g_bootInfo.framebufferCount += 1;

        }
        else if (!g_console)
        {
            // // Assume a standard VGA card at 0xB8000
            // g_vgaConsole.Initialize((void*)0x000B8000, 80, 25);
            // g_console = &g_vgaConsole;
        }
    }

    g_console->Rainbow();

    Log(" BIOS Bootloader (" STRINGIZE(KERNEL_ARCH) ")\n\n");

    if (gotMultibootInfo)
    {
        // InstallBiosTrampoline();

        // g_display.Initialize();

        // for (int i = 0; i != g_display.GetModeCount(); ++i)
        // {
        //     DisplayMode mode;
        //     g_display.GetMode(i, &mode);

        //     if (mode.format == PIXFMT_X8R8G8B8)
        //     {
        //         //Log("Mode %d: %d x %d - %d\n", i, mode.width, mode.height, mode.format);
        //     }
        // }

        // Boot!
        Boot((void*)g_bootInfo.initrdAddress, g_bootInfo.initrdSize);
    }
    else
    {
        Fatal(" No multiboot information!\n");
    }
}
Esempio n. 28
0
static void ProcessMultibootInfo(multiboot2_info const * const mbi)
{
     // Add multiboot data header
    g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, (uintptr_t)mbi, mbi->total_size);

    const multiboot2_tag_basic_meminfo* meminfo = NULL;
    const multiboot2_tag_mmap* mmap = NULL;

    for (multiboot2_tag* tag = (multiboot2_tag*)(mbi + 1);
         tag->type != MULTIBOOT2_TAG_TYPE_END;
         tag = (multiboot2_tag*) align_up((uintptr_t)tag + tag->size, MULTIBOOT2_TAG_ALIGN))
    {
        switch (tag->type)
        {
        case MULTIBOOT2_TAG_TYPE_BASIC_MEMINFO:
            meminfo = (multiboot2_tag_basic_meminfo*)tag;
            break;

        case MULTIBOOT2_TAG_TYPE_MMAP:
            mmap = (multiboot2_tag_mmap*)tag;
            break;

        case MULTIBOOT2_TAG_TYPE_MODULE:
            {
                const multiboot2_module* module = (multiboot2_module*)tag;

                if (strcmp(module->string, "initrd")==0)
                {
                    g_bootInfo.initrdAddress = module->mod_start;
                    g_bootInfo.initrdSize = module->mod_end - module->mod_start;
                }

                g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, module->mod_start, module->mod_end - module->mod_start);
            }
        break;

        case MULTIBOOT2_TAG_TYPE_FRAMEBUFFER:
            {
                const multiboot2_tag_framebuffer* mbi = (multiboot2_tag_framebuffer*)tag;

                switch (mbi->common.framebuffer_type)
                {
                case MULTIBOOT2_FRAMEBUFFER_TYPE_RGB:
                    {
                        const auto redMask = ((1 << mbi->framebuffer_red_mask_size) - 1) << mbi->framebuffer_red_field_position;
                        const auto greenMask = ((1 << mbi->framebuffer_green_mask_size) - 1) << mbi->framebuffer_green_field_position;
                        const auto blueMask = ((1 << mbi->framebuffer_blue_mask_size) - 1) << mbi->framebuffer_blue_field_position;
                        const auto pixelMask = mbi->common.framebuffer_bpp < 32 ? (1 << mbi->common.framebuffer_bpp) - 1 : -1;
                        const auto reservedMask = pixelMask ^ redMask ^ greenMask ^ blueMask;

                        g_frameBuffer.width = mbi->common.framebuffer_width;
                        g_frameBuffer.height = mbi->common.framebuffer_height;
                        g_frameBuffer.pitch = mbi->common.framebuffer_pitch;
                        g_frameBuffer.pixels = (void*)mbi->common.framebuffer_addr;
                        g_frameBuffer.format = DeterminePixelFormat(redMask, greenMask, blueMask, reservedMask);
                    }
                    break;

                case MULTIBOOT2_FRAMEBUFFER_TYPE_EGA_TEXT:
                    {
                        // OK to initialize VgaConsole here since it doesn't allocate any memory
                        // g_vgaConsole.Initialize((void*)mbi->common.framebuffer_addr, mbi->common.framebuffer_width, mbi->common.framebuffer_height);
                        // g_console = &g_vgaConsole;
                    }
                    break;
                }
            }
            break;
        }
    }

    if (mmap)
    {
        // Add memory map itself
        g_memoryMap.AddBytes(MemoryType_Bootloader, MemoryFlag_ReadOnly, (uintptr_t)mmap->entries, mmap->size);

        const multiboot2_mmap_entry* entry = mmap->entries;
        const multiboot2_mmap_entry* end = (multiboot2_mmap_entry*) ((uintptr_t)mmap + mmap->size);

        while (entry < end)
        {
            MemoryType type;
            uint32_t flags;

            switch (entry->type)
            {
            case MULTIBOOT2_MEMORY_AVAILABLE:
                type = MemoryType_Available;
                flags = 0;
                break;

            case MULTIBOOT2_MEMORY_ACPI_RECLAIMABLE:
                type = MemoryType_AcpiReclaimable;
                flags = 0;
                break;

            case MULTIBOOT2_MEMORY_NVS:
                type = MemoryType_AcpiNvs;
                flags = 0;
                break;

            case MULTIBOOT2_MEMORY_BADRAM:
                type = MemoryType_Unusable;
                flags = 0;
                break;

            case MULTIBOOT2_MEMORY_RESERVED:
            default:
                type = MemoryType_Reserved;
                flags = 0;
                break;
            }

            g_memoryMap.AddBytes(type, flags, entry->addr, entry->len);

            // Go to next entry
            entry = (multiboot2_mmap_entry*) ((uintptr_t)entry + mmap->entry_size);
        }
    }
    else if (meminfo)
    {
        g_memoryMap.AddBytes(MemoryType_Available, 0, 0, (uint64_t)meminfo->mem_lower * 1024);
        g_memoryMap.AddBytes(MemoryType_Available, 0, 1024*1024, (uint64_t)meminfo->mem_upper * 1024);
    }
}
Esempio n. 29
0
	MemoryCacheLayer(CachePolicy *policy, CacheLayer *tryNext)
			: CacheLayer(tryNext),
			mData(NULL, policy) {
		mData.setOwner(this);//to avoid warning in visual studio
	}
static inline bool
isGoodAddr(const std::set<rose_addr_t> &goodVas, const MemoryMap &map, rose_addr_t va) {
    return !map.at(va).exists() || goodVas.find(va)!=goodVas.end();
}