mirror of
https://github.com/zeek/zeek.git
synced 2025-10-02 14:48:21 +00:00

While we support initializing records via coercion from an expression list, e.g., local x: X = [$x1=1, $x2=2]; this can sometimes obscure the code to readers, e.g., when assigning to value declared and typed elsewhere. The language runtime has a similar overhead since instead of just constructing a known type it needs to check at runtime that the coercion from the expression list is valid; this can be slower than just writing the readible code in the first place, see #4559. With this patch we use explicit construction, e.g., local x = X($x1=1, $x2=2);
139 lines
4.1 KiB
Text
139 lines
4.1 KiB
Text
module PE;
|
|
|
|
@load ./consts
|
|
|
|
export {
|
|
redef enum Log::ID += { LOG };
|
|
|
|
global log_policy: Log::PolicyHook;
|
|
|
|
type Info: record {
|
|
## Current timestamp.
|
|
ts: time &log;
|
|
## File id of this portable executable file.
|
|
id: string &log;
|
|
## The target machine that the file was compiled for.
|
|
machine: string &log &optional;
|
|
## The time that the file was created at.
|
|
compile_ts: time &log &optional;
|
|
## The required operating system.
|
|
os: string &log &optional;
|
|
## The subsystem that is required to run this file.
|
|
subsystem: string &log &optional;
|
|
## Is the file an executable, or just an object file?
|
|
is_exe: bool &log &default=T;
|
|
## Is the file a 64-bit executable?
|
|
is_64bit: bool &log &default=T;
|
|
## Does the file support Address Space Layout Randomization?
|
|
uses_aslr: bool &log &default=F;
|
|
## Does the file support Data Execution Prevention?
|
|
uses_dep: bool &log &default=F;
|
|
## Does the file enforce code integrity checks?
|
|
uses_code_integrity: bool &log &default=F;
|
|
## Does the file use structured exception handing?
|
|
uses_seh: bool &log &default=T;
|
|
## Does the file have an import table?
|
|
has_import_table: bool &log &optional;
|
|
## Does the file have an export table?
|
|
has_export_table: bool &log &optional;
|
|
## Does the file have an attribute certificate table?
|
|
has_cert_table: bool &log &optional;
|
|
## Does the file have a debug table?
|
|
has_debug_data: bool &log &optional;
|
|
## The names of the sections, in order.
|
|
section_names: vector of string &log &optional;
|
|
};
|
|
|
|
## Event for accessing logged records.
|
|
global log_pe: event(rec: Info);
|
|
|
|
## A hook that gets called when we first see a PE file.
|
|
global set_file: hook(f: fa_file);
|
|
}
|
|
|
|
redef record fa_file += {
|
|
pe: Info &optional;
|
|
};
|
|
|
|
const pe_mime_types = { "application/x-dosexec" };
|
|
|
|
event zeek_init() &priority=5
|
|
{
|
|
Files::register_for_mime_types(Files::ANALYZER_PE, pe_mime_types);
|
|
Log::create_stream(LOG, Log::Stream($columns=Info, $ev=log_pe, $path="pe", $policy=log_policy));
|
|
}
|
|
|
|
hook set_file(f: fa_file) &priority=5
|
|
{
|
|
if ( ! f?$pe )
|
|
f$pe = PE::Info($ts=f$info$ts, $id=f$id);
|
|
}
|
|
|
|
event pe_dos_header(f: fa_file, h: PE::DOSHeader) &priority=5
|
|
{
|
|
hook set_file(f);
|
|
}
|
|
|
|
event pe_file_header(f: fa_file, h: PE::FileHeader) &priority=5
|
|
{
|
|
hook set_file(f);
|
|
|
|
f$pe$machine = machine_types[h$machine];
|
|
f$pe$compile_ts = h$ts;
|
|
f$pe$is_exe = ( h$optional_header_size > 0 );
|
|
|
|
for ( c in h$characteristics )
|
|
{
|
|
if ( file_characteristics[c] == "32BIT_MACHINE" )
|
|
f$pe$is_64bit = F;
|
|
}
|
|
}
|
|
|
|
event pe_optional_header(f: fa_file, h: PE::OptionalHeader) &priority=5
|
|
{
|
|
hook set_file(f);
|
|
|
|
# Only EXEs have optional headers
|
|
if ( ! f$pe$is_exe )
|
|
return;
|
|
|
|
f$pe$os = os_versions[h$os_version_major, h$os_version_minor];
|
|
f$pe$subsystem = windows_subsystems[h$subsystem];
|
|
|
|
for ( c in h$dll_characteristics )
|
|
{
|
|
if ( dll_characteristics[c] == "DYNAMIC_BASE" )
|
|
f$pe$uses_aslr = T;
|
|
if ( dll_characteristics[c] == "FORCE_INTEGRITY" )
|
|
f$pe$uses_code_integrity = T;
|
|
if ( dll_characteristics[c] == "NX_COMPAT" )
|
|
f$pe$uses_dep = T;
|
|
if ( dll_characteristics[c] == "NO_SEH" )
|
|
f$pe$uses_seh = F;
|
|
}
|
|
|
|
f$pe$has_export_table = (|h$table_sizes| > 0 && h$table_sizes[0] > 0);
|
|
f$pe$has_import_table = (|h$table_sizes| > 1 && h$table_sizes[1] > 0);
|
|
f$pe$has_cert_table = (|h$table_sizes| > 4 && h$table_sizes[4] > 0);
|
|
f$pe$has_debug_data = (|h$table_sizes| > 6 && h$table_sizes[6] > 0);
|
|
}
|
|
|
|
event pe_section_header(f: fa_file, h: PE::SectionHeader) &priority=5
|
|
{
|
|
hook set_file(f);
|
|
|
|
# Only EXEs have section headers
|
|
if ( ! f$pe$is_exe )
|
|
return;
|
|
|
|
if ( ! f$pe?$section_names )
|
|
f$pe$section_names = vector();
|
|
f$pe$section_names += h$name;
|
|
}
|
|
|
|
event file_state_remove(f: fa_file) &priority=-5
|
|
{
|
|
if ( f?$pe && f$pe?$machine )
|
|
Log::write(LOG, f$pe);
|
|
}
|
|
|