Browse Source

Implemented AI based "saccades" engine to improve scanning efficiency. The Saccades engine borrows from vision systems research and allows SNF to learn important message structures and adapt it's scanning technique in real-time. Using this engine SNF can often avoid scanning large portions of each message without missing important content resulting in potentially 10 fold improvements in scanner efficiency.

git-svn-id: https://svn.microneil.com/svn/SNFMulti/trunk@53 dc71a809-1921-45c4-985c-09c81d0142d9
wx
madscientist 11 years ago
parent
commit
48babc91c7
4 changed files with 148 additions and 18 deletions
  1. 67
    7
      SNFMulti.cpp
  2. 38
    6
      SNFMulti.hpp
  3. 33
    2
      snf_engine.cpp
  4. 10
    3
      snf_engine.hpp

+ 67
- 7
SNFMulti.cpp View File

#include <cstdlib> #include <cstdlib>


#include <sstream> #include <sstream>
#include "SNFMulti.hpp"
#include "SNFMulti.hpp"
#include "snf_saccades.hpp"

#include "../CodeDweller/timing.hpp" #include "../CodeDweller/timing.hpp"


//#include "../nvwa-0.6/nvwa/debug_new.h" //#include "../nvwa-0.6/nvwa/debug_new.h"


//// Version Info //// Version Info


const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.0.24 Build: " __DATE__ " " __TIME__;
const char* SNF_ENGINE_VERSION = "SNFMulti Engine Version 3.1.0 Build: " __DATE__ " " __TIME__;


//// Script Caller Methods //// Script Caller Methods


M.index = R->MatchStartPosition; M.index = R->MatchStartPosition;
M.endex = R->MatchEndPosition; M.endex = R->MatchEndPosition;
} }

void snf_SaccadesHandler::applySaccades(EvaluationMatrix* Scanner, vector<unsigned char>& Data) {
if(NULL == Scanner) return;
bool isTimeToPeek = (0 >= TimeToPeekCounter);
if(isTimeToPeek) {
TimeToPeekCounter = TimeToPeekReset;
return;
} else {
--TimeToPeekCounter;
}
vector<saccade> Saccades = grabSaccades();
for(vector<saccade>::iterator i = Saccades.begin(); i != Saccades.end(); i++) {
const saccade& s = (*i);
if(s.start >= Data.size()) break;
Scanner->evaluateSegment(Data, s.start, s.finish);
}
}
bool isLearnableMatch(MatchRecord* m) {
bool isGoodSymbol = (0 <= m->RuleGroup() && 64 > m->RuleGroup());
bool isBeyondAlwaysScan = (snf_SaccadesHandler::AlwaysScanLength < m->MatchEndPosition);
return (isGoodSymbol && isBeyondAlwaysScan);
}
void snf_SaccadesHandler::learnMatches(MatchRecord* Matches) {
if(NULL == Matches) return;
vector<saccade> MatchesToLearn;
saccade WatchForHeaderWhiteRules(0, AlwaysScanLength);
MatchesToLearn.push_back(WatchForHeaderWhiteRules);
for(MatchRecord* m = Matches; NULL != m; m = m->NextMatchRecord) {
if(isLearnableMatch(m)) {
MatchesToLearn.push_back(
saccade(
m->MatchStartPosition,
m->MatchEndPosition)
);
}
}
if(0 < MatchesToLearn.size()) {
lockAndLearn(MatchesToLearn);
}
}
static snf_SaccadesHandler SaccadeBrain;
int snf_EngineHandler::scanMessage( // Scan this message (in buffer). int snf_EngineHandler::scanMessage( // Scan this message (in buffer).
const unsigned char* inputMessageBuffer, // -- this is the message buffer. const unsigned char* inputMessageBuffer, // -- this is the message buffer.
const int inputMessageLength, // -- this is the length of the buffer. const int inputMessageLength, // -- this is the length of the buffer.
DebugInfo = "scanMessage() EvaluateThis(FilteredData)"; // If we panic, here we are. DebugInfo = "scanMessage() EvaluateThis(FilteredData)"; // If we panic, here we are.
if(false == MyScanData.GBUdbTruncateExecuted) { // If we haven't already truncated: if(false == MyScanData.GBUdbTruncateExecuted) { // If we haven't already truncated:
for(int a = 0, b = MyScanData.FilteredData.size(); a < b; a++) // Scan through the filtered data one
CurrentMatrix->EvaluateThis(MyScanData.FilteredData[a]); // byte at a time.
//for(int a = 0, b = MyScanData.FilteredData.size(); a < b; a++) // Scan through the filtered data one
// CurrentMatrix->EvaluateThis(MyScanData.FilteredData[a]); // byte at a time.
unsigned int fullLength = MyScanData.FilteredData.size();
SaccadeBrain.applySaccades(CurrentMatrix, MyScanData.FilteredData);
bool messageNotRecognized = (NULL == CurrentMatrix->ResultList);
if(messageNotRecognized) {
CurrentMatrix->evaluateSegment(MyScanData.FilteredData, 0, fullLength);
SaccadeBrain.learnMatches(CurrentMatrix->ResultList);
}
} }


