Checkpoint

This commit is contained in:
Seth Hall 2013-04-24 12:56:20 -04:00
parent e0df278de6
commit 4cc9ca4243
9 changed files with 161 additions and 60 deletions

View file

@ -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

View file

@ -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%);

View file

@ -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%);

View file

@ -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)

View file

@ -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;
}

View file

@ -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

View file

@ -1,26 +1,55 @@
%extern{
#include "Event.h"
#include "file_analysis/File.h"
#include "file_analysis.bif.func_h"
%}
refine flow File += {
function proc_the_file(): bool
%{
printf("ending the flow!\n");
connection()->bro_analyzer()->EndOfFile();
connection()->FlowEOF(true);
connection()->FlowEOF(false);
return true;
%}
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(${h.signature}.length(), (const char*) ${h.signature}.begin()),
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::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_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();
};

View file

@ -1,12 +1,15 @@
type TheFile = record {
dos_header : DOS_Header;
dos_code : bytestring &length=(dos_header.AddressOfNewExeHeader - 64);
dos_code : bytestring &length=dos_code_len;
pe_header : IMAGE_NT_HEADERS;
pad : bytestring &length=1316134912 &transient;
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;
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 &length=len;
type MEM_INFO32 = record {
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;
} &byteorder=littleendian &length=16;
type IMAGE_OPTIONAL_HEADER64 = record {
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;
} &byteorder=littleendian;
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;
};

View file

@ -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;