Ejemplo n.º 1
0
QStringList MemoryMap::loadedKernelModules()
{
    QStringList ret;
    const MemoryDump* mem = _symbols->memDumps().at(_vmem->memDumpIndex());
    Instance modules = mem->queryInstance("modules", ksNone);
    const Structured* module_t = dynamic_cast<const Structured*>(
                factory()->findBaseTypeByName("module"));

    if (modules.isValid() && module_t) {
        // First module in the list
        Instance m = modules.member("next", BaseType::trAny, 1, ksNone);
        qint64 offset = -module_t->memberOffset("list");
        // Go through linked list and add all module names
        while (m.isValid() && m.address() != modules.address()) {
            m.setType(module_t);
            m.addToAddress(offset);
            QString name = m.member("name").toString();
            if (!name.isEmpty()) {
                // Get rid of quotes
                if (name.startsWith('"'))
                    name = name.mid(1, name.size() - 2);
                // Module binaries use dashes, the names use underscores
                name.replace('_', "-");
                ret += name + ".ko";
            }
            m = m.member("list").member("next", BaseType::trAny, 1, ksNone);
        }
    }

    return ret;
}
Ejemplo n.º 2
0
QVector<quint64> MemoryMap::perCpuOffsets()
{
    // Get all the data that we need to handle per_cpu variables.
    quint32 nr_cpus = 1;

    // Get the number of cpus from the dump if possible
    Variable *var = factory()->findVarByName("nr_cpu_ids");
    if (var != 0)
        nr_cpus = var->value<quint32>(_vmem);

    // Get the per_cpu offsets
    QVector<quint64> per_cpu_offset(nr_cpus, 0);

    // Get the variable
    var = factory()->findVarByName("__per_cpu_offset");
    Instance inst = var ?
                var->toInstance(_vmem, BaseType::trLexical, ksNone) :
                Instance();
    // Fill the array
    for (quint32 i = 0; i < nr_cpus; ++i) {
        if (!inst.isNull()) {
            per_cpu_offset[i] = inst.toULong();
            // Go to next array field
            inst.addToAddress(_vmem->memSpecs().sizeofLong);
        }
        else
            per_cpu_offset[i] = -1ULL;
    }

    return per_cpu_offset;

}
Ejemplo n.º 3
0
void MemoryMap::addVariableWithCandidates(const Variable *var)
{
    // Check manually: Is this a per_cpu variable?
    if (var->name().startsWith("per_cpu__")) {

        // Dereference the variable for each cpu
        for (int i = 0; i < _perCpuOffset.size(); i++) {
            Instance inst = var->toInstance(_vmem, BaseType::trLexical, ksNone);

            // Add offset
            if (!inst.isNull() && _perCpuOffset[i] != -1ULL)
                inst.addToAddress(_perCpuOffset[i]);

            addVarInstance(inst);
        }
    }
    else {
        addVarInstance(var->toInstance(_vmem, BaseType::trLexical, _knowSrc));
    }
}
Ejemplo n.º 4
0
Instance MemoryDump::getNextInstance(const QString& component,
									 const Instance& instance,
									 KnowledgeSources src) const
{
	Instance result;
	QString typeString, symbol, offsetString, candidate, arrayIndexString;
	bool okay;
//    quint32 compatibleCnt = 0;

	// A component should have the form (symbol(-offset)?)?symbol(<candidate>)?([index])?
#define SYMBOL "[A-Za-z0-9_]+"
#define NUMBER "\\d+"
	QRegExp re(
				"^\\s*(?:"
					"\\(\\s*"
						"(" SYMBOL ")"
						"(?:"
							"\\s*-\\s*(" SYMBOL ")"
						")?"
					"\\s*\\)"
				")?"
				"\\s*(" SYMBOL ")\\s*"
				"(?:<\\s*(" NUMBER ")\\s*>\\s*)?"
				"((?:\\[\\s*" NUMBER "\\s*\\]\\s*)*)\\s*");
	 
	if (!re.exactMatch(component)) {
		queryError(QString("Could not parse a part of the query string: %1")
		            .arg(component));
    }
	
	// Set variables according to the matching
	typeString = re.cap(1);
	offsetString = re.cap(2).trimmed();
	symbol = re.cap(3);
	candidate = re.cap(4);
	arrayIndexString = re.cap(5).trimmed();

	int candidateIndex = candidate.isEmpty() ? -1 : candidate.toInt();

//	debugmsg(QString("1: %1, 2: %2, 3: %3, 4: %4, 5: %5")
//			 .arg(re.cap(1))
//			 .arg(re.cap(2))
//			 .arg(re.cap(3))
//			 .arg(re.cap(4))
//			 .arg(re.cap(5)));

	// A candidate index of 0 means to ignore the alternative types
	if (candidateIndex == 0)
		src = static_cast<KnowledgeSources>(src|ksNoAltTypes);

	// If the given instance is Null, we interpret this as the first component
	// in the query string and will therefore try to resolve the variable.
	if (!instance.isValid()) {
		 Variable* v = _factory->findVarByName(symbol);

		if (!v)
			queryError(QString("Variable does not exist: %1").arg(symbol));

		if (candidateIndex > 0) {
			if (v->altRefTypeCount() < candidateIndex)
				queryError(QString("Variable \"%1\" does not have a candidate "
								   "with index %2")
							.arg(symbol)
							.arg(candidateIndex));
			result = v->altRefTypeInstance(_vmem, candidateIndex - 1);
		}
		else {
			result = v->toInstance(_vmem, BaseType::trLexical, src);
		}
	}
	else {
		// Dereference any pointers/arrays first
		result = instance.dereference(BaseType::trAnyNonNull);

		// Did we get a null instance?
		if (!(result.type()->type() & StructOrUnion) &&
			(result.isNull() || !result.toPointer()))
			queryError(QString("Member \"%1\" is null")
					   .arg(result.fullName()));
		// We have a instance therefore we resolve the member
		if (!(result.type()->type() & StructOrUnion))
            queryError(QString("Member \"%1\" is not a struct or union")
                        .arg(result.fullName()));

        if (!result.memberExists(symbol))
            queryError(QString("Struct \"%1\" has no member named \"%2\"")
                        .arg(result.typeName())
                        .arg(symbol));

        // Do we have a candidate index?
        if (candidateIndex > 0) {
            if (result.memberCandidatesCount(symbol) < candidateIndex)
                queryError(QString("Member \"%1\" does not have a candidate "
                                   "with index %2")
                            .arg(symbol)
                            .arg(candidateIndex));
            result = result.memberCandidate(symbol, candidateIndex - 1);
        }
        else {
            result = result.member(symbol, BaseType::trLexical, 0, src);
        }
	}

	if (!result.isValid())
		return result;
	
	// Cast the instance if necessary
	if (!typeString.isEmpty()) {
		quint32 offset = 0;
		// Is a offset given?
		if (!offsetString.isEmpty()) {
			// Is the offset given as string or as int?
			offset = offsetString.toUInt(&okay, 10);
			
			if (!okay) {
				// String.
				BaseType* type = getType(typeString);
				
				if (!type ||
					!(type->type() & StructOrUnion))
					queryError(QString("The given type \"%1\" is not a struct "
					            "or union and therefore has no offset")
					            .arg(typeString));
				
				Structured* structd = dynamic_cast<Structured *>(type);
				
				if (!structd->memberExists(offsetString)) {
					queryError(QString("Struct of type \"%1\" has no member "
					            "named \"%2\"")
								.arg(typeString)
								.arg(offsetString));
				}
				else {
					StructuredMember* structdMember =
							structd->member(offsetString);
					offset = structdMember->offset();
				}
			}
		}

		// Get address
		size_t address;
		if (result.type()->type() & (rtPointer))
			address = (size_t)result.toPointer() - offset;
		else
			address = result.address() - offset;
		
		result = getInstanceAt(typeString, address, result.fullNameComponents());
	}
	
	// Add array index
	if (!arrayIndexString.isEmpty()) {
		QRegExp reArrayIndex("\\[\\s*(" NUMBER ")\\s*\\]\\s*");
		QStringList matches;
		int strpos = 0;
		while (strpos < arrayIndexString.size() &&
			   (strpos = arrayIndexString.indexOf(reArrayIndex, strpos)) >= 0)
		{
			matches.append(reArrayIndex.cap(1));
			strpos += reArrayIndex.cap(0).size();
		}

		for (int i = 0; i < matches.count(); ++i) {
			quint32 arrayIndex = matches[i].toUInt(&okay, 10);

			if (okay) {
				// Is the result already an instance list?
				if (result.isList()) {
					InstanceList list(result.toList());
					if (arrayIndex < (quint32)list.size())
						result = list[arrayIndex];
					else
						queryError(QString("Given array index %1 is out of bounds.")
								   .arg(arrayIndex));
				}
				else {
					// Is this a pointer or an array type?
					Instance tmp = result.arrayElem(arrayIndex);
					if (!tmp.isNull())
						result = tmp.dereference(BaseType::trLexical);
					// Manually update the address
					else {
						result.addToAddress(arrayIndex * result.type()->size());
						result.setName(QString("%1[%2]").arg(result.name()).arg(arrayIndex));
					}
				}
			}
			else {
				queryError(QString("Given array index %1 could not be converted "
								   "to a number.")
						   .arg(matches[i]));
			}
		}
		
	}
	// Try to dereference this instance as deep as possible
	return result.dereference(BaseType::trLexicalAndPointers);
}