mirror of
https://github.com/zeek/zeek.git
synced 2025-10-04 23:58:20 +00:00
Checkpoint
This commit is contained in:
parent
e0df278de6
commit
4cc9ca4243
9 changed files with 161 additions and 60 deletions
|
@ -2486,6 +2486,20 @@ type irc_join_info: record {
|
|||
## .. bro:see:: irc_join_message
|
||||
type irc_join_list: set[irc_join_info];
|
||||
|
||||
## Record for Portable Executable (PE) section headers.
|
||||
type PESectionHeader: record {
|
||||
name : string;
|
||||
virtual_size : count;
|
||||
virtual_addr : count;
|
||||
size_of_raw_data : count;
|
||||
ptr_to_raw_data : count;
|
||||
non_used_ptr_to_relocs : count;
|
||||
non_used_ptr_to_line_nums : count;
|
||||
non_used_num_of_relocs : count;
|
||||
non_used_num_of_line_nums : count;
|
||||
characteristics : count;
|
||||
};
|
||||
|
||||
## Deprecated.
|
||||
##
|
||||
## .. todo:: Remove. It's still declared internally but doesn't seem used anywhere
|
||||
|
|
|
@ -7026,6 +7026,12 @@ event file_state_remove%(f: fa_file%);
|
|||
## FileAnalysis::ACTION_SHA1 FileAnalysis::ACTION_SHA256
|
||||
event file_hash%(f: fa_file, kind: string, hash: string%);
|
||||
|
||||
|
||||
event file_pe_dosstub%(f: fa_file, checksum: count%);
|
||||
event file_pe_timestamp%(f: fa_file, ts: time%);
|
||||
event file_pe_section_header%(f: fa_file, h: PESectionHeader%);
|
||||
|
||||
|
||||
## Deprecated. Will be removed.
|
||||
event stp_create_endp%(c: connection, e: int, is_orig: bool%);
|
||||
|
||||
|
|
|
@ -97,10 +97,3 @@ function set_file_handle%(handle: string%): any
|
|||
file_mgr->SetHandle(handle->CheckString());
|
||||
return 0;
|
||||
%}
|
||||
|
||||
# Define file analysis framework events.
|
||||
|
||||
#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%);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ static ActionInstantiator action_factory[] = {
|
|||
file_analysis::SHA256::Instantiate,
|
||||
file_analysis::DataEvent::Instantiate,
|
||||
|
||||
PE_Analyzer::Instantiate,
|
||||
file_analysis::PE_Analyzer::Instantiate,
|
||||
};
|
||||
|
||||
static void action_del_func(void* v)
|
||||
|
|
|
@ -3,14 +3,16 @@
|
|||
#include "PE.h"
|
||||
#include "pe_pac.h"
|
||||
#include "util.h"
|
||||
#include "Event.h"
|
||||
|
||||
using namespace file_analysis;
|
||||
|
||||
PE_Analyzer::PE_Analyzer(RecordVal* args, Info* info)
|
||||
: Action(args, info)
|
||||
PE_Analyzer::PE_Analyzer(RecordVal* args, File* file)
|
||||
: Action(args, file)
|
||||
{
|
||||
conn = new binpac::PE::MockConnection(this);
|
||||
interp = new binpac::PE::File(conn);
|
||||
done=false;
|
||||
}
|
||||
|
||||
PE_Analyzer::~PE_Analyzer()
|
||||
|
@ -18,23 +20,21 @@ PE_Analyzer::~PE_Analyzer()
|
|||
delete interp;
|
||||
}
|
||||
|
||||
Action* PE_Analyzer::Instantiate(RecordVal* args, Info* info)
|
||||
Action* PE_Analyzer::Instantiate(RecordVal* args, File* file)
|
||||
{
|
||||
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);
|
||||
return new PE_Analyzer(args, file);
|
||||
}
|
||||
|
||||
bool PE_Analyzer::DeliverStream(const u_char* data, uint64 len)
|
||||
{
|
||||
Action::DeliverStream(data, len);
|
||||
printf("deliver stream\n");
|
||||
if (done)
|
||||
{
|
||||
printf("analyzer done\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
Action::DeliverStream(data, len);
|
||||
try
|
||||
{
|
||||
interp->NewData(data, data + len);
|
||||
|
@ -47,3 +47,10 @@ bool PE_Analyzer::DeliverStream(const u_char* data, uint64 len)
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PE_Analyzer::EndOfFile()
|
||||
{
|
||||
printf("end of file!\n");
|
||||
done=true;
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
#include <string>
|
||||
|
||||
#include "Val.h"
|
||||
#include "../Info.h"
|
||||
#include "../File.h"
|
||||
#include "pe_pac.h"
|
||||
|
||||
namespace file_analysis {
|
||||
|
@ -14,16 +14,19 @@ namespace file_analysis {
|
|||
*/
|
||||
class PE_Analyzer : Action {
|
||||
public:
|
||||
static Action* Instantiate(RecordVal* args, Info* info);
|
||||
static Action* Instantiate(RecordVal* args, File* file);
|
||||
|
||||
~PE_Analyzer();
|
||||
|
||||
virtual bool DeliverStream(const u_char* data, uint64 len);
|
||||
|
||||
virtual bool EndOfFile();
|
||||
|
||||
protected:
|
||||
PE_Analyzer(RecordVal* args, Info* info);
|
||||
PE_Analyzer(RecordVal* args, File* file);
|
||||
binpac::PE::File* interp;
|
||||
binpac::PE::MockConnection* conn;
|
||||
bool done;
|
||||
};
|
||||
|
||||
} // namespace file_analysis
|
||||
|
|
|
@ -1,26 +1,55 @@
|
|||
|
||||
%extern{
|
||||
#include "Event.h"
|
||||
#include "file_analysis/File.h"
|
||||
#include "file_analysis.bif.func_h"
|
||||
%}
|
||||
|
||||
refine flow File += {
|
||||
|
||||
function proc_dos_header(h: DOS_Header) : bool
|
||||
function proc_the_file(): bool
|
||||
%{
|
||||
BifEvent::FileAnalysis::generate_windows_pe_dosstub((Analyzer *) connection()->bro_analyzer(),
|
||||
//(Val *) connection()->bro_analyzer()->GetInfo(),
|
||||
//new StringVal(${h.signature}.length(), (const char*) ${h.signature}.begin()),
|
||||
${h.AddressOfNewExeHeader}-64);
|
||||
printf("ending the flow!\n");
|
||||
connection()->bro_analyzer()->EndOfFile();
|
||||
connection()->FlowEOF(true);
|
||||
connection()->FlowEOF(false);
|
||||
return true;
|
||||
%}
|
||||
|
||||
function proc_pe_header(h: IMAGE_NT_HEADERS) : bool
|
||||
function proc_dos_header(h: DOS_Header): 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});
|
||||
BifEvent::generate_file_pe_dosstub((Analyzer *) connection()->bro_analyzer(),
|
||||
connection()->bro_analyzer()->GetFile()->GetVal()->Ref(),
|
||||
${h.AddressOfNewExeHeader}-64);
|
||||
return true;
|
||||
%}
|
||||
|
||||
function proc_pe_header(h: IMAGE_NT_HEADERS): bool
|
||||
%{
|
||||
BifEvent::generate_file_pe_timestamp((Analyzer *) connection()->bro_analyzer(),
|
||||
connection()->bro_analyzer()->GetFile()->GetVal()->Ref(),
|
||||
${h.file_header.TimeDateStamp});
|
||||
return true;
|
||||
%}
|
||||
|
||||
|
||||
function proc_section_header(h: IMAGE_SECTION_HEADER): bool
|
||||
%{
|
||||
RecordVal* section_header = new RecordVal(BifType::Record::PESectionHeader);
|
||||
section_header->Assign(0, new StringVal(${h.name}.length(), (const char*) ${h.name}.data()));
|
||||
section_header->Assign(1, new Val(${h.virtual_size}, TYPE_COUNT));
|
||||
section_header->Assign(2, new Val(${h.virtual_addr}, TYPE_COUNT));
|
||||
section_header->Assign(3, new Val(${h.size_of_raw_data}, TYPE_COUNT));
|
||||
section_header->Assign(4, new Val(${h.ptr_to_raw_data}, TYPE_COUNT));
|
||||
section_header->Assign(5, new Val(${h.non_used_ptr_to_relocs}, TYPE_COUNT));
|
||||
section_header->Assign(6, new Val(${h.non_used_ptr_to_line_nums}, TYPE_COUNT));
|
||||
section_header->Assign(7, new Val(${h.non_used_num_of_relocs}, TYPE_COUNT));
|
||||
section_header->Assign(8, new Val(${h.non_used_num_of_line_nums}, TYPE_COUNT));
|
||||
section_header->Assign(9, new Val(${h.characteristics}, TYPE_COUNT));
|
||||
|
||||
BifEvent::generate_file_pe_section_header((Analyzer *) connection()->bro_analyzer(),
|
||||
connection()->bro_analyzer()->GetFile()->GetVal()->Ref(),
|
||||
section_header);
|
||||
return true;
|
||||
%}
|
||||
};
|
||||
|
@ -33,3 +62,10 @@ refine typeattr IMAGE_NT_HEADERS += &let {
|
|||
proc : bool = $context.flow.proc_pe_header(this);
|
||||
};
|
||||
|
||||
refine typeattr IMAGE_SECTION_HEADER += &let {
|
||||
proc: bool = $context.flow.proc_section_header(this);
|
||||
};
|
||||
|
||||
refine typeattr TheFile += &let {
|
||||
proc: bool = $context.flow.proc_the_file();
|
||||
};
|
|
@ -1,12 +1,15 @@
|
|||
|
||||
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;
|
||||
dos_header : DOS_Header;
|
||||
dos_code : bytestring &length=dos_code_len;
|
||||
pe_header : IMAGE_NT_HEADERS;
|
||||
sections_table : IMAGE_SECTION_HEADER[] &length=pe_header.file_header.NumberOfSections*40 &transient;
|
||||
#pad : bytestring &length=offsetof(pe_header.data_directories + pe_header.data_directories[1].virtual_address);
|
||||
#data_sections : DATA_SECTIONS[pe_header.file_header.NumberOfSections];
|
||||
#pad : bytestring &restofdata;
|
||||
} &let {
|
||||
dos_code_len: uint32 = (dos_header.AddressOfNewExeHeader - 64);
|
||||
} &transient &byteorder=littleendian;
|
||||
dos_code_len: uint32 = dos_header.AddressOfNewExeHeader - 64;
|
||||
} &byteorder=littleendian;
|
||||
|
||||
type DOS_Header = record {
|
||||
signature : bytestring &length=2;
|
||||
|
@ -32,9 +35,9 @@ type DOS_Header = record {
|
|||
|
||||
type IMAGE_NT_HEADERS = record {
|
||||
PESignature : uint32;
|
||||
FileHeader : IMAGE_FILE_HEADER;
|
||||
OptionalHeader : OPTIONAL_HEADER(FileHeader.SizeOfOptionalHeader);
|
||||
} &byteorder=littleendian &length=FileHeader.SizeOfOptionalHeader+offsetof(OptionalHeader);
|
||||
file_header : IMAGE_FILE_HEADER;
|
||||
OptionalHeader : IMAGE_OPTIONAL_HEADER(file_header.SizeOfOptionalHeader);
|
||||
} &byteorder=littleendian &length=file_header.SizeOfOptionalHeader+offsetof(OptionalHeader);
|
||||
|
||||
type IMAGE_FILE_HEADER = record {
|
||||
Machine : uint16;
|
||||
|
@ -46,16 +49,8 @@ type IMAGE_FILE_HEADER = record {
|
|||
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 {
|
||||
type IMAGE_OPTIONAL_HEADER(len: uint16) = record {
|
||||
magic : uint16;
|
||||
major_linker_version : uint8;
|
||||
minor_linker_version : uint8;
|
||||
size_of_code : uint32;
|
||||
|
@ -79,14 +74,56 @@ type IMAGE_OPTIONAL_HEADER32 = record {
|
|||
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;
|
||||
mem: case magic of {
|
||||
0x0b01 -> i32 : MEM_INFO32;
|
||||
0x0b02 -> i64 : MEM_INFO64;
|
||||
default -> InvalidPEFile : bytestring &length=0;
|
||||
};
|
||||
loader_flags : uint32;
|
||||
number_of_rva_and_sizes : uint32;
|
||||
} &byteorder=littleendian;
|
||||
} &byteorder=littleendian &length=len;
|
||||
|
||||
type IMAGE_OPTIONAL_HEADER64 = record {
|
||||
type MEM_INFO32 = record {
|
||||
size_of_stack_reserve : uint32;
|
||||
size_of_stack_commit : uint32;
|
||||
size_of_heap_reserve : uint32;
|
||||
size_of_heap_commit : uint32;
|
||||
} &byteorder=littleendian &length=16;
|
||||
|
||||
} &byteorder=littleendian;
|
||||
type MEM_INFO64 = record {
|
||||
size_of_stack_reserve : uint64;
|
||||
size_of_stack_commit : uint64;
|
||||
size_of_heap_reserve : uint64;
|
||||
size_of_heap_commit : uint64;
|
||||
} &byteorder=littleendian &length=32;
|
||||
|
||||
type IMAGE_SECTION_HEADER = record {
|
||||
name : bytestring &length=8;
|
||||
virtual_size : uint32;
|
||||
virtual_addr : uint32;
|
||||
size_of_raw_data : uint32;
|
||||
ptr_to_raw_data : uint32;
|
||||
non_used_ptr_to_relocs : uint32;
|
||||
non_used_ptr_to_line_nums : uint32;
|
||||
non_used_num_of_relocs : uint16;
|
||||
non_used_num_of_line_nums : uint16;
|
||||
characteristics : uint32;
|
||||
} &byteorder=littleendian &length=40;
|
||||
|
||||
|
||||
type IMAGE_DATA_DIRECTORY = record {
|
||||
virtual_address : uint32;
|
||||
size : uint16;
|
||||
};
|
||||
|
||||
type IMAGE_IMPORT_DIRECTORY = record {
|
||||
rva_import_lookup_table : uint32;
|
||||
time_date_stamp : uint32;
|
||||
forwarder_chain : uint32;
|
||||
rva_module_name : uint32;
|
||||
rva_import_addr_table : uint32;
|
||||
};
|
||||
|
||||
type DATA_SECTIONS = record {
|
||||
blah: bytestring &length=10;
|
||||
};
|
|
@ -163,6 +163,8 @@ type ModbusHeaders: record;
|
|||
type ModbusCoils: vector;
|
||||
type ModbusRegisters: vector;
|
||||
|
||||
type PESectionHeader: record;
|
||||
|
||||
module Log;
|
||||
|
||||
enum Writer %{
|
||||
|
@ -248,6 +250,9 @@ enum Action %{
|
|||
|
||||
## Deliver the file contents to the script-layer in an event.
|
||||
ACTION_DATA_EVENT,
|
||||
|
||||
## Windows executable analyzer
|
||||
ACTION_PE_ANALYZER,
|
||||
%}
|
||||
|
||||
module GLOBAL;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue