diff --git a/src/file_analysis.bif b/src/file_analysis.bif index ba62e58855..6ded10b251 100644 --- a/src/file_analysis.bif +++ b/src/file_analysis.bif @@ -125,3 +125,7 @@ function FileAnalysis::eof%(source: string%): any file_mgr->EndOfFile(source->CheckString()); return 0; %} + +# Define file analysis framework events. + +event FileAnalysis::windows_pe_sig%(fi: FileAnalysis::Info, sig: string%); diff --git a/src/file_analysis/ActionSet.cc b/src/file_analysis/ActionSet.cc index 51cab26478..dabda1c931 100644 --- a/src/file_analysis/ActionSet.cc +++ b/src/file_analysis/ActionSet.cc @@ -5,6 +5,8 @@ #include "DataEvent.h" #include "Hash.h" +#include "analyzers/PE.h" + using namespace file_analysis; // keep in order w/ declared enum values in file_analysis.bif @@ -14,6 +16,8 @@ static ActionInstantiator action_factory[] = { SHA1::Instantiate, SHA256::Instantiate, DataEvent::Instantiate, + + PE_Analyzer::Instantiate, }; static void action_del_func(void* v) diff --git a/src/file_analysis/analyzers/PE.cc b/src/file_analysis/analyzers/PE.cc index 622cbb945f..e5b924e9fb 100644 --- a/src/file_analysis/analyzers/PE.cc +++ b/src/file_analysis/analyzers/PE.cc @@ -6,13 +6,11 @@ using namespace file_analysis; -PE_Analyzer::PE_Analyzer(Info* arg_info) - : Action(arg_info, BifEnum::FileAnalysis::ACTION_PE_ANALYZER) +PE_Analyzer::PE_Analyzer(RecordVal* args, Info* info, uint64 fsize) + : Action(args, info) { - interp = new binpac::PE::File(this); - - // Close the reverse flow. - interp->FlowEOF(false); + conn = new binpac::PE::MockConnection(this); + interp = new binpac::PE::File(conn, fsize); } PE_Analyzer::~PE_Analyzer() @@ -20,17 +18,32 @@ PE_Analyzer::~PE_Analyzer() delete interp; } -Action* PE_Analyzer::Instantiate(const RecordVal* args, Info* info) +Action* PE_Analyzer::Instantiate(RecordVal* args, Info* info) { - return new PE_Analyzer(info); + using BifType::Record::FileAnalysis::Info; + const char* field = "total_bytes"; + Val* filesize = info->GetVal()->Lookup(Info->FieldOffset(field)); + if ( ! filesize ) + // TODO: this should be a reporter message? or better yet stop relying on the file size. + return 0; + + bro_uint_t fsize = filesize->AsCount(); + return new PE_Analyzer(args, info, fsize); } bool PE_Analyzer::DeliverStream(const u_char* data, uint64 len) { Action::DeliverStream(data, len); - // Data is exclusively sent into the "up" flow. - interp->NewData(true, data, data + len); + try + { + interp->NewData(data, data + len); + } + catch ( const binpac::Exception& e ) + { + printf("Binpac exception: %s\n", e.c_msg()); + } + return true; } diff --git a/src/file_analysis/analyzers/PE.h b/src/file_analysis/analyzers/PE.h index d511f3e9bf..95b5083aff 100644 --- a/src/file_analysis/analyzers/PE.h +++ b/src/file_analysis/analyzers/PE.h @@ -14,16 +14,18 @@ namespace file_analysis { */ class PE_Analyzer : Action { public: - static Action* Instantiate(const RecordVal* args, Info* info); + static Action* Instantiate(RecordVal* args, Info* info); ~PE_Analyzer(); virtual bool DeliverStream(const u_char* data, uint64 len); protected: - - PE_Analyzer(Info* arg_info); + PE_Analyzer(RecordVal* args, Info* info, uint64 fsize); binpac::PE::File* interp; + binpac::PE::MockConnection* conn; + + uint64 fsize; }; } // namespace file_analysis diff --git a/src/file_analysis/analyzers/pe-analyzer.pac b/src/file_analysis/analyzers/pe-analyzer.pac index 1a295f2d30..77edfa3434 100644 --- a/src/file_analysis/analyzers/pe-analyzer.pac +++ b/src/file_analysis/analyzers/pe-analyzer.pac @@ -1,16 +1,26 @@ +%extern{ +#include "Event.h" +#include "file_analysis.bif.func_h" +%} -refine connection File += { +refine flow File += { function proc_sig(sig: bytestring) : bool %{ - if ( strcmp("MZ", (const char *) ${sig}.data()) == 0 ) - printf("yep: %s\n", ${sig}.data()); + //val_list* vl = new val_list; + //StringVal *sigval = new StringVal(${sig}.length(), (const char*) ${sig}.begin()); + //vl->append(sigval); + //mgr.QueueEvent(FileAnalysis::windows_pe_sig, vl); + + BifEvent::FileAnalysis::generate_windows_pe_sig((Analyzer *) connection()->bro_analyzer(), + (Val *) connection()->bro_analyzer()->GetInfo(), + new StringVal(${sig}.length(), (const char*) ${sig}.begin())); return true; %} }; refine typeattr DOSStub += &let { - proc : bool = $context.connection.proc_sig(signature); + proc : bool = $context.flow.proc_sig(signature); }; diff --git a/src/file_analysis/analyzers/pe-file.pac b/src/file_analysis/analyzers/pe-file.pac index 4cec173ae3..33cd1270f7 100644 --- a/src/file_analysis/analyzers/pe-file.pac +++ b/src/file_analysis/analyzers/pe-file.pac @@ -1,7 +1,7 @@ -type TheFile() = record { - barf: DOSStub; -} &byteorder=bigendian &length=-1; +type TheFile(fsize: uint64) = record { + dos_stub: DOSStub; +} &byteorder=bigendian &length=fsize; type DOSStub() = record { signature : bytestring &length=2; diff --git a/src/file_analysis/analyzers/pe.pac b/src/file_analysis/analyzers/pe.pac index be91643b21..9cd4f4f112 100644 --- a/src/file_analysis/analyzers/pe.pac +++ b/src/file_analysis/analyzers/pe.pac @@ -2,19 +2,19 @@ %include bro.pac analyzer PE withcontext { - connection: File; - flow: Bytes; + connection: MockConnection; + flow: File; }; -connection File(bro_analyzer: BroFileAnalyzer) { - upflow = Bytes(true); - downflow = Bytes(false); +connection MockConnection(bro_analyzer: BroFileAnalyzer) { + upflow = File(0); + downflow = File(0); }; %include pe-file.pac -flow Bytes(is_orig: bool) { - flowunit = TheFile() withcontext(connection, this); +flow File(fsize: uint64) { + flowunit = TheFile(fsize) withcontext(connection, this); } %include pe-analyzer.pac