Revision: 2000
Author:
vo...@in.tum.de
Date: Thu Jul 11 00:43:25 2013
Log: Detect now prints some statistics about func pointer.
http://code.google.com/p/insight-vmi/source/detail?r=2000
Modified:
/trunk/libinsight/detect.cpp
/trunk/libinsight/include/insight/detect.h
=======================================
--- /trunk/libinsight/detect.cpp Wed Jul 10 04:14:19 2013
+++ /trunk/libinsight/detect.cpp Thu Jul 11 00:43:25 2013
@@ -18,7 +18,7 @@
Detect::Detect(KernelSymbols &sym) :
_kernel_code_begin(0), _kernel_code_end(0), _kernel_data_exec_end(0),
- _vsyscall_page(0), ExecutableSections(0), _sym(sym)
+ _vsyscall_page(0), ExecutableSections(0), Functions(0), _sym(sym)
{
// Get data from System.map
_kernel_code_begin = _sym.memSpecs().systemMap.value("_text").address;
@@ -319,13 +319,88 @@
delete(ExecutablePages);
ExecutablePages = current;
}
+
+void Detect::buildFunctionList(MemoryMap *map)
+{
+ if (Functions)
+ Functions->clear();
+ else
+ Functions = new QMultiHash<quint64, const Function *>();
+
+ NodeList roots = map->roots();
+
+ for (int i = 0; i < roots.size(); ++i) {
+ if (
roots.at(i)->type()->type() == rtFunction) {
+ const Function* f = dynamic_cast<const
Function*>(
roots.at(i)->type());
+
+ if (f)
+ Functions->insert(f->pcLow(), f);
+ }
+ }
+}
+
+bool Detect::pointsToKernelFunction(MemoryMap *map, Instance &funcPointer)
+{
+ if (!Functions)
+ buildFunctionList(map);
+
+ if (Functions->contains((quint64)funcPointer.toPointer()))
+ return true;
+
+ return false;
+}
+
+void Detect::verifyFunctionPointer(MemoryMap *map, Instance &funcPointer,
+ FunctionPointerStats &stats)
+{
+ // Target
+ quint64 pointsTo = (quint64)funcPointer.toPointer();
+
+ // Increase total count
+ stats.total++;
+
+ // Verify the function pointer and gather statistics
+ if (MemoryMapHeuristics::isUserLandAddress(pointsTo, _sym.memSpecs()))
{
+ // Function Pointer points to userland
+ stats.userlandPointer++;
+ return;
+ }
+
+ if (MemoryMapHeuristics::isDefaultValue(pointsTo, _sym.memSpecs())) {
+ // Function pointer points to a default value
+ stats.defaultValue++;
+ return;
+ }
+
+ if (!MemoryMapHeuristics::isValidAddress(pointsTo, _sym.memSpecs())) {
+ // Function pointer points to an invalid address
+ stats.invalidAddress++;
+ return;
+ }
+
+ // For NX
+ struct PageTableEntries ptEntries;
+ int pageSize = 0;
+ map->vmem()->virtualToPhysical(pointsTo, &pageSize, false, &ptEntries);
+
+ if (!ptEntries.isExecutable()) {
+ // Points to is not executeable
+ stats.pointToNXMemory++;
+ return;
+ }
+
+ if (!pointsToKernelFunction(map, funcPointer)) {
+ stats.pointsNotToKernelFunction++;
+ return;
+ }
+}
void Detect::verifyFunctionPointers(MemoryMap *map)
{
assert(map);
- quint64 validPointers = 0;
- quint64 invalidPointers = 0;
+ // Statistics
+ FunctionPointerStats stats;
const QList<FuncPointersInNode> funcPointers = map->funcPointers();
@@ -366,10 +441,7 @@
}
// Verify Function Pointer
- if
(!MemoryMapHeuristics::isValidFunctionPointer(funcPointer))
- invalidPointers++;
- else
- validPointers++;
+ verifyFunctionPointer(map, funcPointer, stats);
}
}
else {
@@ -382,10 +454,7 @@
}
// Verify Function Pointer
- if (!MemoryMapHeuristics::isValidFunctionPointer(node))
- invalidPointers++;
- else
- validPointers++;
+ verifyFunctionPointer(map, node, stats);
}
}
@@ -395,10 +464,28 @@
// Print Stats
Console::out() << "\r\nProcessed " << Console::color(ctWarningLight)
- << invalidPointers+validPointers <<
Console::color(ctReset)
+ << stats.total << Console::color(ctReset)
<< " Function Pointers in " << elapsedTime() << " min"
<< endl;
+ Console::out() << "\t Found " << Console::color(ctNumber)
+ << stats.userlandPointer << Console::color(ctReset)
<< " userland pointer." << endl;
+ Console::out() << "\t Found " << Console::color(ctNumber)
+ << stats.defaultValue << Console::color(ctReset) << "
pointer with default values." << endl;
+ Console::out() << "\t Found " << Console::color(ctNumber)
+ << stats.total - (stats.userlandPointer +
stats.defaultValue + stats.invalidAddress +
+ stats.pointToNXMemory +
stats.pointsNotToKernelFunction)
+ << Console::color(ctReset) << " point to the beginning
of a function within kernelspace." << endl;
Console::out() << "\t Detected " << Console::color(ctError)
- << invalidPointers << Console::color(ctReset) << "
invalid Function Pointers.\n" << endl;
+ << stats.invalidAddress + stats.pointToNXMemory +
stats.pointsNotToKernelFunction
+ << Console::color(ctReset) << " invalid Function
Pointers." << endl;
+ Console::out() << "\t\t " << Console::color(ctError)
+ << stats.invalidAddress
+ << Console::color(ctReset) << " point to an invalid
address." << endl;
+ Console::out() << "\t\t " << Console::color(ctError)
+ << stats.pointToNXMemory
+ << Console::color(ctReset) << " point to a NX region."
<< endl;
+ Console::out() << "\t\t " << Console::color(ctError)
+ << stats.pointsNotToKernelFunction
+ << Console::color(ctReset) << " point NOT to the
beginning of a kernel function.\n" << endl;
}
=======================================
--- /trunk/libinsight/include/insight/detect.h Wed Jul 10 04:14:19 2013
+++ /trunk/libinsight/include/insight/detect.h Thu Jul 11 00:43:25 2013
@@ -2,6 +2,7 @@
#define DETECT_H
#include "kernelsymbols.h"
+#include "function.h"
class Detect : public LongOperation
{
@@ -45,6 +46,24 @@
QByteArray data;
};
+ struct FunctionPointerStats
+ {
+ FunctionPointerStats() : total(0), userlandPointer(0),
defaultValue(0),
+ invalidAddress(0), pointToNXMemory(0),
pointsNotToKernelFunction(0) {}
+
+ // Convenient
+ quint64 total;
+
+ // Valid
+ quint64 userlandPointer;
+ quint64 defaultValue;
+
+ // Invalid
+ quint64 invalidAddress;
+ quint64 pointToNXMemory;
+ quint64 pointsNotToKernelFunction;
+ };
+
Detect(KernelSymbols &sym);
void hiddenCode(int index);
@@ -62,14 +81,19 @@
QString _current_file;
QMultiHash<QString, ExecutableSection> *ExecutableSections;
+ QMultiHash<quint64, const Function *> *Functions;
- KernelSymbols &_sym;
+ const KernelSymbols &_sym;
static QMultiHash<quint64, ExecutablePage> *ExecutablePages;
void getExecutableSections(QString file);
quint64 inVmap(quint64 address, VirtualMemory *vmem);
void verifyHashes(QMultiHash<quint64, ExecutablePage> *current);
+ void buildFunctionList(MemoryMap *map);
+ bool pointsToKernelFunction(MemoryMap *map, Instance &funcPointer);
+ void verifyFunctionPointer(MemoryMap *map, Instance &funcPointer,
+ FunctionPointerStats &stats);
void verifyFunctionPointers(MemoryMap *map);
};