First commit of file entropy analyzer.

- Code comments need cleaned up still.
This commit is contained in:
Seth Hall 2013-08-05 00:02:48 -04:00
parent 2f0671aeeb
commit b7877792c9
7 changed files with 221 additions and 0 deletions

View file

@ -0,0 +1,19 @@
module Files;
export {
redef record Files::Info += {
## The information density of the contents of the file, expressed as a number of bits per character.
entropy: double &log &optional;
};
}
event file_new(f: fa_file)
{
Files::add_analyzer(f, Files::ANALYZER_ENTROPY);
}
event file_entropy(f: fa_file, ent: entropy_test_result)
{
f$info$entropy = ent$entropy;
}

View file

@ -1,3 +1,4 @@
add_subdirectory(data_event)
add_subdirectory(entropy)
add_subdirectory(extract)
add_subdirectory(hash)

View file

@ -0,0 +1,9 @@
include(BroPlugin)
include_directories(BEFORE ${CMAKE_CURRENT_SOURCE_DIR}
${CMAKE_CURRENT_BINARY_DIR})
bro_plugin_begin(Bro FileEntropy)
bro_plugin_cc(Entropy.cc Plugin.cc ../../Analyzer.cc)
bro_plugin_bif(events.bif)
bro_plugin_end()

View file

@ -0,0 +1,71 @@
// See the file "COPYING" in the main distribution directory for copyright.
#include <string>
#include "Entropy.h"
#include "util.h"
#include "Event.h"
#include "file_analysis/Manager.h"
using namespace file_analysis;
Entropy::Entropy(RecordVal* args, File* file)
: file_analysis::Analyzer(file_mgr->GetComponentTag("ENTROPY"), args, file)
{
//entropy->Init();
entropy = new EntropyVal;
}
Entropy::~Entropy()
{
Unref(entropy);
}
file_analysis::Analyzer* Entropy::Instantiate(RecordVal* args, File* file)
{
return new Entropy(args, file);
}
bool Entropy::DeliverStream(const u_char* data, uint64 len)
{
if ( ! fed )
fed = len > 0;
entropy->Feed(data, len);
return true;
}
bool Entropy::EndOfFile()
{
Finalize();
return false;
}
bool Entropy::Undelivered(uint64 offset, uint64 len)
{
return false;
}
void Entropy::Finalize()
{
//if ( ! entropy->IsValid() || ! fed )
if ( ! fed )
return;
val_list* vl = new val_list();
vl->append(GetFile()->GetVal()->Ref());
double montepi, scc, ent, mean, chisq;
montepi = scc = ent = mean = chisq = 0.0;
entropy->Get(&ent, &chisq, &mean, &montepi, &scc);
RecordVal* ent_result = new RecordVal(entropy_test_result);
ent_result->Assign(0, new Val(ent, TYPE_DOUBLE));
ent_result->Assign(1, new Val(chisq, TYPE_DOUBLE));
ent_result->Assign(2, new Val(mean, TYPE_DOUBLE));
ent_result->Assign(3, new Val(montepi, TYPE_DOUBLE));
ent_result->Assign(4, new Val(scc, TYPE_DOUBLE));
vl->append(ent_result);
mgr.QueueEvent(file_entropy, vl);
}

View file

@ -0,0 +1,84 @@
// See the file "COPYING" in the main distribution directory for copyright.
#ifndef FILE_ANALYSIS_ENTROPY_H
#define FILE_ANALYSIS_ENTROPY_H
#include <string>
#include "Val.h"
#include "OpaqueVal.h"
#include "File.h"
#include "Analyzer.h"
#include "events.bif.h"
namespace file_analysis {
/**
* An analyzer to produce a hash of file contents.
*/
class Entropy : public file_analysis::Analyzer {
public:
/**
* Destructor.
*/
virtual ~Entropy();
/**
* Create a new instance of an Extract analyzer.
* @param args the \c AnalyzerArgs value which represents the analyzer.
* @param file the file to which the analyzer will be attached.
* @return the new Extract analyzer instance or a null pointer if the
* the "extraction_file" field of \a args wasn't set.
*/
static file_analysis::Analyzer* Instantiate(RecordVal* args, File* file);
/**
* Incrementally hash next chunk of file contents.
* @param data pointer to start of a chunk of a file data.
* @param len number of bytes in the data chunk.
* @return false if the digest is in an invalid state, else true.
*/
virtual bool DeliverStream(const u_char* data, uint64 len);
/**
* Finalizes the hash and raises a "file_entropy_test" event.
* @return always false so analyze will be deteched from file.
*/
virtual bool EndOfFile();
/**
* Missing data can't be handled, so just indicate the this analyzer should
* be removed from receiving further data. The hash will not be finalized.
* @param offset byte offset in file at which missing chunk starts.
* @param len number of missing bytes.
* @return always false so analyzer will detach from file.
*/
virtual bool Undelivered(uint64 offset, uint64 len);
protected:
/**
* Constructor.
* @param args the \c AnalyzerArgs value which represents the analyzer.
* @param file the file to which the analyzer will be attached.
* @param hv specific hash calculator object.
* @param kind human readable name of the hash algorithm to use.
*/
Entropy(RecordVal* args, File* file);
/**
* If some file contents have been seen, finalizes the hash of them and
* raises the "file_hash" event with the results.
*/
void Finalize();
private:
EntropyVal* entropy;
bool fed;
};
} // namespace file_analysis
#endif

View file

@ -0,0 +1,29 @@
#include "plugin/Plugin.h"
#include "file_analysis/Component.h"
#include "Entropy.h"
namespace plugin { namespace Bro_FileEntropy {
class Plugin : public plugin::Plugin {
protected:
void InitPreScript()
{
SetName("Bro::FileEntropy");
SetVersion(-1);
SetAPIVersion(BRO_PLUGIN_API_VERSION);
SetDynamicPlugin(false);
SetDescription("Entropy test file content");
AddComponent(new ::file_analysis::Component("ENTROPY",
::file_analysis::Entropy::Instantiate));
extern std::list<std::pair<const char*, int> > __bif_events_init();
AddBifInitFunction(&__bif_events_init);
}
};
Plugin __plugin;
} }

View file

@ -0,0 +1,8 @@
## This event is generated each time file analysis performs
## entropy testing on a file.
##
## f: The file.
##
## ent: The results of the entropy testing.
##
event file_entropy%(f: fa_file, ent: entropy_test_result%);