diff --git a/src/file_analysis.bif b/src/file_analysis.bif index df4ed98a53..43aab3bb4f 100644 --- a/src/file_analysis.bif +++ b/src/file_analysis.bif @@ -153,3 +153,5 @@ function FileAnalysis::__eof%(source: string%): any #event FileAnalysis::windows_pe_dosstub%(fi: FileAnalysis::Info, sig: string, checksum: count%); event FileAnalysis::windows_pe_dosstub%(checksum: count%); +event FileAnalysis::windows_pe_timestamp%(ts: time%); + diff --git a/src/file_analysis/ActionSet.cc b/src/file_analysis/ActionSet.cc index 314650a210..d7b1dc9d11 100644 --- a/src/file_analysis/ActionSet.cc +++ b/src/file_analysis/ActionSet.cc @@ -16,6 +16,8 @@ static ActionInstantiator action_factory[] = { file_analysis::SHA1::Instantiate, file_analysis::SHA256::Instantiate, file_analysis::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 e5b924e9fb..daf679ce82 100644 --- a/src/file_analysis/analyzers/PE.cc +++ b/src/file_analysis/analyzers/PE.cc @@ -6,11 +6,11 @@ using namespace file_analysis; -PE_Analyzer::PE_Analyzer(RecordVal* args, Info* info, uint64 fsize) +PE_Analyzer::PE_Analyzer(RecordVal* args, Info* info) : Action(args, info) { conn = new binpac::PE::MockConnection(this); - interp = new binpac::PE::File(conn, fsize); + interp = new binpac::PE::File(conn); } PE_Analyzer::~PE_Analyzer() @@ -21,14 +21,14 @@ PE_Analyzer::~PE_Analyzer() Action* PE_Analyzer::Instantiate(RecordVal* args, Info* 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); + //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); } bool PE_Analyzer::DeliverStream(const u_char* data, uint64 len) @@ -42,8 +42,8 @@ bool PE_Analyzer::DeliverStream(const u_char* data, uint64 len) catch ( const binpac::Exception& e ) { printf("Binpac exception: %s\n", e.c_msg()); + return false; } - return true; } diff --git a/src/file_analysis/analyzers/PE.h b/src/file_analysis/analyzers/PE.h index 95b5083aff..34a76e7e00 100644 --- a/src/file_analysis/analyzers/PE.h +++ b/src/file_analysis/analyzers/PE.h @@ -21,11 +21,9 @@ public: virtual bool DeliverStream(const u_char* data, uint64 len); protected: - PE_Analyzer(RecordVal* args, Info* info, uint64 fsize); + PE_Analyzer(RecordVal* args, Info* info); 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 63f722b18c..d0407f348a 100644 --- a/src/file_analysis/analyzers/pe-analyzer.pac +++ b/src/file_analysis/analyzers/pe-analyzer.pac @@ -6,17 +6,30 @@ refine flow File += { - function proc_dosstub(stub: DOSStub) : bool + function proc_dos_header(h: DOS_Header) : bool %{ BifEvent::FileAnalysis::generate_windows_pe_dosstub((Analyzer *) connection()->bro_analyzer(), //(Val *) connection()->bro_analyzer()->GetInfo(), - //new StringVal(${stub.signature}.length(), (const char*) ${stub.signature}.begin()), - ${stub.HeaderSizeInParagraphs}); + //new StringVal(${h.signature}.length(), (const char*) ${h.signature}.begin()), + ${h.AddressOfNewExeHeader}-64); return true; %} + function proc_pe_header(h: IMAGE_NT_HEADERS) : bool + %{ + BifEvent::FileAnalysis::generate_windows_pe_timestamp((Analyzer *) connection()->bro_analyzer(), + //(Val *) connection()->bro_analyzer()->GetInfo(), + //new StringVal(${h.signature}.length(), (const char*) ${h.signature}.begin()), + ${h.FileHeader.TimeDateStamp}); + return true; + %} }; -refine typeattr DOSStub += &let { - proc : bool = $context.flow.proc_dosstub(this); +refine typeattr DOS_Header += &let { + proc : bool = $context.flow.proc_dos_header(this); }; + +refine typeattr IMAGE_NT_HEADERS += &let { + proc : bool = $context.flow.proc_pe_header(this); +}; + diff --git a/src/file_analysis/analyzers/pe-file.pac b/src/file_analysis/analyzers/pe-file.pac index 50647b7275..5854fd2bd8 100644 --- a/src/file_analysis/analyzers/pe-file.pac +++ b/src/file_analysis/analyzers/pe-file.pac @@ -1,10 +1,14 @@ -type TheFile(fsize: uint64) = record { - dos_stub: DOSStub; - blah: bytestring &length=1316134912 &transient; +type TheFile = record { + dos_header : DOS_Header; + dos_code : bytestring &length=(dos_header.AddressOfNewExeHeader - 64); + pe_header : IMAGE_NT_HEADERS; + pad : bytestring &length=1316134912 &transient; +} &let { + dos_code_len: uint32 = (dos_header.AddressOfNewExeHeader - 64); } &transient &byteorder=littleendian; -type DOSStub() = record { +type DOS_Header = record { signature : bytestring &length=2; UsedBytesInTheLastPage : uint16; FileSizeInPages : uint16; @@ -25,3 +29,64 @@ type DOSStub() = record { Reserved2 : uint16[10]; AddressOfNewExeHeader : uint32; } &byteorder=littleendian &length=64; + +type IMAGE_NT_HEADERS = record { + PESignature : uint32; + FileHeader : IMAGE_FILE_HEADER; + OptionalHeader : OPTIONAL_HEADER(FileHeader.SizeOfOptionalHeader); +} &byteorder=littleendian &length=FileHeader.SizeOfOptionalHeader+offsetof(OptionalHeader); + +type IMAGE_FILE_HEADER = record { + Machine : uint16; + NumberOfSections : uint16; + TimeDateStamp : uint32; + PointerToSymbolTable : uint32; + NumberOfSymbols : uint32; + SizeOfOptionalHeader : uint16; + Characteristics : uint16; +}; + +type OPTIONAL_HEADER(len: uint16) = record { + OptionalHeaderMagic : uint16; + Header : case OptionalHeaderMagic of { + 0x0b01 -> OptionalHeader32 : IMAGE_OPTIONAL_HEADER32; + 0x0b02 -> OptionalHeader64 : IMAGE_OPTIONAL_HEADER64; + default -> InvalidPEFile : bytestring &restofdata; + }; +} &length=len; + +type IMAGE_OPTIONAL_HEADER32 = record { + major_linker_version : uint8; + minor_linker_version : uint8; + size_of_code : uint32; + size_of_init_data : uint32; + size_of_uninit_data : uint32; + addr_of_entry_point : uint32; + base_of_code : uint32; + base_of_data : uint32; + image_base : uint32; + section_alignment : uint32; + file_alignment : uint32; + os_version_major : uint16; + os_version_minor : uint16; + major_image_version : uint16; + minor_image_version : uint16; + major_subsys_version : uint16; + minor_subsys_version : uint16; + win32_version : uint32; + size_of_image : uint32; + size_of_headers : uint32; + checksum : uint32; + subsystem : uint16; + dll_characteristics : uint16; + size_of_stack_reserve : uint32; + size_of_stack_commit : uint32; + size_of_heap_reserve : uint32; + size_of_heap_commit : uint32; + loader_flags : uint32; + number_of_rva_and_sizes : uint32; +} &byteorder=littleendian; + +type IMAGE_OPTIONAL_HEADER64 = record { + +} &byteorder=littleendian; diff --git a/src/file_analysis/analyzers/pe.pac b/src/file_analysis/analyzers/pe.pac index 9cd4f4f112..8a20fa3c62 100644 --- a/src/file_analysis/analyzers/pe.pac +++ b/src/file_analysis/analyzers/pe.pac @@ -7,14 +7,14 @@ analyzer PE withcontext { }; connection MockConnection(bro_analyzer: BroFileAnalyzer) { - upflow = File(0); - downflow = File(0); + upflow = File; + downflow = File; }; %include pe-file.pac -flow File(fsize: uint64) { - flowunit = TheFile(fsize) withcontext(connection, this); +flow File { + flowunit = TheFile withcontext(connection, this); } %include pe-analyzer.pac