DebugInfo = "scanMessage() Scan Data Complete"; // If we panic, here we are. DebugInfo = "scanMessage() Scan Data Complete"; // If we panic, here we are.
int S = NO_SYMBOL; // so we start there and work down. int S = NO_SYMBOL; // so we start there and work down.


snf_match TmpSNFMatch; // We'll need a buffer for our matches. snf_match TmpSNFMatch; // We'll need a buffer for our matches.
while(NULL!=ResultCursor) { // While we have records to process... while(NULL!=ResultCursor) { // While we have records to process...
captureMatchRecord(TmpSNFMatch, ResultCursor); // grab the next record and evaluate it. captureMatchRecord(TmpSNFMatch, ResultCursor); // grab the next record and evaluate it.
ResultsCount++; ResultsCount++;
ResultCursor=ResultCursor->NextMatchRecord; ResultCursor=ResultCursor->NextMatchRecord;
} }
if(NO_SYMBOL != S) { // If a pattern match was detected then if(NO_SYMBOL != S) { // If a pattern match was detected then
MyScanData.PatternWasFound = true; // trip the flag and record the MyScanData.PatternWasFound = true; // trip the flag and record the
MyScanData.PatternID = FinalResult->RuleId(); // Rule ID and the MyScanData.PatternID = FinalResult->RuleId(); // Rule ID and the

+ 38
- 6
SNFMulti.hpp View File

#include "snfLOGmgr.hpp" #include "snfLOGmgr.hpp"
#include "snfNETmgr.hpp" #include "snfNETmgr.hpp"
#include "snfGBUdbmgr.hpp" #include "snfGBUdbmgr.hpp"
#include "snfXCImgr.hpp"

#include "snfXCImgr.hpp"
#include "snf_saccades.hpp"
#include <cassert> #include <cassert>


extern const char* SNF_ENGINE_VERSION; extern const char* SNF_ENGINE_VERSION;
snfXCIServerCommandHandler* myXCIServerCommandHandler; // ptr to Installed Srv Cmd Handler. snfXCIServerCommandHandler* myXCIServerCommandHandler; // ptr to Installed Srv Cmd Handler.


void grab(snfCFGPacket& CP); // Activate this Rulebase for a scan. void grab(snfCFGPacket& CP); // Activate this Rulebase for a scan.
void drop(snfCFGPacket& CP); // Deactiveate this Rulebase after it.
void drop(snfCFGPacket& CP); // Deactiveate this Rulebase after it.
public: public:


class ConfigurationError : public runtime_error { // When the configuration won't load. class ConfigurationError : public runtime_error { // When the configuration won't load.
RetiringCount(0), RetiringCount(0),
RefreshInProgress(false), RefreshInProgress(false),
MyGeneration(0), MyGeneration(0),
myXCIServerCommandHandler(0) {
myXCIServerCommandHandler(0){
MyNETmgr.linkLOGmgr(MyLOGmgr); // Link the NET manager to the LOGmgr. MyNETmgr.linkLOGmgr(MyLOGmgr); // Link the NET manager to the LOGmgr.
MyNETmgr.linkGBUdbmgr(MyGBUdbmgr); // Link the NET manager to the GBUdbmgr. MyNETmgr.linkGBUdbmgr(MyGBUdbmgr); // Link the NET manager to the GBUdbmgr.
MyGBUdbmgr.linkGBUdb(MyGBUdb); // Link the GBUdb manager to it's db. MyGBUdbmgr.linkGBUdb(MyGBUdb); // Link the GBUdb manager to it's db.
string EngineVersion(); // Get engine version info. string EngineVersion(); // Get engine version info.


void XCIServerCommandHandler(snfXCIServerCommandHandler& XCH); // Registers a new XCI Srvr Cmd handler. void XCIServerCommandHandler(snfXCIServerCommandHandler& XCH); // Registers a new XCI Srvr Cmd handler.
string processXCIServerCommandRequest(snf_xci& X); // Handle a parsed XCI Srvr Cmd request.
string processXCIServerCommandRequest(snf_xci& X); // Handle a parsed XCI Srvr Cmd request.
}; };


// IPTestEngine w/ GBUdb interface. // IPTestEngine w/ GBUdb interface.


string& test(string& input, string& output); // Our obligatory test function. string& test(string& input, string& output); // Our obligatory test function.
}; };
class snf_SaccadesHandler {
private:
Mutex MyMutex;
saccades_engine MyEngine;
void lockAndLearn(vector<saccade>& Matches) {
ScopeMutex SafetyFirst(MyMutex);
MyEngine.learn(Matches);
}
vector<saccade> grabSaccades() {
ScopeMutex SafetyFirst(MyMutex);
return MyEngine.recall();
}
int TimeToPeekCounter;
static const int TimeToPeekReset = 32;
public:
static const int AlwaysScanLength = 2048;
snf_SaccadesHandler() :
MyEngine(128),
TimeToPeekCounter(0) {}
void applySaccades(EvaluationMatrix* Scanner, vector<unsigned char>& Data);
void learnMatches(MatchRecord* Matches);
};


