Пример #1
0
 bool operator()(const MemoryMap::Super &map, const AddressInterval &interval) {
     rose_addr_t va = interval.least();
     while (va <= interval.greatest()) {
         uint8_t byte;
         map.at(va).limit(1).read(&byte);
         if (!self->isAsciiCharacter(byte))
             return false;
         ++nBytes;
         if (va == interval.greatest())
             return true;                            // prevent overflow
         ++va;
     }
     return true;
 }
Пример #2
0
/** Returns a list of parts of a single section that have been referenced.  The offsets are relative to the start of the
 *  section. */
AddressIntervalSet
SgAsmGenericSection::get_referenced_extents() const
{
    if (0==get_size())
        return AddressIntervalSet();

    AddressIntervalSet retval;
    AddressInterval segment = AddressInterval::baseSize(get_offset(), get_size());
    const AddressIntervalSet &fileExtents = get_file()->get_referenced_extents();
    BOOST_FOREACH (const AddressInterval &interval, fileExtents.intervals()) {
        if (segment.isContaining(interval)) {
            retval.insert(AddressInterval::baseSize(interval.least()-get_offset(), interval.size()));
        } else if (interval.isLeftOf(segment) || interval.isRightOf(segment)) {
            // no overlap
        } else if (interval.isContaining(segment)) {
            retval.insert(AddressInterval::baseSize(0, get_size()));
            break;                                      // no point in continuing since we've referenced whole segment now
        } else if (interval.least() < segment.least()) {
            retval.insert(AddressInterval::baseSize(0, interval.least()+interval.size()-get_offset()));
        } else if (interval.greatest() > segment.greatest()) {
            retval.insert(AddressInterval::baseSize(interval.least()-get_offset(), get_offset()+get_size()-interval.least()));
        } else {
            ASSERT_not_reachable("invalid extent overlap category");
        }
    }
    return retval;
}
Пример #3
0
Sawyer::Optional<rose_addr_t>
MemoryMap::findAny(const AddressInterval &limits, const std::vector<uint8_t> &bytesToFind,
                   unsigned requiredPerms, unsigned prohibitedPerms) const
{
    if (!limits || bytesToFind.empty())
        return Sawyer::Nothing();

    // Read a bunch of bytes at a time.  If the buffer size is large then we'll have fewer read calls before finding a match,
    // which is good if a match is unlikely.  But if a match is likely, then it's better to use a smaller buffer so we don't
    // ready more than necessary to find a match.  We'll compromise by starting with a small buffer that grows up to some
    // limit.
    size_t nremaining = limits.size();                  // bytes remaining to search (could be zero if limits is universe)
    size_t bufsize = 8;                                 // initial buffer size
    uint8_t buffer[4096];                               // full buffer

    Sawyer::Optional<rose_addr_t> atVa = this->at(limits.least()).require(requiredPerms).prohibit(prohibitedPerms).next();
    while (atVa && *atVa <= limits.greatest()) {
        if (nremaining > 0)                             // zero implies entire address space
            bufsize = std::min(bufsize, nremaining);
        size_t nread = at(*atVa).limit(bufsize).require(requiredPerms).prohibit(prohibitedPerms).read(buffer).size();
        assert(nread > 0);                              // because of the next() calls
        for (size_t offset=0; offset<nread; ++offset) {
            if (std::find(bytesToFind.begin(), bytesToFind.end(), buffer[offset]) != bytesToFind.end())
                return *atVa + offset;                  // found
        }
        atVa = at(*atVa+nread).require(requiredPerms).prohibit(prohibitedPerms).next();
        bufsize = std::min(2*bufsize, sizeof buffer);   // use a larger buffer next time if possible
        nremaining -= nread;                            // ok if nremaining is already zero
    }

    return Sawyer::Nothing();
}
Пример #4
0
 bool operator()(const MemoryMap::Super &map, const AddressInterval &interval) {
     rose_addr_t va = interval.least();
     if (startVa + nChars != va)
         nChars = 0;
     while (va <= interval.greatest()) {
         uint8_t byte;
         map.at(va).limit(1).read(&byte);
         if (self->isAsciiCharacter(byte)) {
             if (1 == ++nChars)
                 startVa = va;
             if (nChars >= minChars)
                 return false;
         } else {
             nChars = 0;
         }
         if (va == interval.greatest())
             return true;                            // prevent overflow
         ++va;
     }
     return true;
 }
Пример #5
0
int
main(int argc, char *argv[]) {
    ROSE_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::Ptr 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
        }
    }
}
Пример #6
0
void
MemoryMap::eraseZeros(size_t minsize)
{
    if (isEmpty())
        return;
    unsigned permissions = READABLE | EXECUTABLE;       // access permissions that must be present
    AddressIntervalSet toRemove;                        // to save up intervals until we're done iterating
    AddressInterval zeroInterval;
    uint8_t buf[8192];
    rose_addr_t va = hull().least();
    while (AddressInterval accessed = atOrAfter(va).require(permissions).limit(sizeof buf).read(buf)) {
        for (size_t offset=0; offset<accessed.size(); ++offset) {
            if (0 == buf[offset]) {
                if (zeroInterval.isEmpty()) {
                    zeroInterval = AddressInterval(accessed.least()+offset);
                } else if (zeroInterval.greatest()+1 < offset) {
                    if (zeroInterval.size() >= minsize)
                        toRemove.insert(zeroInterval);
                    zeroInterval = AddressInterval(accessed.least()+offset);
                } else {
                    zeroInterval = AddressInterval::hull(zeroInterval.least(), zeroInterval.greatest()+1);
                }
            } else if (!zeroInterval.isEmpty()) {
                if (zeroInterval.size() >= minsize)
                    toRemove.insert(zeroInterval);
                zeroInterval = AddressInterval();
            }
        }
        if (accessed.greatest() == hull().greatest())
            break;                                      // prevent overflow in next statement
        va += accessed.size();
    }
    if (zeroInterval.size() >= minsize)
        toRemove.insert(zeroInterval);
    BOOST_FOREACH (const AddressInterval &interval, toRemove.intervals())
        erase(interval);
}
Пример #7
0
Extent toExtent(const AddressInterval &x) {
    return x.isEmpty() ? Extent() : Extent::inin(x.least(), x.greatest());
}