// Here's where we pull it all together. // Here's where we pull it all together.



+ 33
- 2
snf_engine.cpp View File

#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <string>
#include <string>
#include <vector>
#include "../CodeDweller/mangler.hpp" #include "../CodeDweller/mangler.hpp"
#include "snf_engine.hpp" #include "snf_engine.hpp"


--CountOfEvaluators; // Reduce our evaluator count. --CountOfEvaluators; // Reduce our evaluator count.


} }

Evaluator* findEvaluatorListTail(Evaluator* head) {
Evaluator* next = head;
while(NULL != (next->NextEvaluator)) next = next->NextEvaluator;
return next;
}
void EvaluationMatrix::dropAllEvaluators() {
bool haveActiveEvaluators = (NULL != EvaluatorList);
if(haveActiveEvaluators) {
Evaluator* tail = findEvaluatorListTail(EvaluatorList);
tail->NextEvaluator = EvaluatorCache;
EvaluatorCache = EvaluatorList;
}
PreviousEvaluator = NULL;
CurrentEvaluator = NULL;
EvaluatorList = NULL;
CountOfEvaluators = 0;
}
void EvaluationMatrix::restartEngineAt(int newCharacterCount) {
dropAllEvaluators();
CountOfCharacters = newCharacterCount;
}


// EvaluationMatrix::EvaluateThis() // EvaluationMatrix::EvaluateThis()
// //


return PassResult; // When we're finished, return the last known result. return PassResult; // When we're finished, return the last known result.
} }
void EvaluationMatrix::evaluateSegment(vector<unsigned char>& data, unsigned int start, unsigned int finish) {
restartEngineAt(start);
finish = (finish < data.size()) ? finish : data.size();
for(unsigned int a = start; a < finish; a++) EvaluateThis(data[a]);
}

+ 10
- 3
snf_engine.hpp View File

#include <cstdlib> #include <cstdlib>
#include <fstream> #include <fstream>
#include <iostream> #include <iostream>
#include <string>
#include <string>
#include <vector>
#include <exception> #include <exception>
#include "../CodeDweller/faults.hpp" #include "../CodeDweller/faults.hpp"
#include "../CodeDweller/mangler.hpp" #include "../CodeDweller/mangler.hpp"
// evaluator node if it exists. Therefore, the caller should skip it's normal // evaluator node if it exists. Therefore, the caller should skip it's normal
// list itteration code when this function has been called. // list itteration code when this function has been called.


void DropEvaluator();
void DropEvaluator();
void dropAllEvaluators();


public: public:


// EvaluateThis() Moves each evaluator with the current character and creates a new // EvaluateThis() Moves each evaluator with the current character and creates a new
// evaluator for the current spot in the input file to make all rules global. // evaluator for the current spot in the input file to make all rules global.


int EvaluateThis(unsigned short int i);
int EvaluateThis(unsigned short int i);
void evaluateSegment(vector<unsigned char>& data, unsigned int start, unsigned int finish);
void restartEngineAt(int newCharacterCount);


EvaluationMatrix(TokenMatrix* m) { // Constructor w/ pointer to Token Matrix... EvaluationMatrix(TokenMatrix* m) { // Constructor w/ pointer to Token Matrix...



Loading…
Cancel
Save