From 55a783a12c587c556862c0b473c10ac0ac9165e6 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Sat, 24 May 2025 17:48:00 +0200 Subject: [PATCH 1/4] refactor: Trim the `k` prefix from types and packages Historically, Fibratus has been envisioned as a tool to exclusively interact with the NT Kernel Logger ETW provider. Since then, more providers have been integrated, some of them operating in userspace. Thus, the assumption that the provenance of all events is coming out the kernel is no longer valid. It is semantically more correct to represent all types, packages, and identifier in a generic way. The most prominent example is the `Kevent` structure being renamed to `Event`. --- .github/workflows/master.yml | 4 +- .github/workflows/pr.yml | 4 +- .github/workflows/release.yml | 2 +- .golangci.yml | 2 +- cmd/fibratus/app/capture/capture_windows.go | 2 +- cmd/fibratus/app/list/list.go | 15 +- cmd/fibratus/app/replay/replay_windows.go | 2 +- cmd/fibratus/app/stats/stats.go | 53 +- filaments/fishy_netio.py | 31 +- filaments/teamviewer_remote_file_copy.py | 6 +- filaments/top_in_packets.py | 6 +- filaments/top_keys.py | 6 +- filaments/top_out_packets.py | 6 +- filaments/utils/dotdict.py | 8 +- filaments/watch_files.py | 8 +- internal/bootstrap/bootstrap.go | 34 +- internal/bootstrap/source.go | 10 +- internal/etw/consumer.go | 29 +- internal/etw/processors/chain.go | 12 +- internal/etw/processors/fs_windows.go | 111 ++-- internal/etw/processors/fs_windows_test.go | 243 ++++--- internal/etw/processors/handle_windows.go | 29 +- .../etw/processors/handle_windows_test.go | 51 +- internal/etw/processors/image_windows.go | 22 +- internal/etw/processors/image_windows_test.go | 81 ++- internal/etw/processors/mem_windows.go | 27 +- internal/etw/processors/mem_windows_test.go | 59 +- internal/etw/processors/net_windows.go | 27 +- internal/etw/processors/net_windows_test.go | 61 +- internal/etw/processors/processor.go | 4 +- internal/etw/processors/ps_windows.go | 43 +- internal/etw/processors/ps_windows_test.go | 165 +++-- internal/etw/processors/registry_windows.go | 39 +- .../etw/processors/registry_windows_test.go | 105 ++- internal/etw/source.go | 73 +-- internal/etw/source_test.go | 255 ++++---- internal/etw/stackext.go | 40 +- internal/etw/stackext_test.go | 16 +- internal/etw/trace.go | 2 +- make.bat | 2 +- pkg/aggregator/aggregator.go | 40 +- pkg/aggregator/aggregator_test.go | 39 +- pkg/aggregator/submitter.go | 4 +- pkg/aggregator/transformers/config.go | 2 +- pkg/aggregator/transformers/remove/config.go | 8 +- pkg/aggregator/transformers/remove/remove.go | 10 +- .../transformers/remove/remove_test.go | 27 +- pkg/aggregator/transformers/rename/config.go | 4 +- pkg/aggregator/transformers/rename/rename.go | 16 +- .../transformers/rename/rename_test.go | 33 +- pkg/aggregator/transformers/replace/config.go | 10 +- .../transformers/replace/replace.go | 14 +- .../transformers/replace/replace_test.go | 21 +- pkg/aggregator/transformers/tags/tags.go | 6 +- pkg/aggregator/transformers/tags/tags_test.go | 31 +- pkg/aggregator/transformers/transformer.go | 10 +- pkg/aggregator/transformers/trim/config.go | 6 +- pkg/aggregator/transformers/trim/trim.go | 24 +- pkg/aggregator/transformers/trim/trim_test.go | 39 +- pkg/aggregator/worker_test.go | 16 +- pkg/alertsender/alert.go | 6 +- pkg/alertsender/alert_test.go | 29 +- pkg/alertsender/eventlog/eventlog_test.go | 37 +- pkg/alertsender/mail/renderer_test.go | 37 +- pkg/alertsender/mail/template.go | 2 +- pkg/alertsender/systray/systray.go | 4 +- .../cap.kcap => cap/_fixtures/cap.cap} | Bin .../cap1.kcap => cap/_fixtures/cap1.cap} | Bin .../cap2.kcap => cap/_fixtures/cap2.cap} | Bin pkg/{kcap => cap}/config.go | 2 +- pkg/{kcap => cap}/header.go | 18 +- pkg/{kcap => cap}/reader.go | 26 +- pkg/{kcap => cap}/reader_unsupported.go | 10 +- pkg/{kcap => cap}/reader_windows.go | 103 ++- pkg/{kcap => cap}/reader_windows_test.go | 16 +- pkg/{kcap => cap}/section/section.go | 10 +- pkg/{kcap => cap}/section/section_windows.go | 10 +- .../section/section_windows_test.go | 2 +- pkg/{kcap => cap}/types_linux.go | 16 +- pkg/{kcap => cap}/types_windows.go | 24 +- pkg/{kcap => cap}/version/version_windows.go | 8 +- pkg/{kcap => cap}/writer.go | 22 +- pkg/{kcap => cap}/writer_unsupported.go | 8 +- pkg/{kcap => cap}/writer_windows.go | 52 +- pkg/{kcap => cap}/writer_windows_test.go | 47 +- pkg/config/_fixtures/fibratus.json | 2 +- pkg/config/_fixtures/fibratus.yml | 14 +- .../filters/default-with-template.yml | 2 +- pkg/config/_fixtures/filters/default.yml | 2 +- pkg/config/_fixtures/filters/default1.yml | 2 +- pkg/config/_fixtures/transformers.yml | 4 +- pkg/config/config_windows.go | 28 +- pkg/config/config_windows_test.go | 4 +- pkg/config/filters.go | 13 +- pkg/config/filters_test.go | 6 +- pkg/config/kstream.go | 30 +- pkg/config/kstream_test.go | 7 +- pkg/config/schema_windows.go | 18 +- pkg/errors/errors.go | 12 +- pkg/errors/errors_windows.go | 12 +- pkg/{kevent => event}/_fixtures/handles.json | 0 pkg/{kevent => event}/batch.go | 12 +- pkg/{kevent => event}/batch_test.go | 79 ++- pkg/{kevent/ktypes => event}/category.go | 4 +- pkg/{kevent => event}/doc.go | 6 +- pkg/{kevent => event}/enum.go | 2 +- pkg/{kevent/kevent.go => event/event.go} | 79 ++- .../event_windows.go} | 465 +++++++------- .../event_windows_test.go} | 51 +- pkg/{kevent/ktypes => event}/eventset.go | 8 +- pkg/{kevent/ktypes => event}/eventset_test.go | 4 +- pkg/{kevent => event}/flags.go | 2 +- pkg/{kevent => event}/flags_test.go | 2 +- pkg/{kevent => event}/formatter.go | 112 ++-- pkg/{kevent => event}/formatter_test.go | 34 +- pkg/{kevent => event}/formatter_windows.go | 38 +- pkg/{kevent => event}/marshaller.go | 2 +- pkg/{kevent => event}/marshaller_test.go | 234 +++---- pkg/{kevent => event}/marshaller_windows.go | 305 +++++---- .../ktypes => event}/metainfo_windows.go | 199 +++--- .../ktypes => event}/metainfo_windows_test.go | 30 +- pkg/{kevent/kparam.go => event/param.go} | 381 ++++++----- pkg/event/param_test.go | 60 ++ .../param_windows.go} | 533 ++++++++-------- .../params/params_windows.go} | 2 +- pkg/event/params/types.go | 27 + .../kparams => event/params}/types_windows.go | 14 +- pkg/{kevent => event}/queue.go | 26 +- pkg/{kevent => event}/queue_test.go | 113 ++-- pkg/{kevent => event}/sequencer_windows.go | 10 +- .../sequencer_windows_test.go | 2 +- pkg/{kevent => event}/stackwalk.go | 20 +- pkg/event/stackwalk_test.go | 129 ++++ pkg/{kevent => event}/template.go | 84 +-- .../types_windows.go} | 92 +-- .../types_windows_test.go} | 24 +- pkg/filament/_fixtures/test_filter.py | 2 +- pkg/filament/_fixtures/test_on_next_kevent.py | 4 +- pkg/filament/_fixtures/top_hives_io.py | 2 +- pkg/filament/_fixtures/top_keys_io_table.py | 2 +- .../cpython/_fixtures/top_hives_io.py | 4 +- pkg/filament/dict.go | 114 ++++ pkg/filament/{kdict_test.go => dict_test.go} | 39 +- pkg/filament/filament.go | 84 +-- pkg/filament/filament_test.go | 43 +- pkg/filament/filament_unsupported.go | 4 +- pkg/filament/kdict.go | 114 ---- pkg/filament/types.go | 4 +- pkg/filter/accessor.go | 94 +-- pkg/filter/accessor_windows.go | 529 ++++++++------- pkg/filter/accessor_windows_test.go | 39 +- pkg/filter/fields/fields.go | 6 +- pkg/filter/fields/fields_windows.go | 544 ++++++++-------- pkg/filter/fields/fields_windows_test.go | 4 +- pkg/filter/filter.go | 34 +- pkg/filter/filter_test.go | 603 +++++++++--------- pkg/filter/filter_windows.go | 2 +- pkg/filter/ql/error_test.go | 4 +- pkg/filter/ql/function.go | 4 +- pkg/filter/ql/literal.go | 21 +- pkg/filter/ql/parser_test.go | 132 ++-- pkg/filter/util.go | 15 +- pkg/handle/snapshotter.go | 26 +- pkg/handle/snapshotter_mock.go | 10 +- pkg/handle/types/marshaller.go | 2 +- pkg/handle/types/types.go | 2 +- pkg/kevent/README.md | 27 - pkg/kevent/kparam_test.go | 60 -- pkg/kevent/stackwalk_test.go | 130 ---- pkg/outputs/amqp/amqp.go | 4 +- pkg/outputs/amqp/amqp_test.go | 81 ++- pkg/outputs/client.go | 4 +- pkg/outputs/console/config.go | 2 +- pkg/outputs/console/console.go | 18 +- pkg/outputs/elasticsearch/elasticsearch.go | 14 +- .../elasticsearch/elasticsearch_test.go | 79 ++- pkg/outputs/elasticsearch/index.go | 6 +- pkg/outputs/elasticsearch/index_test.go | 10 +- pkg/outputs/elasticsearch/template.go | 2 +- pkg/outputs/eventlog/config.go | 4 +- pkg/outputs/eventlog/eventlog.go | 34 +- pkg/outputs/eventlog/eventlog_test.go | 35 +- pkg/outputs/eventlog/mc/gen.go | 10 +- pkg/outputs/http/http.go | 4 +- pkg/outputs/http/http_test.go | 79 ++- pkg/outputs/null/null.go | 4 +- pkg/pe/marshaller.go | 8 +- pkg/pe/marshaller_test.go | 2 +- pkg/ps/snapshotter.go | 16 +- pkg/ps/snapshotter_mock.go | 30 +- pkg/ps/snapshotter_windows.go | 111 ++-- pkg/ps/snapshotter_windows_test.go | 431 +++++++------ pkg/ps/types/marshaller_windows.go | 24 +- pkg/ps/types/marshaller_windows_test.go | 4 +- pkg/ps/types/types_windows.go | 2 +- .../_fixtures/default/microsoft_edge.yml | 2 +- .../default/sequence_rule_simple.yml | 4 +- .../_fixtures/default/suspicious_domains.yml | 2 +- .../default/suspicious_module_loaded.yml | 2 +- ...suspicious_network_connecting_binaries.yml | 2 +- ..._error_reporting_and_wmi_provider_host.yml | 2 +- pkg/rules/_fixtures/kill_action.yml | 2 +- .../_fixtures/merged_filters/filter1.yml | 2 +- .../_fixtures/merged_filters/filter2.yml | 2 +- .../_fixtures/merged_filters/filter3.yml | 2 +- .../_fixtures/merged_filters/filter4.yml | 2 +- .../min_engine_version/fail/filter1.yml | 2 +- .../min_engine_version/fail/filter2.yml | 2 +- .../min_engine_version/fail/filter3.yml | 2 +- .../min_engine_version/ok/filter1.yml | 2 +- .../min_engine_version/ok/filter2.yml | 2 +- .../min_engine_version/ok/filter3.yml | 2 +- pkg/rules/_fixtures/sequence_rule_complex.yml | 6 +- pkg/rules/_fixtures/sequence_rule_ps_uuid.yml | 4 +- .../command_shell_spawned_chrome_browser.yml | 4 +- .../powershell_created_temp_file.yml | 4 +- .../process_spawned_by_powershell.yml | 2 +- .../spawn_chrome_browser.yml | 2 +- pkg/rules/_fixtures/simple_emit_alert.yml | 2 +- pkg/rules/_fixtures/simple_matches.yml | 2 +- .../_fixtures/simple_matches/filter1.yml | 2 +- .../_fixtures/simple_matches/filter2.yml | 2 +- .../_fixtures/simple_matches/filter3.yml | 2 +- .../_fixtures/simple_matches/filter4.yml | 2 +- pkg/rules/compiler.go | 34 +- pkg/rules/compiler_test.go | 12 +- pkg/rules/engine.go | 35 +- pkg/rules/engine_test.go | 227 ++++--- pkg/rules/sequence.go | 55 +- pkg/rules/sequence_test.go | 451 +++++++------ pkg/{ksource => source}/doc.go | 4 +- pkg/{ksource => source}/source.go | 10 +- pkg/symbolize/symbolizer.go | 67 +- pkg/symbolize/symbolizer_test.go | 113 ++-- pkg/sys/etw/etw.go | 20 +- pkg/util/eventlog/eventlog.go | 4 +- pkg/yara/config/config.go | 13 +- pkg/yara/config/config_test.go | 27 +- pkg/yara/scanner.go | 81 ++- pkg/yara/scanner_test.go | 255 ++++---- pkg/yara/types.go | 6 +- 241 files changed, 5506 insertions(+), 5585 deletions(-) rename pkg/{kcap/_fixtures/cap.kcap => cap/_fixtures/cap.cap} (100%) rename pkg/{kcap/_fixtures/cap1.kcap => cap/_fixtures/cap1.cap} (100%) rename pkg/{kcap/_fixtures/cap2.kcap => cap/_fixtures/cap2.cap} (100%) rename pkg/{kcap => cap}/config.go (98%) rename pkg/{kcap => cap}/header.go (70%) rename pkg/{kcap => cap}/reader.go (59%) rename pkg/{kcap => cap}/reader_unsupported.go (84%) rename pkg/{kcap => cap}/reader_windows.go (69%) rename pkg/{kcap => cap}/reader_windows_test.go (72%) rename pkg/{kcap => cap}/section/section.go (83%) rename pkg/{kcap => cap}/section/section_windows.go (89%) rename pkg/{kcap => cap}/section/section_windows_test.go (94%) rename pkg/{kcap => cap}/types_linux.go (64%) rename pkg/{kcap => cap}/types_windows.go (71%) rename pkg/{kcap => cap}/version/version_windows.go (90%) rename pkg/{kcap => cap}/writer.go (67%) rename pkg/{kcap => cap}/writer_unsupported.go (90%) rename pkg/{kcap => cap}/writer_windows.go (83%) rename pkg/{kcap => cap}/writer_windows_test.go (83%) rename pkg/{kevent => event}/_fixtures/handles.json (100%) rename pkg/{kevent => event}/batch.go (86%) rename pkg/{kevent => event}/batch_test.go (78%) rename pkg/{kevent/ktypes => event}/category.go (96%) rename pkg/{kevent => event}/doc.go (81%) rename pkg/{kevent => event}/enum.go (99%) rename pkg/{kevent/kevent.go => event/event.go} (79%) rename pkg/{kevent/kevent_windows.go => event/event_windows.go} (53%) rename pkg/{kevent/kevent_windows_test.go => event/event_windows_test.go} (59%) rename pkg/{kevent/ktypes => event}/eventset.go (93%) rename pkg/{kevent/ktypes => event}/eventset_test.go (98%) rename pkg/{kevent => event}/flags.go (99%) rename pkg/{kevent => event}/flags_test.go (98%) rename pkg/{kevent => event}/formatter.go (72%) rename pkg/{kevent => event}/formatter_test.go (79%) rename pkg/{kevent => event}/formatter_windows.go (66%) rename pkg/{kevent => event}/marshaller.go (99%) rename pkg/{kevent => event}/marshaller_test.go (71%) rename pkg/{kevent => event}/marshaller_windows.go (74%) rename pkg/{kevent/ktypes => event}/metainfo_windows.go (74%) rename pkg/{kevent/ktypes => event}/metainfo_windows_test.go (57%) rename pkg/{kevent/kparam.go => event/param.go} (61%) create mode 100644 pkg/event/param_test.go rename pkg/{kevent/kparam_windows.go => event/param_windows.go} (50%) rename pkg/{kevent/kparams/fields_windows.go => event/params/params_windows.go} (99%) create mode 100644 pkg/event/params/types.go rename pkg/{kevent/kparams => event/params}/types_windows.go (93%) rename pkg/{kevent => event}/queue.go (90%) rename pkg/{kevent => event}/queue_test.go (51%) rename pkg/{kevent => event}/sequencer_windows.go (92%) rename pkg/{kevent => event}/sequencer_windows_test.go (99%) rename pkg/{kevent => event}/stackwalk.go (92%) create mode 100644 pkg/event/stackwalk_test.go rename pkg/{kevent => event}/template.go (59%) rename pkg/{kevent/ktypes/ktypes_windows.go => event/types_windows.go} (92%) rename pkg/{kevent/ktypes/ktypes_windows_test.go => event/types_windows_test.go} (89%) create mode 100644 pkg/filament/dict.go rename pkg/filament/{kdict_test.go => dict_test.go} (76%) delete mode 100644 pkg/filament/kdict.go delete mode 100644 pkg/kevent/README.md delete mode 100644 pkg/kevent/kparam_test.go delete mode 100644 pkg/kevent/stackwalk_test.go rename pkg/{ksource => source}/doc.go (87%) rename pkg/{ksource => source}/source.go (91%) diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index 780abe967..95ce6d833 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -84,7 +84,7 @@ jobs: ./make.bat mc ./make.bat env: - TAGS: kcap,filament,yara,yara_static + TAGS: cap,filament,yara,yara_static - uses: actions/upload-artifact@v4 with: name: "fibratus-amd64.exe" @@ -176,7 +176,7 @@ jobs: export PKG_CONFIG_PATH=$(pwd)/pkg-config ./make.bat test env: - TAGS: kcap,yara,yara_static + TAGS: cap,yara,yara_static lint: runs-on: windows-latest diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 656aca943..1f08d0888 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -86,7 +86,7 @@ jobs: ./make.bat mc ./make.bat env: - TAGS: kcap,filament,yara,yara_static + TAGS: cap,filament,yara,yara_static - uses: actions/upload-artifact@v4 with: name: "fibratus-amd64.exe" @@ -158,7 +158,7 @@ jobs: export PKG_CONFIG_PATH=$(pwd)/pkg-config ./make.bat test env: - TAGS: kcap,yara,yara_static + TAGS: cap,yara,yara_static lint: runs-on: windows-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 43944be4d..df7a782eb 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -85,7 +85,7 @@ jobs: ./make.bat mc ./make.bat env: - TAGS: kcap,filament,yara,yara_static + TAGS: cap,filament,yara,yara_static - name: Install Wix shell: bash run: | diff --git a/.golangci.yml b/.golangci.yml index b107ad968..5cded955a 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,6 +1,6 @@ run: build-tags: - - kcap + - cap - filament deadline: 10m diff --git a/cmd/fibratus/app/capture/capture_windows.go b/cmd/fibratus/app/capture/capture_windows.go index 98dae1631..99b7ea2ba 100644 --- a/cmd/fibratus/app/capture/capture_windows.go +++ b/cmd/fibratus/app/capture/capture_windows.go @@ -29,7 +29,7 @@ import ( var Command = &cobra.Command{ Use: "capture [filter]", - Short: "Capture event stream to the kcap (capture) file", + Short: "Capture event stream to the cap (capture) file", RunE: capture, } diff --git a/cmd/fibratus/app/list/list.go b/cmd/fibratus/app/list/list.go index d9aeb124a..92ab1eff6 100644 --- a/cmd/fibratus/app/list/list.go +++ b/cmd/fibratus/app/list/list.go @@ -24,8 +24,8 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rabbitstack/fibratus/internal/bootstrap" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/spf13/cobra" "os" "path/filepath" @@ -34,7 +34,7 @@ import ( var Command = &cobra.Command{ Use: "list", - Short: "Show info about filaments, filter fields or kernel event types", + Short: "Show info about filaments, filter fields or event types", } var listFilamentsCmd = &cobra.Command{ @@ -50,10 +50,9 @@ var listFieldsCmd = &cobra.Command{ } var listEventsCmd = &cobra.Command{ - Use: "kevents", - Aliases: []string{"events"}, - Short: "List supported kernel event types", - Run: listEvents, + Use: "events", + Short: "List supported event types", + Run: listEvents, } var cfg = config.NewWithOpts(config.WithList()) @@ -131,8 +130,8 @@ func listEvents(cmd *cobra.Command, args []string) { t.AppendHeader(table.Row{"Name", "Category", "Description"}) t.SetStyle(table.StyleLight) - for _, ktyp := range ktypes.GetKtypesMeta() { - t.AppendRow(table.Row{ktyp.Name, ktyp.Category, ktyp.Description}) + for _, ev := range event.GetTypesMeta() { + t.AppendRow(table.Row{ev.Name, ev.Category, ev.Description}) } t.Render() diff --git a/cmd/fibratus/app/replay/replay_windows.go b/cmd/fibratus/app/replay/replay_windows.go index e30301217..f9e891184 100644 --- a/cmd/fibratus/app/replay/replay_windows.go +++ b/cmd/fibratus/app/replay/replay_windows.go @@ -28,7 +28,7 @@ import ( var Command = &cobra.Command{ Use: "replay", - Short: "Replay event stream from the kcap (capture) file", + Short: "Replay event stream from the cap (capture) file", RunE: replay, } diff --git a/cmd/fibratus/app/stats/stats.go b/cmd/fibratus/app/stats/stats.go index cd29c088d..1335217ed 100644 --- a/cmd/fibratus/app/stats/stats.go +++ b/cmd/fibratus/app/stats/stats.go @@ -47,13 +47,13 @@ func init() { type Stats struct { AggregatorBatchEvents int `json:"aggregator.batch.events"` AggregatorFlushesCount int `json:"aggregator.flushes.count"` - AggregatorKeventErrors int `json:"aggregator.kevent.errors"` + AggregatorEventErrors int `json:"aggregator.event.errors"` AggregatorTransformerErrors map[string]int `json:"aggregator.transformer.errors"` AggregatorWorkerClientPublishErrors int `json:"aggregator.worker.client.publish.errors"` - FilamentKdictErrors int `json:"filament.kdict.errors"` - FilamentKeventBatchFlushes int `json:"filament.kevent.batch.flushes"` - FilamentKeventErrors map[string]int `json:"filament.kevent.errors"` - FilamentKeventProcessErrors int `json:"filament.kevent.process.errors"` + FilamentDictErrors int `json:"filament.dict.errors"` + FilamentEventBatchFlushes int `json:"filament.event.batch.flushes"` + FilamentEventErrors map[string]int `json:"filament.event.errors"` + FilamentEventProcessErrors int `json:"filament.event.process.errors"` FilterAccessorErrors map[string]int `json:"filter.accessor.errors"` FsFileObjectHandleHits int `json:"fs.file.object.handle.hits"` FsFileObjectMisses int `json:"fs.file.object.misses"` @@ -67,28 +67,27 @@ type Stats struct { HandleTypeNameMisses int `json:"handle.type.name.misses"` HandleWaitTimeouts int `json:"handle.wait.timeouts"` HostnameErrors map[string]int `json:"hostname.errors"` - KcapFlusherErrors map[string]int `json:"kcap.flusher.errors"` - KcapHandleWriteErrors int `json:"kcap.handle.write.errors"` - KcapKeventUnmarshalErrors int `json:"kcap.kevent.unmarshal.errors"` - KcapKeventWriteErrors int `json:"kcap.kevent.write.errors"` - KcapKstreamConsumerErrors int `json:"kcap.kstream.consumer.errors"` - KcapOverflowErrors int `json:"kcap.overflow.errors"` - KcapReadBytes int `json:"kcap.read.bytes"` - KcapReadKevents int `json:"kcap.read.kevents"` - KcapReaderDroppedByFilter int `json:"kcap.reader.dropped.by.filter"` - KcapReaderHandleUnmarshalErrors int `json:"kcap.reader.handle.unmarshal.errors"` - KeventPrcoessorFailures int `json:"kevent.processor.failures"` - KeventSeqInitErrors map[string]int `json:"kevent.seq.init.errors"` - KeventSeqStoreErrors int `json:"kevent.seq.store.errors"` - KeventTimestampUnmarshalErrors int `json:"kevent.timestamp.unmarshal.errors"` - KstreamDroppedKevents int `json:"kstream.dropped.kevents"` - KstreamKbuffersRead int `json:"kstream.kbuffers.read"` - KstreamKeventsEnqueued int `json:"kstream.kevents.enqueued"` - KstreamKeventsDequeued int `json:"kstream.kevents.dequeued"` - KstreamUnknownKevents int `json:"kstream.kevents.unknown"` - KstreamKeventsProcessed int `json:"kstream.kevents.processed"` - KstreamExcludedKevents int `json:"kstream.excluded.kevents"` - KstreamKeventsFailures map[string]int `json:"kstream.kevents.failures"` + CapFlusherErrors map[string]int `json:"cap.flusher.errors"` + CapHandleWriteErrors int `json:"cap.handle.write.errors"` + CapEventUnmarshalErrors int `json:"cap.event.unmarshal.errors"` + CapEventWriteErrors int `json:"cap.event.write.errors"` + CapEventSourceConsumerErrors int `json:"cap.eventsource.consumer.errors"` + CapOverflowErrors int `json:"cap.overflow.errors"` + CapReadBytes int `json:"cap.read.bytes"` + CapReadEvents int `json:"cap.read.events"` + CapReaderDroppedByFilter int `json:"cap.reader.dropped.by.filter"` + CapReaderHandleUnmarshalErrors int `json:"cap.reader.handle.unmarshal.errors"` + EventProcessorFailures int `json:"event.processor.failures"` + EventSeqInitErrors map[string]int `json:"event.seq.init.errors"` + EventSeqStoreErrors int `json:"event.seq.store.errors"` + EventTimestampUnmarshalErrors int `json:"event.timestamp.unmarshal.errors"` + EventSourceBuffersRead int `json:"eventsource.buffers.read"` + EventSourceEventsEnqueued int `json:"eventsource.events.enqueued"` + EventSourceEventsDequeued int `json:"eventsource.events.dequeued"` + EventSourceUnknownEvents int `json:"eventsource.events.unknown"` + EventSourceEventsProcessed int `json:"eventsource.events.processed"` + EventSourceExcludedEvents int `json:"eventsource.excluded.events"` + EventSourceEventsFailures map[string]int `json:"eventsource.events.failures"` LoggerErrors map[string]int `json:"logger.errors"` OutputAMQPChannelFailures int `json:"output.amqp.channel.failures"` OutputAMQPConnectionFailures int `json:"output.amqp.connection.failures"` diff --git a/filaments/fishy_netio.py b/filaments/fishy_netio.py index 87451de3f..a15570019 100644 --- a/filaments/fishy_netio.py +++ b/filaments/fishy_netio.py @@ -29,24 +29,23 @@ def on_init(): - kfilter("kevt.category = 'net' and ps.name in (%s)" % (', '.join([f'\'{ps}\'' for ps in __procs__]))) + set_filter("evt.category = 'net' and ps.name in (%s)" % (', '.join([f'\'{ps}\'' for ps in __procs__]))) @dotdictify -def on_next_kevent(kevent): - print(kevent) - notify = True if kevent.pid in __pids__ else False +def on_next_event(event): + notify = True if event.pid in __pids__ else False if not notify: emit_alert( - f'Anomalous network I/O detected to {kevent.kparams.dip}:{kevent.kparams.dport}', - text(kevent), + f'Anomalous network I/O detected to {event.params.dip}:{event.params.dport}', + text(Event), severity='critical', tags=['anomalous netio'] ) - __pids__.append(kevent.pid) + __pids__.append(event.pid) -def text(kevent): +def text(event): return """ Source IP: %s @@ -63,11 +62,11 @@ def text(kevent): User: %s """ % ( - kevent.kparams.sip, - kevent.kparams.sport, - kevent.kparams.dip, - kevent.kparams.dport, - kevent.kparams.dport_name, - kevent.exe, - kevent.comm, - kevent.cwd, kevent.sid) + event.params.sip, + event.params.sport, + event.params.dip, + event.params.dport, + event.params.dport_name, + event.exe, + event.comm, + event.cwd, event.sid) diff --git a/filaments/teamviewer_remote_file_copy.py b/filaments/teamviewer_remote_file_copy.py index e103dbbc4..5e8ae067b 100644 --- a/filaments/teamviewer_remote_file_copy.py +++ b/filaments/teamviewer_remote_file_copy.py @@ -52,16 +52,16 @@ def on_init(): - kfilter("kevt.name = 'CreateFile' and ps.name = 'TeamViewer.exe' and file.operation = 'create' " + kfilter("evt.name = 'CreateFile' and ps.name = 'TeamViewer.exe' and file.operation = 'create' " "and file.extension in (%s)" % (', '.join([f'\'{ext}\'' for ext in extensions]))) @dotdictify -def on_next_kevent(kevent): +def on_next_kevent(event): emit_alert( f'Remote File Copy via TeamViewer', - f'TeamViewer downloaded an executable or script file {kevent.kparams.file_name} via transfer session', + f'TeamViewer downloaded an executable or script file {event.params.file_name} via transfer session', severity=__severity__, tags=[__tags__] ) diff --git a/filaments/top_in_packets.py b/filaments/top_in_packets.py index fa51db168..5edd1f35d 100644 --- a/filaments/top_in_packets.py +++ b/filaments/top_in_packets.py @@ -25,15 +25,15 @@ def on_init(): - kfilter("kevt.name = 'Recv'") + set_filter("evt.name = 'Recv'") columns(["Source", "Count"]) sort_by('Count') interval(1) @dotdictify -def on_next_kevent(kevent): - src = ['%s:%d' % (kevent.kparams.sip, kevent.kparams.sport)] +def on_next_event(event): + src = ['%s:%d' % (event.params.sip, event.params.sport)] __connections__.update(src) diff --git a/filaments/top_keys.py b/filaments/top_keys.py index d8580bae8..6dcf7ddf6 100644 --- a/filaments/top_keys.py +++ b/filaments/top_keys.py @@ -26,15 +26,15 @@ def on_init(): - kfilter("kevt.category = 'registry'") + set_filter("evt.category = 'registry'") columns(["Key", "#Ops"]) sort_by('#Ops') interval(1) @dotdictify -def on_next_kevent(kevent): - key = kevent.kparams.key_name +def on_next_event(event): + key = event.params.key_name if key: __keys__.update((key, )) diff --git a/filaments/top_out_packets.py b/filaments/top_out_packets.py index ac00e10b2..25bdb61ad 100644 --- a/filaments/top_out_packets.py +++ b/filaments/top_out_packets.py @@ -25,15 +25,15 @@ def on_init(): - kfilter("kevt.name = 'Send'") + set_filter("evt.name = 'Send'") columns(["Destination", "Count"]) sort_by('Count') interval(1) @dotdictify -def on_next_kevent(kevent): - dst = ['%s:%d' % (kevent.kparams.dip, kevent.kparams.dport)] +def on_next_event(event): + dst = ['%s:%d' % (event.params.dip, event.params.dport)] __connections__.update(dst) diff --git a/filaments/utils/dotdict.py b/filaments/utils/dotdict.py index bda93f304..9aec3260a 100644 --- a/filaments/utils/dotdict.py +++ b/filaments/utils/dotdict.py @@ -10,8 +10,8 @@ def dotdictify(fn): """ The decorator for converting the dict parameter to dot notation access dictionary. """ - def __wrap(kevent): - kevent = dotdict(kevent) - kevent.kparams = dotdict(kevent.kparams) - return fn(kevent) + def __wrap(event): + event = dotdict(event) + event.params = dotdict(event.params) + return fn(event) return __wrap diff --git a/filaments/watch_files.py b/filaments/watch_files.py index 4fe4a5886..69da265fd 100644 --- a/filaments/watch_files.py +++ b/filaments/watch_files.py @@ -24,15 +24,15 @@ def on_init(): - kfilter("kevt.name = 'CreateFile' and file.operation != 'OPEN'") + set_filter("evt.name = 'CreateFile' and file.operation != 'OPEN'") columns(["Process", "File"]) @dotdictify -def on_next_kevent(kevent): - file_name = kevent.kparams.file_name +def on_next_event(event): + file_name = event.params.file_name if file_name: - __files__.append((kevent.exe, file_name, )) + __files__.append((event.exe, file_name, )) for f in __files__: add_row([f[0], f[1]]) render_table() diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 6c9c67e5a..395c8d4b5 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -24,11 +24,11 @@ import ( "github.com/rabbitstack/fibratus/pkg/aggregator" "github.com/rabbitstack/fibratus/pkg/alertsender" "github.com/rabbitstack/fibratus/pkg/api" + "github.com/rabbitstack/fibratus/pkg/cap" "github.com/rabbitstack/fibratus/pkg/config" "github.com/rabbitstack/fibratus/pkg/filament" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kcap" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/rules" "github.com/rabbitstack/fibratus/pkg/symbolize" @@ -58,8 +58,8 @@ type App struct { psnap ps.Snapshotter filament filament.Filament agg *aggregator.BufferedAggregator - writer kcap.Writer - reader kcap.Reader + writer cap.Writer + reader cap.Reader signals chan struct{} } @@ -120,7 +120,7 @@ func NewApp(cfg *config.Config, options ...Option) (*App, error) { sigs = signals.Install() } if opts.isCaptureReplay { - reader, err := kcap.NewReader(cfg.KcapFile, cfg) + reader, err := cap.NewReader(cfg.KcapFile, cfg) if err != nil { return nil, err } @@ -186,12 +186,12 @@ func (f *App) Run(args []string) error { // build the filter from the CLI argument. If we got // a valid expression the filter is attached to the // event consumer - kfilter, err := filter.NewFromCLI(args, cfg) + fltr, err := filter.NewFromCLI(args, cfg) if err != nil { return err } - if kfilter != nil { - f.evs.SetFilter(kfilter) + if fltr != nil { + f.evs.SetFilter(fltr) } // user can either instruct to bootstrap a filament or // start a regular run. We'll set up the corresponding @@ -277,18 +277,18 @@ func (f *App) WriteCapture(args []string) error { return ErrAlreadyRunning } - kfilter, err := filter.NewFromCLI(args, f.config) + fltr, err := filter.NewFromCLI(args, f.config) if err != nil { return err } - if kfilter != nil { - f.evs.SetFilter(kfilter) + if fltr != nil { + f.evs.SetFilter(fltr) } err = f.evs.Open(f.config) if err != nil { return err } - f.writer, err = kcap.NewWriter(f.config.KcapFile, f.psnap, f.hsnap) + f.writer, err = cap.NewWriter(f.config.KcapFile, f.psnap, f.hsnap) if err != nil { return err } @@ -306,7 +306,7 @@ func (f *App) ReadCapture(ctx context.Context, args []string) error { if f.reader == nil { panic("reader is nil") } - kfilter, err := filter.NewFromCLIWithAllAccessors(args) + fltr, err := filter.NewFromCLIWithAllAccessors(args) if err != nil { return err } @@ -323,10 +323,10 @@ func (f *App) ReadCapture(ctx context.Context, args []string) error { if f.filament.Filter() != nil { // filament filter overrides CLI filter f.reader.SetFilter(f.filament.Filter()) - } else if kfilter != nil { - f.reader.SetFilter(kfilter) + } else if fltr != nil { + f.reader.SetFilter(fltr) } - // returns the channel where events are read from the kcap + // returns the channel where events are read from the cap evts, errs := f.reader.Read(ctx) go func() { defer f.filament.Close() @@ -337,8 +337,8 @@ func (f *App) ReadCapture(ctx context.Context, args []string) error { } }() } else { - if kfilter != nil { - f.reader.SetFilter(kfilter) + if fltr != nil { + f.reader.SetFilter(fltr) } // use the channels where events are read // from the capture as aggregator source diff --git a/internal/bootstrap/source.go b/internal/bootstrap/source.go index 6a8eb8f3e..683ee22f9 100644 --- a/internal/bootstrap/source.go +++ b/internal/bootstrap/source.go @@ -21,11 +21,11 @@ package bootstrap import ( "github.com/rabbitstack/fibratus/internal/etw" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/ksource" "github.com/rabbitstack/fibratus/pkg/ps" + "github.com/rabbitstack/fibratus/pkg/source" ) // EventSourceControl abstracts away the management of event sources. @@ -37,7 +37,7 @@ import ( // of telemetry than the ETW subsystem. In this scenario, the event source // control will bootstrap the instrumentation engine based on eBPF. type EventSourceControl struct { - evs ksource.EventSource + evs source.EventSource } func NewEventSourceControl( @@ -61,7 +61,7 @@ func (s *EventSourceControl) Errors() <-chan error { return s.evs.Errors() } -func (s *EventSourceControl) Events() <-chan *kevent.Kevent { +func (s *EventSourceControl) Events() <-chan *event.Event { return s.evs.Events() } @@ -69,6 +69,6 @@ func (s *EventSourceControl) SetFilter(f filter.Filter) { s.evs.SetFilter(f) } -func (s *EventSourceControl) RegisterEventListener(lis kevent.Listener) { +func (s *EventSourceControl) RegisterEventListener(lis event.Listener) { s.evs.RegisterEventListener(lis) } diff --git a/internal/etw/consumer.go b/internal/etw/consumer.go index a1b8ccefd..f3d4cff65 100644 --- a/internal/etw/consumer.go +++ b/internal/etw/consumer.go @@ -21,10 +21,9 @@ package etw import ( "github.com/rabbitstack/fibratus/internal/etw/processors" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/sys/etw" ) @@ -36,8 +35,8 @@ import ( // with additional attributes. The event is sent to the queue where // all registered listeners are executed. type Consumer struct { - q *kevent.Queue - sequencer *kevent.Sequencer + q *event.Queue + sequencer *event.Sequencer processors processors.Chain psnap ps.Snapshotter config *config.Config @@ -50,11 +49,11 @@ func NewConsumer( psnap ps.Snapshotter, hsnap handle.Snapshotter, config *config.Config, - sequencer *kevent.Sequencer, - evts chan *kevent.Kevent, + sequencer *event.Sequencer, + evts chan *event.Event, ) *Consumer { return &Consumer{ - q: kevent.NewQueueWithChannel(evts, config.Kstream.StackEnrichment, config.ForwardMode || config.IsCaptureSet()), + q: event.NewQueueWithChannel(evts, config.Kstream.StackEnrichment, config.ForwardMode || config.IsCaptureSet()), sequencer: sequencer, processors: processors.NewChain(psnap, hsnap, config), psnap: psnap, @@ -75,22 +74,22 @@ func (c *Consumer) ProcessEvent(ev *etw.EventRecord) error { if c.isClosing { return nil } - if kevent.IsCurrentProcDropped(ev.Header.ProcessID) { + if event.IsCurrentProcDropped(ev.Header.ProcessID) { return nil } if c.config.Kstream.ExcludeKevent(ev.Header.ProviderID, ev.HookID()) { - excludedKevents.Add(1) + eventsExcluded.Add(1) return nil } - ktype := ktypes.NewFromEventRecord(ev) - if !ktype.Exists() { - keventsUnknown.Add(1) + etype := event.NewFromEventRecord(ev) + if !etype.Exists() { + eventsUnknown.Add(1) return nil } - keventsProcessed.Add(1) - evt := kevent.New(c.sequencer.Get(), ktype, ev) + eventsProcessed.Add(1) + evt := event.New(c.sequencer.Get(), etype, ev) // Dispatch each event to the processor chain. // Processors may further augment the event with @@ -131,7 +130,7 @@ func (c *Consumer) ProcessEvent(ev *etw.EventRecord) error { // decide whether it should get dropped if (evt.IsDropped(c.config.IsCaptureSet()) || c.config.Kstream.ExcludeImage(evt.PS)) && !evt.IsStackWalk() { - keventsDropped.Add(1) + eventsExcluded.Add(1) return nil } if c.filter != nil && !evt.IsStackWalk() && !c.filter.Run(evt) { diff --git a/internal/etw/processors/chain.go b/internal/etw/processors/chain.go index e2e19fa5f..81012a919 100644 --- a/internal/etw/processors/chain.go +++ b/internal/etw/processors/chain.go @@ -21,19 +21,19 @@ package processors import ( "expvar" "fmt" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/util/multierror" ) // processorFailures counts the number of failures caused by event processors -var processorFailures = expvar.NewInt("kevent.processor.failures") +var processorFailures = expvar.NewInt("event.processor.failures") // Chain defines the event process chain has to satisfy. type Chain interface { // ProcessEvent pushes the event into processor chain. Processors are applied sequentially, so we have to make // sure that any processor providing additional context to the next processor is defined first in the chain. If // one processor fails, the next processor in chain is invoked. - ProcessEvent(kevt *kevent.Kevent) (*kevent.Kevent, error) + ProcessEvent(evt *event.Event) (*event.Event, error) // Close closes the processor chain and frees all allocated resources. Close() error } @@ -45,14 +45,14 @@ func (c *chain) addProcessor(processor Processor) { c.processors = append(c.processors, processor) } -func (c chain) ProcessEvent(kevt *kevent.Kevent) (*kevent.Kevent, error) { +func (c chain) ProcessEvent(e *event.Event) (*event.Event, error) { var errs = make([]error, 0) - var evt *kevent.Kevent + var evt *event.Event for _, processor := range c.processors { var err error var next bool - evt, next, err = processor.ProcessEvent(kevt) + evt, next, err = processor.ProcessEvent(e) if err != nil { processorFailures.Add(1) errs = append(errs, fmt.Errorf("%q processor failed with error: %v", processor.Name(), err)) diff --git a/internal/etw/processors/fs_windows.go b/internal/etw/processors/fs_windows.go index 0f46dca0b..b1090ee60 100644 --- a/internal/etw/processors/fs_windows.go +++ b/internal/etw/processors/fs_windows.go @@ -21,12 +21,11 @@ package processors import ( "expvar" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -56,14 +55,14 @@ type fsProcessor struct { psnap ps.Snapshotter // irps contains a mapping between the IRP (I/O request packet) and CreateFile events - irps map[uint64]*kevent.Kevent + irps map[uint64]*event.Event devMapper fs.DevMapper devPathResolver fs.DevPathResolver config *config.Config // buckets stores stack walk events per stack id - buckets map[uint64][]*kevent.Kevent + buckets map[uint64][]*event.Event mu sync.Mutex purger *time.Ticker @@ -87,13 +86,13 @@ func newFsProcessor( ) Processor { f := &fsProcessor{ files: make(map[uint64]*FileInfo), - irps: make(map[uint64]*kevent.Kevent), + irps: make(map[uint64]*event.Event), hsnap: hsnap, psnap: psnap, devMapper: devMapper, devPathResolver: devPathResolver, config: config, - buckets: make(map[uint64][]*kevent.Kevent), + buckets: make(map[uint64][]*event.Event), purger: time.NewTicker(time.Second * 5), quit: make(chan struct{}, 1), lim: rate.NewLimiter(30, 40), // allow 30 parse ops per second or bursts of 40 ops @@ -104,8 +103,8 @@ func newFsProcessor( return f } -func (f *fsProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { - if e.Category == ktypes.File || e.IsStackWalk() { +func (f *fsProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { + if e.Category == event.File || e.IsStackWalk() { evt, err := f.processEvent(e) return evt, false, err } @@ -119,14 +118,14 @@ func (f *fsProcessor) getFileInfo(name string, opts uint32) *FileInfo { return &FileInfo{Name: name, Type: fs.GetFileType(name, opts)} } -func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { +func (f *fsProcessor) processEvent(e *event.Event) (*event.Event, error) { switch e.Type { - case ktypes.FileRundown: + case event.FileRundown: // when the file rundown event comes in we store the file info // in internal state in order to augment the rest of file events // that lack the file path field - filepath := e.GetParamAsString(kparams.FilePath) - fileObject, err := e.Kparams.GetUint64(kparams.FileObject) + filepath := e.GetParamAsString(params.FilePath) + fileObject, err := e.Params.GetUint64(params.FileObject) if err != nil { return nil, err } @@ -134,35 +133,35 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { totalRundownFiles.Add(1) f.files[fileObject] = &FileInfo{Name: filepath, Type: fs.GetFileType(filepath, 0)} } - case ktypes.MapFileRundown: - fileKey := e.Kparams.MustGetUint64(kparams.FileKey) + case event.MapFileRundown: + fileKey := e.Params.MustGetUint64(params.FileKey) fileinfo := f.files[fileKey] if fileinfo != nil { totalMapRundownFiles.Add(1) - e.AppendParam(kparams.FilePath, kparams.Path, fileinfo.Name) + e.AppendParam(params.FilePath, params.Path, fileinfo.Name) } else { // if the view of section is backed by the data/image file // try to get the mapped file name and append it to params - sec := e.Kparams.MustGetUint32(kparams.FileViewSectionType) + sec := e.Params.MustGetUint32(params.FileViewSectionType) isMapped := sec != va.SectionPagefile && sec != va.SectionPhysical if isMapped { totalMapRundownFiles.Add(1) - addr := e.Kparams.MustGetUint64(kparams.FileViewBase) + (e.Kparams.MustGetUint64(kparams.FileOffset)) - e.AppendParam(kparams.FilePath, kparams.Path, f.getMappedFile(e.PID, addr)) + addr := e.Params.MustGetUint64(params.FileViewBase) + (e.Params.MustGetUint64(params.FileOffset)) + e.AppendParam(params.FilePath, params.Path, f.getMappedFile(e.PID, addr)) } } return e, f.psnap.AddMmap(e) - case ktypes.CreateFile: + case event.CreateFile: // we defer the processing of the CreateFile event until we get // the matching FileOpEnd event. This event contains the operation // that was done on behalf of the file, e.g. create or open. - irp := e.Kparams.MustGetUint64(kparams.FileIrpPtr) + irp := e.Params.MustGetUint64(params.FileIrpPtr) e.WaitEnqueue = true f.irps[irp] = e - case ktypes.StackWalk: - if !kevent.IsCurrentProcDropped(e.PID) { + case event.StackWalk: + if !event.IsCurrentProcDropped(e.PID) { f.mu.Lock() defer f.mu.Unlock() @@ -170,18 +169,18 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { id := e.StackID() q, ok := f.buckets[id] if !ok { - f.buckets[id] = []*kevent.Kevent{e} + f.buckets[id] = []*event.Event{e} } else { f.buckets[id] = append(q, e) } } - case ktypes.FileOpEnd: + case event.FileOpEnd: // get the CreateFile pending event by IRP identifier // and fetch the file create disposition value var ( - irp = e.Kparams.MustGetUint64(kparams.FileIrpPtr) - dispo = e.Kparams.MustGetUint64(kparams.FileExtraInfo) - status = e.Kparams.MustGetUint32(kparams.NTStatus) + irp = e.Params.MustGetUint64(params.FileIrpPtr) + dispo = e.Params.MustGetUint64(params.FileExtraInfo) + status = e.Params.MustGetUint32(params.NTStatus) ) if dispo > windows.FILE_MAXIMUM_DISPOSITION { @@ -196,28 +195,28 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { // reset the wait status to allow passage of this event to // the aggregator queue. Additionally, append params to it ev.WaitEnqueue = false - fileObject := ev.Kparams.MustGetUint64(kparams.FileObject) + fileObject := ev.Params.MustGetUint64(params.FileObject) // try to get extended file info. If the file object is already // present in the map, we'll reuse the existing file information fileinfo, ok := f.files[fileObject] if !ok { - opts := ev.Kparams.MustGetUint32(kparams.FileCreateOptions) + opts := ev.Params.MustGetUint32(params.FileCreateOptions) opts &= 0xFFFFFF - filepath := ev.GetParamAsString(kparams.FilePath) + filepath := ev.GetParamAsString(params.FilePath) fileinfo = f.getFileInfo(filepath, opts) f.files[fileObject] = fileinfo } if f.config.Kstream.EnableHandleKevents { - f.devPathResolver.AddPath(ev.GetParamAsString(kparams.FilePath)) + f.devPathResolver.AddPath(ev.GetParamAsString(params.FilePath)) } - ev.AppendParam(kparams.NTStatus, kparams.Status, status) + ev.AppendParam(params.NTStatus, params.Status, status) if fileinfo.Type != fs.Unknown { - ev.AppendEnum(kparams.FileType, uint32(fileinfo.Type), fs.FileTypes) + ev.AppendEnum(params.FileType, uint32(fileinfo.Type), fs.FileTypes) } - ev.AppendEnum(kparams.FileOperation, uint32(dispo), fs.FileCreateDispositions) + ev.AppendEnum(params.FileOperation, uint32(dispo), fs.FileCreateDispositions) // attach stack walk return addresses. CreateFile events // represent an edge case in callstack enrichment. Since @@ -236,10 +235,10 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { id := ev.StackID() q, ok := f.buckets[id] if ok && len(q) > 0 { - var s *kevent.Kevent + var s *event.Event s, f.buckets[id] = q[len(q)-1], q[:len(q)-1] - callstack := s.Kparams.MustGetSlice(kparams.Callstack) - ev.AppendParam(kparams.Callstack, kparams.Slice, callstack) + callstack := s.Params.MustGetSlice(params.Callstack) + ev.AppendParam(params.Callstack, params.Slice, callstack) } } @@ -249,30 +248,30 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { fsFileCharacteristicsRateLimits.Add(1) return ev, nil } - path := ev.GetParamAsString(kparams.FilePath) + path := ev.GetParamAsString(params.FilePath) c, err := parseImageFileCharacteristics(path) if err != nil { return ev, nil } - ev.AppendParam(kparams.FileIsDLL, kparams.Bool, c.isDLL) - ev.AppendParam(kparams.FileIsDriver, kparams.Bool, c.isDriver) - ev.AppendParam(kparams.FileIsExecutable, kparams.Bool, c.isExe) - ev.AppendParam(kparams.FileIsDotnet, kparams.Bool, c.isDotnet) + ev.AppendParam(params.FileIsDLL, params.Bool, c.isDLL) + ev.AppendParam(params.FileIsDriver, params.Bool, c.isDriver) + ev.AppendParam(params.FileIsExecutable, params.Bool, c.isExe) + ev.AppendParam(params.FileIsDotnet, params.Bool, c.isDotnet) } return ev, nil - case ktypes.ReleaseFile: + case event.ReleaseFile: fileReleaseCount.Add(1) // delete file metadata by file object address - fileObject := e.Kparams.MustGetUint64(kparams.FileObject) + fileObject := e.Params.MustGetUint64(params.FileObject) delete(f.files, fileObject) - case ktypes.UnmapViewFile: + case event.UnmapViewFile: ok, proc := f.psnap.Find(e.PID) - addr := e.Kparams.TryGetAddress(kparams.FileViewBase) + addr := e.Params.TryGetAddress(params.FileViewBase) if ok { mmap := proc.FindMmap(addr) if mmap != nil { - e.AppendParam(kparams.FilePath, kparams.Path, mmap.File) + e.AppendParam(params.FilePath, params.Path, mmap.File) } } @@ -281,10 +280,10 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { return e, f.psnap.RemoveMmap(e.PID, addr) default: var fileObject uint64 - fileKey := e.Kparams.MustGetUint64(kparams.FileKey) + fileKey := e.Params.MustGetUint64(params.FileKey) if !e.IsMapViewFile() { - fileObject = e.Kparams.MustGetUint64(kparams.FileObject) + fileObject = e.Params.MustGetUint64(params.FileObject) } // attempt to get the file by file key. If there is no such file referenced @@ -294,12 +293,12 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { // try to resolve mapped file name if not found in internal state if fileinfo == nil && e.IsMapViewFile() { - sec := e.Kparams.MustGetUint32(kparams.FileViewSectionType) + sec := e.Params.MustGetUint32(params.FileViewSectionType) isMapped := sec != va.SectionPagefile && sec != va.SectionPhysical if isMapped { totalMapRundownFiles.Add(1) - addr := e.Kparams.MustGetUint64(kparams.FileViewBase) + (e.Kparams.MustGetUint64(kparams.FileOffset)) - e.AppendParam(kparams.FilePath, kparams.Path, f.getMappedFile(e.PID, addr)) + addr := e.Params.MustGetUint64(params.FileViewBase) + (e.Params.MustGetUint64(params.FileOffset)) + e.AppendParam(params.FilePath, params.Path, f.getMappedFile(e.PID, addr)) } } @@ -313,16 +312,16 @@ func (f *fsProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { } if e.IsEnumDirectory() { if fileinfo != nil { - e.AppendParam(kparams.FileDirectory, kparams.Path, fileinfo.Name) + e.AppendParam(params.FileDirectory, params.Path, fileinfo.Name) } return e, nil } if fileinfo != nil { if fileinfo.Type != fs.Unknown { - e.AppendEnum(kparams.FileType, uint32(fileinfo.Type), fs.FileTypes) + e.AppendEnum(params.FileType, uint32(fileinfo.Type), fs.FileTypes) } - e.AppendParam(kparams.FilePath, kparams.Path, fileinfo.Name) + e.AppendParam(params.FilePath, params.Path, fileinfo.Name) } if e.IsMapViewFile() { diff --git a/internal/etw/processors/fs_windows_test.go b/internal/etw/processors/fs_windows_test.go index d9e675834..6b754c7b4 100644 --- a/internal/etw/processors/fs_windows_test.go +++ b/internal/etw/processors/fs_windows_test.go @@ -20,12 +20,11 @@ package processors import ( "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -43,19 +42,19 @@ func TestFsProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent + e *event.Event setupProcessor func(Processor) hsnap func() *handle.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *handle.SnapshotterMock, Processor) + assertions func(*event.Event, *testing.T, *handle.SnapshotterMock, Processor) }{ { "process file rundown", - &kevent.Kevent{ - Type: ktypes.FileRundown, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(124567380264)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + &event.Event{ + Type: event.FileRundown, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(124567380264)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, }, }, nil, @@ -63,7 +62,7 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) assert.Contains(t, fsProcessor.files, uint64(124567380264)) file := fsProcessor.files[124567380264] @@ -73,15 +72,15 @@ func TestFsProcessor(t *testing.T) { }, { "process mapped file rundown", - &kevent.Kevent{ + &event.Event{ PID: 10233, - Type: ktypes.MapFileRundown, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(124567380264)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(3098)}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Uint64, Value: uint64(0xffff23433)}, - kparams.FileViewSectionType: {Name: kparams.FileViewSectionType, Type: kparams.Enum, Value: uint32(va.SectionImage), Enum: kevent.ViewSectionTypes}, + Type: event.MapFileRundown, + Category: event.File, + Params: event.Params{ + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(124567380264)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(3098)}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Uint64, Value: uint64(0xffff23433)}, + params.FileViewSectionType: {Name: params.FileViewSectionType, Type: params.Enum, Value: uint32(va.SectionImage), Enum: event.ViewSectionTypes}, }, }, func(p Processor) { @@ -92,10 +91,10 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) - assert.Equal(t, "C:\\Windows\\System32\\kernel32.dll", e.GetParamAsString(kparams.FilePath)) + assert.Equal(t, "C:\\Windows\\System32\\kernel32.dll", e.GetParamAsString(params.FilePath)) psnap := fsProcessor.psnap.(*ps.SnapshotterMock) psnap.AssertNumberOfCalls(t, "AddMmap", 1) @@ -103,16 +102,16 @@ func TestFsProcessor(t *testing.T) { }, { "wait enqueue for create file events", - &kevent.Kevent{ - Type: ktypes.CreateFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.Uint32, Value: uint32(1484)}, - kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(1223456)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, - kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, - kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1234543123112321)}, + &event.Event{ + Type: event.CreateFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.ThreadID: {Name: params.ThreadID, Type: params.Uint32, Value: uint32(1484)}, + params.FileCreateOptions: {Name: params.FileCreateOptions, Type: params.Uint32, Value: uint32(1223456)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + params.FileShareMask: {Name: params.FileShareMask, Type: params.Uint32, Value: uint32(5)}, + params.FileIrpPtr: {Name: params.FileIrpPtr, Type: params.Uint64, Value: uint64(1234543123112321)}, }, }, nil, @@ -120,7 +119,7 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) assert.True(t, e.WaitEnqueue) assert.Contains(t, fsProcessor.irps, uint64(1234543123112321)) @@ -129,27 +128,27 @@ func TestFsProcessor(t *testing.T) { }, { "get IRP completion for create file event", - &kevent.Kevent{ - Type: ktypes.FileOpEnd, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.FileExtraInfo: {Name: kparams.FileExtraInfo, Type: kparams.Uint64, Value: uint64(2)}, - kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1334543123112321)}, - kparams.NTStatus: {Name: kparams.NTStatus, Type: kparams.Status, Value: uint32(0)}, + &event.Event{ + Type: event.FileOpEnd, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.FileExtraInfo: {Name: params.FileExtraInfo, Type: params.Uint64, Value: uint64(2)}, + params.FileIrpPtr: {Name: params.FileIrpPtr, Type: params.Uint64, Value: uint64(1334543123112321)}, + params.NTStatus: {Name: params.NTStatus, Type: params.Status, Value: uint32(0)}, }, }, func(p Processor) { fsProcessor := p.(*fsProcessor) - fsProcessor.irps[1334543123112321] = &kevent.Kevent{ - Type: ktypes.CreateFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12446738026482168384)}, - kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(18874368)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: exe}, - kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, - kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1334543123112321)}, + fsProcessor.irps[1334543123112321] = &event.Event{ + Type: event.CreateFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12446738026482168384)}, + params.FileCreateOptions: {Name: params.FileCreateOptions, Type: params.Uint32, Value: uint32(18874368)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: exe}, + params.FileShareMask: {Name: params.FileShareMask, Type: params.Uint32, Value: uint32(5)}, + params.FileIrpPtr: {Name: params.FileIrpPtr, Type: params.Uint64, Value: uint64(1334543123112321)}, }, } }, @@ -157,30 +156,30 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) - assert.Equal(t, ktypes.CreateFile, e.Type) + assert.Equal(t, event.CreateFile, e.Type) assert.NotContains(t, fsProcessor.irps, uint64(1334543123112321)) assert.False(t, e.WaitEnqueue) assert.Contains(t, fsProcessor.files, uint64(12446738026482168384)) assert.Equal(t, exe, fsProcessor.files[12446738026482168384].Name) - assert.Equal(t, "Success", e.GetParamAsString(kparams.NTStatus)) - assert.Equal(t, "File", e.GetParamAsString(kparams.FileType)) - assert.Equal(t, "CREATE", e.GetParamAsString(kparams.FileOperation)) - assert.True(t, e.Kparams.MustGetBool(kparams.FileIsExecutable)) - assert.False(t, e.Kparams.MustGetBool(kparams.FileIsDotnet)) - assert.False(t, e.Kparams.MustGetBool(kparams.FileIsDLL)) - assert.False(t, e.Kparams.MustGetBool(kparams.FileIsDriver)) + assert.Equal(t, "Success", e.GetParamAsString(params.NTStatus)) + assert.Equal(t, "File", e.GetParamAsString(params.FileType)) + assert.Equal(t, "CREATE", e.GetParamAsString(params.FileOperation)) + assert.True(t, e.Params.MustGetBool(params.FileIsExecutable)) + assert.False(t, e.Params.MustGetBool(params.FileIsDotnet)) + assert.False(t, e.Params.MustGetBool(params.FileIsDLL)) + assert.False(t, e.Params.MustGetBool(params.FileIsDriver)) }, }, { "release file and remove file info", - &kevent.Kevent{ - Type: ktypes.ReleaseFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(14446538026482168384)}, + &event.Event{ + Type: event.ReleaseFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(14446538026482168384)}, }, }, func(p Processor) { @@ -191,24 +190,24 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) assert.Empty(t, fsProcessor.files) }, }, { "parse created file characteristics", - &kevent.Kevent{ - Type: ktypes.CreateFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.Uint32, Value: uint32(1484)}, - kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(1223456)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: exe}, - kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, - kparams.FileIrpPtr: {Name: kparams.FileIrpPtr, Type: kparams.Uint64, Value: uint64(1234543123112321)}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint64, Value: uint64(2)}, + &event.Event{ + Type: event.CreateFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.ThreadID: {Name: params.ThreadID, Type: params.Uint32, Value: uint32(1484)}, + params.FileCreateOptions: {Name: params.FileCreateOptions, Type: params.Uint32, Value: uint32(1223456)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: exe}, + params.FileShareMask: {Name: params.FileShareMask, Type: params.Uint32, Value: uint32(5)}, + params.FileIrpPtr: {Name: params.FileIrpPtr, Type: params.Uint64, Value: uint64(1234543123112321)}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint64, Value: uint64(2)}, }, }, nil, @@ -216,7 +215,7 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) assert.True(t, e.WaitEnqueue) assert.Contains(t, fsProcessor.irps, uint64(1234543123112321)) @@ -225,15 +224,15 @@ func TestFsProcessor(t *testing.T) { }, { "unmap view file", - &kevent.Kevent{ + &event.Event{ PID: 10233, - Type: ktypes.UnmapViewFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(124567380264)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(3098)}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Uint64, Value: uint64(0xffff23433)}, - kparams.FileViewSectionType: {Name: kparams.FileViewSectionType, Type: kparams.Enum, Value: uint32(va.SectionImage), Enum: kevent.ViewSectionTypes}, + Type: event.UnmapViewFile, + Category: event.File, + Params: event.Params{ + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(124567380264)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(3098)}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Uint64, Value: uint64(0xffff23433)}, + params.FileViewSectionType: {Name: params.FileViewSectionType, Type: params.Enum, Value: uint32(va.SectionImage), Enum: event.ViewSectionTypes}, }, }, nil, @@ -241,7 +240,7 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { fsProcessor := p.(*fsProcessor) psnap := fsProcessor.psnap.(*ps.SnapshotterMock) @@ -250,13 +249,13 @@ func TestFsProcessor(t *testing.T) { }, { "process write file", - &kevent.Kevent{ - Type: ktypes.WriteFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(14446538026482168384)}, - kparams.FileIoSize: {Name: kparams.FileIoSize, Type: kparams.Uint32, Value: uint32(1024)}, + &event.Event{ + Type: event.WriteFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(14446538026482168384)}, + params.FileIoSize: {Name: params.FileIoSize, Type: params.Uint32, Value: uint32(1024)}, }, }, func(p Processor) { @@ -267,22 +266,22 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, ktypes.WriteFile, e.Type) - assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileType) - assert.Equal(t, "C:\\Windows\\temp\\idxx.exe", e.GetParamAsString(kparams.FilePath)) - assert.Equal(t, "File", e.GetParamAsString(kparams.FileType)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, event.WriteFile, e.Type) + assert.Contains(t, e.Params, params.FilePath, params.FileType) + assert.Equal(t, "C:\\Windows\\temp\\idxx.exe", e.GetParamAsString(params.FilePath)) + assert.Equal(t, "File", e.GetParamAsString(params.FileType)) }, }, { "process write file consult handle snapshotter", - &kevent.Kevent{ - Type: ktypes.WriteFile, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(14446538026482168384)}, - kparams.FileIoSize: {Name: kparams.FileIoSize, Type: kparams.Uint32, Value: uint32(1024)}, + &event.Event{ + Type: event.WriteFile, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(14446538026482168384)}, + params.FileIoSize: {Name: params.FileIoSize, Type: params.Uint32, Value: uint32(1024)}, }, }, nil, @@ -291,23 +290,23 @@ func TestFsProcessor(t *testing.T) { hsnap.On("FindByObject", uint64(18446738026482168384)).Return(htypes.Handle{Type: handle.File, Name: "C:\\Windows\\temp\\doc.docx"}, true) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, ktypes.WriteFile, e.Type) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, event.WriteFile, e.Type) hsnap.AssertNumberOfCalls(t, "FindByObject", 1) - assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileType) - assert.Equal(t, "C:\\Windows\\temp\\doc.docx", e.GetParamAsString(kparams.FilePath)) - assert.Equal(t, "File", e.GetParamAsString(kparams.FileType)) + assert.Contains(t, e.Params, params.FilePath, params.FileType) + assert.Equal(t, "C:\\Windows\\temp\\doc.docx", e.GetParamAsString(params.FilePath)) + assert.Equal(t, "File", e.GetParamAsString(params.FileType)) }, }, { "process enum directory", - &kevent.Kevent{ - Type: ktypes.EnumDirectory, - Category: ktypes.File, - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.FileKey: {Name: kparams.FileKey, Type: kparams.Uint64, Value: uint64(14446538026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "*"}, + &event.Event{ + Type: event.EnumDirectory, + Category: event.File, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.FileKey: {Name: params.FileKey, Type: params.Uint64, Value: uint64(14446538026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "*"}, }, }, func(p Processor) { @@ -318,10 +317,10 @@ func TestFsProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, ktypes.EnumDirectory, e.Type) - assert.Contains(t, e.Kparams, kparams.FilePath, kparams.FileDirectory) - assert.Equal(t, "C:\\Windows\\temp", e.GetParamAsString(kparams.FileDirectory)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, event.EnumDirectory, e.Type) + assert.Contains(t, e.Params, params.FilePath, params.FileDirectory) + assert.Equal(t, "C:\\Windows\\temp", e.GetParamAsString(params.FileDirectory)) }, }, } diff --git a/internal/etw/processors/handle_windows.go b/internal/etw/processors/handle_windows.go index e054a24a4..453996c9a 100644 --- a/internal/etw/processors/handle_windows.go +++ b/internal/etw/processors/handle_windows.go @@ -19,11 +19,10 @@ package processors import ( + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/key" "strings" @@ -50,28 +49,28 @@ func newHandleProcessor( } } -func (h *handleProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { - if e.Category == ktypes.Handle { +func (h *handleProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { + if e.Category == event.Handle { evt, err := h.processEvent(e) return evt, false, err } return e, true, nil } -func (h *handleProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { - if e.Type == ktypes.DuplicateHandle { +func (h *handleProcessor) processEvent(e *event.Event) (*event.Event, error) { + if e.Type == event.DuplicateHandle { // enrich event with process parameters - pid := e.Kparams.MustGetPid() + pid := e.Params.MustGetPid() proc := h.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) - e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) + e.AppendParam(params.Exe, params.Path, proc.Exe) + e.AppendParam(params.ProcessName, params.AnsiString, proc.Name) } return e, nil } - name := e.GetParamAsString(kparams.HandleObjectName) - typ := e.GetParamAsString(kparams.HandleObjectTypeID) + name := e.GetParamAsString(params.HandleObjectName) + typ := e.GetParamAsString(params.HandleObjectTypeID) if name != "" { switch typ { @@ -93,15 +92,15 @@ func (h *handleProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) driverPath = driverName } h.devPathResolver.RemovePath(driverName) - e.Kparams.Append(kparams.ImagePath, kparams.Path, driverPath) + e.Params.Append(params.ImagePath, params.Path, driverPath) } // assign the formatted handle name - if err := e.Kparams.SetValue(kparams.HandleObjectName, name); err != nil { + if err := e.Params.SetValue(params.HandleObjectName, name); err != nil { return e, err } } - if e.Type == ktypes.CreateHandle { + if e.Type == event.CreateHandle { return e, h.hsnap.Write(e) } diff --git a/internal/etw/processors/handle_windows_test.go b/internal/etw/processors/handle_windows_test.go index e6c4258a8..c3b6b437d 100644 --- a/internal/etw/processors/handle_windows_test.go +++ b/internal/etw/processors/handle_windows_test.go @@ -19,11 +19,10 @@ package processors import ( + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" @@ -34,56 +33,56 @@ import ( func TestHandleProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent + e *event.Event hsnap func() *handle.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *handle.SnapshotterMock) + assertions func(*event.Event, *testing.T, *handle.SnapshotterMock) }{ { "process create handle", - &kevent.Kevent{ - Type: ktypes.CreateHandle, + &event.Event{ + Type: event.CreateHandle, Tid: 2484, PID: 859, - Category: ktypes.Handle, - Kparams: kevent.Kparams{ - kparams.HandleID: {Name: kparams.HandleID, Type: kparams.Uint32, Value: uint32(21)}, - kparams.HandleObjectTypeID: {Name: kparams.HandleObjectTypeID, Type: kparams.AnsiString, Value: "Key"}, - kparams.HandleObject: {Name: kparams.HandleObject, Type: kparams.Uint64, Value: uint64(18446692422059208560)}, - kparams.HandleObjectName: {Name: kparams.HandleObjectName, Type: kparams.UnicodeString, Value: ""}, + Category: event.Handle, + Params: event.Params{ + params.HandleID: {Name: params.HandleID, Type: params.Uint32, Value: uint32(21)}, + params.HandleObjectTypeID: {Name: params.HandleObjectTypeID, Type: params.AnsiString, Value: "Key"}, + params.HandleObject: {Name: params.HandleObject, Type: params.Uint64, Value: uint64(18446692422059208560)}, + params.HandleObjectName: {Name: params.HandleObjectName, Type: params.UnicodeString, Value: ""}, }, - Metadata: make(kevent.Metadata), + Metadata: make(event.Metadata), }, func() *handle.SnapshotterMock { hsnap := new(handle.SnapshotterMock) hsnap.On("Write", mock.Anything).Return(nil) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock) { hsnap.AssertNumberOfCalls(t, "Write", 1) }, }, { "process close handle", - &kevent.Kevent{ - Type: ktypes.CloseHandle, + &event.Event{ + Type: event.CloseHandle, Tid: 2484, PID: 859, - Category: ktypes.Handle, - Kparams: kevent.Kparams{ - kparams.HandleID: {Name: kparams.HandleID, Type: kparams.Uint32, Value: uint32(21)}, - kparams.HandleObjectTypeID: {Name: kparams.HandleObjectTypeID, Type: kparams.AnsiString, Value: "Key"}, - kparams.HandleObject: {Name: kparams.HandleObject, Type: kparams.Uint64, Value: uint64(18446692422059208560)}, - kparams.HandleObjectName: {Name: kparams.HandleObjectName, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`}, + Category: event.Handle, + Params: event.Params{ + params.HandleID: {Name: params.HandleID, Type: params.Uint32, Value: uint32(21)}, + params.HandleObjectTypeID: {Name: params.HandleObjectTypeID, Type: params.AnsiString, Value: "Key"}, + params.HandleObject: {Name: params.HandleObject, Type: params.Uint64, Value: uint64(18446692422059208560)}, + params.HandleObjectName: {Name: params.HandleObjectName, Type: params.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`}, }, - Metadata: make(kevent.Metadata), + Metadata: make(event.Metadata), }, func() *handle.SnapshotterMock { hsnap := new(handle.SnapshotterMock) hsnap.On("Remove", mock.Anything).Return(nil) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`, e.GetParamAsString(kparams.HandleObjectName)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock) { + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`, e.GetParamAsString(params.HandleObjectName)) hsnap.AssertNumberOfCalls(t, "Remove", 1) }, }, diff --git a/internal/etw/processors/image_windows.go b/internal/etw/processors/image_windows.go index fb276e9fd..c0d262a87 100644 --- a/internal/etw/processors/image_windows.go +++ b/internal/etw/processors/image_windows.go @@ -20,8 +20,8 @@ package processors import ( "expvar" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/ps" "sync" "time" @@ -54,11 +54,11 @@ func newImageProcessor(psnap ps.Snapshotter) Processor { func (*imageProcessor) Name() ProcessorType { return Image } -func (m *imageProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { +func (m *imageProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { if e.IsLoadImage() { // is image characteristics data cached? - path := e.GetParamAsString(kparams.ImagePath) - key := path + e.GetParamAsString(kparams.ImageCheckSum) + path := e.GetParamAsString(params.ImagePath) + key := path + e.GetParamAsString(params.ImageCheckSum) m.mu.Lock() defer m.mu.Unlock() @@ -78,15 +78,15 @@ func (m *imageProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, e } // append event parameters - e.AppendParam(kparams.FileIsDLL, kparams.Bool, c.isDLL) - e.AppendParam(kparams.FileIsDriver, kparams.Bool, c.isDriver) - e.AppendParam(kparams.FileIsExecutable, kparams.Bool, c.isExe) - e.AppendParam(kparams.FileIsDotnet, kparams.Bool, c.isDotnet) + e.AppendParam(params.FileIsDLL, params.Bool, c.isDLL) + e.AppendParam(params.FileIsDriver, params.Bool, c.isDriver) + e.AppendParam(params.FileIsExecutable, params.Bool, c.isExe) + e.AppendParam(params.FileIsDotnet, params.Bool, c.isDotnet) } if e.IsUnloadImage() { - pid := e.Kparams.MustGetPid() - addr := e.Kparams.TryGetAddress(kparams.ImageBase) + pid := e.Params.MustGetPid() + addr := e.Params.TryGetAddress(params.ImageBase) if pid == 0 { pid = e.PID } diff --git a/internal/etw/processors/image_windows_test.go b/internal/etw/processors/image_windows_test.go index 135fcda46..0e9cb8ba4 100644 --- a/internal/etw/processors/image_windows_test.go +++ b/internal/etw/processors/image_windows_test.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/signature" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -36,21 +35,21 @@ import ( func TestImageProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent + e *event.Event psnap func() *ps.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *ps.SnapshotterMock) + assertions func(*event.Event, *testing.T, *ps.SnapshotterMock) }{ { "load new image", - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, - kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ffb313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(1), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(4), Enum: signature.Levels}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, + params.ImageCheckSum: {Name: params.ImageCheckSum, Type: params.Uint32, Value: uint32(2323432)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x7ffb313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(1), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(4), Enum: signature.Levels}, }, }, func() *ps.SnapshotterMock { @@ -58,24 +57,24 @@ func TestImageProcessor(t *testing.T) { psnap.On("AddModule", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { psnap.AssertNumberOfCalls(t, "AddModule", 1) // should get the signature verified - assert.Equal(t, "EMBEDDED", e.GetParamAsString(kparams.ImageSignatureType)) - assert.Equal(t, "AUTHENTICODE", e.GetParamAsString(kparams.ImageSignatureLevel)) + assert.Equal(t, "EMBEDDED", e.GetParamAsString(params.ImageSignatureType)) + assert.Equal(t, "AUTHENTICODE", e.GetParamAsString(params.ImageSignatureLevel)) }, }, { "parse image characteristics", - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "../_fixtures/mscorlib.dll"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, - kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ffb313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(1), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(4), Enum: signature.Levels}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "../_fixtures/mscorlib.dll"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, + params.ImageCheckSum: {Name: params.ImageCheckSum, Type: params.Uint32, Value: uint32(2323432)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x7ffb313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(1), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(4), Enum: signature.Levels}, }, }, func() *ps.SnapshotterMock { @@ -83,26 +82,26 @@ func TestImageProcessor(t *testing.T) { psnap.On("AddModule", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { psnap.AssertNumberOfCalls(t, "AddModule", 1) // should be enriched with image characteristics params - assert.True(t, e.Kparams.MustGetBool(kparams.FileIsDLL)) - assert.True(t, e.Kparams.MustGetBool(kparams.FileIsDotnet)) - assert.False(t, e.Kparams.MustGetBool(kparams.FileIsExecutable)) - assert.False(t, e.Kparams.MustGetBool(kparams.FileIsDriver)) + assert.True(t, e.Params.MustGetBool(params.FileIsDLL)) + assert.True(t, e.Params.MustGetBool(params.FileIsDotnet)) + assert.False(t, e.Params.MustGetBool(params.FileIsExecutable)) + assert.False(t, e.Params.MustGetBool(params.FileIsDriver)) }, }, { "unload image", - &kevent.Kevent{ - Type: ktypes.UnloadImage, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "csrss.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(676)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0xfffb313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(0), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(0), Enum: signature.Levels}, + &event.Event{ + Type: event.UnloadImage, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "csrss.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(676)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0xfffb313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(0), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(0), Enum: signature.Levels}, }, }, func() *ps.SnapshotterMock { @@ -111,7 +110,7 @@ func TestImageProcessor(t *testing.T) { psnap.On("FindModule", mock.Anything).Return(false, nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { psnap.AssertNumberOfCalls(t, "RemoveModule", 1) }, }, diff --git a/internal/etw/processors/mem_windows.go b/internal/etw/processors/mem_windows.go index 459aa9207..2e51c4c49 100644 --- a/internal/etw/processors/mem_windows.go +++ b/internal/etw/processors/mem_windows.go @@ -19,15 +19,14 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" psnap "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/va" ) // MemPageTypes represents the type of the pages in the allocated region. -var MemPageTypes = kevent.ParamEnum{ +var MemPageTypes = event.ParamEnum{ va.MemImage: "IMAGE", va.MemMapped: "MAPPED", va.MemPrivate: "PRIVATE", @@ -48,29 +47,29 @@ func (m memProcessor) Close() { m.regionProber.Close() } -func (m memProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { - if e.Category == ktypes.Mem { - pid := e.Kparams.MustGetPid() +func (m memProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { + if e.Category == event.Mem { + pid := e.Params.MustGetPid() if e.IsVirtualAlloc() { // retrieve info about the range of pages and enrich the event // with allocation protection options and the type of pages in // the allocated region. If the region is mapped, we try to find // the backing file name - addr := e.Kparams.MustGetUint64(kparams.MemBaseAddress) + addr := e.Params.MustGetUint64(params.MemBaseAddress) region := m.regionProber.Query(pid, addr) if region != nil { if region.IsMapped() { - e.AppendParam(kparams.FilePath, kparams.DOSPath, region.GetMappedFile()) + e.AppendParam(params.FilePath, params.DOSPath, region.GetMappedFile()) } - e.AppendEnum(kparams.MemPageType, region.Type, MemPageTypes) - e.AppendFlags(kparams.MemProtect, region.Protect, kevent.MemProtectionFlags) - e.AppendParam(kparams.MemProtectMask, kparams.AnsiString, region.ProtectMask()) + e.AppendEnum(params.MemPageType, region.Type, MemPageTypes) + e.AppendFlags(params.MemProtect, region.Protect, event.MemProtectionFlags) + e.AppendParam(params.MemProtectMask, params.AnsiString, region.ProtectMask()) } } proc := m.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) - e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) + e.AppendParam(params.Exe, params.Path, proc.Exe) + e.AppendParam(params.ProcessName, params.AnsiString, proc.Name) } return e, false, nil } diff --git a/internal/etw/processors/mem_windows_test.go b/internal/etw/processors/mem_windows_test.go index d3ef09d5c..dcf666b3e 100644 --- a/internal/etw/processors/mem_windows_test.go +++ b/internal/etw/processors/mem_windows_test.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -41,20 +40,20 @@ func TestMemProcessor(t *testing.T) { }() var tests = []struct { name string - e *kevent.Kevent + e *event.Event psnap func() *ps.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *ps.SnapshotterMock) + assertions func(*event.Event, *testing.T, *ps.SnapshotterMock) }{ { "virtual alloc", - &kevent.Kevent{ - Type: ktypes.VirtualAlloc, - Category: ktypes.Mem, - Kparams: kevent.Kparams{ - kparams.MemRegionSize: {Name: kparams.MemRegionSize, Type: kparams.Uint64, Value: uint64(1024)}, - kparams.MemBaseAddress: {Name: kparams.MemBaseAddress, Type: kparams.Address, Value: uint64(base)}, - kparams.MemAllocType: {Name: kparams.MemAllocType, Type: kparams.Flags, Value: uint32(0x00001000 | 0x00002000), Flags: kevent.MemAllocationFlags}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + &event.Event{ + Type: event.VirtualAlloc, + Category: event.Mem, + Params: event.Params{ + params.MemRegionSize: {Name: params.MemRegionSize, Type: params.Uint64, Value: uint64(1024)}, + params.MemBaseAddress: {Name: params.MemBaseAddress, Type: params.Address, Value: uint64(base)}, + params.MemAllocType: {Name: params.MemAllocType, Type: params.Flags, Value: uint32(0x00001000 | 0x00002000), Flags: event.MemAllocationFlags}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, }, }, func() *ps.SnapshotterMock { @@ -62,25 +61,25 @@ func TestMemProcessor(t *testing.T) { psnap.On("FindAndPut", mock.Anything).Return(&pstypes.PS{Name: "svchost.exe", Exe: "C:\\Windows\\System32\\svchost.exe"}) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { psnap.AssertNumberOfCalls(t, "FindAndPut", 1) - assert.Equal(t, "PRIVATE", e.GetParamAsString(kparams.MemPageType)) - assert.Equal(t, "EXECUTE_READWRITE", e.GetParamAsString(kparams.MemProtect)) - assert.Equal(t, "RWX", e.GetParamAsString(kparams.MemProtectMask)) - assert.Equal(t, "svchost.exe", e.GetParamAsString(kparams.ProcessName)) - assert.Equal(t, "C:\\Windows\\System32\\svchost.exe", e.GetParamAsString(kparams.Exe)) + assert.Equal(t, "PRIVATE", e.GetParamAsString(params.MemPageType)) + assert.Equal(t, "EXECUTE_READWRITE", e.GetParamAsString(params.MemProtect)) + assert.Equal(t, "RWX", e.GetParamAsString(params.MemProtectMask)) + assert.Equal(t, "svchost.exe", e.GetParamAsString(params.ProcessName)) + assert.Equal(t, "C:\\Windows\\System32\\svchost.exe", e.GetParamAsString(params.Exe)) }, }, { "virtual free", - &kevent.Kevent{ - Type: ktypes.VirtualFree, - Category: ktypes.Mem, - Kparams: kevent.Kparams{ - kparams.MemRegionSize: {Name: kparams.MemRegionSize, Type: kparams.Uint64, Value: uint64(1024)}, - kparams.MemBaseAddress: {Name: kparams.MemBaseAddress, Type: kparams.Address, Value: uint64(base)}, - kparams.MemAllocType: {Name: kparams.MemAllocType, Type: kparams.Flags, Value: uint32(0x00008000), Flags: kevent.MemAllocationFlags}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + &event.Event{ + Type: event.VirtualFree, + Category: event.Mem, + Params: event.Params{ + params.MemRegionSize: {Name: params.MemRegionSize, Type: params.Uint64, Value: uint64(1024)}, + params.MemBaseAddress: {Name: params.MemBaseAddress, Type: params.Address, Value: uint64(base)}, + params.MemAllocType: {Name: params.MemAllocType, Type: params.Flags, Value: uint32(0x00008000), Flags: event.MemAllocationFlags}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, }, }, func() *ps.SnapshotterMock { @@ -88,10 +87,10 @@ func TestMemProcessor(t *testing.T) { psnap.On("FindAndPut", mock.Anything).Return(&pstypes.PS{Name: "svchost.exe", Exe: "C:\\Windows\\System32\\svchost.exe"}) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { psnap.AssertNumberOfCalls(t, "FindAndPut", 1) - assert.Equal(t, "svchost.exe", e.GetParamAsString(kparams.ProcessName)) - assert.Equal(t, "C:\\Windows\\System32\\svchost.exe", e.GetParamAsString(kparams.Exe)) + assert.Equal(t, "svchost.exe", e.GetParamAsString(params.ProcessName)) + assert.Equal(t, "C:\\Windows\\System32\\svchost.exe", e.GetParamAsString(params.Exe)) }, }, } diff --git a/internal/etw/processors/net_windows.go b/internal/etw/processors/net_windows.go index 2dc5a56dc..a09001f2b 100644 --- a/internal/etw/processors/net_windows.go +++ b/internal/etw/processors/net_windows.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/network" "github.com/rabbitstack/fibratus/pkg/util/ports" ) @@ -38,13 +37,13 @@ func (netProcessor) Name() ProcessorType { return Net } func (n netProcessor) Close() {} -func (n *netProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { - if e.Category == ktypes.Net { +func (n *netProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { + if e.Category == event.Net { if e.IsNetworkTCP() && !e.IsDNS() { - e.AppendEnum(kparams.NetL4Proto, uint32(network.TCP), network.ProtoNames) + e.AppendEnum(params.NetL4Proto, uint32(network.TCP), network.ProtoNames) } if e.IsNetworkUDP() && !e.IsDNS() { - e.AppendEnum(kparams.NetL4Proto, uint32(network.UDP), network.ProtoNames) + e.AppendEnum(params.NetL4Proto, uint32(network.UDP), network.ProtoNames) } if e.IsDNS() { @@ -60,25 +59,25 @@ func (n *netProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, err // resolvePortName resolves the IANA service name for the particular port and transport protocol as // per https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xhtml. -func (n netProcessor) resolvePortName(e *kevent.Kevent) *kevent.Kevent { - dport := e.Kparams.TryGetUint16(kparams.NetDport) - sport := e.Kparams.TryGetUint16(kparams.NetSport) +func (n netProcessor) resolvePortName(e *event.Event) *event.Event { + dport := e.Params.TryGetUint16(params.NetDport) + sport := e.Params.TryGetUint16(params.NetSport) if e.IsNetworkTCP() { if name, ok := ports.TCPPortNames[dport]; ok { - e.Kparams.Append(kparams.NetDportName, kparams.AnsiString, name) + e.Params.Append(params.NetDportName, params.AnsiString, name) } if name, ok := ports.TCPPortNames[sport]; ok { - e.Kparams.Append(kparams.NetSportName, kparams.AnsiString, name) + e.Params.Append(params.NetSportName, params.AnsiString, name) } return e } if name, ok := ports.UDPPortNames[dport]; ok { - e.Kparams.Append(kparams.NetDportName, kparams.AnsiString, name) + e.Params.Append(params.NetDportName, params.AnsiString, name) } if name, ok := ports.UDPPortNames[sport]; ok { - e.Kparams.Append(kparams.NetSportName, kparams.AnsiString, name) + e.Params.Append(params.NetSportName, params.AnsiString, name) } return e } diff --git a/internal/etw/processors/net_windows_test.go b/internal/etw/processors/net_windows_test.go index 23511cf66..6f6e36bc0 100644 --- a/internal/etw/processors/net_windows_test.go +++ b/internal/etw/processors/net_windows_test.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" @@ -31,47 +30,47 @@ import ( func TestNetworkProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent - assertions func(*kevent.Kevent, *testing.T) + e *event.Event + assertions func(*event.Event, *testing.T) }{ { "send tcpv4", - &kevent.Kevent{ - Type: ktypes.SendTCPv4, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("8.8.8.8")}, + &event.Event{ + Type: event.SendTCPv4, + Category: event.Net, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("8.8.8.8")}, }, }, - func(e *kevent.Kevent, t *testing.T) { + func(e *event.Event, t *testing.T) { assert.Equal(t, "Send", e.Type.String()) - assert.Equal(t, "https", e.GetParamAsString(kparams.NetDportName)) - assert.Equal(t, "TCP", e.GetParamAsString(kparams.NetL4Proto)) - assert.Equal(t, "127.0.0.1", e.GetParamAsString(kparams.NetSIP)) - assert.Equal(t, "8.8.8.8", e.GetParamAsString(kparams.NetDIP)) - assert.Equal(t, "443", e.GetParamAsString(kparams.NetDport)) - assert.Equal(t, "43123", e.GetParamAsString(kparams.NetSport)) + assert.Equal(t, "https", e.GetParamAsString(params.NetDportName)) + assert.Equal(t, "TCP", e.GetParamAsString(params.NetL4Proto)) + assert.Equal(t, "127.0.0.1", e.GetParamAsString(params.NetSIP)) + assert.Equal(t, "8.8.8.8", e.GetParamAsString(params.NetDIP)) + assert.Equal(t, "443", e.GetParamAsString(params.NetDport)) + assert.Equal(t, "43123", e.GetParamAsString(params.NetSport)) }, }, { "recv udp6", - &kevent.Kevent{ - Type: ktypes.RecvUDPv6, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(53)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("8.8.8.8")}, + &event.Event{ + Type: event.RecvUDPv6, + Category: event.Net, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(53)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("8.8.8.8")}, }, }, - func(e *kevent.Kevent, t *testing.T) { + func(e *event.Event, t *testing.T) { assert.Equal(t, "Recv", e.Type.String()) - assert.Equal(t, "domain", e.GetParamAsString(kparams.NetDportName)) - assert.Equal(t, "UDP", e.GetParamAsString(kparams.NetL4Proto)) + assert.Equal(t, "domain", e.GetParamAsString(params.NetDportName)) + assert.Equal(t, "UDP", e.GetParamAsString(params.NetL4Proto)) }, }, } diff --git a/internal/etw/processors/processor.go b/internal/etw/processors/processor.go index 9f9cf1779..dcb929223 100644 --- a/internal/etw/processors/processor.go +++ b/internal/etw/processors/processor.go @@ -19,8 +19,8 @@ package processors import ( + "github.com/rabbitstack/fibratus/pkg/event" libntfs "github.com/rabbitstack/fibratus/pkg/fs/ntfs" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/rabbitstack/fibratus/pkg/pe" "os" "time" @@ -52,7 +52,7 @@ const ( type Processor interface { // ProcessEvent receives an existing event possibly mutating its state. // If it returns true, the next processor in the chain is evaluated. - ProcessEvent(*kevent.Kevent) (*kevent.Kevent, bool, error) + ProcessEvent(*event.Event) (*event.Event, bool, error) // Name returns a human-readable name of this processor. Name() ProcessorType diff --git a/internal/etw/processors/ps_windows.go b/internal/etw/processors/ps_windows.go index b5e0fccc9..a52fe2e83 100644 --- a/internal/etw/processors/ps_windows.go +++ b/internal/etw/processors/ps_windows.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/cmdline" "github.com/rabbitstack/fibratus/pkg/util/multierror" @@ -40,43 +39,43 @@ func newPsProcessor(psnap ps.Snapshotter, regionProber *va.RegionProber) Process return &psProcessor{psnap: psnap, regionProber: regionProber} } -func (p psProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { +func (p psProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { switch e.Type { - case ktypes.CreateProcess, ktypes.TerminateProcess, ktypes.ProcessRundown: + case event.CreateProcess, event.TerminateProcess, event.ProcessRundown: evt, err := p.processEvent(e) if evt.IsTerminateProcess() { - p.regionProber.Remove(evt.Kparams.MustGetPid()) + p.regionProber.Remove(evt.Params.MustGetPid()) return evt, false, multierror.Wrap(err, p.psnap.Remove(evt)) } return evt, false, multierror.Wrap(err, p.psnap.Write(evt)) - case ktypes.CreateThread, ktypes.TerminateThread, ktypes.ThreadRundown: - pid, err := e.Kparams.GetPid() + case event.CreateThread, event.TerminateThread, event.ThreadRundown: + pid, err := e.Params.GetPid() if err != nil { return e, false, err } proc := p.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.UnicodeString, proc.Exe) + e.AppendParam(params.Exe, params.UnicodeString, proc.Exe) } if !e.IsTerminateThread() { return e, false, p.psnap.AddThread(e) } - tid, err := e.Kparams.GetTid() + tid, err := e.Params.GetTid() if err != nil { return e, false, err } return e, false, p.psnap.RemoveThread(pid, tid) - case ktypes.OpenProcess, ktypes.OpenThread: - pid, err := e.Kparams.GetPid() + case event.OpenProcess, event.OpenThread: + pid, err := e.Params.GetPid() if err != nil { return e, false, err } proc := p.psnap.FindAndPut(pid) if proc != nil { - e.AppendParam(kparams.Exe, kparams.Path, proc.Exe) - e.AppendParam(kparams.ProcessName, kparams.AnsiString, proc.Name) + e.AppendParam(params.Exe, params.Path, proc.Exe) + e.AppendParam(params.ProcessName, params.AnsiString, proc.Name) } return e, false, nil @@ -86,34 +85,34 @@ func (p psProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error } //nolint:unparam -func (p psProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { - cmndline := cmdline.New(e.GetParamAsString(kparams.Cmdline)). +func (p psProcessor) processEvent(e *event.Event) (*event.Event, error) { + cmndline := cmdline.New(e.GetParamAsString(params.Cmdline)). // get rid of leading/trailing quotes in the executable path CleanExe(). // expand all variations of the SystemRoot environment variable ExpandSystemRoot(). // some system processes are reported without the path in the command line, // but we can expand the path from the SystemRoot environment variable - CompleteSysProc(e.GetParamAsString(kparams.ProcessName)) + CompleteSysProc(e.GetParamAsString(params.ProcessName)) // append executable path parameter exe := cmndline.Exeline() if exe == "" { - exe = e.GetParamAsString(kparams.ProcessName) + exe = e.GetParamAsString(params.ProcessName) } - e.AppendParam(kparams.Exe, kparams.Path, exe) + e.AppendParam(params.Exe, params.Path, exe) if e.IsTerminateProcess() { return e, nil } // query process start time - pid := e.Kparams.MustGetPid() + pid := e.Params.MustGetPid() started, err := getStartTime(pid, e) if err != nil { started = e.Timestamp } - e.AppendParam(kparams.StartTime, kparams.Time, started) + e.AppendParam(params.StartTime, params.Time, started) return e, nil } @@ -121,7 +120,7 @@ func (p psProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { func (psProcessor) Name() ProcessorType { return Ps } func (p psProcessor) Close() {} -func getStartTime(pid uint32, e *kevent.Kevent) (time.Time, error) { +func getStartTime(pid uint32, e *event.Event) (time.Time, error) { proc, err := windows.OpenProcess(windows.PROCESS_QUERY_LIMITED_INFORMATION, false, pid) if err != nil { return e.Timestamp, err diff --git a/internal/etw/processors/ps_windows_test.go b/internal/etw/processors/ps_windows_test.go index d00302e8a..9093e2ce7 100644 --- a/internal/etw/processors/ps_windows_test.go +++ b/internal/etw/processors/ps_windows_test.go @@ -19,9 +19,8 @@ package processors import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -37,17 +36,17 @@ func TestPsProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent + e *event.Event psnap func() *ps.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *ps.SnapshotterMock) + assertions func(*event.Event, *testing.T, *ps.SnapshotterMock) }{ { "create exe parameter from cmdline", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, }, }, func() *ps.SnapshotterMock { @@ -55,20 +54,20 @@ func TestPsProcessor(t *testing.T) { psnap.On("Write", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, "C:\\Windows\\system32\\svchost.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, "C:\\Windows\\system32\\svchost.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "Write", 1) }, }, { "complete exe for system procs", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "csrss.exe"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "csrss.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(676)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "csrss.exe"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "csrss.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(676)}, }, }, func() *ps.SnapshotterMock { @@ -76,20 +75,20 @@ func TestPsProcessor(t *testing.T) { psnap.On("Write", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, "csrss.exe", e.GetParamAsString(kparams.Cmdline)) - require.Equal(t, "C:\\Windows\\System32\\csrss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, "csrss.exe", e.GetParamAsString(params.Cmdline)) + require.Equal(t, "C:\\Windows\\System32\\csrss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "Write", 1) }, }, { "clean quoted executable path", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "\"C:\\Windows\\System32\\smss.exe\""}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "\"C:\\Windows\\System32\\smss.exe\""}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, }, }, func() *ps.SnapshotterMock { @@ -97,20 +96,20 @@ func TestPsProcessor(t *testing.T) { psnap.On("Write", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, "\"C:\\Windows\\System32\\smss.exe\"", e.GetParamAsString(kparams.Cmdline)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, "\"C:\\Windows\\System32\\smss.exe\"", e.GetParamAsString(params.Cmdline)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "Write", 1) }, }, { "expand SystemRoot in executable path", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `\SystemRoot\System32\smss.exe`}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `\SystemRoot\System32\smss.exe`}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, }, }, func() *ps.SnapshotterMock { @@ -118,21 +117,21 @@ func TestPsProcessor(t *testing.T) { psnap.On("Write", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, `\SystemRoot\System32\smss.exe`, e.GetParamAsString(kparams.Cmdline)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, `\SystemRoot\System32\smss.exe`, e.GetParamAsString(params.Cmdline)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "Write", 1) }, }, { "add process start time parameter", - &kevent.Kevent{ - Type: ktypes.CreateProcess, + &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now(), - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Program Files\Fibratus\fibratus.exe`}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Program Files\Fibratus\fibratus.exe`}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, }, }, func() *ps.SnapshotterMock { @@ -140,18 +139,18 @@ func TestPsProcessor(t *testing.T) { psnap.On("Write", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.StartTime)) - require.NotEqual(t, e.Timestamp, e.Kparams.MustGetTime(kparams.StartTime)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.StartTime)) + require.NotEqual(t, e.Timestamp, e.Params.MustGetTime(params.StartTime)) }, }, { "terminate process", - &kevent.Kevent{ - Type: ktypes.TerminateProcess, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `\SystemRoot\System32\smss.exe`}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, + &event.Event{ + Type: event.TerminateProcess, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `\SystemRoot\System32\smss.exe`}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, }, }, func() *ps.SnapshotterMock { @@ -159,21 +158,21 @@ func TestPsProcessor(t *testing.T) { psnap.On("Remove", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, `\SystemRoot\System32\smss.exe`, e.GetParamAsString(kparams.Cmdline)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, `\SystemRoot\System32\smss.exe`, e.GetParamAsString(params.Cmdline)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "Remove", 1) psnap.AssertNotCalled(t, "Write") }, }, { "create thread", - &kevent.Kevent{ - Type: ktypes.CreateThread, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(10234)}, + &event.Event{ + Type: event.CreateThread, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(10234)}, }, }, func() *ps.SnapshotterMock { @@ -182,19 +181,19 @@ func TestPsProcessor(t *testing.T) { psnap.On("AddThread", mock.Anything).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "AddThread", 1) }, }, { "terminate thread", - &kevent.Kevent{ - Type: ktypes.TerminateThread, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(10234)}, + &event.Event{ + Type: event.TerminateThread, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(10234)}, }, }, func() *ps.SnapshotterMock { @@ -203,19 +202,19 @@ func TestPsProcessor(t *testing.T) { psnap.On("RemoveThread", uint32(760), uint32(10234)).Return(nil) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) psnap.AssertNumberOfCalls(t, "RemoveThread", 1) psnap.AssertNotCalled(t, "AddThread") }, }, { "open process", - &kevent.Kevent{ - Type: ktypes.OpenProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(760)}, + &event.Event{ + Type: event.OpenProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(760)}, }, }, func() *ps.SnapshotterMock { @@ -223,11 +222,11 @@ func TestPsProcessor(t *testing.T) { psnap.On("FindAndPut", uint32(760)).Return(&pstypes.PS{Name: "smss.exe", Exe: "C:\\Windows\\System32\\smss.exe"}) return psnap }, - func(e *kevent.Kevent, t *testing.T, psnap *ps.SnapshotterMock) { - require.True(t, e.Kparams.Contains(kparams.Exe)) - require.True(t, e.Kparams.Contains(kparams.ProcessName)) - require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(kparams.Exe)) - require.Equal(t, "smss.exe", e.GetParamAsString(kparams.ProcessName)) + func(e *event.Event, t *testing.T, psnap *ps.SnapshotterMock) { + require.True(t, e.Params.Contains(params.Exe)) + require.True(t, e.Params.Contains(params.ProcessName)) + require.Equal(t, "C:\\Windows\\System32\\smss.exe", e.GetParamAsString(params.Exe)) + require.Equal(t, "smss.exe", e.GetParamAsString(params.ProcessName)) }, }, } diff --git a/internal/etw/processors/registry_windows.go b/internal/etw/processors/registry_windows.go index 50441be54..02f132aa7 100644 --- a/internal/etw/processors/registry_windows.go +++ b/internal/etw/processors/registry_windows.go @@ -30,10 +30,9 @@ import ( "sync/atomic" "time" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" ) var ( @@ -75,26 +74,26 @@ func newRegistryProcessor(hsnap handle.Snapshotter) Processor { } } -func (r *registryProcessor) ProcessEvent(e *kevent.Kevent) (*kevent.Kevent, bool, error) { - if e.Category == ktypes.Registry { +func (r *registryProcessor) ProcessEvent(e *event.Event) (*event.Event, bool, error) { + if e.Category == event.Registry { evt, err := r.processEvent(e) return evt, false, err } return e, true, nil } -func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, error) { +func (r *registryProcessor) processEvent(e *event.Event) (*event.Event, error) { switch e.Type { - case ktypes.RegKCBRundown, ktypes.RegCreateKCB: - khandle := e.Kparams.MustGetUint64(kparams.RegKeyHandle) - r.keys[khandle] = e.Kparams.MustGetString(kparams.RegPath) + case event.RegKCBRundown, event.RegCreateKCB: + khandle := e.Params.MustGetUint64(params.RegKeyHandle) + r.keys[khandle] = e.Params.MustGetString(params.RegPath) kcbCount.Add(1) - case ktypes.RegDeleteKCB: - khandle := e.Kparams.MustGetUint64(kparams.RegKeyHandle) + case event.RegDeleteKCB: + khandle := e.Params.MustGetUint64(params.RegKeyHandle) delete(r.keys, khandle) kcbCount.Add(-1) default: - khandle := e.Kparams.MustGetUint64(kparams.RegKeyHandle) + khandle := e.Params.MustGetUint64(params.RegKeyHandle) // we have to obey a straightforward algorithm to connect relative // key names to their root keys. If key handle is equal to zero we // have a full key name and don't have to go further resolving the @@ -104,7 +103,7 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro // last resort is to scan process' handles and check if any of the // key handles contain the partial key name. In this case we assume // the correct key is encountered. - keyName := e.Kparams.MustGetString(kparams.RegPath) + keyName := e.Params.MustGetString(params.RegPath) if khandle != 0 { if baseKey, ok := r.keys[khandle]; ok { keyName = baseKey + "\\" + keyName @@ -112,7 +111,7 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro kcbMissCount.Add(1) keyName = r.findMatchingKey(e.PID, keyName) } - if err := e.Kparams.SetValue(kparams.RegPath, keyName); err != nil { + if err := e.Params.SetValue(params.RegPath, keyName); err != nil { return e, err } } @@ -137,18 +136,18 @@ func (r *registryProcessor) processEvent(e *kevent.Kevent) (*kevent.Kevent, erro } return e, ErrReadValue(rootkey.String(), keyName, err) } - e.AppendEnum(kparams.RegValueType, typ, key.RegistryValueTypes) + e.AppendEnum(params.RegValueType, typ, key.RegistryValueTypes) switch typ { case registry.SZ, registry.EXPAND_SZ: - e.AppendParam(kparams.RegValue, kparams.UnicodeString, val) + e.AppendParam(params.RegValue, params.UnicodeString, val) case registry.MULTI_SZ: - e.AppendParam(kparams.RegValue, kparams.Slice, val) + e.AppendParam(params.RegValue, params.Slice, val) case registry.BINARY: - e.AppendParam(kparams.RegValue, kparams.Binary, val) + e.AppendParam(params.RegValue, params.Binary, val) case registry.QWORD: - e.AppendParam(kparams.RegValue, kparams.Uint64, val) + e.AppendParam(params.RegValue, params.Uint64, val) case registry.DWORD: - e.AppendParam(kparams.RegValue, kparams.Uint32, uint32(val.(uint64))) + e.AppendParam(params.RegValue, params.Uint32, uint32(val.(uint64))) } } } diff --git a/internal/etw/processors/registry_windows_test.go b/internal/etw/processors/registry_windows_test.go index f7347a938..16c0d88db 100644 --- a/internal/etw/processors/registry_windows_test.go +++ b/internal/etw/processors/registry_windows_test.go @@ -19,11 +19,10 @@ package processors import ( + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "testing" @@ -32,19 +31,19 @@ import ( func TestRegistryProcessor(t *testing.T) { var tests = []struct { name string - e *kevent.Kevent + e *event.Event setupProcessor func(Processor) hsnap func() *handle.SnapshotterMock - assertions func(*kevent.Kevent, *testing.T, *handle.SnapshotterMock, Processor) + assertions func(*event.Event, *testing.T, *handle.SnapshotterMock, Processor) }{ { "process KCB rundown", - &kevent.Kevent{ - Type: ktypes.RegKCBRundown, - Category: ktypes.Registry, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, + &event.Event{ + Type: event.RegKCBRundown, + Category: event.Registry, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(18446666033549154696)}, }, }, nil, @@ -52,7 +51,7 @@ func TestRegistryProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { registryProcessor := p.(*registryProcessor) assert.Contains(t, registryProcessor.keys, uint64(18446666033549154696)) assert.Equal(t, `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`, registryProcessor.keys[18446666033549154696]) @@ -60,12 +59,12 @@ func TestRegistryProcessor(t *testing.T) { }, { "process delete KCB", - &kevent.Kevent{ - Type: ktypes.RegDeleteKCB, - Category: ktypes.Registry, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, + &event.Event{ + Type: event.RegDeleteKCB, + Category: event.Registry, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(18446666033549154696)}, }, }, func(p Processor) { @@ -75,19 +74,19 @@ func TestRegistryProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { registryProcessor := p.(*registryProcessor) assert.Empty(t, registryProcessor.keys) }, }, { "full key name", - &kevent.Kevent{ - Type: ktypes.RegOpenKey, - Category: ktypes.Registry, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(0)}, + &event.Event{ + Type: event.RegOpenKey, + Category: event.Registry, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.Key, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(0)}, }, }, nil, @@ -95,18 +94,18 @@ func TestRegistryProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`, e.GetParamAsString(kparams.RegPath)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\ControlSet001\Services\bthserv\Parameters`, e.GetParamAsString(params.RegPath)) }, }, { "incomplete key name", - &kevent.Kevent{ - Type: ktypes.RegOpenKey, - Category: ktypes.Registry, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `Pid`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, + &event.Event{ + Type: event.RegOpenKey, + Category: event.Registry, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.Key, Value: `Pid`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(18446666033549154696)}, }, }, func(p Processor) { @@ -116,19 +115,19 @@ func TestRegistryProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegPath)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(params.RegPath)) }, }, { "incomplete key name consult handle snapshotter", - &kevent.Kevent{ - Type: ktypes.RegOpenKey, - Category: ktypes.Registry, + &event.Event{ + Type: event.RegOpenKey, + Category: event.Registry, PID: 23234, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `Pid`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(18446666033549154696)}, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.Key, Value: `Pid`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(18446666033549154696)}, }, }, nil, @@ -138,20 +137,20 @@ func TestRegistryProcessor(t *testing.T) { hsnap.On("FindHandles", uint32(23234)).Return(handles, nil) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { hsnap.AssertNumberOfCalls(t, "FindHandles", 1) - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(kparams.RegPath)) + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`, e.GetParamAsString(params.RegPath)) }, }, { "process registry set value", - &kevent.Kevent{ - Type: ktypes.RegSetValue, - Category: ktypes.Registry, + &event.Event{ + Type: event.RegSetValue, + Category: event.Registry, PID: 23234, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.Key, Value: `\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Uint64, Value: uint64(0)}, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.Key, Value: `\REGISTRY\MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Uint64, Value: uint64(0)}, }, }, nil, @@ -159,10 +158,10 @@ func TestRegistryProcessor(t *testing.T) { hsnap := new(handle.SnapshotterMock) return hsnap }, - func(e *kevent.Kevent, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { - assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`, e.GetParamAsString(kparams.RegPath)) - assert.Equal(t, `REG_EXPAND_SZ`, e.GetParamAsString(kparams.RegValueType)) - assert.Equal(t, `%SystemRoot%`, e.GetParamAsString(kparams.RegValue)) + func(e *event.Event, t *testing.T, hsnap *handle.SnapshotterMock, p Processor) { + assert.Equal(t, `HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Windows\Directory`, e.GetParamAsString(params.RegPath)) + assert.Equal(t, `REG_EXPAND_SZ`, e.GetParamAsString(params.RegValueType)) + assert.Equal(t, `%SystemRoot%`, e.GetParamAsString(params.RegValue)) }, }, } diff --git a/internal/etw/source.go b/internal/etw/source.go index 71eb328fa..3404a337a 100644 --- a/internal/etw/source.go +++ b/internal/etw/source.go @@ -23,13 +23,12 @@ import ( "expvar" "fmt" "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" - "github.com/rabbitstack/fibratus/pkg/ksource" "github.com/rabbitstack/fibratus/pkg/ps" + "github.com/rabbitstack/fibratus/pkg/source" "github.com/rabbitstack/fibratus/pkg/sys/etw" "github.com/rabbitstack/fibratus/pkg/util/multierror" log "github.com/sirupsen/logrus" @@ -55,20 +54,16 @@ const ( ) var ( - // failedKevents counts the number of kevents that failed to process - failedKevents = expvar.NewMap("kstream.kevents.failures") - // keventsProcessed counts the number of total processed events - keventsProcessed = expvar.NewInt("kstream.kevents.processed") - // keventsDropped counts the number of overall dropped events - keventsDropped = expvar.NewInt("kstream.kevents.dropped") - // keventsUnknown counts the number of published events which types are not present in the internal catalog - keventsUnknown = expvar.NewInt("kstream.kevents.unknown") - - // excludedKevents counts the number of excluded events - excludedKevents = expvar.NewInt("kstream.excluded.kevents") - + // eventsFailed counts the number of events that failed to process + eventsFailed = expvar.NewMap("eventsource.events.failed") + // eventsProcessed counts the number of total processed events + eventsProcessed = expvar.NewInt("eventsource.events.processed") + // eventsUnknown counts the number of published events which types are not present in the internal catalog + eventsUnknown = expvar.NewInt("eventsource.events.unknown") + // eventsExcluded counts the number of excluded events + eventsExcluded = expvar.NewInt("eventsource.events.excluded") // buffersRead amount of buffers fetched from the ETW session - buffersRead = expvar.NewInt("kstream.kbuffers.read") + buffersRead = expvar.NewInt("eventsource.buffers.read") ) // EventSource is the core component responsible for @@ -80,8 +75,8 @@ type EventSource struct { consumers []*Consumer errs chan error - evts chan *kevent.Kevent - sequencer *kevent.Sequencer + evts chan *event.Event + sequencer *event.Sequencer config *config.Config stop chan struct{} @@ -89,7 +84,7 @@ type EventSource struct { hsnap handle.Snapshotter filter filter.Filter - listeners []kevent.Listener + listeners []event.Listener isClosed bool } @@ -100,19 +95,19 @@ func NewEventSource( hsnap handle.Snapshotter, config *config.Config, compiler *config.RulesCompileResult, -) ksource.EventSource { +) source.EventSource { evs := &EventSource{ r: compiler, traces: make([]*Trace, 0), consumers: make([]*Consumer, 0), errs: make(chan error, 1000), - evts: make(chan *kevent.Kevent, 500), - sequencer: kevent.NewSequencer(), + evts: make(chan *event.Event, 500), + sequencer: event.NewSequencer(), config: config, stop: make(chan struct{}), psnap: psnap, hsnap: hsnap, - listeners: make([]kevent.Listener, 0), + listeners: make([]event.Listener, 0), } return evs } @@ -140,29 +135,29 @@ func (e *EventSource) Open(config *config.Config) error { config.Kstream.EnableDNSEvents = config.Kstream.EnableDNSEvents && e.r.HasDNSEvents config.Kstream.EnableAuditAPIEvents = config.Kstream.EnableAuditAPIEvents && e.r.HasAuditAPIEvents config.Kstream.EnableThreadpoolEvents = config.Kstream.EnableThreadpoolEvents && e.r.HasThreadpoolEvents - for _, ktype := range ktypes.All() { - if ktype == ktypes.CreateProcess || ktype == ktypes.TerminateProcess || - ktype == ktypes.LoadImage || ktype == ktypes.UnloadImage { + for _, typ := range event.All() { + if typ == event.CreateProcess || typ == event.TerminateProcess || + typ == event.LoadImage || typ == event.UnloadImage { // always allow fundamental events continue } // allow events required for memory/file scanning - if ktype == ktypes.MapViewFile && config.Yara.Enabled && !config.Yara.SkipMmaps { + if typ == event.MapViewFile && config.Yara.Enabled && !config.Yara.SkipMmaps { continue } - if ktype == ktypes.VirtualAlloc && config.Yara.Enabled && !config.Yara.SkipAllocs { + if typ == event.VirtualAlloc && config.Yara.Enabled && !config.Yara.SkipAllocs { continue } - if ktype == ktypes.CreateFile && config.Yara.Enabled && !config.Yara.SkipFiles { + if typ == event.CreateFile && config.Yara.Enabled && !config.Yara.SkipFiles { continue } - if ktype == ktypes.RegSetValue && config.Yara.Enabled && !config.Yara.SkipRegistry { + if typ == event.RegSetValue && config.Yara.Enabled && !config.Yara.SkipRegistry { continue } - if !e.r.ContainsEvent(ktype) { - config.Kstream.SetDropMask(ktype) + if !e.r.ContainsEvent(typ) { + config.Kstream.SetDropMask(typ) } } } @@ -182,16 +177,16 @@ func (e *EventSource) Open(config *config.Config) error { for _, trace := range e.traces { err := trace.Start() switch err { - case kerrors.ErrTraceAlreadyRunning: + case errs.ErrTraceAlreadyRunning: log.Debugf("%s trace is already running. Trying to restart...", trace.Name) if err := trace.Stop(); err != nil { return err } time.Sleep(time.Millisecond * 100) if err := trace.Start(); err != nil { - return multierror.Wrap(kerrors.ErrRestartTrace, err) + return multierror.Wrap(errs.ErrRestartTrace, err) } - case kerrors.ErrTraceNoSysResources: + case errs.ErrTraceNoSysResources: // get the number of maximum allowed loggers from registry key, err := registry.OpenKey(registry.LOCAL_MACHINE, etwMaxLoggersPath, registry.QUERY_VALUE) if err != nil { @@ -238,7 +233,7 @@ func (e *EventSource) Open(config *config.Config) error { return case err := <-errch: log.Infof("stopping [%s] trace processing", trace.Name) - if err != nil && !errors.Is(err, kerrors.ErrTraceCancelled) { + if err != nil && !errors.Is(err, errs.ErrTraceCancelled) { e.errs <- fmt.Errorf("unable to process %s trace: %v", trace.Name, err) } } @@ -293,7 +288,7 @@ func (e *EventSource) Errors() <-chan error { } // Events returns the buffered event channel. -func (e *EventSource) Events() <-chan *kevent.Kevent { +func (e *EventSource) Events() <-chan *event.Event { return e.evts } @@ -306,7 +301,7 @@ func (e *EventSource) SetFilter(f filter.Filter) { // RegisterEventListener registers a new event listener for each consumer queue. // The event is pushed to the output queue if at least one of the listeners allows. -func (e *EventSource) RegisterEventListener(lis kevent.Listener) { +func (e *EventSource) RegisterEventListener(lis event.Listener) { e.listeners = append(e.listeners, lis) } diff --git a/internal/etw/source_test.go b/internal/etw/source_test.go index 326431198..a3a73b9ea 100644 --- a/internal/etw/source_test.go +++ b/internal/etw/source_test.go @@ -21,11 +21,10 @@ import ( "context" "fmt" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/symbolize" @@ -58,7 +57,7 @@ type MockListener struct { func (l *MockListener) CanEnqueue() bool { return true } -func (l *MockListener) ProcessEvent(e *kevent.Kevent) (bool, error) { +func (l *MockListener) ProcessEvent(e *event.Event) (bool, error) { l.gotEvent = true return true, nil } @@ -171,16 +170,16 @@ func TestEventSourceEnableFlagsDynamically(t *testing.T) { HasThreadEvents: false, HasVAMapEvents: true, HasAuditAPIEvents: true, - UsedEvents: []ktypes.Ktype{ - ktypes.CreateProcess, - ktypes.LoadImage, - ktypes.RegCreateKey, - ktypes.RegSetValue, - ktypes.CreateFile, - ktypes.RenameFile, - ktypes.MapViewFile, - ktypes.OpenProcess, - ktypes.ConnectTCPv4, + UsedEvents: []event.Type{ + event.CreateProcess, + event.LoadImage, + event.RegCreateKey, + event.RegSetValue, + event.CreateFile, + event.RenameFile, + event.MapViewFile, + event.OpenProcess, + event.ConnectTCPv4, }, } cfg := &config.Config{ @@ -217,10 +216,10 @@ func TestEventSourceEnableFlagsDynamically(t *testing.T) { // but VAMap is disabled in the config require.True(t, flags&etw.VaMap == 0) - require.False(t, cfg.Kstream.TestDropMask(ktypes.UnloadImage)) - require.True(t, cfg.Kstream.TestDropMask(ktypes.WriteFile)) - require.True(t, cfg.Kstream.TestDropMask(ktypes.UnmapViewFile)) - require.False(t, cfg.Kstream.TestDropMask(ktypes.OpenProcess)) + require.False(t, cfg.Kstream.TestDropMask(event.UnloadImage)) + require.True(t, cfg.Kstream.TestDropMask(event.WriteFile)) + require.True(t, cfg.Kstream.TestDropMask(event.UnmapViewFile)) + require.False(t, cfg.Kstream.TestDropMask(event.OpenProcess)) } func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { @@ -249,14 +248,14 @@ func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { HasFileEvents: false, HasThreadEvents: false, HasAuditAPIEvents: true, - UsedEvents: []ktypes.Ktype{ - ktypes.CreateProcess, - ktypes.LoadImage, - ktypes.RegCreateKey, - ktypes.RegSetValue, - ktypes.RenameFile, - ktypes.OpenProcess, - ktypes.ConnectTCPv4, + UsedEvents: []event.Type{ + event.CreateProcess, + event.LoadImage, + event.RegCreateKey, + event.RegSetValue, + event.RenameFile, + event.OpenProcess, + event.ConnectTCPv4, }, } cfg := &config.Config{ @@ -293,9 +292,9 @@ func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { // alloc scanning is enabled require.True(t, flags&etw.VirtualAlloc != 0) - require.False(t, cfg.Kstream.TestDropMask(ktypes.CreateFile)) - require.True(t, cfg.Kstream.TestDropMask(ktypes.MapViewFile)) - require.False(t, cfg.Kstream.TestDropMask(ktypes.VirtualAlloc)) + require.False(t, cfg.Kstream.TestDropMask(event.CreateFile)) + require.True(t, cfg.Kstream.TestDropMask(event.MapViewFile)) + require.False(t, cfg.Kstream.TestDropMask(event.VirtualAlloc)) } func TestEventSourceRundownEvents(t *testing.T) { @@ -325,7 +324,7 @@ func TestEventSourceRundownEvents(t *testing.T) { } cfg := &config.Config{ Kstream: kstreamConfig, - KcapFile: "fake.kcap", // simulate capture to receive state/rundown events + KcapFile: "fake.cap", // simulate capture to receive state/rundown events Filters: &config.Filters{}, } @@ -336,12 +335,12 @@ func TestEventSourceRundownEvents(t *testing.T) { require.NoError(t, evs.Open(cfg)) defer evs.Close() - rundownsByType := map[ktypes.Ktype]bool{ - ktypes.ProcessRundown: false, - ktypes.ThreadRundown: false, - ktypes.ImageRundown: false, - ktypes.FileRundown: false, - ktypes.RegKCBRundown: false, + rundownsByType := map[event.Type]bool{ + event.ProcessRundown: false, + event.ThreadRundown: false, + event.ImageRundown: false, + event.FileRundown: false, + event.RegKCBRundown: false, } rundownsByHash := make(map[uint64]uint8) timeout := time.After(time.Minute) @@ -374,7 +373,7 @@ func TestEventSourceRundownEvents(t *testing.T) { } func TestEventSourceAllEvents(t *testing.T) { - kevent.DropCurrentProc = false + event.DropCurrentProc = false var viewBase uintptr var freeAddress uintptr var dupHandleID windows.Handle @@ -382,7 +381,7 @@ func TestEventSourceAllEvents(t *testing.T) { var tests = []*struct { name string gen func() error - want func(e *kevent.Kevent) bool + want func(e *event.Event) bool completed bool }{ { @@ -411,26 +410,26 @@ func TestEventSourceAllEvents(t *testing.T) { defer windows.TerminateProcess(pi.Process, 0) return nil }, - func(e *kevent.Kevent) bool { + func(e *event.Event) bool { return e.IsCreateProcess() && e.CurrentPid() && - strings.EqualFold(e.GetParamAsString(kparams.ProcessName), "notepad.exe") + strings.EqualFold(e.GetParamAsString(params.ProcessName), "notepad.exe") }, false, }, { "terminate process", nil, - func(e *kevent.Kevent) bool { - return e.IsTerminateProcess() && strings.EqualFold(e.GetParamAsString(kparams.ProcessName), "notepad.exe") + func(e *event.Event) bool { + return e.IsTerminateProcess() && strings.EqualFold(e.GetParamAsString(params.ProcessName), "notepad.exe") }, false, }, { "load image", nil, - func(e *kevent.Kevent) bool { + func(e *event.Event) bool { img := filepath.Join(os.Getenv("windir"), "System32", "notepad.exe") - return e.IsLoadImage() && strings.EqualFold(img, e.GetParamAsString(kparams.ImagePath)) + return e.IsLoadImage() && strings.EqualFold(img, e.GetParamAsString(params.ImagePath)) }, false, }, @@ -444,9 +443,9 @@ func TestEventSourceAllEvents(t *testing.T) { defer f.Close() return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-test") && + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.CreateFile && + strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FilePath)), "fibratus-test") && !e.IsOpenDisposition() }, false, @@ -474,8 +473,8 @@ func TestEventSourceAllEvents(t *testing.T) { }() return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && (e.Type == ktypes.ConnectTCPv4 || e.Type == ktypes.ConnectTCPv6) + func(e *event.Event) bool { + return e.CurrentPid() && (e.Type == event.ConnectTCPv4 || e.Type == event.ConnectTCPv6) }, false, }, @@ -527,11 +526,11 @@ func TestEventSourceAllEvents(t *testing.T) { } return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.MapViewFile && - e.GetParamAsString(kparams.MemProtect) == "EXECUTE_READWRITE|READONLY" && - e.GetParamAsString(kparams.FileViewSectionType) == "IMAGE" && - strings.Contains(e.GetParamAsString(kparams.FilePath), "_fixtures\\yara-test.dll") + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.MapViewFile && + e.GetParamAsString(params.MemProtect) == "EXECUTE_READWRITE|READONLY" && + e.GetParamAsString(params.FileViewSectionType) == "IMAGE" && + strings.Contains(e.GetParamAsString(params.FilePath), "_fixtures\\yara-test.dll") }, false, }, @@ -575,10 +574,10 @@ func TestEventSourceAllEvents(t *testing.T) { } return sys.NtUnmapViewOfSection(windows.CurrentProcess(), viewBase) }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.UnmapViewFile && - e.GetParamAsString(kparams.MemProtect) == "READONLY" && - e.Kparams.MustGetUint64(kparams.FileViewBase) == uint64(viewBase) + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.UnmapViewFile && + e.GetParamAsString(params.MemProtect) == "READONLY" && + e.Params.MustGetUint64(params.FileViewBase) == uint64(viewBase) }, false, }, @@ -594,9 +593,9 @@ func TestEventSourceAllEvents(t *testing.T) { }() return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.VirtualAlloc && - e.GetParamAsString(kparams.MemAllocType) == "COMMIT|RESERVE" && e.GetParamAsString(kparams.MemProtectMask) == "RWX" + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.VirtualAlloc && + e.GetParamAsString(params.MemAllocType) == "COMMIT|RESERVE" && e.GetParamAsString(params.MemProtectMask) == "RWX" }, false, }, @@ -610,9 +609,9 @@ func TestEventSourceAllEvents(t *testing.T) { } return windows.VirtualFree(freeAddress, 1024, windows.MEM_DECOMMIT) }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.VirtualFree && - e.GetParamAsString(kparams.MemAllocType) == "DECOMMIT" && e.Kparams.MustGetUint64(kparams.MemBaseAddress) == uint64(freeAddress) + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.VirtualFree && + e.GetParamAsString(params.MemAllocType) == "DECOMMIT" && e.Params.MustGetUint64(params.MemBaseAddress) == uint64(freeAddress) }, false, }, @@ -660,10 +659,10 @@ func TestEventSourceAllEvents(t *testing.T) { defer windows.Close(dup) return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.DuplicateHandle && - e.GetParamAsString(kparams.HandleObjectTypeID) == handle.Key && - windows.Handle(e.Kparams.MustGetUint32(kparams.HandleSourceID)) == dupHandleID + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.DuplicateHandle && + e.GetParamAsString(params.HandleObjectTypeID) == handle.Key && + windows.Handle(e.Params.MustGetUint32(params.HandleSourceID)) == dupHandleID }, false, }, @@ -673,11 +672,11 @@ func TestEventSourceAllEvents(t *testing.T) { _, err := net.LookupHost("dns.google") return err }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.QueryDNS && e.IsDNS() && - e.Type.Subcategory() == ktypes.DNS && - e.GetParamAsString(kparams.DNSName) == "dns.google" && - e.GetParamAsString(kparams.DNSRR) == "A" + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.QueryDNS && e.IsDNS() && + e.Type.Subcategory() == event.DNS && + e.GetParamAsString(params.DNSName) == "dns.google" && + e.GetParamAsString(params.DNSRR) == "A" }, false, }, @@ -687,13 +686,13 @@ func TestEventSourceAllEvents(t *testing.T) { _, err := net.LookupHost("dns.google") return err }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.ReplyDNS && e.IsDNS() && - e.Type.Subcategory() == ktypes.DNS && - e.GetParamAsString(kparams.DNSName) == "dns.google" && - e.GetParamAsString(kparams.DNSRR) == "AAAA" && - e.GetParamAsString(kparams.DNSRcode) == "NOERROR" && - e.GetParamAsString(kparams.DNSAnswers) != "" + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.ReplyDNS && e.IsDNS() && + e.Type.Subcategory() == event.DNS && + e.GetParamAsString(params.DNSName) == "dns.google" && + e.GetParamAsString(params.DNSRR) == "AAAA" && + e.GetParamAsString(params.DNSRcode) == "NOERROR" && + e.GetParamAsString(params.DNSAnswers) != "" }, false, }, @@ -702,8 +701,8 @@ func TestEventSourceAllEvents(t *testing.T) { func() error { return nil }, - func(e *kevent.Kevent) bool { - return e.CurrentPid() && e.Type == ktypes.SetThreadContext && e.GetParamAsString(kparams.NTStatus) == "Success" + func(e *event.Event) bool { + return e.CurrentPid() && e.Type == event.SetThreadContext && e.GetParamAsString(params.NTStatus) == "Success" }, false, }, @@ -806,21 +805,21 @@ type NoopPsSnapshotter struct{} var fakeProc = &pstypes.PS{PID: 111111, Name: "fake.exe"} -func (s *NoopPsSnapshotter) Write(kevt *kevent.Kevent) error { return nil } -func (s *NoopPsSnapshotter) Remove(kevt *kevent.Kevent) error { return nil } +func (s *NoopPsSnapshotter) Write(evt *event.Event) error { return nil } +func (s *NoopPsSnapshotter) Remove(evt *event.Event) error { return nil } func (s *NoopPsSnapshotter) Find(pid uint32) (bool, *pstypes.PS) { return true, fakeProc } func (s *NoopPsSnapshotter) FindAndPut(pid uint32) *pstypes.PS { return fakeProc } func (s *NoopPsSnapshotter) Put(ps *pstypes.PS) {} func (s *NoopPsSnapshotter) Size() uint32 { return 1 } func (s *NoopPsSnapshotter) Close() error { return nil } func (s *NoopPsSnapshotter) GetSnapshot() []*pstypes.PS { return nil } -func (s *NoopPsSnapshotter) AddThread(kevt *kevent.Kevent) error { return nil } -func (s *NoopPsSnapshotter) AddModule(kevt *kevent.Kevent) error { return nil } +func (s *NoopPsSnapshotter) AddThread(evt *event.Event) error { return nil } +func (s *NoopPsSnapshotter) AddModule(evt *event.Event) error { return nil } func (s *NoopPsSnapshotter) FindModule(addr va.Address) (bool, *pstypes.Module) { return false, nil } func (s *NoopPsSnapshotter) RemoveThread(pid uint32, tid uint32) error { return nil } func (s *NoopPsSnapshotter) RemoveModule(pid uint32, addr va.Address) error { return nil } -func (s *NoopPsSnapshotter) WriteFromKcap(kevt *kevent.Kevent) error { return nil } -func (s *NoopPsSnapshotter) AddMmap(kevt *kevent.Kevent) error { return nil } +func (s *NoopPsSnapshotter) WriteFromKcap(evt *event.Event) error { return nil } +func (s *NoopPsSnapshotter) AddMmap(evt *event.Event) error { return nil } func (s *NoopPsSnapshotter) RemoveMmap(pid uint32, addr va.Address) error { return nil } func TestCallstackEnrichment(t *testing.T) { @@ -851,14 +850,14 @@ func TestCallstackEnrichment(t *testing.T) { } func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Snapshotter) { - kevent.DropCurrentProc = false + event.DropCurrentProc = false var procHandle windows.Handle var tests = []*struct { name string gen func() error - want func(e *kevent.Kevent) bool + want func(e *event.Event) bool completed bool }{ { @@ -887,9 +886,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn procHandle = pi.Process return nil }, - func(e *kevent.Kevent) bool { + func(e *event.Event) bool { if e.IsCreateProcess() && e.CurrentPid() && - strings.EqualFold(e.GetParamAsString(kparams.ProcessName), "notepad.exe") { + strings.EqualFold(e.GetParamAsString(params.ProcessName), "notepad.exe") { callstack := e.Callstack.String() log.Infof("create process event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -902,8 +901,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "load image callstack", nil, - func(e *kevent.Kevent) bool { - if e.IsLoadImage() && filepath.Ext(e.GetParamAsString(kparams.FilePath)) == ".dll" { + func(e *event.Event) bool { + if e.IsLoadImage() && filepath.Ext(e.GetParamAsString(params.FilePath)) == ".dll" { callstack := e.Callstack.String() return strings.Contains(strings.ToLower(callstack), strings.ToLower("\\WINDOWS\\System32\\KERNELBASE.dll!LoadLibraryExW")) && strings.Contains(strings.ToLower(callstack), strings.ToLower("\\WINDOWS\\system32\\ntoskrnl.exe!NtMapViewOfSection")) @@ -915,7 +914,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "create thread callstack", nil, - func(e *kevent.Kevent) bool { + func(e *event.Event) bool { if e.IsCreateThread() { callstack := e.Callstack.String() log.Infof("create thread event %s: %s", e.String(), callstack) @@ -929,7 +928,7 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "terminate thread callstack", nil, - func(e *kevent.Kevent) bool { + func(e *event.Event) bool { if e.IsTerminateThread() { callstack := e.Callstack.String() log.Infof("terminate thread event %s: %s", e.String(), callstack) @@ -954,8 +953,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn defer registry.DeleteKey(registry.CURRENT_USER, path) return nil }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegCreateKey && e.GetParamAsString(kparams.RegPath) == "HKEY_CURRENT_USER\\Volatile Environment\\CallstackTest" { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.RegCreateKey && e.GetParamAsString(params.RegPath) == "HKEY_CURRENT_USER\\Volatile Environment\\CallstackTest" { callstack := e.Callstack.String() log.Infof("create key event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -970,8 +969,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "delete registry key callstack", nil, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegDeleteKey { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.RegDeleteKey { callstack := e.Callstack.String() log.Infof("delete key event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -992,8 +991,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn defer key.DeleteValue("FibratusCallstack") return key.SetStringValue("FibratusCallstack", "Callstack") }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegSetValue && strings.HasSuffix(e.GetParamAsString(kparams.RegPath), "FibratusCallstack") { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.RegSetValue && strings.HasSuffix(e.GetParamAsString(params.RegPath), "FibratusCallstack") { callstack := e.Callstack.String() log.Infof("set value event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1008,8 +1007,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "delete registry value callstack", nil, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RegDeleteValue { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.RegDeleteValue { callstack := e.Callstack.String() log.Infof("delete value event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1022,8 +1021,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn { "set thread context callstack", nil, - func(e *kevent.Kevent) bool { - return e.Type == ktypes.SetThreadContext && + func(e *event.Event) bool { + return e.Type == event.SetThreadContext && callstackContainsTestExe(e.Callstack.String()) && strings.Contains(strings.ToLower(e.Callstack.String()), strings.ToLower("\\WINDOWS\\System32\\KERNELBASE.dll!SetThreadContext")) }, @@ -1039,9 +1038,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn defer f.Close() return nil }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-callstack") && + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.CreateFile && + strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FilePath)), "fibratus-callstack") && !e.IsOpenDisposition() { callstack := e.Callstack.String() log.Infof("create file event %s: %s", e.String(), callstack) @@ -1068,9 +1067,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn defer windows.Close(h) return nil }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.CreateFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-file-transacted") && + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.CreateFile && + strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FilePath)), "fibratus-file-transacted") && !e.IsOpenDisposition() { callstack := e.Callstack.String() log.Infof("create transacted file event %s: %s", e.String(), callstack) @@ -1090,9 +1089,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn } return nil }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.VirtualAlloc && - e.GetParamAsString(kparams.MemAllocType) == "COMMIT|RESERVE" { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.VirtualAlloc && + e.GetParamAsString(params.MemAllocType) == "COMMIT|RESERVE" { callstack := e.Callstack.String() log.Infof("virtual alloc event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1115,9 +1114,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn // to, _ := windows.UTF16PtrFromString(filepath.Join(os.TempDir(), "copied-file")) // return copyFile(from, to) // }, - // func(e *kevent.Kevent) bool { - // if e.CurrentPid() && e.Type == ktypes.CreateFile && - // strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FileName)), "copied-file") && + // func(e *event.Event) bool { + // if e.CurrentPid() && e.Type == event.CreateFile && + // strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FileName)), "copied-file") && // !e.IsOpenDisposition() { // callstack := e.Callstack.String() // log.Infof("copy file event %s: %s", e.String(), callstack) @@ -1138,9 +1137,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn f.Close() return os.Remove(f.Name()) }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.DeleteFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-delete") { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.DeleteFile && + strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FilePath)), "fibratus-delete") { callstack := e.Callstack.String() log.Infof("delete file event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1163,9 +1162,9 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn } return os.Remove(filepath.Join(os.TempDir(), "fibratus-ren")) }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.RenameFile && - strings.HasPrefix(filepath.Base(e.GetParamAsString(kparams.FilePath)), "fibratus-rename") { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.RenameFile && + strings.HasPrefix(filepath.Base(e.GetParamAsString(params.FilePath)), "fibratus-rename") { callstack := e.Callstack.String() log.Infof("rename file event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1181,8 +1180,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn _, err := windows.OpenProcess(windows.PROCESS_VM_READ, false, uint32(os.Getpid())) return err }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.OpenProcess { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.OpenProcess { callstack := e.Callstack.String() log.Infof("open process event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && @@ -1198,8 +1197,8 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn _, err := windows.OpenThread(windows.THREAD_IMPERSONATE, false, windows.GetCurrentThreadId()) return err }, - func(e *kevent.Kevent) bool { - if e.CurrentPid() && e.Type == ktypes.OpenThread { + func(e *event.Event) bool { + if e.CurrentPid() && e.Type == event.OpenThread { callstack := e.Callstack.String() log.Infof("open thread event %s: %s", e.String(), callstack) return callstackContainsTestExe(callstack) && diff --git a/internal/etw/stackext.go b/internal/etw/stackext.go index 03c348c1a..e87cc53e8 100644 --- a/internal/etw/stackext.go +++ b/internal/etw/stackext.go @@ -20,7 +20,7 @@ package etw import ( "github.com/rabbitstack/fibratus/pkg/config" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/sys/etw" "golang.org/x/sys/windows" ) @@ -38,15 +38,15 @@ func NewStackExtensions(config config.KstreamConfig) *StackExtensions { } // AddStackTracing enables stack tracing for the specified event type. -func (s *StackExtensions) AddStackTracing(ktype ktypes.Ktype) { - if !s.config.TestDropMask(ktype) { - s.ids = append(s.ids, etw.NewClassicEventID(ktype.GUID(), ktype.HookID())) +func (s *StackExtensions) AddStackTracing(Type event.Type) { + if !s.config.TestDropMask(Type) { + s.ids = append(s.ids, etw.NewClassicEventID(Type.GUID(), Type.HookID())) } } // AddStackTracingWith enables stack tracing for the specified provider GUID and event hook id. func (s *StackExtensions) AddStackTracingWith(guid windows.GUID, hookID uint16) { - if !s.config.TestDropMask(ktypes.FromParts(guid, hookID)) { + if !s.config.TestDropMask(event.TypeFromParts(guid, hookID)) { s.ids = append(s.ids, etw.NewClassicEventID(guid, hookID)) } } @@ -60,13 +60,13 @@ func (s *StackExtensions) EventIds() []etw.ClassicEventID { return s.ids } // creating/terminating a thread or loading an image into // process address space. func (s *StackExtensions) EnableProcessCallstack() { - s.AddStackTracing(ktypes.CreateProcess) + s.AddStackTracing(event.CreateProcess) if s.config.EnableThreadKevents { - s.AddStackTracing(ktypes.CreateThread) - s.AddStackTracing(ktypes.TerminateThread) + s.AddStackTracing(event.CreateThread) + s.AddStackTracing(event.TerminateThread) } if s.config.EnableImageKevents { - s.AddStackTracingWith(ktypes.ProcessEventGUID, ktypes.LoadImage.HookID()) + s.AddStackTracingWith(event.ProcessEventGUID, event.LoadImage.HookID()) } } @@ -75,9 +75,9 @@ func (s *StackExtensions) EnableProcessCallstack() { // return addresses for file system activity. func (s *StackExtensions) EnableFileCallstack() { if s.config.EnableFileIOKevents { - s.AddStackTracing(ktypes.CreateFile) - s.AddStackTracing(ktypes.DeleteFile) - s.AddStackTracing(ktypes.RenameFile) + s.AddStackTracing(event.CreateFile) + s.AddStackTracing(event.DeleteFile) + s.AddStackTracing(event.RenameFile) } } @@ -86,10 +86,10 @@ func (s *StackExtensions) EnableFileCallstack() { // return addresses for registry operations. func (s *StackExtensions) EnableRegistryCallstack() { if s.config.EnableRegistryKevents { - s.AddStackTracing(ktypes.RegCreateKey) - s.AddStackTracing(ktypes.RegDeleteKey) - s.AddStackTracing(ktypes.RegSetValue) - s.AddStackTracing(ktypes.RegDeleteValue) + s.AddStackTracing(event.RegCreateKey) + s.AddStackTracing(event.RegDeleteKey) + s.AddStackTracing(event.RegSetValue) + s.AddStackTracing(event.RegDeleteValue) } } @@ -97,15 +97,15 @@ func (s *StackExtensions) EnableRegistryCallstack() { // events such as memory allocations. func (s *StackExtensions) EnableMemoryCallstack() { if s.config.EnableMemKevents { - s.AddStackTracing(ktypes.VirtualAlloc) + s.AddStackTracing(event.VirtualAlloc) } } // EnableThreadpoolCallstack enables stack tracing for thread pool events. func (s *StackExtensions) EnableThreadpoolCallstack() { if s.config.EnableThreadpoolEvents { - s.AddStackTracing(ktypes.SubmitThreadpoolWork) - s.AddStackTracing(ktypes.SubmitThreadpoolCallback) - s.AddStackTracing(ktypes.SetThreadpoolTimer) + s.AddStackTracing(event.SubmitThreadpoolWork) + s.AddStackTracing(event.SubmitThreadpoolCallback) + s.AddStackTracing(event.SetThreadpoolTimer) } } diff --git a/internal/etw/stackext_test.go b/internal/etw/stackext_test.go index 0f8457b86..a2ea5470c 100644 --- a/internal/etw/stackext_test.go +++ b/internal/etw/stackext_test.go @@ -20,7 +20,7 @@ package etw import ( "github.com/rabbitstack/fibratus/pkg/config" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/sys/etw" "github.com/stretchr/testify/assert" "testing" @@ -47,11 +47,11 @@ func TestStackExtensions(t *testing.T) { exts.EnableMemoryCallstack() assert.Len(t, exts.EventIds(), 7) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.ProcessEventGUID, Type: uint8(ktypes.CreateProcess.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.ThreadEventGUID, Type: uint8(ktypes.CreateThread.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.ThreadEventGUID, Type: uint8(ktypes.TerminateThread.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.FileEventGUID, Type: uint8(ktypes.CreateFile.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.FileEventGUID, Type: uint8(ktypes.RenameFile.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.FileEventGUID, Type: uint8(ktypes.DeleteFile.HookID())}) - assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: ktypes.MemEventGUID, Type: uint8(ktypes.VirtualAlloc.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.ProcessEventGUID, Type: uint8(event.CreateProcess.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.ThreadEventGUID, Type: uint8(event.CreateThread.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.ThreadEventGUID, Type: uint8(event.TerminateThread.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.FileEventGUID, Type: uint8(event.CreateFile.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.FileEventGUID, Type: uint8(event.RenameFile.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.FileEventGUID, Type: uint8(event.DeleteFile.HookID())}) + assert.Contains(t, exts.EventIds(), etw.ClassicEventID{GUID: event.MemEventGUID, Type: uint8(event.VirtualAlloc.HookID())}) } diff --git a/internal/etw/trace.go b/internal/etw/trace.go index 1f6fce354..7a85963c4 100644 --- a/internal/etw/trace.go +++ b/internal/etw/trace.go @@ -284,7 +284,7 @@ func (t *Trace) processEventCallback(ev *etw.EventRecord) uintptr { } if err := t.consumer.ProcessEvent(ev); err != nil { t.errs <- err - failedKevents.Add(err.Error(), 1) + eventsFailed.Add(err.Error(), 1) } return callbackNext } diff --git a/make.bat b/make.bat index c6dd53632..b17ae597d 100644 --- a/make.bat +++ b/make.bat @@ -29,7 +29,7 @@ set LDFLAGS="-s -w -X github.com/rabbitstack/fibratus/cmd/fibratus/app.version=% :: In case you want to avoid CGO overhead or don't need a specific feature, try tweaking the following compilation tags: :: -:: kcap: enables capture support +:: cap: enables capture support :: filament: enables running filaments and thus interacting with the CPython interpreter :: yara: enables YARA scanner via cgo bindings if NOT DEFINED TAGS ( diff --git a/pkg/aggregator/aggregator.go b/pkg/aggregator/aggregator.go index 991be1ca9..5993bba0c 100644 --- a/pkg/aggregator/aggregator.go +++ b/pkg/aggregator/aggregator.go @@ -25,7 +25,7 @@ import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" "github.com/rabbitstack/fibratus/pkg/alertsender" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" log "github.com/sirupsen/logrus" @@ -51,27 +51,27 @@ import ( ) var ( - // keventsDequeued counts the number of dequeued events - keventsDequeued = expvar.NewInt("kstream.kevents.dequeued") + // eventsDequeued counts the number of dequeued events + eventsDequeued = expvar.NewInt("aggregator.events.dequeued") // flushesCount computes the total count of aggregator flushes flushesCount = expvar.NewInt("aggregator.flushes.count") // batchEvents represents the overall number of processed batches batchEvents = expvar.NewInt("aggregator.batch.events") // transformerErrors is the count of errors occurred when applying transformers transformerErrors = expvar.NewMap("aggregator.transformer.errors") - // keventErrors is the number of event errors - keventErrors = expvar.NewInt("aggregator.kevent.errors") + // eventsErrors is the number of event errors + eventsErrors = expvar.NewInt("aggregator.event.errors") ) // BufferedAggregator collects events from the inbound channel and produces batches on regular intervals. The batches // are pushed to the work queue from which load-balanced configured workers consume the batches and publish to the outputs. type BufferedAggregator struct { - kevtsc <-chan *kevent.Kevent + evtsc <-chan *event.Event errsc <-chan error stop chan struct{} flusher *time.Ticker - // queue of inbound kernel events - kevts []*kevent.Kevent + // queue of inbound events + evts []*event.Event // work queue that forwarder passes to outputs wq queue submitter *submitter @@ -81,7 +81,7 @@ type BufferedAggregator struct { // NewBuffered creates a new instance of the event aggregator. func NewBuffered( - evts <-chan *kevent.Kevent, + evts <-chan *event.Event, errs <-chan error, aggConfig Config, outputConfig outputs.Config, @@ -93,12 +93,12 @@ func NewBuffered( flushInterval = time.Millisecond * 250 } agg := &BufferedAggregator{ - kevtsc: evts, - kevts: make([]*kevent.Kevent, 0), + evtsc: evts, + evts: make([]*event.Event, 0), errsc: errs, stop: make(chan struct{}, 1), flusher: time.NewTicker(flushInterval), - wq: make(chan *kevent.Batch), + wq: make(chan *event.Batch), c: aggConfig, } @@ -127,7 +127,7 @@ func (agg *BufferedAggregator) Stop() error { agg.stop <- struct{}{} // flush enqueued events - b := kevent.NewBatch(agg.kevts...) + b := event.NewBatch(agg.evts...) if b.Len() > 0 { done := make(chan struct{}, 1) go func() { @@ -163,10 +163,10 @@ func (agg *BufferedAggregator) run() { agg.flusher.Stop() return case <-agg.flusher.C: - if len(agg.kevts) == 0 { + if len(agg.evts) == 0 { continue } - b := kevent.NewBatch(agg.kevts...) + b := event.NewBatch(agg.evts...) l := b.Len() batchEvents.Add(l) // push the batch to the work queue @@ -175,8 +175,8 @@ func (agg *BufferedAggregator) run() { } flushesCount.Add(1) // clear the queue - agg.kevts = nil - case evt := <-agg.kevtsc: + agg.evts = nil + case evt := <-agg.evtsc: for _, transform := range agg.transforms { err := transform.Transform(evt) if err != nil { @@ -184,10 +184,10 @@ func (agg *BufferedAggregator) run() { } } // push the event to the queue - agg.kevts = append(agg.kevts, evt) - keventsDequeued.Add(1) + agg.evts = append(agg.evts, evt) + eventsDequeued.Add(1) case err := <-agg.errsc: - keventErrors.Add(1) + eventsErrors.Add(1) log.Errorf("event processing failure: %v", err) } } diff --git a/pkg/aggregator/aggregator_test.go b/pkg/aggregator/aggregator_test.go index 8e3568f6b..37ad1bbb6 100644 --- a/pkg/aggregator/aggregator_test.go +++ b/pkg/aggregator/aggregator_test.go @@ -19,9 +19,8 @@ package aggregator import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/outputs" "github.com/rabbitstack/fibratus/pkg/outputs/console" "github.com/stretchr/testify/assert" @@ -32,7 +31,7 @@ import ( ) func TestNewBufferedAggregator(t *testing.T) { - keventsc := make(chan *kevent.Kevent, 20) + keventsc := make(chan *event.Event, 20) errsc := make(chan error, 1) agg, err := NewBuffered( keventsc, @@ -46,36 +45,36 @@ func TestNewBufferedAggregator(t *testing.T) { require.NotNil(t, agg) for i := 0; i < 4; i++ { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - keventsc <- kevt + keventsc <- evt } <-time.After(time.Millisecond * 275) assert.Equal(t, int64(4), batchEvents.Value()) for i := 0; i < 2; i++ { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, Seq: uint64(i), - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - keventsc <- kevt + keventsc <- evt } <-time.After(time.Millisecond * 260) assert.Equal(t, int64(6), batchEvents.Value()) diff --git a/pkg/aggregator/submitter.go b/pkg/aggregator/submitter.go index 528f7c20d..2b1aadba4 100644 --- a/pkg/aggregator/submitter.go +++ b/pkg/aggregator/submitter.go @@ -19,12 +19,12 @@ package aggregator import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" ) // queue defines the type alias for the batch worker queue -type queue chan *kevent.Batch +type queue chan *event.Batch // submitter initializes a group of load balanced output producers. type submitter struct { diff --git a/pkg/aggregator/transformers/config.go b/pkg/aggregator/transformers/config.go index 41f9d60a3..b80270fc7 100644 --- a/pkg/aggregator/transformers/config.go +++ b/pkg/aggregator/transformers/config.go @@ -20,7 +20,7 @@ package transformers import "fmt" -// ErrInvalidConfig signals an invalid configuration input +// ErrInvalidConfig signals an invalid transformer configuration var ErrInvalidConfig = func(name Type) error { return fmt.Errorf("invalid config for %q transformer", name) } // Config acts as a container for the transformer configuration structures. diff --git a/pkg/aggregator/transformers/remove/config.go b/pkg/aggregator/transformers/remove/config.go index 1362a983f..daf7dfd1d 100644 --- a/pkg/aggregator/transformers/remove/config.go +++ b/pkg/aggregator/transformers/remove/config.go @@ -21,20 +21,20 @@ package remove import "github.com/spf13/pflag" const ( - kpars = "transformers.remove.kparams" + pars = "transformers.remove.params" enabled = "transformers.remove.enabled" ) // Config stores the configuration for the remove transformer. type Config struct { - // Kparams is the list of parameters that are dropped from the event. - Kparams []string `mapstructure:"kparams"` + // Params is the list of parameters that are dropped from the event. + Params []string `mapstructure:"params"` // Enabled indicates whether this transformer is enabled Enabled bool `mapstructure:"enabled"` } // AddFlags registers persistent flags. func AddFlags(flags *pflag.FlagSet) { - flags.StringSlice(kpars, []string{}, "A list of comma-separated parameters that will be removed from the event") + flags.StringSlice(pars, []string{}, "A list of comma-separated parameters that will be removed from the event") flags.Bool(enabled, false, "Indicates if remove transformer is enabled") } diff --git a/pkg/aggregator/transformers/remove/remove.go b/pkg/aggregator/transformers/remove/remove.go index 1b81c71af..0a8856349 100644 --- a/pkg/aggregator/transformers/remove/remove.go +++ b/pkg/aggregator/transformers/remove/remove.go @@ -21,12 +21,12 @@ package remove import ( "expvar" "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" ) var removedCount = expvar.NewInt("transformers.removed.params") -// remove transformer deletes kparams that are given in the list. +// remove transformer deletes params that are given in the list. type remove struct { c Config } @@ -43,9 +43,9 @@ func initRemoveTransformer(config transformers.Config) (transformers.Transformer return &remove{c: cfg}, nil } -func (r remove) Transform(kevt *kevent.Kevent) error { - for _, kpar := range r.c.Kparams { - delete(kevt.Kparams, kpar) +func (r remove) Transform(evt *event.Event) error { + for _, par := range r.c.Params { + delete(evt.Params, par) removedCount.Add(1) } return nil diff --git a/pkg/aggregator/transformers/remove/remove_test.go b/pkg/aggregator/transformers/remove/remove_test.go index 75dfbb4ec..0e114be1a 100644 --- a/pkg/aggregator/transformers/remove/remove_test.go +++ b/pkg/aggregator/transformers/remove/remove_test.go @@ -20,9 +20,8 @@ package remove import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" @@ -30,24 +29,24 @@ import ( ) func TestTransform(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - assert.Len(t, kevt.Kparams, 4) + assert.Len(t, evt.Params, 4) - transf, err := transformers.Load(transformers.Config{Type: transformers.Remove, Transformer: Config{Kparams: []string{"dip", "sport", "foo"}}}) + transf, err := transformers.Load(transformers.Config{Type: transformers.Remove, Transformer: Config{Params: []string{"dip", "sport", "foo"}}}) require.NoError(t, err) - err = transf.Transform(kevt) + err = transf.Transform(evt) require.NoError(t, err) - assert.Len(t, kevt.Kparams, 2) + assert.Len(t, evt.Params, 2) } diff --git a/pkg/aggregator/transformers/rename/config.go b/pkg/aggregator/transformers/rename/config.go index b0b742dee..0464a75ec 100644 --- a/pkg/aggregator/transformers/rename/config.go +++ b/pkg/aggregator/transformers/rename/config.go @@ -32,8 +32,8 @@ type Rename struct { // Config stores the configuration of the rename transformer. type Config struct { - // Kparams is the list of parameters that will be renamed. - Kparams []Rename + // Params is the list of parameters that will be renamed. + Params []Rename // Enabled indicates whether this transformer is enabled. Enabled bool } diff --git a/pkg/aggregator/transformers/rename/rename.go b/pkg/aggregator/transformers/rename/rename.go index 7f89cb977..4ac17cc6b 100644 --- a/pkg/aggregator/transformers/rename/rename.go +++ b/pkg/aggregator/transformers/rename/rename.go @@ -20,10 +20,10 @@ package rename import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" ) -// rename as it name implies, it renames a sequence of kparams to their new names. +// rename as it name implies, it renames a sequence of params to their new names. type rename struct { c Config } @@ -40,15 +40,15 @@ func initRenameTransformer(config transformers.Config) (transformers.Transformer return &rename{c: cfg}, nil } -func (r rename) Transform(kevt *kevent.Kevent) error { - for _, par := range r.c.Kparams { - kpar, ok := kevt.Kparams[par.Old] +func (r rename) Transform(evt *event.Event) error { + for _, p := range r.c.Params { + par, ok := evt.Params[p.Old] if !ok { continue } - kevt.Kparams.Remove(par.Old) - kpar.Name = par.New - kevt.Kparams[par.New] = kpar + evt.Params.Remove(p.Old) + par.Name = p.New + evt.Params[p.New] = par } return nil } diff --git a/pkg/aggregator/transformers/rename/rename_test.go b/pkg/aggregator/transformers/rename/rename_test.go index e3e7ed736..8a90259f4 100644 --- a/pkg/aggregator/transformers/rename/rename_test.go +++ b/pkg/aggregator/transformers/rename/rename_test.go @@ -20,9 +20,8 @@ package rename import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" @@ -30,26 +29,26 @@ import ( ) func TestTransform(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), } - transf, err := transformers.Load(transformers.Config{Type: transformers.Rename, Transformer: Config{Kparams: []Rename{{Old: "dport", New: "dstport"}, {Old: "sip", New: "srcip"}}}}) + transf, err := transformers.Load(transformers.Config{Type: transformers.Rename, Transformer: Config{Params: []Rename{{Old: "dport", New: "dstport"}, {Old: "sip", New: "srcip"}}}}) require.NoError(t, err) - require.NoError(t, transf.Transform(kevt)) + require.NoError(t, transf.Transform(evt)) - assert.True(t, kevt.Kparams.Contains("dstport")) - assert.False(t, kevt.Kparams.Contains("dport")) - assert.True(t, kevt.Kparams.Contains("srcip")) - assert.False(t, kevt.Kparams.Contains("sip")) + assert.True(t, evt.Params.Contains("dstport")) + assert.False(t, evt.Params.Contains("dport")) + assert.True(t, evt.Params.Contains("srcip")) + assert.False(t, evt.Params.Contains("sip")) } diff --git a/pkg/aggregator/transformers/replace/config.go b/pkg/aggregator/transformers/replace/config.go index ea8c65cfd..a96f0e64a 100644 --- a/pkg/aggregator/transformers/replace/config.go +++ b/pkg/aggregator/transformers/replace/config.go @@ -26,17 +26,17 @@ const ( // Config stores the configuration for the replace transformer type Config struct { - // Replacements describes a list of replacements that are applied on the kparam. + // Replacements describes a list of replacements that are applied on the Param. Replacements []Replacement `mapstructure:"replacements"` // Enabled indicates whether this transformer is enabled Enabled bool `mapstructure:"enabled"` } -// Replacement defines the string replacement config for a specific kparam. +// Replacement defines the string replacement config for a specific Param. type Replacement struct { - Kpar string `mapstructure:"kparam"` - Old string `mapstructure:"old"` - New string `mapstructure:"new"` + Param string `mapstructure:"param"` + Old string `mapstructure:"old"` + New string `mapstructure:"new"` } // AddFlags registers persistent flags. diff --git a/pkg/aggregator/transformers/replace/replace.go b/pkg/aggregator/transformers/replace/replace.go index 2a449ff33..4889b331a 100644 --- a/pkg/aggregator/transformers/replace/replace.go +++ b/pkg/aggregator/transformers/replace/replace.go @@ -21,13 +21,13 @@ package replace import ( "expvar" "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "strings" ) var replaceCount = expvar.NewInt("transformers.replaced.params") -// replace applies string substitutions in kpar values. +// replace applies string substitutions in par values. type replace struct { c Config } @@ -44,17 +44,17 @@ func initReplaceTransformer(config transformers.Config) (transformers.Transforme return &replace{c: cfg}, nil } -func (r replace) Transform(kevt *kevent.Kevent) error { +func (r replace) Transform(evt *event.Event) error { for _, repl := range r.c.Replacements { - kpar := kevt.Kparams.Find(repl.Kpar) - if kpar == nil { + par := evt.Params.Find(repl.Param) + if par == nil { continue } - _, ok := kpar.Value.(string) + _, ok := par.Value.(string) if !ok { continue } - kpar.Value = strings.ReplaceAll(kevt.GetParamAsString(kpar.Name), repl.Old, repl.New) + par.Value = strings.ReplaceAll(evt.GetParamAsString(par.Name), repl.Old, repl.New) replaceCount.Add(1) } return nil diff --git a/pkg/aggregator/transformers/replace/replace_test.go b/pkg/aggregator/transformers/replace/replace_test.go index d2ed0dc45..8a48c99e5 100644 --- a/pkg/aggregator/transformers/replace/replace_test.go +++ b/pkg/aggregator/transformers/replace/replace_test.go @@ -20,31 +20,30 @@ package replace import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "testing" ) func TestTransform(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.RegCreateKey, + evt := &event.Event{ + Type: event.RegCreateKey, Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Address, Value: uint64(18446666033449935464)}, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Address, Value: uint64(18446666033449935464)}, }, } - transf, err := transformers.Load(transformers.Config{Type: transformers.Replace, Transformer: Config{Replacements: []Replacement{{Kpar: "key_path", Old: "HKEY_LOCAL_MACHINE", New: "HKLM"}}}}) + transf, err := transformers.Load(transformers.Config{Type: transformers.Replace, Transformer: Config{Replacements: []Replacement{{Param: "key_path", Old: "HKEY_LOCAL_MACHINE", New: "HKLM"}}}}) require.NoError(t, err) - require.NoError(t, transf.Transform(kevt)) + require.NoError(t, transf.Transform(evt)) - keyName, _ := kevt.Kparams.GetString(kparams.RegPath) + keyName, _ := evt.Params.GetString(params.RegPath) assert.Equal(t, `HKLM\SYSTEM\Setup\Pid`, keyName) } diff --git a/pkg/aggregator/transformers/tags/tags.go b/pkg/aggregator/transformers/tags/tags.go index d1909f5e1..e479dd748 100644 --- a/pkg/aggregator/transformers/tags/tags.go +++ b/pkg/aggregator/transformers/tags/tags.go @@ -23,7 +23,7 @@ import ( "strings" "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" ) // tags transformer appends tags to the event's metadata. It is capable of adding literal values as well as @@ -61,9 +61,9 @@ func initTagsTransformer(config transformers.Config) (transformers.Transformer, return &tags{tags: ktags}, nil } -func (t tags) Transform(kevt *kevent.Kevent) error { +func (t tags) Transform(evt *event.Event) error { for k, v := range t.tags { - kevt.AddMeta(kevent.MetadataKey(k), v) + evt.AddMeta(event.MetadataKey(k), v) } return nil } diff --git a/pkg/aggregator/transformers/tags/tags_test.go b/pkg/aggregator/transformers/tags/tags_test.go index 8651a9371..4d3a84cf4 100644 --- a/pkg/aggregator/transformers/tags/tags_test.go +++ b/pkg/aggregator/transformers/tags/tags_test.go @@ -24,35 +24,34 @@ import ( "testing" "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) func TestTransform(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), } require.NoError(t, os.Setenv("NODENAME", "archbunny")) transf, err := transformers.Load(transformers.Config{Type: transformers.Tags, Transformer: Config{Tags: []Tag{{Key: "env", Value: "staging"}, {Key: "zone", Value: "dmz"}, {Key: "node", Value: "%NODENAME%"}}}}) require.NoError(t, err) - require.NoError(t, transf.Transform(kevt)) + require.NoError(t, transf.Transform(evt)) - require.Len(t, kevt.Metadata, 3) + require.Len(t, evt.Metadata, 3) - assert.Equal(t, "staging", kevt.Metadata["env"]) - assert.Equal(t, "dmz", kevt.Metadata["zone"]) - assert.Equal(t, "archbunny", kevt.Metadata["node"]) + assert.Equal(t, "staging", evt.Metadata["env"]) + assert.Equal(t, "dmz", evt.Metadata["zone"]) + assert.Equal(t, "archbunny", evt.Metadata["node"]) } diff --git a/pkg/aggregator/transformers/transformer.go b/pkg/aggregator/transformers/transformer.go index 6242f2855..e08841637 100644 --- a/pkg/aggregator/transformers/transformer.go +++ b/pkg/aggregator/transformers/transformer.go @@ -20,7 +20,7 @@ package transformers import ( "fmt" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" ) var transformers = map[Type]Factory{} @@ -34,11 +34,11 @@ type Type uint8 const ( // Remove represents the remove transformer type. This transformer deletes the given list of parameters from the event. Remove Type = iota - // Rename represents the rename transformer type. It renames a sequence of kparam from old to new names. + // Rename represents the rename transformer type. It renames a sequence of Param from old to new names. Rename - // Replace represents the replace tranformer type. It applies string replacements on specific kparams. + // Replace represents the replace transformer type. It applies string replacements on specific params. Replace - // Trim represents the trim transformer type that that removes suffix/prefix from string kparams. + // Trim represents the trim transformer type that that removes suffix/prefix from string params. Trim // Tags represents the tags transformer type. This transformer appends tags to the event's metadata. Tags @@ -95,5 +95,5 @@ func Load(config Config) (Transformer, error) { // Transformer is the minimal interface all transformers have to satisfy. type Transformer interface { - Transform(*kevent.Kevent) error + Transform(*event.Event) error } diff --git a/pkg/aggregator/transformers/trim/config.go b/pkg/aggregator/transformers/trim/config.go index 60f56c6a4..de05166d4 100644 --- a/pkg/aggregator/transformers/trim/config.go +++ b/pkg/aggregator/transformers/trim/config.go @@ -26,15 +26,15 @@ const ( // Trim defines the trim configuration for a single event parameter. type Trim struct { - Name string `mapstructure:"kparam"` + Name string `mapstructure:"Param"` Trim string `mapstructure:"trim"` } // Config stores the configuration for the trim transformer. type Config struct { - // Prefixes contains the mapping between distinct kparam names and the prefixes that will get trimmed from their values. + // Prefixes contains the mapping between distinct Param names and the prefixes that will get trimmed from their values. Prefixes []Trim `mapstructure:"prefixes"` - // Suffixes contains the mapping between distinct kparam names and the suffixes that will get trimmed from their values. + // Suffixes contains the mapping between distinct Param names and the suffixes that will get trimmed from their values. Suffixes []Trim `mapstructure:"suffixes"` // Enabled determines whether trim transformer is enabled or disabled. Enabled bool `mapstructure:"enabled"` diff --git a/pkg/aggregator/transformers/trim/trim.go b/pkg/aggregator/transformers/trim/trim.go index abce5754d..bbcaa99a7 100644 --- a/pkg/aggregator/transformers/trim/trim.go +++ b/pkg/aggregator/transformers/trim/trim.go @@ -20,11 +20,11 @@ package trim import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "strings" ) -// trim transformer trims suffixes/prefixes from kpar values. +// trim transformer trims suffixes/prefixes from par values. type trim struct { c Config } @@ -41,29 +41,29 @@ func initTrimTransformer(config transformers.Config) (transformers.Transformer, return &trim{c: cfg}, nil } -func (r trim) Transform(kevt *kevent.Kevent) error { - for _, kpar := range kevt.Kparams { +func (r trim) Transform(evt *event.Event) error { + for _, par := range evt.Params { // trim prefixes - for _, par := range r.c.Prefixes { - if kpar.Name != par.Name { + for _, pre := range r.c.Prefixes { + if par.Name != pre.Name { continue } - _, ok := kpar.Value.(string) + _, ok := par.Value.(string) if !ok { continue } - kpar.Value = strings.TrimPrefix(kevt.GetParamAsString(kpar.Name), par.Trim) + par.Value = strings.TrimPrefix(evt.GetParamAsString(par.Name), pre.Trim) } // trim suffixes - for _, par := range r.c.Suffixes { - if kpar.Name != par.Name { + for _, suf := range r.c.Suffixes { + if par.Name != suf.Name { continue } - _, ok := kpar.Value.(string) + _, ok := par.Value.(string) if !ok { continue } - kpar.Value = strings.TrimSuffix(kevt.GetParamAsString(kpar.Name), par.Trim) + par.Value = strings.TrimSuffix(evt.GetParamAsString(par.Name), suf.Trim) } } return nil diff --git a/pkg/aggregator/transformers/trim/trim_test.go b/pkg/aggregator/transformers/trim/trim_test.go index dc8e78b00..43270822b 100644 --- a/pkg/aggregator/transformers/trim/trim_test.go +++ b/pkg/aggregator/transformers/trim/trim_test.go @@ -20,9 +20,8 @@ package trim import ( "github.com/rabbitstack/fibratus/pkg/aggregator/transformers" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "testing" @@ -30,36 +29,36 @@ import ( ) func TestTransform(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "overwriteif"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(18884888488889)}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1204)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "overwriteif"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(18884888488889)}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1204)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barz"}, } transf, err := transformers.Load(transformers.Config{Type: transformers.Trim, Transformer: Config{Prefixes: []Trim{{Name: "file_path", Trim: "\\Device"}}, Suffixes: []Trim{{Name: "create_disposition", Trim: "if"}}}}) require.NoError(t, err) - require.NoError(t, transf.Transform(kevt)) - filename, _ := kevt.Kparams.GetString(kparams.FilePath) - dispo, _ := kevt.Kparams.GetString(kparams.FileOperation) + require.NoError(t, transf.Transform(evt)) + filename, _ := evt.Params.GetString(params.FilePath) + dispo, _ := evt.Params.GetString(params.FileOperation) assert.Equal(t, "\\HarddiskVolume2\\Windows\\system32\\user32.dll", filename) assert.Equal(t, "overwrite", dispo) diff --git a/pkg/aggregator/worker_test.go b/pkg/aggregator/worker_test.go index 20eb708e5..66d493619 100644 --- a/pkg/aggregator/worker_test.go +++ b/pkg/aggregator/worker_test.go @@ -19,7 +19,7 @@ package aggregator import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/stretchr/testify/assert" "net/http" "net/http/httptest" @@ -51,7 +51,7 @@ func (c *httpClient) Connect() error { func (c *httpClient) Close() error { return nil } -func (c *httpClient) Publish(b *kevent.Batch) error { +func (c *httpClient) Publish(b *event.Batch) error { //nolint:noctx res, err := http.Post(c.url+"/publish", "application/json", nil) if err != nil { @@ -68,9 +68,9 @@ func (c *httpClient) Publish(b *kevent.Batch) error { } func TestRunWorker(t *testing.T) { - q := make(chan *kevent.Batch, 2) - q <- &kevent.Batch{} - q <- &kevent.Batch{} + q := make(chan *event.Batch, 2) + q <- &event.Batch{} + q <- &event.Batch{} mux := http.NewServeMux() mux.HandleFunc("/publish", func(w http.ResponseWriter, r *http.Request) { @@ -91,9 +91,9 @@ func TestRunWorker(t *testing.T) { } func TestConnectClientBackoff(t *testing.T) { - q := make(chan *kevent.Batch, 2) - q <- &kevent.Batch{} - q <- &kevent.Batch{} + q := make(chan *event.Batch, 2) + q <- &event.Batch{} + q <- &event.Batch{} fail := true diff --git a/pkg/alertsender/alert.go b/pkg/alertsender/alert.go index 6f07284d3..9c3243717 100644 --- a/pkg/alertsender/alert.go +++ b/pkg/alertsender/alert.go @@ -21,7 +21,7 @@ package alertsender import ( "bytes" "fmt" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/yuin/goldmark" "github.com/yuin/goldmark/extension" "github.com/yuin/goldmark/renderer/html" @@ -95,7 +95,7 @@ type Alert struct { // Severity determines the severity of this alert. Severity Severity // Events contains a list of events that trigger the alert. - Events []*kevent.Kevent + Events []*event.Event } // String returns the alert string representation. If verbose @@ -146,6 +146,6 @@ func NewAlert(title, text string, tags []string, severity Severity) Alert { } // NewAlertWithEvents builds a new alert with associated events. -func NewAlertWithEvents(title, text string, tags []string, severity Severity, evts []*kevent.Kevent) Alert { +func NewAlertWithEvents(title, text string, tags []string, severity Severity, evts []*event.Event) Alert { return Alert{Title: title, Text: text, Tags: tags, Severity: severity, Events: evts} } diff --git a/pkg/alertsender/alert_test.go b/pkg/alertsender/alert_test.go index 21d04b16e..697596269 100644 --- a/pkg/alertsender/alert_test.go +++ b/pkg/alertsender/alert_test.go @@ -19,9 +19,8 @@ package alertsender import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/require" "testing" @@ -44,12 +43,12 @@ func TestAlertString(t *testing.T) { "Credential discovery via VaultCmd.exe\n\nSuspicious vault enumeration via VaultCmd tool", }, { - NewAlertWithEvents("Credential discovery via VaultCmd.exe", "Suspicious vault enumeration via VaultCmd tool", nil, Normal, []*kevent.Kevent{{ - Type: ktypes.CreateProcess, - Category: ktypes.Process, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "svchost-fake.exe"}}, + NewAlertWithEvents("Credential discovery via VaultCmd.exe", "Suspicious vault enumeration via VaultCmd tool", nil, Normal, []*event.Event{{ + Type: event.CreateProcess, + Category: event.Process, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "svchost-fake.exe"}}, Name: "CreateProcess", PID: 1023, PS: &pstypes.PS{ @@ -65,12 +64,12 @@ func TestAlertString(t *testing.T) { "Credential discovery via VaultCmd.exe\n\nSuspicious vault enumeration via VaultCmd tool\n\nSeverity: low\n\nSystem event involved in this alert:\n\n\tEvent #1:\n\n\t\tSeq: 0\n\t\tPid: 1023\n\t\tTid: 0\n\t\tName: CreateProcess\n\t\tCategory: process\n\t\tHost: \n\t\tTimestamp: 0001-01-01 00:00:00 +0000 UTC\n\t\tParameters: cmdline➜ C:\\Windows\\system32\\svchost-fake.exe -k RPCSS, name➜ svchost-fake.exe\n \n\t\tPid: 0\n\t\tPpid: 345\n\t\tName: svchost.exe\n\t\tCmdline: C:\\Windows\\System32\\svchost.exe\n\t\tExe: \n\t\tCwd: \n\t\tSID: S-1-5-18\n\t\tUsername: SYSTEM\n\t\tDomain: NT AUTHORITY\n\t\tArgs: []\n\t\tSession ID: 0\n\t\tAncestors: \n\t\n", }, { - NewAlertWithEvents("Credential discovery via VaultCmd.exe", "", nil, Normal, []*kevent.Kevent{{ - Type: ktypes.CreateProcess, - Category: ktypes.Process, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "svchost-fake.exe"}}, + NewAlertWithEvents("Credential discovery via VaultCmd.exe", "", nil, Normal, []*event.Event{{ + Type: event.CreateProcess, + Category: event.Process, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "svchost-fake.exe"}}, Name: "CreateProcess", PID: 1023, PS: &pstypes.PS{ diff --git a/pkg/alertsender/eventlog/eventlog_test.go b/pkg/alertsender/eventlog/eventlog_test.go index 894073910..3567dd8f6 100644 --- a/pkg/alertsender/eventlog/eventlog_test.go +++ b/pkg/alertsender/eventlog/eventlog_test.go @@ -20,10 +20,9 @@ package eventlog import ( "github.com/rabbitstack/fibratus/pkg/alertsender" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pex "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -39,25 +38,25 @@ func TestEventlogSender(t *testing.T) { require.NotNil(t, s) require.NoError(t, s.Send(alertsender.Alert{ - Events: []*kevent.Kevent{ + Events: []*event.Event{ { - Type: ktypes.CreateFile, + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -136,22 +135,22 @@ func TestEventlogSender(t *testing.T) { }, }, { - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Tid: 2184, PID: 1022, CPU: 2, Seq: 3, Name: "CreateProcess", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates a new process", - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe"}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.UnicodeString, Value: "admin\\SYSTEM"}, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe"}, + params.UserSID: {Name: params.UserSID, Type: params.UnicodeString, Value: "admin\\SYSTEM"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, diff --git a/pkg/alertsender/mail/renderer_test.go b/pkg/alertsender/mail/renderer_test.go index 32033f009..751244347 100644 --- a/pkg/alertsender/mail/renderer_test.go +++ b/pkg/alertsender/mail/renderer_test.go @@ -21,10 +21,9 @@ package mail import ( "github.com/antchfx/htmlquery" "github.com/rabbitstack/fibratus/pkg/alertsender" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pex "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -50,25 +49,25 @@ func TestRenderHTMLTemplate(t *testing.T) { "subtechnique.name": "Windows Credential Manager", "subtechnique.ref": "https://attack.mitre.org/techniques/T1555/004/", }, - Events: []*kevent.Kevent{ + Events: []*event.Event{ { - Type: ktypes.CreateFile, + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -147,22 +146,22 @@ func TestRenderHTMLTemplate(t *testing.T) { }, }, { - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Tid: 2184, PID: 1022, CPU: 2, Seq: 3, Name: "CreateProcess", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates a new process", - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe"}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.UnicodeString, Value: "admin\\SYSTEM"}, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe"}, + params.UserSID: {Name: params.UserSID, Type: params.UnicodeString, Value: "admin\\SYSTEM"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, diff --git a/pkg/alertsender/mail/template.go b/pkg/alertsender/mail/template.go index dd3163060..f8345d89f 100644 --- a/pkg/alertsender/mail/template.go +++ b/pkg/alertsender/mail/template.go @@ -132,7 +132,7 @@ var htmlTemplate = ` - {{- range $key, $par := .Kparams }} + {{- range $key, $par := .Params }}
{{ regexReplaceAll "_" $key " " | title }} diff --git a/pkg/alertsender/systray/systray.go b/pkg/alertsender/systray/systray.go index cab1bfd7c..f0353ba7d 100644 --- a/pkg/alertsender/systray/systray.go +++ b/pkg/alertsender/systray/systray.go @@ -25,7 +25,7 @@ import ( "github.com/Microsoft/go-winio" "github.com/cenkalti/backoff/v4" "github.com/rabbitstack/fibratus/pkg/alertsender" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/sys" log "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -198,7 +198,7 @@ func makeSender(config alertsender.Config) (alertsender.Sender, error) { func (s *systray) Send(alert alertsender.Alert) error { // remove all events to avoid decoding errors on systray server end - alert.Events = make([]*kevent.Kevent, 0) + alert.Events = make([]*event.Event, 0) return s.send(&Msg{Type: Balloon, Data: alert}) } diff --git a/pkg/kcap/_fixtures/cap.kcap b/pkg/cap/_fixtures/cap.cap similarity index 100% rename from pkg/kcap/_fixtures/cap.kcap rename to pkg/cap/_fixtures/cap.cap diff --git a/pkg/kcap/_fixtures/cap1.kcap b/pkg/cap/_fixtures/cap1.cap similarity index 100% rename from pkg/kcap/_fixtures/cap1.kcap rename to pkg/cap/_fixtures/cap1.cap diff --git a/pkg/kcap/_fixtures/cap2.kcap b/pkg/cap/_fixtures/cap2.cap similarity index 100% rename from pkg/kcap/_fixtures/cap2.kcap rename to pkg/cap/_fixtures/cap2.cap diff --git a/pkg/kcap/config.go b/pkg/cap/config.go similarity index 98% rename from pkg/kcap/config.go rename to pkg/cap/config.go index bf63f3655..f73c0a8d5 100644 --- a/pkg/kcap/config.go +++ b/pkg/cap/config.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kcap +package cap import "time" diff --git a/pkg/kcap/header.go b/pkg/cap/header.go similarity index 70% rename from pkg/kcap/header.go rename to pkg/cap/header.go index 169ff25de..c1720164c 100644 --- a/pkg/kcap/header.go +++ b/pkg/cap/header.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,24 +19,24 @@ * limitations under the License. */ -package kcap +package cap import ( - "github.com/rabbitstack/fibratus/pkg/kcap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + "github.com/rabbitstack/fibratus/pkg/cap/section" + kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" ) -// magic has two purposes. It is used to identify kcap files. The magic is stored within the first 8 bytes of the file. +// magic has two purposes. It is used to identify cap files. The magic is stored within the first 8 bytes of the file. // The reader ensures the magic number matches this constant. Besides identifying the capture file, it serves as an -// input for initializing the byte order on the machine where kcap file is read. This implies capture can be taken on a +// input for initializing the byte order on the machine where cap file is read. This implies capture can be taken on a // machine with different endianness from the one capture is replayed. const magic = 0x6669627261747573 -// major represents the major digit of the kcap file format. Incrementing the major digit makes older kcap readers not +// major represents the major digit of the cap file format. Incrementing the major digit makes older cap readers not // capable to replay the capture file const major = uint8(2) -// minor represents the minor digit of the kcap file format +// minor represents the minor digit of the cap file format const minor = uint8(0) // flags denotes extra flags for the purpose of the header description diff --git a/pkg/kcap/reader.go b/pkg/cap/reader.go similarity index 59% rename from pkg/kcap/reader.go rename to pkg/cap/reader.go index f4d0c513f..9f52ec153 100644 --- a/pkg/kcap/reader.go +++ b/pkg/cap/reader.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2020-2021 by Nedim Sabic Sabic @@ -19,30 +19,30 @@ * limitations under the License. */ -package kcap +package cap import ( "errors" "expvar" "fmt" - "github.com/rabbitstack/fibratus/pkg/kcap/section" + "github.com/rabbitstack/fibratus/pkg/cap/section" ) var ( - // ErrKcapMagicMismatch signals invalid kcap binary format - ErrKcapMagicMismatch = errors.New("invalid kcap file magic number") - // ErrMajorVer signals incompatible kcap version + // ErrCapMagicMismatch signals invalid capture binary format + ErrCapMagicMismatch = errors.New("invalid capture file magic number") + // ErrMajorVer signals incompatible cap version ErrMajorVer = func(maj, min byte) error { - return fmt.Errorf("incompatible kcap version format. Required version %d.%d but %d.%d found", major, minor, maj, min) + return fmt.Errorf("incompatible cap version format. Required version %d.%d but %d.%d found", major, minor, maj, min) } // ErrReadVersion is thrown when version digit errors occur ErrReadVersion = func(s string, err error) error { return fmt.Errorf("couldn't read %s version digit: %v", s, err) } // ErrReadSection is thrown when section read errors occur ErrReadSection = func(s section.Type, err error) error { return fmt.Errorf("couldn't read %s section: %v", s, err) } - kcapReadKevents = expvar.NewInt("kcap.read.kevents") - kcapReadBytes = expvar.NewInt("kcap.read.bytes") - kcapKeventUnmarshalErrors = expvar.NewInt("kcap.kevent.unmarshal.errors") - kcapHandleUnmarshalErrors = expvar.NewInt("kcap.reader.handle.unmarshal.errors") - kcapDroppedByFilter = expvar.NewInt("kcap.reader.dropped.by.filter") + capReadKevents = expvar.NewInt("cap.read.events") + capReadBytes = expvar.NewInt("cap.read.bytes") + capKeventUnmarshalErrors = expvar.NewInt("cap.event.unmarshal.errors") + capHandleUnmarshalErrors = expvar.NewInt("cap.reader.handle.unmarshal.errors") + capDroppedByFilter = expvar.NewInt("cap.reader.dropped.by.filter") ) diff --git a/pkg/kcap/reader_unsupported.go b/pkg/cap/reader_unsupported.go similarity index 84% rename from pkg/kcap/reader_unsupported.go rename to pkg/cap/reader_unsupported.go index c6ed5f86d..b344bd68f 100644 --- a/pkg/kcap/reader_unsupported.go +++ b/pkg/cap/reader_unsupported.go @@ -1,5 +1,5 @@ -//go:build !kcap -// +build !kcap +//go:build !cap +// +build !cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,14 +19,14 @@ * limitations under the License. */ -package kcap +package cap import ( "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + "github.com/rabbitstack/fibratus/pkg/errors" ) // NewReader returns unsupported reader. func NewReader(filename string, config *config.Config) (Reader, error) { - return nil, kerrors.ErrFeatureUnsupported("kcap") + return nil, errors.ErrFeatureUnsupported("cap") } diff --git a/pkg/kcap/reader_windows.go b/pkg/cap/reader_windows.go similarity index 69% rename from pkg/kcap/reader_windows.go rename to pkg/cap/reader_windows.go index 049f2cc63..be00cb3f7 100644 --- a/pkg/kcap/reader_windows.go +++ b/pkg/cap/reader_windows.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,19 +19,18 @@ * limitations under the License. */ -package kcap +package cap import ( "context" "fmt" + "github.com/rabbitstack/fibratus/pkg/cap/section" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kcap/section" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/bytes" log "github.com/sirupsen/logrus" @@ -52,10 +51,10 @@ type reader struct { mu sync.Mutex // guards the underlying zstd byte buffer } -// NewReader builds a new instance of the kcap reader. +// NewReader builds a new instance of the cap reader. func NewReader(filename string, config *config.Config) (Reader, error) { if filepath.Ext(filename) == "" { - filename += ".kcap" + filename += ".cap" } f, err := os.Open(filename) if err != nil { @@ -68,7 +67,7 @@ func NewReader(filename string, config *config.Config) (Reader, error) { mag := make([]byte, 8) if n, err := zr.Read(mag); err != nil || n != 8 { - return nil, ErrKcapMagicMismatch + return nil, ErrCapMagicMismatch } bytes.InitNativeEndian(mag) // from now on all byte reads will use the endianness of the magic number. @@ -76,7 +75,7 @@ func NewReader(filename string, config *config.Config) (Reader, error) { // on a machine with a different endianness from the machine where // actual capture is being read. if bytes.ReadUint64(mag) != magic { - return nil, ErrKcapMagicMismatch + return nil, ErrCapMagicMismatch } maj := make([]byte, 1) @@ -95,7 +94,7 @@ func NewReader(filename string, config *config.Config) (Reader, error) { // read the flags bit vector but do nothing with it at the moment flags := make([]byte, 8) if n, err := zr.Read(flags); err != nil || n != 8 { - return nil, fmt.Errorf("fail to read kcap flags: %v", err) + return nil, fmt.Errorf("fail to read cap flags: %v", err) } return &reader{f: f, zr: zr, config: config}, nil @@ -103,9 +102,9 @@ func NewReader(filename string, config *config.Config) (Reader, error) { func (r *reader) SetFilter(f filter.Filter) { r.filter = f } -func (r *reader) Read(ctx context.Context) (chan *kevent.Kevent, chan error) { +func (r *reader) Read(ctx context.Context) (chan *event.Event, chan error) { errsc := make(chan error, 100) - keventsc := make(chan *kevent.Kevent, 2000) + eventsc := make(chan *event.Event, 2000) go func() { r.mu.Lock() defer r.mu.Unlock() @@ -134,23 +133,23 @@ func (r *reader) Read(ctx context.Context) (chan *kevent.Kevent, chan error) { } break } - kevt, err := kevent.NewFromKcap(buf, sec.Version()) + evt, err := event.NewFromCapture(buf, sec.Version()) if err != nil { - errsc <- fmt.Errorf("fail to unmarshal kevent: %v", err) - kcapKeventUnmarshalErrors.Add(1) + errsc <- fmt.Errorf("fail to unmarshal event: %v", err) + capKeventUnmarshalErrors.Add(1) continue } - kcapReadBytes.Add(int64(len(buf))) + capReadBytes.Add(int64(len(buf))) // update the state of the ps/handle snapshotters - if err := r.updateSnapshotters(kevt); err != nil { + if err := r.updateSnapshotters(evt); err != nil { log.Warn(err) } // push the event to the chanel - r.read(kevt, keventsc) + r.read(evt, eventsc) } }() - return keventsc, errsc + return eventsc, errsc } func (r *reader) Close() error { @@ -165,56 +164,56 @@ func (r *reader) Close() error { return nil } -func (r *reader) read(kevt *kevent.Kevent, keventsc chan *kevent.Kevent) { - if kevt.Type.OnlyState() { +func (r *reader) read(evt *event.Event, eventsc chan *event.Event) { + if evt.Type.OnlyState() { return } - if r.filter != nil && !r.filter.Run(kevt) { - kcapDroppedByFilter.Add(1) + if r.filter != nil && !r.filter.Run(evt) { + capDroppedByFilter.Add(1) return } - keventsc <- kevt - kcapReadKevents.Add(1) + eventsc <- evt + capReadKevents.Add(1) } -func (r *reader) updateSnapshotters(kevt *kevent.Kevent) error { - switch kevt.Type { - case ktypes.TerminateProcess: - if err := r.psnapshotter.Remove(kevt); err != nil { +func (r *reader) updateSnapshotters(evt *event.Event) error { + switch evt.Type { + case event.TerminateProcess: + if err := r.psnapshotter.Remove(evt); err != nil { return err } - case ktypes.TerminateThread: - pid := kevt.Kparams.MustGetPid() - tid := kevt.Kparams.MustGetTid() + case event.TerminateThread: + pid := evt.Params.MustGetPid() + tid := evt.Params.MustGetTid() if err := r.psnapshotter.RemoveThread(pid, tid); err != nil { return err } - case ktypes.UnloadImage: - pid := kevt.Kparams.MustGetPid() - addr := kevt.Kparams.TryGetAddress(kparams.ImageBase) + case event.UnloadImage: + pid := evt.Params.MustGetPid() + addr := evt.Params.TryGetAddress(params.ImageBase) if err := r.psnapshotter.RemoveModule(pid, addr); err != nil { return err } - case ktypes.CreateProcess, - ktypes.ProcessRundown, - ktypes.LoadImage, - ktypes.ImageRundown, - ktypes.CreateThread, - ktypes.ThreadRundown: - if err := r.psnapshotter.WriteFromKcap(kevt); err != nil { + case event.CreateProcess, + event.ProcessRundown, + event.LoadImage, + event.ImageRundown, + event.CreateThread, + event.ThreadRundown: + if err := r.psnapshotter.WriteFromCapture(evt); err != nil { return err } - case ktypes.CreateHandle: - if err := r.hsnapshotter.Write(kevt); err != nil { + case event.CreateHandle: + if err := r.hsnapshotter.Write(evt); err != nil { return err } - case ktypes.CloseHandle: - if err := r.hsnapshotter.Remove(kevt); err != nil { + case event.CloseHandle: + if err := r.hsnapshotter.Remove(evt); err != nil { return err } } - if kevt.PS == nil { - _, kevt.PS = r.psnapshotter.Find(kevt.PID) + if evt.PS == nil { + _, evt.PS = r.psnapshotter.Find(evt.PID) } return nil } @@ -224,7 +223,7 @@ func (r *reader) RecoverSnapshotters() (handle.Snapshotter, ps.Snapshotter, erro if err != nil { return nil, nil, err } - r.psnapshotter = ps.NewSnapshotterFromKcap(hsnap, r.config) + r.psnapshotter = ps.NewSnapshotterFromCapture(hsnap, r.config) return hsnap, r.psnapshotter, nil } @@ -250,7 +249,7 @@ func (r *reader) recoverHandleSnapshotter() (handle.Snapshotter, error) { var err error handles[i], err = htypes.NewFromKcap(b) if err != nil { - kcapHandleUnmarshalErrors.Add(1) + capHandleUnmarshalErrors.Add(1) } } r.hsnapshotter = handle.NewFromKcap(handles) diff --git a/pkg/kcap/reader_windows_test.go b/pkg/cap/reader_windows_test.go similarity index 72% rename from pkg/kcap/reader_windows_test.go rename to pkg/cap/reader_windows_test.go index 539188121..cc69b7739 100644 --- a/pkg/kcap/reader_windows_test.go +++ b/pkg/cap/reader_windows_test.go @@ -19,7 +19,7 @@ * limitations under the License. */ -package kcap +package cap import ( "context" @@ -30,13 +30,13 @@ import ( ) func TestReadIncompatibleFormat(t *testing.T) { - r, err := NewReader("_fixtures/cap1.kcap", &config.Config{}) + r, err := NewReader("_fixtures/cap1.cap", &config.Config{}) require.Nil(t, r) - require.EqualErrorf(t, err, fmt.Sprintf("incompatible kcap version format. Required version %d.%d but 1.0 found", major, minor), "incompatible kcap version format. Required version %d.%d but 1.0 found", major, minor) + require.EqualErrorf(t, err, fmt.Sprintf("incompatible cap version format. Required version %d.%d but 1.0 found", major, minor), "incompatible cap version format. Required version %d.%d but 1.0 found", major, minor) } func TestRead(t *testing.T) { - r, err := NewReader("_fixtures/cap2.kcap", &config.Config{}) + r, err := NewReader("_fixtures/cap2.cap", &config.Config{}) if err != nil { t.Fatal(err) } @@ -46,13 +46,13 @@ func TestRead(t *testing.T) { ctx, cancel := context.WithCancel(context.Background()) - kevtsc, errs := r.Read(ctx) + evtsc, errs := r.Read(ctx) i := 0 for { select { - case kevt := <-kevtsc: - require.NotNil(t, kevt) - require.True(t, kevt.Seq > 0) + case evt := <-evtsc: + require.NotNil(t, evt) + require.True(t, evt.Seq > 0) i++ if i == 90 { cancel() diff --git a/pkg/kcap/section/section.go b/pkg/cap/section/section.go similarity index 83% rename from pkg/kcap/section/section.go rename to pkg/cap/section/section.go index d602125be..ca64bca5b 100644 --- a/pkg/kcap/section/section.go +++ b/pkg/cap/section/section.go @@ -20,20 +20,20 @@ package section import ( "fmt" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/util/bytes" ) // Section represents the header describing the type, length and the version of each section. type Section [10]byte -// String returns the string representation of the kcap section. +// String returns the string representation of the cap section. func (s Section) String() string { return fmt.Sprintf("type: %s, version: %d, len: %d, size: %d", s.Type(), s.Version(), s.Len(), s.Size()) } // New builds a new section block with the specified type, version, optional length and size. -func New(typ Type, ver kcapver.Version, l, size uint32) Section { +func New(typ Type, ver capver.Version, l, size uint32) Section { var s Section s[0] = uint8(typ) s[1] = uint8(ver) @@ -52,8 +52,8 @@ func Read(b []byte) Section { // Type returns the type of this section. func (s Section) Type() Type { return Type(s[0]) } -// Version returns the version of the captured section block. -func (s Section) Version() kcapver.Version { return kcapver.Version(s[1]) } +// Version returns the version of the capture section block. +func (s Section) Version() capver.Version { return capver.Version(s[1]) } // Len returns the length of the section. func (s Section) Len() uint32 { return bytes.ReadUint32(s[2:6]) } diff --git a/pkg/kcap/section/section_windows.go b/pkg/cap/section/section_windows.go similarity index 89% rename from pkg/kcap/section/section_windows.go rename to pkg/cap/section/section_windows.go index ebcb4f2a2..1930cfab9 100644 --- a/pkg/kcap/section/section_windows.go +++ b/pkg/cap/section/section_windows.go @@ -18,7 +18,7 @@ package section -// Type describes the type of a section +// Type describes the type of the capture section type Type uint8 const ( @@ -26,8 +26,8 @@ const ( Process Type = iota + 1 // Handle is the handle header type Handle - // Kevt is the kernel event header type - Kevt + // Event is the event header type + Event // PE is the Portable Executable header type PE ) @@ -39,8 +39,8 @@ func (s Type) String() string { return "process" case Handle: return "handle" - case Kevt: - return "kevent" + case Event: + return "event" case PE: return "pe" default: diff --git a/pkg/kcap/section/section_windows_test.go b/pkg/cap/section/section_windows_test.go similarity index 94% rename from pkg/kcap/section/section_windows_test.go rename to pkg/cap/section/section_windows_test.go index e464708c1..41fa28def 100644 --- a/pkg/kcap/section/section_windows_test.go +++ b/pkg/cap/section/section_windows_test.go @@ -19,7 +19,7 @@ package section import ( - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/stretchr/testify/assert" "testing" ) diff --git a/pkg/kcap/types_linux.go b/pkg/cap/types_linux.go similarity index 64% rename from pkg/kcap/types_linux.go rename to pkg/cap/types_linux.go index 52f0ef6d0..73f1d4226 100644 --- a/pkg/kcap/types_linux.go +++ b/pkg/cap/types_linux.go @@ -16,23 +16,23 @@ * limitations under the License. */ -package kcap +package cap type Writer interface { - // Write accepts two channels. The event channel receives events pushed by the kstream consumer. When the event + // Write accepts two channels. The event channel receives events pushed by the event source. When the event // is peeked from the channel, it is serialized and written to the underlying byte buffer. - Write(chan *kevent.Kevent, chan error) chan error + Write(chan *Event.Event, chan error) chan error // Close disposes all resources allocated by the writer. Close() error } -// Reader offers the mechanism for recovering the state of the kcapture and replaying all captured events. +// Reader offers the mechanism for recovering the state of the capture and replaying all captured events. type Reader interface { - // Read returns two channels. The event channel is poplated with event instances pulled from the kcap. If - // any error occurs during kcap processing, it is pushed to the error channel. - Read(ctx context.Context) (chan *kevent.Kevent, chan error) + // Read returns two channels. The event channel is populated with event instances pulled from the cap. If + // any error occurs during cap processing, it is pushed to the error channel. + Read(ctx context.Context) (chan *Event.Event, chan error) // Close shutdowns the reader gracefully. Close() error - // SetFilter sets the filter that's is applied to each event coming out of the kcap. + // SetFilter sets the filter that is applied to each event coming out of the capture. SetFilter(f filter.Filter) } diff --git a/pkg/kcap/types_windows.go b/pkg/cap/types_windows.go similarity index 71% rename from pkg/kcap/types_windows.go rename to pkg/cap/types_windows.go index fa30a0b17..2461ae7c9 100644 --- a/pkg/kcap/types_windows.go +++ b/pkg/cap/types_windows.go @@ -16,17 +16,17 @@ * limitations under the License. */ -package kcap +package cap import ( "context" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/rabbitstack/fibratus/pkg/ps" ) -// Writer is the minimal interface that all kcap writers need to satisfy. The Windows kcap +// Writer is the minimal interface that all cap writers need to satisfy. The Windows cap // file format has the layout as depicted in the following diagram: // // +-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-++-+-+-+ @@ -34,30 +34,30 @@ import ( // |---------------------------------------- // | Handle Section | Handles | // ----------------------------------------- -// | Kevt Section | Kevt ..................| +// | evt Section | evt ..................| // | ......................................| // | ......................................| // | ......................................| -// | ........ Kevt Section n Kevt n EOF | +// | ........ evt Section n evt n EOF | // +-+-+-+-+-+-+-+-++-+-+-+-+-+-+-+-++-+-+-+ type Writer interface { // Write accepts two channels. The event channel receives events pushed by the event consumer. // When the event is peeked from the channel, it is serialized and written to the underlying // byte buffer. - Write(<-chan *kevent.Kevent, <-chan error) chan error + Write(<-chan *event.Event, <-chan error) chan error // Close disposes all resources allocated by the writer. Close() error } -// Reader offers the mechanism for recovering the state of the kcapture and replaying all captured events. +// Reader offers the mechanism for recovering the state of the capture and replaying all captured events. type Reader interface { - // Read returns two channels. The event channel is poplated with event instances pulled from the kcap. If - // any error occurs during kcap processing, it is pushed to the error channel. - Read(ctx context.Context) (chan *kevent.Kevent, chan error) + // Read returns two channels. The event channel is populated with event instances pulled from the cap. If + // any error occurs during capture processing, it is pushed to the error channel. + Read(ctx context.Context) (chan *event.Event, chan error) // Close shutdowns the reader gracefully. Close() error - // RecoverSnapshotters recovers the statate of the snapshotters from the kcap. + // RecoverSnapshotters recovers the state of the snapshotters from the cap. RecoverSnapshotters() (handle.Snapshotter, ps.Snapshotter, error) - // SetFilter sets the filter applied to each event coming out of the kcap. + // SetFilter sets the filter applied to each event coming out of the cap. SetFilter(f filter.Filter) } diff --git a/pkg/kcap/version/version_windows.go b/pkg/cap/version/version_windows.go similarity index 90% rename from pkg/kcap/version/version_windows.go rename to pkg/cap/version/version_windows.go index e4da2de99..d2172bbe9 100644 --- a/pkg/kcap/version/version_windows.go +++ b/pkg/cap/version/version_windows.go @@ -22,10 +22,10 @@ package version type Version uint16 const ( - // KevtSecV1 is the v1 of the event section - KevtSecV1 Version = iota + 1 - // KevtSecV2 is the v2 of the event section - KevtSecV2 + // EvtSecV1 is the v1 of the event section + EvtSecV1 Version = iota + 1 + // EvtSecV2 is the v2 of the event section + EvtSecV2 ) const ( diff --git a/pkg/kcap/writer.go b/pkg/cap/writer.go similarity index 67% rename from pkg/kcap/writer.go rename to pkg/cap/writer.go index 53891b1ac..9d1ac0844 100644 --- a/pkg/kcap/writer.go +++ b/pkg/cap/writer.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2020-2021 by Nedim Sabic Sabic @@ -19,12 +19,12 @@ * limitations under the License. */ -package kcap +package cap import ( "expvar" "fmt" - "github.com/rabbitstack/fibratus/pkg/kcap/section" + "github.com/rabbitstack/fibratus/pkg/cap/section" "math" ) @@ -32,15 +32,15 @@ var ( // ErrWriteMagic signals magic write errors ErrWriteMagic = func(err error) error { return fmt.Errorf("couldn't write magic number: %v", err) } // ErrWriteVersion signals version write errors - ErrWriteVersion = func(v string, err error) error { return fmt.Errorf("couldn't write %s kcap digit: %v", v, err) } + ErrWriteVersion = func(v string, err error) error { return fmt.Errorf("couldn't write %s cap digit: %v", v, err) } // ErrWriteSection signals section write errors - ErrWriteSection = func(s section.Type, err error) error { return fmt.Errorf("couldn't write %s kcap section: %v", s, err) } + ErrWriteSection = func(s section.Type, err error) error { return fmt.Errorf("couldn't write %s cap section: %v", s, err) } - handleWriteErrors = expvar.NewInt("kcap.handle.write.errors") - kevtWriteErrors = expvar.NewInt("kcap.kevt.write.errors") - flusherErrors = expvar.NewMap("kcap.flusher.errors") - overflowKevents = expvar.NewInt("kcap.overflow.kevents") - kstreamConsumerErrors = expvar.NewInt("kcap.kstream.consumer.errors") + handleWriteErrors = expvar.NewInt("cap.handle.write.errors") + evtWriteErrors = expvar.NewInt("cap.evt.write.errors") + flusherErrors = expvar.NewMap("cap.flusher.errors") + overflowKevents = expvar.NewInt("cap.overflow.kevents") + eventSourceErrors = expvar.NewInt("cap.eventsource.errors") ) const maxKevtSize = math.MaxUint32 diff --git a/pkg/kcap/writer_unsupported.go b/pkg/cap/writer_unsupported.go similarity index 90% rename from pkg/kcap/writer_unsupported.go rename to pkg/cap/writer_unsupported.go index 3fb7cea24..c6c85cfba 100644 --- a/pkg/kcap/writer_unsupported.go +++ b/pkg/cap/writer_unsupported.go @@ -1,5 +1,5 @@ -//go:build !kcap -// +build !kcap +//go:build !cap +// +build !cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,7 +19,7 @@ * limitations under the License. */ -package kcap +package cap import ( kerrors "github.com/rabbitstack/fibratus/pkg/errors" @@ -29,5 +29,5 @@ import ( // NewWriter returns unsupported writer. func NewWriter(filename string, psnap ps.Snapshotter, hsnap handle.Snapshotter) (Writer, error) { - return nil, kerrors.ErrFeatureUnsupported("kcap") + return nil, kerrors.ErrFeatureUnsupported("cap") } diff --git a/pkg/kcap/writer_windows.go b/pkg/cap/writer_windows.go similarity index 83% rename from pkg/kcap/writer_windows.go rename to pkg/cap/writer_windows.go index 9dac3cb8a..08845273c 100644 --- a/pkg/kcap/writer_windows.go +++ b/pkg/cap/writer_windows.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,7 +19,7 @@ * limitations under the License. */ -package kcap +package cap import ( "fmt" @@ -31,10 +31,10 @@ import ( "github.com/dustin/go-humanize" "github.com/jedib0t/go-pretty/v6/table" + "github.com/rabbitstack/fibratus/pkg/cap/section" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kcap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/bytes" zstd "github.com/valyala/gozstd" @@ -42,21 +42,21 @@ import ( type stats struct { kcapFile string - kevtsWritten uint64 + evtsWritten uint64 bytesWritten uint64 handlesWritten uint64 procsWritten uint64 } -func (s *stats) incKevts(kevt *kevent.Kevent) { - if !kevt.Type.OnlyState() { - atomic.AddUint64(&s.kevtsWritten, 1) +func (s *stats) incKevts(evt *event.Event) { + if !evt.Type.OnlyState() { + atomic.AddUint64(&s.evtsWritten, 1) } } func (s *stats) incBytes(bytes uint64) { atomic.AddUint64(&s.bytesWritten, bytes) } func (s *stats) incHandles() { atomic.AddUint64(&s.handlesWritten, 1) } -func (s *stats) incProcs(kevt *kevent.Kevent) { - if kevt.IsCreateProcess() || kevt.IsProcessRundown() { +func (s *stats) incProcs(evt *event.Event) { + if evt.IsCreateProcess() || evt.IsProcessRundown() { atomic.AddUint64(&s.procsWritten, 1) } } @@ -70,7 +70,7 @@ func (s *stats) printStats() { t.AppendRow(table.Row{"File", filepath.Base(s.kcapFile)}) t.AppendSeparator() - t.AppendRow(table.Row{"Events written", atomic.LoadUint64(&s.kevtsWritten)}) + t.AppendRow(table.Row{"Events written", atomic.LoadUint64(&s.evtsWritten)}) t.AppendRow(table.Row{"Bytes written", atomic.LoadUint64(&s.bytesWritten)}) t.AppendRow(table.Row{"Processes written", atomic.LoadUint64(&s.procsWritten)}) t.AppendRow(table.Row{"Handles written", atomic.LoadUint64(&s.handlesWritten)}) @@ -101,17 +101,17 @@ type writer struct { released atomic.Bool } -// NewWriter constructs a new instance of the kcap writer. +// NewWriter constructs a new instance of the cap writer. func NewWriter(filename string, psnap ps.Snapshotter, hsnap handle.Snapshotter) (Writer, error) { if filepath.Ext(filename) == "" { - filename += ".kcap" + filename += ".cap" } f, err := os.Create(filename) if err != nil { return nil, err } zw := zstd.NewWriter(f) - // start by writing the kcap header that is composed + // start by writing the cap header that is composed // of magic number, major/minor digits and the optional // flags bit vector. The flags bit vector is reserved // for the future uses. @@ -157,7 +157,7 @@ func NewWriter(filename string, psnap ps.Snapshotter, hsnap handle.Snapshotter) func (w *writer) writeSnapshots() error { handles := w.hsnap.GetSnapshot() // write handle section and the data blocks - err := w.ws(section.Handle, kcapver.HandleSecV1, uint32(len(handles)), 0) + err := w.ws(section.Handle, capver.HandleSecV1, uint32(len(handles)), 0) if err != nil { return err } @@ -183,13 +183,13 @@ func (w *writer) writeSnapshots() error { return w.zw.Flush() } -func (w *writer) Write(kevtsc <-chan *kevent.Kevent, errs <-chan error) chan error { +func (w *writer) Write(evtsc <-chan *event.Event, errs <-chan error) chan error { errsc := make(chan error, 100) go func() { for { select { - case kevt := <-kevtsc: - b := kevt.MarshalRaw() + case evt := <-evtsc: + b := evt.MarshalRaw() l := len(b) if l == 0 { continue @@ -201,12 +201,12 @@ func (w *writer) Write(kevtsc <-chan *kevent.Kevent, errs <-chan error) chan err continue } // update stats - w.stats.incKevts(kevt) + w.stats.incKevts(evt) w.stats.incBytes(uint64(l)) - w.stats.incProcs(kevt) + w.stats.incProcs(evt) case err := <-errs: errsc <- err - kstreamConsumerErrors.Add(1) + eventSourceErrors.Add(1) case <-w.stop: return } @@ -223,12 +223,12 @@ func (w *writer) write(b []byte) error { overflowKevents.Add(1) return fmt.Errorf("event size overflow by %d bytes", l-maxKevtSize) } - if err := w.ws(section.Kevt, kcapver.KevtSecV2, 0, uint32(l)); err != nil { - kevtWriteErrors.Add(1) + if err := w.ws(section.Event, capver.EvtSecV2, 0, uint32(l)); err != nil { + evtWriteErrors.Add(1) return err } if _, err := w.zw.Write(b); err != nil { - kevtWriteErrors.Add(1) + evtWriteErrors.Add(1) return err } return nil diff --git a/pkg/kcap/writer_windows_test.go b/pkg/cap/writer_windows_test.go similarity index 83% rename from pkg/kcap/writer_windows_test.go rename to pkg/cap/writer_windows_test.go index 582569ebb..6a8d16618 100644 --- a/pkg/kcap/writer_windows_test.go +++ b/pkg/cap/writer_windows_test.go @@ -1,5 +1,5 @@ -//go:build kcap -// +build kcap +//go:build cap +// +build cap /* * Copyright 2019-2020 by Nedim Sabic Sabic @@ -19,16 +19,15 @@ * limitations under the License. */ -package kcap +package cap import ( "github.com/rabbitstack/fibratus/internal/etw" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" log "github.com/sirupsen/logrus" @@ -58,32 +57,32 @@ func TestWrite(t *testing.T) { hsnap.On("GetSnapshot").Return(handles) - w, err := NewWriter("_fixtures/cap.kcap", psnap, hsnap) + w, err := NewWriter("_fixtures/cap.cap", psnap, hsnap) require.NoError(t, err) require.NotNil(t, w) - kevtsc := make(chan *kevent.Kevent, 100) + evtsc := make(chan *event.Event, 100) errs := make(chan error, 10) for i := 0; i < 100; i++ { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: uint8(i / 2), Seq: uint64(i + 1), Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -143,12 +142,12 @@ func TestWrite(t *testing.T) { }, } if i%2 == 0 { - kevt.PS.Handles = append(kevt.PS.Handles, htypes.Handle{}) + evt.PS.Handles = append(evt.PS.Handles, htypes.Handle{}) } - kevtsc <- kevt + evtsc <- evt } - werrs := w.Write(kevtsc, errs) + werrs := w.Write(evtsc, errs) quit := make(chan struct{}, 1) time.AfterFunc(time.Second*5, func() { quit <- struct{}{} @@ -158,12 +157,12 @@ func TestWrite(t *testing.T) { t.Fatal(err) case <-quit: w.Close() - require.True(t, w.(*writer).stats.kevtsWritten > 0) + require.True(t, w.(*writer).stats.evtsWritten > 0) return } } -func TestLiveKcap(t *testing.T) { +func TestLiveCapture(t *testing.T) { t.SkipNow() cfg := &config.Config{ Kstream: config.KstreamConfig{ @@ -174,7 +173,7 @@ func TestLiveKcap(t *testing.T) { EnableThreadKevents: true, EnableHandleKevents: true, }, - KcapFile: "../../test.kcap", + KcapFile: "../../test.cap", Filters: &config.Filters{}, InitHandleSnapshot: true, } @@ -193,7 +192,7 @@ func TestLiveKcap(t *testing.T) { t.Fatal(err) } - // bootstrap kcap writer with inbound event channel + // bootstrap cap writer with inbound event channel writer, err := NewWriter(cfg.KcapFile, psnap, hsnap) if err != nil { t.Fatal(err) diff --git a/pkg/config/_fixtures/fibratus.json b/pkg/config/_fixtures/fibratus.json index 56bd02b44..cba8b29de 100644 --- a/pkg/config/_fixtures/fibratus.json +++ b/pkg/config/_fixtures/fibratus.json @@ -30,7 +30,7 @@ "init-snapshot": true }, - "kevent": { + "Event": { }, diff --git a/pkg/config/_fixtures/fibratus.yml b/pkg/config/_fixtures/fibratus.yml index b5dafd9dd..9c8c9b9ac 100644 --- a/pkg/config/_fixtures/fibratus.yml +++ b/pkg/config/_fixtures/fibratus.yml @@ -119,9 +119,9 @@ handle: kcap: file: "" -# =============================== Kevent =============================================== +# =============================== Event =============================================== -kevent: +Event: serialize-threads: false serialize-images: false serialize-handles: false @@ -197,11 +197,11 @@ pe: transformers: remove: enabled: true - kparams: + params: - disposition rename: enabled: true - kparams: + params: - old: "a" new: "b" - old: "c" @@ -209,7 +209,7 @@ transformers: replace: enabled: false replacements: - - kparam: key_name + - Param: key_name old: HKEY_CURRENT_USER new: HCU tags: @@ -220,10 +220,10 @@ transformers: trim: enabled: false prefixes: - - kparam: key_name + - Param: key_name trim: CurrentControlSet suffixes: - - kparam: file_name + - Param: file_name trim: .exe # =============================== YARA ================================================= diff --git a/pkg/config/_fixtures/filters/default-with-template.yml b/pkg/config/_fixtures/filters/default-with-template.yml index 04b6b474f..96daef67a 100644 --- a/pkg/config/_fixtures/filters/default-with-template.yml +++ b/pkg/config/_fixtures/filters/default-with-template.yml @@ -3,7 +3,7 @@ id: d6385b50-532a-4464-929a-044f21443dd3 version: 1.0.0 enabled: true description: this rule matches all network signals -condition: kevt.category = 'net' +condition: evt.category = 'net' severity: low output: > {{ upper "all network events" }} diff --git a/pkg/config/_fixtures/filters/default.yml b/pkg/config/_fixtures/filters/default.yml index 6232f1bc2..58c988c68 100644 --- a/pkg/config/_fixtures/filters/default.yml +++ b/pkg/config/_fixtures/filters/default.yml @@ -3,7 +3,7 @@ id: 313933e7-8eb9-45d9-81af-0305fee70e29 version: 1.0.0 enabled: true description: this rule matches all network signals -condition: kevt.category = 'net' +condition: evt.category = 'net' severity: low output: > `%ps.exe` attempted to reach out to `%net.sip` IP address diff --git a/pkg/config/_fixtures/filters/default1.yml b/pkg/config/_fixtures/filters/default1.yml index c24d5a7a7..3a9645a24 100644 --- a/pkg/config/_fixtures/filters/default1.yml +++ b/pkg/config/_fixtures/filters/default1.yml @@ -1,5 +1,5 @@ name: suspicious network {{ upper "activity" }} id: 1a06b6e0-a3f4-44a0-a1f0-89028273761b version: 1.1.0 -condition: kevt.category = 'net' and ps.name in ('at.exe', 'java.exe') +condition: evt.category = 'net' and ps.name in ('at.exe', 'java.exe') min-engine-version: 2.0.0 diff --git a/pkg/config/_fixtures/transformers.yml b/pkg/config/_fixtures/transformers.yml index 9785d071e..37a39665b 100644 --- a/pkg/config/_fixtures/transformers.yml +++ b/pkg/config/_fixtures/transformers.yml @@ -19,11 +19,11 @@ transformers.tags: transformers.remove: enabled: true - kparams: + params: - key_handle transformers.rename: enabled: true - kparams: + params: - old: key_handle new: KeyHandle \ No newline at end of file diff --git a/pkg/config/config_windows.go b/pkg/config/config_windows.go index 2829bb2c8..0921bdcc6 100644 --- a/pkg/config/config_windows.go +++ b/pkg/config/config_windows.go @@ -33,7 +33,7 @@ import ( removet "github.com/rabbitstack/fibratus/pkg/aggregator/transformers/remove" replacet "github.com/rabbitstack/fibratus/pkg/aggregator/transformers/replace" tagst "github.com/rabbitstack/fibratus/pkg/aggregator/transformers/tags" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs/amqp" "github.com/rabbitstack/fibratus/pkg/outputs/elasticsearch" "github.com/rabbitstack/fibratus/pkg/util/log" @@ -62,7 +62,7 @@ import ( ) const ( - kcapFile = "kcap.file" + kcapFile = "cap.file" configFile = "config-file" debugPrivilege = "debug-privilege" initHandleSnapshot = "handle.init-snapshot" @@ -71,11 +71,11 @@ const ( symbolizeKernelAddresses = "symbolize-kernel-addresses" forwardMode = "forward" - serializeThreads = "kevent.serialize-threads" - serializeImages = "kevent.serialize-images" - serializeHandles = "kevent.serialize-handles" - serializePE = "kevent.serialize-pe" - serializeEnvs = "kevent.serialize-envs" + serializeThreads = "event.serialize-threads" + serializeImages = "event.serialize-images" + serializeHandles = "event.serialize-handles" + serializePE = "event.serialize-pe" + serializeEnvs = "event.serialize-envs" ) // Config stores configuration options for fine-tuning the behaviour of Fibratus. @@ -286,11 +286,11 @@ func (c *Config) Init() error { c.ForwardMode = c.viper.GetBool(forwardMode) c.KcapFile = c.viper.GetString(kcapFile) - kevent.SerializeThreads = c.viper.GetBool(serializeThreads) - kevent.SerializeImages = c.viper.GetBool(serializeImages) - kevent.SerializeHandles = c.viper.GetBool(serializeHandles) - kevent.SerializePE = c.viper.GetBool(serializePE) - kevent.SerializeEnvs = c.viper.GetBool(serializeEnvs) + event.SerializeThreads = c.viper.GetBool(serializeThreads) + event.SerializeImages = c.viper.GetBool(serializeImages) + event.SerializeHandles = c.viper.GetBool(serializeHandles) + event.SerializePE = c.viper.GetBool(serializePE) + event.SerializeEnvs = c.viper.GetBool(serializeEnvs) if c.opts.run || c.opts.replay { if err := c.tryLoadOutput(); err != nil { @@ -383,10 +383,10 @@ func (c *Config) addFlags() { c.flags.Bool(matchAll, true, "Indicates if the match all strategy is enabled for the rule engine. If the match all strategy is enabled, a single event can trigger multiple rules") } if c.opts.capture { - c.flags.StringP(kcapFile, "o", "", "The path of the output kcap file") + c.flags.StringP(kcapFile, "o", "", "The path of the output cap file") } if c.opts.replay { - c.flags.StringP(kcapFile, "k", "", "The path of the input kcap file") + c.flags.StringP(kcapFile, "k", "", "The path of the input cap file") } if c.opts.run || c.opts.replay || c.opts.list || c.opts.validate { c.flags.String(filamentPath, filepath.Join(os.Getenv("PROGRAMFILES"), "fibratus", "filaments"), "Denotes the directory where filaments are located") diff --git a/pkg/config/config_windows_test.go b/pkg/config/config_windows_test.go index 1ef4a108c..8510c7b01 100644 --- a/pkg/config/config_windows_test.go +++ b/pkg/config/config_windows_test.go @@ -89,8 +89,8 @@ func TestNewFromYamlFile(t *testing.T) { switch tr.Type { case transformers.Rename: rconfig := tr.Transformer.(rename.Config) - assert.Len(t, rconfig.Kparams, 2) - r1 := rconfig.Kparams[0] + assert.Len(t, rconfig.Params, 2) + r1 := rconfig.Params[0] assert.Equal(t, "b", r1.New) } } diff --git a/pkg/config/filters.go b/pkg/config/filters.go index 5c9cac2d6..c89fd0a11 100644 --- a/pkg/config/filters.go +++ b/pkg/config/filters.go @@ -22,8 +22,7 @@ import ( "bytes" "fmt" "github.com/Masterminds/sprig/v3" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/util/convert" "github.com/rabbitstack/fibratus/pkg/util/multierror" log "github.com/sirupsen/logrus" @@ -161,7 +160,7 @@ type ActionContext struct { // Events contains a single element simple rules // or a list of ordered matched events for sequence // policies - Events []*kevent.Kevent + Events []*event.Event // Filter represents the filter that matched the event Filter *FilterConfig } @@ -173,7 +172,7 @@ func (ctx *ActionContext) UniquePids() []uint32 { pids := make(map[uint32]struct{}) for _, e := range ctx.Events { if e.IsCreateProcess() { - pids[e.Kparams.MustGetPid()] = struct{}{} + pids[e.Params.MustGetPid()] = struct{}{} } else { pids[e.PID] = struct{}{} } @@ -199,13 +198,13 @@ type RulesCompileResult struct { HasDNSEvents bool HasAuditAPIEvents bool HasThreadpoolEvents bool - UsedEvents []ktypes.Ktype + UsedEvents []event.Type NumberRules int } -func (r RulesCompileResult) ContainsEvent(ktype ktypes.Ktype) bool { +func (r RulesCompileResult) ContainsEvent(Type event.Type) bool { for _, ktyp := range r.UsedEvents { - if ktyp == ktype { + if ktyp == Type { return true } } diff --git a/pkg/config/filters_test.go b/pkg/config/filters_test.go index 30a5cf2e2..0e036b71e 100644 --- a/pkg/config/filters_test.go +++ b/pkg/config/filters_test.go @@ -51,7 +51,7 @@ func TestLoadRulesFromPaths(t *testing.T) { assert.Equal(t, "1.0.0", f1.Version) assert.True(t, *f1.Enabled) assert.Contains(t, f1.Tags, "TE") - assert.Equal(t, "kevt.category = 'net'", f1.Condition) + assert.Equal(t, "evt.category = 'net'", f1.Condition) assert.Equal(t, "this rule matches all network signals", f1.Description) assert.Equal(t, "low", f1.Severity) assert.Equal(t, "`%ps.exe` attempted to reach out to `%net.sip` IP address\n", f1.Output) @@ -73,7 +73,7 @@ func TestLoadRulesFromPaths(t *testing.T) { f2 := filters.filters[1] assert.False(t, f2.IsDisabled()) assert.Equal(t, "suspicious network ACTIVITY", f2.Name) - assert.Equal(t, "kevt.category = 'net' and ps.name in ('at.exe', 'java.exe')", f2.Condition) + assert.Equal(t, "evt.category = 'net' and ps.name in ('at.exe', 'java.exe')", f2.Condition) } func TestLoadRulesFromPathsWithTemplate(t *testing.T) { @@ -135,7 +135,7 @@ func TestLoadGroupsFromURLs(t *testing.T) { assert.Equal(t, "only network category", f1.Name) assert.True(t, *f1.Enabled) assert.Contains(t, f1.Tags, "TE") - assert.Equal(t, "kevt.category = 'net'", f1.Condition) + assert.Equal(t, "evt.category = 'net'", f1.Condition) assert.Equal(t, "this rule matches all network signals", f1.Description) assert.Equal(t, "low", f1.Severity) assert.Equal(t, "`%ps.exe` attempted to reach out to `%net.sip` IP address\n", f1.Output) diff --git a/pkg/config/kstream.go b/pkg/config/kstream.go index f9fd33019..e0b09a78f 100644 --- a/pkg/config/kstream.go +++ b/pkg/config/kstream.go @@ -22,11 +22,11 @@ package config import ( + "github.com/rabbitstack/fibratus/pkg/event" "golang.org/x/sys/windows" "runtime" "time" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/spf13/viper" ) @@ -63,17 +63,17 @@ var ( // KstreamConfig stores different configuration options for fine-tuning kstream consumer/controller settings. type KstreamConfig struct { - // EnableThreadKevents indicates if thread kernel events are collected by the ETW provider. + // EnableThreadKevents indicates if thread events are collected by the ETW provider. EnableThreadKevents bool `json:"enable-thread" yaml:"enable-thread"` - // EnableRegistryKevents indicates if registry kernel events are collected by the ETW provider. + // EnableRegistryKevents indicates if registry events are collected by the ETW provider. EnableRegistryKevents bool `json:"enable-registry" yaml:"enable-registry"` // EnableNetKevents determines whether network (TCP/UDP) events are collected by the ETW provider. EnableNetKevents bool `json:"enable-net" yaml:"enable-net"` - // EnableFileIOKevents indicates if file I/O kernel events are collected by the ETW provider. + // EnableFileIOKevents indicates if file I/O events are collected by the ETW provider. EnableFileIOKevents bool `json:"enable-fileio" yaml:"enable-fileio"` // EnableVAMapKevents indicates if VA map/unmap events are collected by the ETW provider. EnableVAMapKevents bool `json:"enable-vamap" yaml:"enable-vamap"` - // EnableImageKevents indicates if image kernel events are collected by the ETW provider. + // EnableImageKevents indicates if image events are collected by the ETW provider. EnableImageKevents bool `json:"enable-image" yaml:"enable-image"` // EnableHandleKevents indicates whether handle creation/disposal events are enabled. EnableHandleKevents bool `json:"enable-handle" yaml:"enable-handle"` @@ -102,7 +102,7 @@ type KstreamConfig struct { // ExcludedImages are process image names that will be rejected if they generate a kernel event. ExcludedImages []string `json:"blacklist.images" yaml:"blacklist.images"` - dropMasks ktypes.EventsetMasks + dropMasks event.EventsetMasks excludedImages map[string]bool } @@ -130,8 +130,8 @@ func (c *KstreamConfig) initFromViper(v *viper.Viper) { c.excludedImages = make(map[string]bool) for _, name := range c.ExcludedKevents { - if ktype := ktypes.KeventNameToKtype(name); ktype != ktypes.UnknownKtype { - c.dropMasks.Set(ktype) + if typ := event.NameToType(name); typ != event.UnknownType { + c.dropMasks.Set(typ) } } for _, name := range c.ExcludedImages { @@ -143,9 +143,9 @@ func (c *KstreamConfig) initFromViper(v *viper.Viper) { func (c *KstreamConfig) Init() { c.excludedImages = make(map[string]bool) for _, name := range c.ExcludedKevents { - for _, ktype := range ktypes.KeventNameToKtypes(name) { - if ktype != ktypes.UnknownKtype { - c.dropMasks.Set(ktype) + for _, typ := range event.NameToTypes(name) { + if typ != event.UnknownType { + c.dropMasks.Set(typ) } } } @@ -157,14 +157,14 @@ func (c *KstreamConfig) Init() { // SetDropMask inserts the event mask in the bitset to // instruct the given event type should be dropped from // the event stream. -func (c *KstreamConfig) SetDropMask(ktype ktypes.Ktype) { - c.dropMasks.Set(ktype) +func (c *KstreamConfig) SetDropMask(Type event.Type) { + c.dropMasks.Set(Type) } // TestDropMask checks if the specified event type has // the drop mask in the bitset. -func (c *KstreamConfig) TestDropMask(ktype ktypes.Ktype) bool { - return c.dropMasks.Test(ktype.GUID(), ktype.HookID()) +func (c *KstreamConfig) TestDropMask(Type event.Type) bool { + return c.dropMasks.Test(Type.GUID(), Type.HookID()) } // ExcludeKevent determines whether the supplied provider GUID diff --git a/pkg/config/kstream_test.go b/pkg/config/kstream_test.go index 56b633fae..7a3d6f258 100644 --- a/pkg/config/kstream_test.go +++ b/pkg/config/kstream_test.go @@ -22,12 +22,11 @@ package config import ( + "github.com/rabbitstack/fibratus/pkg/event" "testing" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" - "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -56,8 +55,8 @@ func TestKstreamConfig(t *testing.T) { assert.False(t, c.Kstream.EnableImageKevents) assert.False(t, c.Kstream.EnableFileIOKevents) - assert.True(t, c.Kstream.ExcludeKevent(ktypes.CloseHandle.GUID(), ktypes.CloseHandle.HookID())) - assert.False(t, c.Kstream.ExcludeKevent(ktypes.CreateProcess.GUID(), ktypes.CreateProcess.HookID())) + assert.True(t, c.Kstream.ExcludeKevent(event.CloseHandle.GUID(), event.CloseHandle.HookID())) + assert.False(t, c.Kstream.ExcludeKevent(event.CreateProcess.GUID(), event.CreateProcess.HookID())) assert.True(t, c.Kstream.ExcludeImage(&pstypes.PS{Name: "svchost.exe"})) assert.False(t, c.Kstream.ExcludeImage(&pstypes.PS{Name: "explorer.exe"})) diff --git a/pkg/config/schema_windows.go b/pkg/config/schema_windows.go index 1a1bb214c..631e76665 100644 --- a/pkg/config/schema_windows.go +++ b/pkg/config/schema_windows.go @@ -127,7 +127,7 @@ var schema = ` }, "additionalProperties": false }, - "kcap": { + "cap": { "type": "object", "properties": { "file": {"type": "string"} @@ -166,7 +166,7 @@ var schema = ` }, "additionalProperties": false }, - "kevent": { + "event": { "type": "object", "properties": { "serialize-threads": {"type": "boolean"}, @@ -339,13 +339,13 @@ var schema = ` "type": "object", "properties": { "enabled": {"type": "boolean"}, - "kparams": {"type": "array", "items": [{"type": "string"}]} + "params": {"type": "array", "items": [{"type": "string"}]} }, "if": { "properties": {"enabled": { "const": true }} }, "then": { - "properties": {"kparams": {"type": "array", "minItems": 1, "items": [{"type": "string"}]}} + "properties": {"params": {"type": "array", "minItems": 1, "items": [{"type": "string"}]}} }, "additionalProperties": false }, @@ -353,7 +353,7 @@ var schema = ` "type": "object", "properties": { "enabled": {"type": "boolean"}, - "kparams": {"type": "array", "items": [ + "params": {"type": "array", "items": [ { "type": "object", "properties": { @@ -368,7 +368,7 @@ var schema = ` "properties": {"enabled": { "const": true }} }, "then": { - "properties": {"kparams": {"minItems": 1}} + "properties": {"params": {"minItems": 1}} }, "additionalProperties": false }, @@ -380,7 +380,7 @@ var schema = ` { "type": "object", "properties": { - "kparam": {"type": "string", "minLength": 1}, + "Param": {"type": "string", "minLength": 1}, "old": {"type": "string", "minLength": 1}, "new": {"type": "string"} }, @@ -427,7 +427,7 @@ var schema = ` { "type": "object", "properties": { - "kparam": {"type": "string", "minLength": 1}, + "Param": {"type": "string", "minLength": 1}, "trim": {"type": "string", "minLength": 1} }, "additionalProperties": false @@ -437,7 +437,7 @@ var schema = ` { "type": "object", "properties": { - "kparam": {"type": "string", "minLength": 1}, + "Param": {"type": "string", "minLength": 1}, "trim": {"type": "string", "minLength": 1} }, "additionalProperties": false diff --git a/pkg/errors/errors.go b/pkg/errors/errors.go index 83a210480..812c79c55 100644 --- a/pkg/errors/errors.go +++ b/pkg/errors/errors.go @@ -34,20 +34,20 @@ var ( } ) -// ErrKparamNotFound is the error is thrown when a parameter is not present in the list of parameters -type ErrKparamNotFound struct { +// ErrParamNotFound is the error is thrown when a parameter is not present in the list of parameters +type ErrParamNotFound struct { Name string } // Error returns the error message. -func (e ErrKparamNotFound) Error() string { +func (e ErrParamNotFound) Error() string { return "couldn't find '" + e.Name + "' in event parameters" } -// IsKparamNotFound returns true if the error is KparamNotFound. -func IsKparamNotFound(err error) bool { +// IsParamNotFound returns true if the error is ErrParamNotFound. +func IsParamNotFound(err error) bool { switch err.(type) { - case *ErrKparamNotFound: + case *ErrParamNotFound: return true default: return false diff --git a/pkg/errors/errors_windows.go b/pkg/errors/errors_windows.go index 9ce976d3b..ba5cd0fac 100644 --- a/pkg/errors/errors_windows.go +++ b/pkg/errors/errors_windows.go @@ -23,7 +23,7 @@ import ( ) var ( - // ErrTraceAccessDenied is returned when user doesn't have enough privileges to start kernel trace + // ErrTraceAccessDenied is returned when user doesn't have enough privileges to start the trace ErrTraceAccessDenied = errors.New("not enough privileges to start the trace. Only users with administrative privileges or users in the Performance Log Users group can start kernel traces") // ErrTraceInvalidParameter signals invalid values for trace session ErrTraceInvalidParameter = errors.New("trace has invalid values") @@ -35,14 +35,14 @@ var ( ErrTraceDiskFull = errors.New("not enough disk space for writing to log file") // ErrInvalidTrace signals invalid trace handle ErrInvalidTrace = errors.New("invalid trace handle") - // ErrRestartTrace signals an error that is thrown when currently running kernel trace cannot be restarted + // ErrRestartTrace signals an error that is thrown when currently running trace cannot be restarted ErrRestartTrace = errors.New("couldn't restart an already running trace") - // ErrTraceAlreadyRunning identifies kernel trace already running errors + // ErrTraceAlreadyRunning identifies trace already running errors ErrTraceAlreadyRunning = errors.New("trace is already running") // ErrEventCallbackException signals that an exception has occurred in the event processing function ErrEventCallbackException = errors.New("an exception occurred in the event callback function") - // ErrKsessionNotRunning is thrown when kernel session from which consumer is trying to collect events is not running - ErrKsessionNotRunning = errors.New("session from which you are trying to consume events in real time is not running") - // ErrTraceCancelled is thrown when in-progress kernel event trace is cancelled + // ErrSessionNotRunning is thrown when session from which consumer is trying to collect events is not running + ErrSessionNotRunning = errors.New("session from which you are trying to consume events in real time is not running") + // ErrTraceCancelled is thrown when in-progress event trace is cancelled ErrTraceCancelled = errors.New("event trace has been cancelled") ) diff --git a/pkg/kevent/_fixtures/handles.json b/pkg/event/_fixtures/handles.json similarity index 100% rename from pkg/kevent/_fixtures/handles.json rename to pkg/event/_fixtures/handles.json diff --git a/pkg/kevent/batch.go b/pkg/event/batch.go similarity index 86% rename from pkg/kevent/batch.go rename to pkg/event/batch.go index fbd86d470..facd8a0d9 100644 --- a/pkg/kevent/batch.go +++ b/pkg/event/batch.go @@ -16,15 +16,15 @@ * limitations under the License. */ -package kevent +package event -// Batch contains a sequence of kernel events. +// Batch contains a group of events. type Batch struct { - Events []*Kevent + Events []*Event } // NewBatch produces a new batch from the group of events. -func NewBatch(evts ...*Kevent) *Batch { +func NewBatch(evts ...*Event) *Batch { return &Batch{Events: evts} } @@ -35,12 +35,12 @@ func (b *Batch) Len() int64 { return int64(len(b.Events)) } func (b *Batch) MarshalJSON() []byte { buf := make([]byte, 0) buf = append(buf, '[') - for i, kevt := range b.Events { + for i, evt := range b.Events { writeMore := true if i == len(b.Events)-1 { writeMore = false } - buf = append(buf, kevt.MarshalJSON()...) + buf = append(buf, evt.MarshalJSON()...) buf = append(buf, '\n') if writeMore { buf = append(buf, ',') diff --git a/pkg/kevent/batch_test.go b/pkg/event/batch_test.go similarity index 78% rename from pkg/kevent/batch_test.go rename to pkg/event/batch_test.go index 41960b6e4..e53039d1b 100644 --- a/pkg/kevent/batch_test.go +++ b/pkg/event/batch_test.go @@ -16,14 +16,13 @@ * limitations under the License. */ -package kevent +package event import ( "encoding/json" "github.com/magiconair/properties/assert" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" "github.com/stretchr/testify/require" @@ -33,24 +32,24 @@ import ( ) func TestBatchMarshalJSON(t *testing.T) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -101,24 +100,24 @@ func TestBatchMarshalJSON(t *testing.T) { }, } - kevt1 := &Kevent{ - Type: ktypes.CreateFile, + evt1 := &Event{ + Type: CreateFile, Tid: 2484, PID: 459, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -169,24 +168,24 @@ func TestBatchMarshalJSON(t *testing.T) { }, } - kevt2 := &Kevent{ - Type: ktypes.CreateFile, + evt2 := &Event{ + Type: CreateFile, Tid: 2484, PID: 829, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -237,17 +236,17 @@ func TestBatchMarshalJSON(t *testing.T) { }, } - b := NewBatch(kevt, kevt1, kevt2) + b := NewBatch(evt, evt1, evt2) require.Equal(t, int64(3), b.Len()) buf := b.MarshalJSON() - var kevts []*Kevent + var evts []*Event - err := json.Unmarshal(buf, &kevts) + err := json.Unmarshal(buf, &evts) require.NoError(t, err) - require.Len(t, kevts, 3) + require.Len(t, evts, 3) - assert.Equal(t, uint32(859), kevts[0].PID) - assert.Equal(t, uint32(459), kevts[1].PID) - assert.Equal(t, uint32(829), kevts[2].PID) + assert.Equal(t, uint32(859), evts[0].PID) + assert.Equal(t, uint32(459), evts[1].PID) + assert.Equal(t, uint32(829), evts[2].PID) } diff --git a/pkg/kevent/ktypes/category.go b/pkg/event/category.go similarity index 96% rename from pkg/kevent/ktypes/category.go rename to pkg/event/category.go index 08f0c5d52..d9d45e966 100644 --- a/pkg/kevent/ktypes/category.go +++ b/pkg/event/category.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package ktypes +package event import ( "github.com/rabbitstack/fibratus/pkg/util/hashers" @@ -29,7 +29,7 @@ type Category string type Subcategory string const ( - // Registry is the category for registry related kernel events + // Registry is the category for registry related events Registry Category = "registry" // File is the category for file system events File Category = "file" diff --git a/pkg/kevent/doc.go b/pkg/event/doc.go similarity index 81% rename from pkg/kevent/doc.go rename to pkg/event/doc.go index 8b601e5c4..655006b76 100644 --- a/pkg/kevent/doc.go +++ b/pkg/event/doc.go @@ -16,6 +16,6 @@ * limitations under the License. */ -// Package kevent defines the fundamental data structures that underpin the state of every kernel event pushed from the -// consumer. -package kevent +// Package event defines the fundamental data structures that underpin the state of the event pushed from the +// event source. +package event diff --git a/pkg/kevent/enum.go b/pkg/event/enum.go similarity index 99% rename from pkg/kevent/enum.go rename to pkg/event/enum.go index a256cded5..6d2f71c52 100644 --- a/pkg/kevent/enum.go +++ b/pkg/event/enum.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "github.com/rabbitstack/fibratus/pkg/util/va" diff --git a/pkg/kevent/kevent.go b/pkg/event/event.go similarity index 79% rename from pkg/kevent/kevent.go rename to pkg/event/event.go index 6b358788b..0383f0c76 100644 --- a/pkg/kevent/kevent.go +++ b/pkg/event/event.go @@ -16,14 +16,13 @@ * limitations under the License. */ -package kevent +package event import ( "fmt" "github.com/rabbitstack/fibratus/pkg/callstack" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" + "github.com/rabbitstack/fibratus/pkg/event/params" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "strings" "sync" @@ -62,32 +61,32 @@ func (md Metadata) String() string { return strings.TrimSuffix(sb.String(), ", ") } -// Kevent encapsulates event's state and provides a set of methods for +// Event encapsulates event's state and provides a set of methods for // accessing and manipulating event parameters, process state, and other // metadata. -type Kevent struct { +type Event struct { // Seq is monotonically incremented kernel event sequence. Seq uint64 `json:"seq"` // PID is the identifier of the process that generated the event. PID uint32 `json:"pid"` // Tid is the thread identifier of the thread that generated the event. Tid uint32 `json:"tid"` - // Type is the internal representation of the kernel event. This field should be ignored by serializers. - Type ktypes.Ktype `json:"-"` + // Type is the internal representation of the event. This field should be ignored by serializers. + Type Type `json:"-"` // CPU designates the processor logical core where the event was originated. CPU uint8 `json:"cpu"` // Name is the human friendly name of the kernel event. Name string `json:"name"` // Category designates the category to which this event pertains. - Category ktypes.Category `json:"category"` + Category Category `json:"category"` // Description is the short explanation that describes the purpose of the event. Description string `json:"description"` // Host is the machine name that reported the generated event. Host string `json:"host"` // Timestamp represents the temporal occurrence of the event. Timestamp time.Time `json:"timestamp"` - // Kparams stores the collection of kernel event parameters. - Kparams Kparams `json:"params"` + // Params stores the collection of event parameters. + Params Params `json:"-"` // Metadata represents any tags that are meaningful to this event. Metadata Metadata `json:"metadata"` // mmux guards the metadata map @@ -104,7 +103,7 @@ type Kevent struct { } // String returns event's string representation. -func (e *Kevent) String() string { +func (e *Event) String() string { e.mmux.RLock() defer e.mmux.RUnlock() if e.PS != nil { @@ -119,7 +118,7 @@ func (e *Kevent) String() string { Description: %s Host: %s Timestamp: %s - Kparams: %s + Params: %s Metadata: %s %s `, @@ -133,7 +132,7 @@ func (e *Kevent) String() string { e.Description, e.Host, e.Timestamp, - e.Kparams, + e.Params, e.Metadata, e.PS, ) @@ -149,7 +148,7 @@ func (e *Kevent) String() string { Description: %s Host: %s Timestamp: %s - Kparams: %s + Params: %s Metadata: %s `, e.Seq, @@ -162,14 +161,14 @@ func (e *Kevent) String() string { e.Description, e.Host, e.Timestamp, - e.Kparams, + e.Params, e.Metadata, ) } // StringShort returns event's string representation // by removing some irrelevant event/process fields. -func (e *Kevent) StringShort() string { +func (e *Event) StringShort() string { e.mmux.RLock() defer e.mmux.RUnlock() if e.PS != nil { @@ -191,7 +190,7 @@ func (e *Kevent) StringShort() string { e.Category, e.Host, e.Timestamp, - e.Kparams, + e.Params, e.PS.StringShort(), ) } @@ -212,23 +211,23 @@ func (e *Kevent) StringShort() string { e.Category, e.Host, e.Timestamp, - e.Kparams, + e.Params, ) } // Empty return a pristine event instance. -func Empty() *Kevent { - return &Kevent{ - Kparams: map[string]*Kparam{}, +func Empty() *Event { + return &Event{ + Params: map[string]*Param{}, Metadata: make(map[MetadataKey]any), PS: &pstypes.PS{}, } } -// NewFromKcap recovers the event instance from the capture byte buffer. -func NewFromKcap(buf []byte, ver kcapver.Version) (*Kevent, error) { - e := &Kevent{ - Kparams: make(Kparams), +// NewFromCapture recovers the event instance from the capture byte buffer. +func NewFromCapture(buf []byte, ver capver.Version) (*Event, error) { + e := &Event{ + Params: make(Params), Metadata: make(map[MetadataKey]any), } if err := e.UnmarshalRaw(buf, ver); err != nil { @@ -238,21 +237,21 @@ func NewFromKcap(buf []byte, ver kcapver.Version) (*Kevent, error) { } // AddMeta appends a key/value pair to event's metadata. -func (e *Kevent) AddMeta(k MetadataKey, v any) { +func (e *Event) AddMeta(k MetadataKey, v any) { e.mmux.Lock() defer e.mmux.Unlock() e.Metadata[k] = v } // RemoveMeta removes the event metadata index by given key. -func (e *Kevent) RemoveMeta(k MetadataKey) { +func (e *Event) RemoveMeta(k MetadataKey) { e.mmux.Lock() defer e.mmux.Unlock() delete(e.Metadata, k) } // GetMetaAsString returns the metadata as a string value. -func (e *Kevent) GetMetaAsString(k MetadataKey) string { +func (e *Event) GetMetaAsString(k MetadataKey) string { e.mmux.RLock() defer e.mmux.RUnlock() if v, ok := e.Metadata[k]; ok { @@ -264,25 +263,25 @@ func (e *Kevent) GetMetaAsString(k MetadataKey) string { } // ContainsMeta returns true if the metadata contains the specified key. -func (e *Kevent) ContainsMeta(k MetadataKey) bool { +func (e *Event) ContainsMeta(k MetadataKey) bool { e.mmux.RLock() defer e.mmux.RUnlock() return e.Metadata[k] != nil } // AppendParam adds a new parameter to this event. -func (e *Kevent) AppendParam(name string, typ kparams.Type, value kparams.Value, opts ...ParamOption) { - e.Kparams.Append(name, typ, value, opts...) +func (e *Event) AppendParam(name string, typ params.Type, value params.Value, opts ...ParamOption) { + e.Params.Append(name, typ, value, opts...) } // AppendEnum adds the enum parameter to this event. -func (e *Kevent) AppendEnum(name string, value uint32, enum ParamEnum) { - e.AppendParam(name, kparams.Enum, value, WithEnum(enum)) +func (e *Event) AppendEnum(name string, value uint32, enum ParamEnum) { + e.AppendParam(name, params.Enum, value, WithEnum(enum)) } // AppendFlags adds the flags parameter to this event. -func (e *Kevent) AppendFlags(name string, value uint32, flags ParamFlags) { - e.AppendParam(name, kparams.Flags, value, WithFlags(flags)) +func (e *Event) AppendFlags(name string, value uint32, flags ParamFlags) { + e.AppendParam(name, params.Flags, value, WithFlags(flags)) } // GetParamAsString returns the specified parameter value as string. @@ -291,8 +290,8 @@ func (e *Kevent) AppendFlags(name string, value uint32, flags ParamFlags) { // to the error message. // Returns an empty string if the given parameter name is not found // in event parameters. -func (e *Kevent) GetParamAsString(name string) string { - par, err := e.Kparams.Get(name) +func (e *Event) GetParamAsString(name string) string { + par, err := e.Params.Get(name) if err != nil { return "" } @@ -300,12 +299,12 @@ func (e *Kevent) GetParamAsString(name string) string { } // GetFlagsAsSlice returns parameter flags as a slice of bitmask string values. -func (e *Kevent) GetFlagsAsSlice(name string) []string { +func (e *Event) GetFlagsAsSlice(name string) []string { return strings.Split(e.GetParamAsString(name), "|") } // SequenceLink returns the sequence link value from event metadata. -func (e *Kevent) SequenceLink() any { +func (e *Event) SequenceLink() any { e.mmux.RLock() defer e.mmux.RUnlock() return e.Metadata[RuleSequenceLink] diff --git a/pkg/kevent/kevent_windows.go b/pkg/event/event_windows.go similarity index 53% rename from pkg/kevent/kevent_windows.go rename to pkg/event/event_windows.go index 4c800520a..6269605ea 100644 --- a/pkg/kevent/kevent_windows.go +++ b/pkg/event/event_windows.go @@ -16,13 +16,12 @@ * limitations under the License. */ -package kevent +package event import ( "encoding/binary" "fmt" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/rabbitstack/fibratus/pkg/sys/etw" "github.com/rabbitstack/fibratus/pkg/util/filetime" @@ -48,23 +47,23 @@ var ( // New constructs a fresh event instance with basic fields and parameters // from the raw ETW event record. -func New(seq uint64, ktype ktypes.Ktype, evt *etw.EventRecord) *Kevent { +func New(seq uint64, typ Type, evt *etw.EventRecord) *Event { var ( pid = evt.Header.ProcessID tid = evt.Header.ThreadID cpu = *(*uint8)(unsafe.Pointer(&evt.BufferContext.ProcessorIndex[0])) ts = filetime.ToEpoch(evt.Header.Timestamp) ) - e := &Kevent{ + e := &Event{ Seq: seq, PID: pid, Tid: tid, CPU: cpu, - Type: ktype, - Category: ktype.Category(), - Name: ktype.String(), - Kparams: make(map[string]*Kparam), - Description: ktype.Description(), + Type: typ, + Category: typ.Category(), + Name: typ.String(), + Params: make(map[string]*Param), + Description: typ.Description(), Timestamp: ts, Metadata: make(map[MetadataKey]any), Host: hostname.Get(), @@ -74,24 +73,24 @@ func New(seq uint64, ktype ktypes.Ktype, evt *etw.EventRecord) *Kevent { return e } -func (e *Kevent) adjustPID() { +func (e *Event) adjustPID() { switch e.Category { - case ktypes.Image: + case Image: // sometimes the pid present in event header is invalid // but, we can get the valid one from the event parameters if e.InvalidPid() { - e.PID, _ = e.Kparams.GetPid() + e.PID, _ = e.Params.GetPid() } - case ktypes.File: + case File: if !e.IsMapViewFile() && !e.IsUnmapViewFile() { // take thread id from the event parameters - e.Tid, _ = e.Kparams.GetTid() + e.Tid, _ = e.Params.GetTid() } switch { - case e.InvalidPid() && e.Type == ktypes.MapFileRundown: + case e.InvalidPid() && e.Type == MapFileRundown: // a valid pid for map rundown events // is located in the event parameters - e.PID = e.Kparams.MustGetPid() + e.PID = e.Params.MustGetPid() case e.InvalidPid(): // on some Windows versions the value of // the PID is invalid in the event header @@ -105,26 +104,26 @@ func (e *Kevent) adjustPID() { }() e.PID = sys.GetProcessIdOfThread(thread) } - case ktypes.Process: + case Process: // process start events may be logged in the context of the parent or child process. // As a result, the ProcessId member of EVENT_TRACE_HEADER may not correspond to the // process being created, so we set the event pid to be the one of the parent process if e.IsCreateProcess() { - e.PID, _ = e.Kparams.GetPpid() + e.PID, _ = e.Params.GetPpid() } - case ktypes.Net: + case Net: if !e.IsDNS() { - e.PID, _ = e.Kparams.GetPid() + e.PID, _ = e.Params.GetPid() } - case ktypes.Handle: - if e.Type == ktypes.DuplicateHandle { - e.PID, _ = e.Kparams.GetUint32(kparams.TargetProcessID) - e.Kparams.Remove(kparams.TargetProcessID) + case Handle: + if e.Type == DuplicateHandle { + e.PID, _ = e.Params.GetUint32(params.TargetProcessID) + e.Params.Remove(params.TargetProcessID) } - case ktypes.Thread: - if e.Type == ktypes.StackWalk { - e.PID, _ = e.Kparams.GetPid() - e.Tid, _ = e.Kparams.GetTid() + case Thread: + if e.Type == StackWalk { + e.PID, _ = e.Params.GetPid() + e.Tid, _ = e.Params.GetTid() } } } @@ -136,7 +135,7 @@ func (e *Kevent) adjustPID() { // we're not storing them into the capture file, it can be dropped // 2. Rundowns events are dropped if they haven't been processed already // 3. If the event is generated by Fibratus process, we can safely ignore it -func (e *Kevent) IsDropped(capture bool) bool { +func (e *Event) IsDropped(capture bool) bool { if e.IsState() && !capture { return true } @@ -154,43 +153,43 @@ func IsCurrentProcDropped(pid uint32) bool { return DropCurrentProc && pid == cu // store and reference delayed events in the event // backlog state. The delayed event is indexed by // the sequence identifier. -func (e *Kevent) DelayKey() uint64 { +func (e *Event) DelayKey() uint64 { switch e.Type { - case ktypes.CreateHandle, ktypes.CloseHandle: - return e.Kparams.MustGetUint64(kparams.HandleObject) + case CreateHandle, CloseHandle: + return e.Params.MustGetUint64(params.HandleObject) } return 0 } // IsNetworkTCP determines whether the event pertains to network TCP events. -func (e *Kevent) IsNetworkTCP() bool { - return e.Category == ktypes.Net && !e.IsNetworkUDP() +func (e *Event) IsNetworkTCP() bool { + return e.Category == Net && !e.IsNetworkUDP() } // IsNetworkUDP determines whether the event pertains to network UDP events. -func (e *Kevent) IsNetworkUDP() bool { - return e.Type == ktypes.RecvUDPv4 || e.Type == ktypes.RecvUDPv6 || e.Type == ktypes.SendUDPv4 || e.Type == ktypes.SendUDPv6 +func (e *Event) IsNetworkUDP() bool { + return e.Type == RecvUDPv4 || e.Type == RecvUDPv6 || e.Type == SendUDPv4 || e.Type == SendUDPv6 } // IsDNS determines whether the event is a DNS question/answer. -func (e *Kevent) IsDNS() bool { - return e.Type.Subcategory() == ktypes.DNS +func (e *Event) IsDNS() bool { + return e.Type.Subcategory() == DNS } // IsRundown determines if this is a rundown events. -func (e *Kevent) IsRundown() bool { - return e.Type == ktypes.ProcessRundown || e.Type == ktypes.ThreadRundown || e.Type == ktypes.ImageRundown || - e.Type == ktypes.FileRundown || e.Type == ktypes.RegKCBRundown +func (e *Event) IsRundown() bool { + return e.Type == ProcessRundown || e.Type == ThreadRundown || e.Type == ImageRundown || + e.Type == FileRundown || e.Type == RegKCBRundown } // IsSuccess checks if the event contains the status parameter // and in such case, returns true if the operation completed // successfully, i.e. the system code is equal to ERROR_SUCCESS. -func (e *Kevent) IsSuccess() bool { - if !e.Kparams.Contains(kparams.NTStatus) { +func (e *Event) IsSuccess() bool { + if !e.Params.Contains(params.NTStatus) { return true } - return e.GetParamAsString(kparams.NTStatus) == ntstatus.Success + return e.GetParamAsString(params.NTStatus) == ntstatus.Success } // IsRundownProcessed checks if the rundown events was processed @@ -201,7 +200,7 @@ func (e *Kevent) IsSuccess() bool { // function which causes duplicate rundown events. // For more pointers check `kstream/controller_windows.go` // and the `etw.SetTraceInformation` API function. -func (e *Kevent) IsRundownProcessed() bool { +func (e *Event) IsRundownProcessed() bool { mu.Lock() defer mu.Unlock() key := e.RundownKey() @@ -213,96 +212,96 @@ func (e *Kevent) IsRundownProcessed() bool { return false } -func (e *Kevent) IsCreateFile() bool { return e.Type == ktypes.CreateFile } -func (e *Kevent) IsCreateProcess() bool { return e.Type == ktypes.CreateProcess } -func (e *Kevent) IsCreateThread() bool { return e.Type == ktypes.CreateThread } -func (e *Kevent) IsCloseFile() bool { return e.Type == ktypes.CloseFile } -func (e *Kevent) IsCreateHandle() bool { return e.Type == ktypes.CreateHandle } -func (e *Kevent) IsCloseHandle() bool { return e.Type == ktypes.CloseHandle } -func (e *Kevent) IsDeleteFile() bool { return e.Type == ktypes.DeleteFile } -func (e *Kevent) IsEnumDirectory() bool { return e.Type == ktypes.EnumDirectory } -func (e *Kevent) IsTerminateProcess() bool { return e.Type == ktypes.TerminateProcess } -func (e *Kevent) IsTerminateThread() bool { return e.Type == ktypes.TerminateThread } -func (e *Kevent) IsUnloadImage() bool { return e.Type == ktypes.UnloadImage } -func (e *Kevent) IsLoadImage() bool { return e.Type == ktypes.LoadImage } -func (e *Kevent) IsImageRundown() bool { return e.Type == ktypes.ImageRundown } -func (e *Kevent) IsFileOpEnd() bool { return e.Type == ktypes.FileOpEnd } -func (e *Kevent) IsRegSetValue() bool { return e.Type == ktypes.RegSetValue } -func (e *Kevent) IsProcessRundown() bool { return e.Type == ktypes.ProcessRundown } -func (e *Kevent) IsVirtualAlloc() bool { return e.Type == ktypes.VirtualAlloc } -func (e *Kevent) IsMapViewFile() bool { return e.Type == ktypes.MapViewFile } -func (e *Kevent) IsUnmapViewFile() bool { return e.Type == ktypes.UnmapViewFile } -func (e *Kevent) IsStackWalk() bool { return e.Type == ktypes.StackWalk } +func (e *Event) IsCreateFile() bool { return e.Type == CreateFile } +func (e *Event) IsCreateProcess() bool { return e.Type == CreateProcess } +func (e *Event) IsCreateThread() bool { return e.Type == CreateThread } +func (e *Event) IsCloseFile() bool { return e.Type == CloseFile } +func (e *Event) IsCreateHandle() bool { return e.Type == CreateHandle } +func (e *Event) IsCloseHandle() bool { return e.Type == CloseHandle } +func (e *Event) IsDeleteFile() bool { return e.Type == DeleteFile } +func (e *Event) IsEnumDirectory() bool { return e.Type == EnumDirectory } +func (e *Event) IsTerminateProcess() bool { return e.Type == TerminateProcess } +func (e *Event) IsTerminateThread() bool { return e.Type == TerminateThread } +func (e *Event) IsUnloadImage() bool { return e.Type == UnloadImage } +func (e *Event) IsLoadImage() bool { return e.Type == LoadImage } +func (e *Event) IsImageRundown() bool { return e.Type == ImageRundown } +func (e *Event) IsFileOpEnd() bool { return e.Type == FileOpEnd } +func (e *Event) IsRegSetValue() bool { return e.Type == RegSetValue } +func (e *Event) IsProcessRundown() bool { return e.Type == ProcessRundown } +func (e *Event) IsVirtualAlloc() bool { return e.Type == VirtualAlloc } +func (e *Event) IsMapViewFile() bool { return e.Type == MapViewFile } +func (e *Event) IsUnmapViewFile() bool { return e.Type == UnmapViewFile } +func (e *Event) IsStackWalk() bool { return e.Type == StackWalk } // InvalidPid indicates if the process generating the event is invalid. -func (e *Kevent) InvalidPid() bool { return e.PID == sys.InvalidProcessID } +func (e *Event) InvalidPid() bool { return e.PID == sys.InvalidProcessID } // CurrentPid indicates if Fibratus is the process generating the event. -func (e *Kevent) CurrentPid() bool { return e.PID == currentPid } +func (e *Event) CurrentPid() bool { return e.PID == currentPid } // IsSystemPid indicates if the process generating the event is the System process. -func (e *Kevent) IsSystemPid() bool { return e.PID == 4 } +func (e *Event) IsSystemPid() bool { return e.PID == 4 } // IsState indicates if this event is only used for state management. -func (e *Kevent) IsState() bool { return e.Type.OnlyState() } +func (e *Event) IsState() bool { return e.Type.OnlyState() } // IsCreateDisposition determines if the file disposition leads to creating a new file. -func (e *Kevent) IsCreateDisposition() bool { - return e.IsCreateFile() && e.Kparams.MustGetUint32(kparams.FileOperation) == windows.FILE_CREATE +func (e *Event) IsCreateDisposition() bool { + return e.IsCreateFile() && e.Params.MustGetUint32(params.FileOperation) == windows.FILE_CREATE } // IsOpenDisposition determines if the file disposition leads to opening a file object. -func (e *Kevent) IsOpenDisposition() bool { - return e.IsCreateFile() && e.Kparams.MustGetUint32(kparams.FileOperation) == windows.FILE_OPEN +func (e *Event) IsOpenDisposition() bool { + return e.IsCreateFile() && e.Params.MustGetUint32(params.FileOperation) == windows.FILE_OPEN } // StackID returns the integer that is used to identify the callstack present in the StackWalk event. -func (e *Kevent) StackID() uint64 { return uint64(e.PID + e.Tid) } +func (e *Event) StackID() uint64 { return uint64(e.PID + e.Tid) } // RundownKey calculates the rundown event hash. The hash is // used to determine if the rundown event was already processed. -func (e *Kevent) RundownKey() uint64 { +func (e *Event) RundownKey() uint64 { switch e.Type { - case ktypes.ProcessRundown: + case ProcessRundown: b := make([]byte, 4) - pid, _ := e.Kparams.GetPid() + pid, _ := e.Params.GetPid() binary.LittleEndian.PutUint32(b, pid) return hashers.FnvUint64(b) - case ktypes.ThreadRundown: + case ThreadRundown: b := make([]byte, 8) - pid, _ := e.Kparams.GetPid() - tid, _ := e.Kparams.GetTid() + pid, _ := e.Params.GetPid() + tid, _ := e.Params.GetTid() binary.LittleEndian.PutUint32(b, pid) binary.LittleEndian.PutUint32(b, tid) return hashers.FnvUint64(b) - case ktypes.ImageRundown: - pid, _ := e.Kparams.GetPid() - mod, _ := e.Kparams.GetString(kparams.ImagePath) + case ImageRundown: + pid, _ := e.Params.GetPid() + mod, _ := e.Params.GetString(params.ImagePath) b := make([]byte, 4+len(mod)) binary.LittleEndian.PutUint32(b, pid) b = append(b, mod...) return hashers.FnvUint64(b) - case ktypes.FileRundown: + case FileRundown: b := make([]byte, 8) - fileObject, _ := e.Kparams.GetUint64(kparams.FileObject) + fileObject, _ := e.Params.GetUint64(params.FileObject) binary.LittleEndian.PutUint64(b, fileObject) return hashers.FnvUint64(b) - case ktypes.MapFileRundown: + case MapFileRundown: b := make([]byte, 12) - fileKey, _ := e.Kparams.GetUint64(kparams.FileKey) + fileKey, _ := e.Params.GetUint64(params.FileKey) binary.LittleEndian.PutUint32(b, e.PID) binary.LittleEndian.PutUint64(b, fileKey) return hashers.FnvUint64(b) - case ktypes.RegKCBRundown: - key, _ := e.Kparams.GetString(kparams.RegPath) + case RegKCBRundown: + key, _ := e.Params.GetString(params.RegPath) b := make([]byte, 4+len(key)) binary.LittleEndian.PutUint32(b, e.PID) @@ -316,76 +315,76 @@ func (e *Kevent) RundownKey() uint64 { // that can be employed to determine if the event // from the given process and source has been processed // in the rule sequences. -func (e *Kevent) PartialKey() uint64 { +func (e *Event) PartialKey() uint64 { switch e.Type { - case ktypes.WriteFile, ktypes.ReadFile: - return e.Kparams.MustGetUint64(kparams.FileObject) + uint64(e.PID) - case ktypes.MapViewFile, ktypes.UnmapViewFile: - return e.Kparams.MustGetUint64(kparams.FileViewBase) + uint64(e.PID) - case ktypes.CreateFile: - file, _ := e.Kparams.GetString(kparams.FilePath) + case WriteFile, ReadFile: + return e.Params.MustGetUint64(params.FileObject) + uint64(e.PID) + case MapViewFile, UnmapViewFile: + return e.Params.MustGetUint64(params.FileViewBase) + uint64(e.PID) + case CreateFile: + file, _ := e.Params.GetString(params.FilePath) b := make([]byte, 4+len(file)) binary.LittleEndian.PutUint32(b, e.PID) b = append(b, []byte(file)...) return hashers.FnvUint64(b) - case ktypes.OpenProcess: - pid := e.Kparams.MustGetUint32(kparams.ProcessID) - access := e.Kparams.MustGetUint32(kparams.DesiredAccess) + case OpenProcess: + pid := e.Params.MustGetUint32(params.ProcessID) + access := e.Params.MustGetUint32(params.DesiredAccess) return uint64(pid + access + e.PID) - case ktypes.OpenThread: - tid := e.Kparams.MustGetUint32(kparams.ThreadID) - access := e.Kparams.MustGetUint32(kparams.DesiredAccess) + case OpenThread: + tid := e.Params.MustGetUint32(params.ThreadID) + access := e.Params.MustGetUint32(params.DesiredAccess) return uint64(tid + access + e.PID) - case ktypes.AcceptTCPv4, ktypes.RecvTCPv4, ktypes.RecvUDPv4: + case AcceptTCPv4, RecvTCPv4, RecvUDPv4: b := make([]byte, 10) - ip, _ := e.Kparams.GetIP(kparams.NetSIP) - port, _ := e.Kparams.GetUint16(kparams.NetSport) + ip, _ := e.Params.GetIP(params.NetSIP) + port, _ := e.Params.GetUint16(params.NetSport) binary.LittleEndian.PutUint32(b, e.PID) binary.LittleEndian.PutUint32(b, binary.BigEndian.Uint32(ip.To4())) binary.LittleEndian.PutUint16(b, port) return hashers.FnvUint64(b) - case ktypes.AcceptTCPv6, ktypes.RecvTCPv6, ktypes.RecvUDPv6: + case AcceptTCPv6, RecvTCPv6, RecvUDPv6: b := make([]byte, 22) - ip, _ := e.Kparams.GetIP(kparams.NetSIP) - port, _ := e.Kparams.GetUint16(kparams.NetSport) + ip, _ := e.Params.GetIP(params.NetSIP) + port, _ := e.Params.GetUint16(params.NetSport) binary.LittleEndian.PutUint32(b, e.PID) binary.LittleEndian.PutUint64(b, binary.BigEndian.Uint64(ip.To16()[0:8])) binary.LittleEndian.PutUint64(b, binary.BigEndian.Uint64(ip.To16()[8:16])) binary.LittleEndian.PutUint16(b, port) return hashers.FnvUint64(b) - case ktypes.ConnectTCPv4, ktypes.SendTCPv4, ktypes.SendUDPv4: + case ConnectTCPv4, SendTCPv4, SendUDPv4: b := make([]byte, 10) - ip, _ := e.Kparams.GetIP(kparams.NetDIP) - port, _ := e.Kparams.GetUint16(kparams.NetDport) + ip, _ := e.Params.GetIP(params.NetDIP) + port, _ := e.Params.GetUint16(params.NetDport) binary.LittleEndian.PutUint32(b, e.PID) binary.LittleEndian.PutUint32(b, binary.BigEndian.Uint32(ip.To4())) binary.LittleEndian.PutUint16(b, port) return hashers.FnvUint64(b) - case ktypes.ConnectTCPv6, ktypes.SendTCPv6, ktypes.SendUDPv6: + case ConnectTCPv6, SendTCPv6, SendUDPv6: b := make([]byte, 22) - ip, _ := e.Kparams.GetIP(kparams.NetDIP) - port, _ := e.Kparams.GetUint16(kparams.NetDport) + ip, _ := e.Params.GetIP(params.NetDIP) + port, _ := e.Params.GetUint16(params.NetDport) binary.LittleEndian.PutUint32(b, e.PID) binary.LittleEndian.PutUint64(b, binary.BigEndian.Uint64(ip.To16()[0:8])) binary.LittleEndian.PutUint64(b, binary.BigEndian.Uint64(ip.To16()[8:16])) binary.LittleEndian.PutUint16(b, port) return hashers.FnvUint64(b) - case ktypes.RegOpenKey, ktypes.RegQueryKey, ktypes.RegQueryValue, - ktypes.RegDeleteKey, ktypes.RegDeleteValue, ktypes.RegSetValue, - ktypes.RegCloseKey: - key, _ := e.Kparams.GetString(kparams.RegPath) + case RegOpenKey, RegQueryKey, RegQueryValue, + RegDeleteKey, RegDeleteValue, RegSetValue, + RegCloseKey: + key, _ := e.Params.GetString(params.RegPath) b := make([]byte, 4+len(key)) binary.LittleEndian.PutUint32(b, e.PID) b = append(b, key...) return hashers.FnvUint64(b) - case ktypes.VirtualAlloc, ktypes.VirtualFree: - return e.Kparams.MustGetUint64(kparams.MemBaseAddress) + uint64(e.PID) - case ktypes.DuplicateHandle: - pid := e.Kparams.MustGetUint32(kparams.ProcessID) - object := e.Kparams.MustGetUint64(kparams.HandleObject) + case VirtualAlloc, VirtualFree: + return e.Params.MustGetUint64(params.MemBaseAddress) + uint64(e.PID) + case DuplicateHandle: + pid := e.Params.MustGetUint32(params.ProcessID) + object := e.Params.MustGetUint64(params.HandleObject) return object + uint64(pid+e.PID) - case ktypes.QueryDNS, ktypes.ReplyDNS: - n, _ := e.Kparams.GetString(kparams.DNSName) + case QueryDNS, ReplyDNS: + n, _ := e.Params.GetString(params.DNSName) b := make([]byte, 4+len(n)) binary.LittleEndian.PutUint32(b, e.PID) b = append(b, n...) @@ -395,182 +394,182 @@ func (e *Kevent) PartialKey() uint64 { } // BacklogKey represents the key used to index the events in the backlog store. -func (e *Kevent) BacklogKey() uint64 { +func (e *Event) BacklogKey() uint64 { switch e.Type { - case ktypes.CreateHandle, ktypes.CloseHandle: - return e.Kparams.MustGetUint64(kparams.HandleObject) + case CreateHandle, CloseHandle: + return e.Params.MustGetUint64(params.HandleObject) } return 0 } // CopyState adds parameters, tags, or process state from the provided event. -func (e *Kevent) CopyState(evt *Kevent) { +func (e *Event) CopyState(evt *Event) { switch evt.Type { - case ktypes.CloseHandle: - if evt.Kparams.Contains(kparams.ImagePath) { - e.Kparams.Append(kparams.ImagePath, kparams.UnicodeString, evt.GetParamAsString(kparams.ImagePath)) + case CloseHandle: + if evt.Params.Contains(params.ImagePath) { + e.Params.Append(params.ImagePath, params.UnicodeString, evt.GetParamAsString(params.ImagePath)) } - _ = e.Kparams.SetValue(kparams.HandleObjectName, evt.GetParamAsString(kparams.HandleObjectName)) + _ = e.Params.SetValue(params.HandleObjectName, evt.GetParamAsString(params.HandleObjectName)) } } // Summary returns a brief summary of this event. Various important substrings // in the summary text are highlighted by surrounding them inside HTML tags. -func (e *Kevent) Summary() string { +func (e *Event) Summary() string { switch e.Type { - case ktypes.CreateProcess: - exe := e.Kparams.MustGetString(kparams.Exe) - sid := e.GetParamAsString(kparams.Username) + case CreateProcess: + exe := e.Params.MustGetString(params.Exe) + sid := e.GetParamAsString(params.Username) return printSummary(e, fmt.Sprintf("spawned %s process as %s user", exe, sid)) - case ktypes.TerminateProcess: - exe := e.Kparams.MustGetString(kparams.Exe) - sid := e.GetParamAsString(kparams.Username) + case TerminateProcess: + exe := e.Params.MustGetString(params.Exe) + sid := e.GetParamAsString(params.Username) return printSummary(e, fmt.Sprintf("terminated %s process as %s user", exe, sid)) - case ktypes.OpenProcess: - access := e.GetParamAsString(kparams.DesiredAccess) - exe, _ := e.Kparams.GetString(kparams.Exe) + case OpenProcess: + access := e.GetParamAsString(params.DesiredAccess) + exe, _ := e.Params.GetString(params.Exe) return printSummary(e, fmt.Sprintf("opened %s process object with %s access right(s)", exe, access)) - case ktypes.CreateThread: - tid, _ := e.Kparams.GetTid() - addr := e.GetParamAsString(kparams.StartAddress) + case CreateThread: + tid, _ := e.Params.GetTid() + addr := e.GetParamAsString(params.StartAddress) return printSummary(e, fmt.Sprintf("spawned a new thread with %d id at %s address", tid, addr)) - case ktypes.TerminateThread: - tid, _ := e.Kparams.GetTid() - addr := e.GetParamAsString(kparams.StartAddress) + case TerminateThread: + tid, _ := e.Params.GetTid() + addr := e.GetParamAsString(params.StartAddress) return printSummary(e, fmt.Sprintf("terminated a thread with %d id at %s address", tid, addr)) - case ktypes.OpenThread: - access := e.GetParamAsString(kparams.DesiredAccess) - exe, _ := e.Kparams.GetString(kparams.Exe) + case OpenThread: + access := e.GetParamAsString(params.DesiredAccess) + exe, _ := e.Params.GetString(params.Exe) return printSummary(e, fmt.Sprintf("opened %s process' thread object with %s access right(s)", exe, access)) - case ktypes.LoadImage: - filename := e.GetParamAsString(kparams.FilePath) + case LoadImage: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("loaded %s module", filename)) - case ktypes.UnloadImage: - filename := e.GetParamAsString(kparams.FilePath) + case UnloadImage: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("unloaded %s module", filename)) - case ktypes.CreateFile: - op := e.GetParamAsString(kparams.FileOperation) - filename := e.GetParamAsString(kparams.FilePath) + case CreateFile: + op := e.GetParamAsString(params.FileOperation) + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("%sed a file %s", strings.ToLower(op), filename)) - case ktypes.ReadFile: - filename := e.GetParamAsString(kparams.FilePath) - size, _ := e.Kparams.GetUint32(kparams.FileIoSize) + case ReadFile: + filename := e.GetParamAsString(params.FilePath) + size, _ := e.Params.GetUint32(params.FileIoSize) return printSummary(e, fmt.Sprintf("read %d bytes from %s file", size, filename)) - case ktypes.WriteFile: - filename := e.GetParamAsString(kparams.FilePath) - size, _ := e.Kparams.GetUint32(kparams.FileIoSize) + case WriteFile: + filename := e.GetParamAsString(params.FilePath) + size, _ := e.Params.GetUint32(params.FileIoSize) return printSummary(e, fmt.Sprintf("wrote %d bytes to %s file", size, filename)) - case ktypes.SetFileInformation: - filename := e.GetParamAsString(kparams.FilePath) - class := e.GetParamAsString(kparams.FileInfoClass) + case SetFileInformation: + filename := e.GetParamAsString(params.FilePath) + class := e.GetParamAsString(params.FileInfoClass) return printSummary(e, fmt.Sprintf("set %s information class on %s file", class, filename)) - case ktypes.DeleteFile: - filename := e.GetParamAsString(kparams.FilePath) + case DeleteFile: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("deleted %s file", filename)) - case ktypes.RenameFile: - filename := e.GetParamAsString(kparams.FilePath) + case RenameFile: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("renamed %s file", filename)) - case ktypes.CloseFile: - filename := e.GetParamAsString(kparams.FilePath) + case CloseFile: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("closed %s file", filename)) - case ktypes.EnumDirectory: - filename := e.GetParamAsString(kparams.FilePath) + case EnumDirectory: + filename := e.GetParamAsString(params.FilePath) return printSummary(e, fmt.Sprintf("enumerated %s directory", filename)) - case ktypes.RegCreateKey: - key := e.GetParamAsString(kparams.RegPath) + case RegCreateKey: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("created %s key", key)) - case ktypes.RegOpenKey: - key := e.GetParamAsString(kparams.RegPath) + case RegOpenKey: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("opened %s key", key)) - case ktypes.RegDeleteKey: - key := e.GetParamAsString(kparams.RegPath) + case RegDeleteKey: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("deleted %s key", key)) - case ktypes.RegQueryKey: - key := e.GetParamAsString(kparams.RegPath) + case RegQueryKey: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("queried %s key", key)) - case ktypes.RegSetValue: - key := e.GetParamAsString(kparams.RegPath) - val, err := e.Kparams.GetString(kparams.RegValue) + case RegSetValue: + key := e.GetParamAsString(params.RegPath) + val, err := e.Params.GetString(params.RegValue) if err != nil { return printSummary(e, fmt.Sprintf("set %s value", key)) } return printSummary(e, fmt.Sprintf("set %s payload in %s value", val, key)) - case ktypes.RegDeleteValue: - key := e.GetParamAsString(kparams.RegPath) + case RegDeleteValue: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("deleted %s value", key)) - case ktypes.RegQueryValue: - key := e.GetParamAsString(kparams.RegPath) + case RegQueryValue: + key := e.GetParamAsString(params.RegPath) return printSummary(e, fmt.Sprintf("queried %s value", key)) - case ktypes.AcceptTCPv4, ktypes.AcceptTCPv6: - ip, _ := e.Kparams.GetIP(kparams.NetSIP) - port, _ := e.Kparams.GetUint16(kparams.NetSport) + case AcceptTCPv4, AcceptTCPv6: + ip, _ := e.Params.GetIP(params.NetSIP) + port, _ := e.Params.GetUint16(params.NetSport) return printSummary(e, fmt.Sprintf("accepted connection from %v and %d port", ip, port)) - case ktypes.ConnectTCPv4, ktypes.ConnectTCPv6: - ip, _ := e.Kparams.GetIP(kparams.NetDIP) - port, _ := e.Kparams.GetUint16(kparams.NetDport) + case ConnectTCPv4, ConnectTCPv6: + ip, _ := e.Params.GetIP(params.NetDIP) + port, _ := e.Params.GetUint16(params.NetDport) return printSummary(e, fmt.Sprintf("connected to %v and %d port", ip, port)) - case ktypes.SendTCPv4, ktypes.SendTCPv6, ktypes.SendUDPv4, ktypes.SendUDPv6: - ip, _ := e.Kparams.GetIP(kparams.NetDIP) - port, _ := e.Kparams.GetUint16(kparams.NetDport) - size, _ := e.Kparams.GetUint32(kparams.NetSize) + case SendTCPv4, SendTCPv6, SendUDPv4, SendUDPv6: + ip, _ := e.Params.GetIP(params.NetDIP) + port, _ := e.Params.GetUint16(params.NetDport) + size, _ := e.Params.GetUint32(params.NetSize) return printSummary(e, fmt.Sprintf("sent %d bytes to %v and %d port", size, ip, port)) - case ktypes.RecvTCPv4, ktypes.RecvTCPv6, ktypes.RecvUDPv4, ktypes.RecvUDPv6: - ip, _ := e.Kparams.GetIP(kparams.NetSIP) - port, _ := e.Kparams.GetUint16(kparams.NetSport) - size, _ := e.Kparams.GetUint32(kparams.NetSize) + case RecvTCPv4, RecvTCPv6, RecvUDPv4, RecvUDPv6: + ip, _ := e.Params.GetIP(params.NetSIP) + port, _ := e.Params.GetUint16(params.NetSport) + size, _ := e.Params.GetUint32(params.NetSize) return printSummary(e, fmt.Sprintf("received %d bytes from %v and %d port", size, ip, port)) - case ktypes.CreateHandle: - handleType := e.GetParamAsString(kparams.HandleObjectTypeID) - handleName := e.GetParamAsString(kparams.HandleObjectName) + case CreateHandle: + handleType := e.GetParamAsString(params.HandleObjectTypeID) + handleName := e.GetParamAsString(params.HandleObjectName) return printSummary(e, fmt.Sprintf("created %s handle of %s type", handleName, handleType)) - case ktypes.CloseHandle: - handleType := e.GetParamAsString(kparams.HandleObjectTypeID) - handleName := e.GetParamAsString(kparams.HandleObjectName) + case CloseHandle: + handleType := e.GetParamAsString(params.HandleObjectTypeID) + handleName := e.GetParamAsString(params.HandleObjectName) return printSummary(e, fmt.Sprintf("closed %s handle of %s type", handleName, handleType)) - case ktypes.VirtualAlloc: - addr := e.GetParamAsString(kparams.MemBaseAddress) + case VirtualAlloc: + addr := e.GetParamAsString(params.MemBaseAddress) return printSummary(e, fmt.Sprintf("allocated memory at %s address", addr)) - case ktypes.VirtualFree: - addr := e.GetParamAsString(kparams.MemBaseAddress) + case VirtualFree: + addr := e.GetParamAsString(params.MemBaseAddress) return printSummary(e, fmt.Sprintf("released memory at %s address", addr)) - case ktypes.MapViewFile: - sec := e.GetParamAsString(kparams.FileViewSectionType) + case MapViewFile: + sec := e.GetParamAsString(params.FileViewSectionType) return printSummary(e, fmt.Sprintf("mapped view of %s section", sec)) - case ktypes.UnmapViewFile: - sec := e.GetParamAsString(kparams.FileViewSectionType) + case UnmapViewFile: + sec := e.GetParamAsString(params.FileViewSectionType) return printSummary(e, fmt.Sprintf("unmapped view of %s section", sec)) - case ktypes.DuplicateHandle: - handleType := e.GetParamAsString(kparams.HandleObjectTypeID) + case DuplicateHandle: + handleType := e.GetParamAsString(params.HandleObjectTypeID) return printSummary(e, fmt.Sprintf("duplicated %s handle", handleType)) - case ktypes.QueryDNS: - dnsName := e.GetParamAsString(kparams.DNSName) + case QueryDNS: + dnsName := e.GetParamAsString(params.DNSName) return printSummary(e, fmt.Sprintf("sent %s DNS query", dnsName)) - case ktypes.ReplyDNS: - dnsName := e.GetParamAsString(kparams.DNSName) + case ReplyDNS: + dnsName := e.GetParamAsString(params.DNSName) return printSummary(e, fmt.Sprintf("received DNS response for %s query", dnsName)) - case ktypes.CreateSymbolicLinkObject: - src := e.GetParamAsString(kparams.LinkSource) - target := e.GetParamAsString(kparams.LinkTarget) + case CreateSymbolicLinkObject: + src := e.GetParamAsString(params.LinkSource) + target := e.GetParamAsString(params.LinkTarget) return printSummary(e, fmt.Sprintf("created symbolic link from %s to %s", src, target)) - case ktypes.SubmitThreadpoolWork: + case SubmitThreadpoolWork: return printSummary(e, "enqueued the work item to the thread pool") - case ktypes.SubmitThreadpoolCallback: + case SubmitThreadpoolCallback: return printSummary(e, "Submitted the thread pool callback for execution within the work item") - case ktypes.SetThreadpoolTimer: + case SetThreadpoolTimer: return printSummary(e, "set thread pool timer object") } return "" } -func printSummary(e *Kevent, text string) string { +func printSummary(e *Event, text string) string { ps := e.PS if ps != nil { return fmt.Sprintf("%s %s", ps.Name, text) diff --git a/pkg/kevent/kevent_windows_test.go b/pkg/event/event_windows_test.go similarity index 59% rename from pkg/kevent/kevent_windows_test.go rename to pkg/event/event_windows_test.go index 4347b3649..573c2c511 100644 --- a/pkg/kevent/kevent_windows_test.go +++ b/pkg/event/event_windows_test.go @@ -16,12 +16,11 @@ * limitations under the License. */ -package kevent +package event import ( + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -29,37 +28,37 @@ import ( "time" ) -func TestKeventIsNetworkTCP(t *testing.T) { - e1 := Kevent{Type: ktypes.AcceptTCPv4, Category: ktypes.Net} - e2 := Kevent{Type: ktypes.SendUDPv6, Category: ktypes.Net} +func TestEventIsNetworkTCP(t *testing.T) { + e1 := Event{Type: AcceptTCPv4, Category: Net} + e2 := Event{Type: SendUDPv6, Category: Net} assert.True(t, e1.IsNetworkTCP()) assert.False(t, e2.IsNetworkTCP()) } -func TestKeventIsNetworkUDP(t *testing.T) { - e1 := Kevent{Type: ktypes.RecvUDPv4} - e2 := Kevent{Type: ktypes.SendTCPv6} +func TestEventIsNetworkUDP(t *testing.T) { + e1 := Event{Type: RecvUDPv4} + e2 := Event{Type: SendTCPv6} assert.True(t, e1.IsNetworkUDP()) assert.False(t, e2.IsNetworkUDP()) } -func TestKeventSummary(t *testing.T) { - kevt := &Kevent{ - Type: ktypes.CreateFile, +func TestEventSummary(t *testing.T) { + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, PS: &pstypes.PS{ PID: 2436, @@ -85,30 +84,30 @@ func TestKeventSummary(t *testing.T) { }, } - require.Equal(t, "firefox.exe opened a file C:\\Windows\\system32\\user32.dll", kevt.Summary()) - kevt.PS = nil - require.Equal(t, "process with 859 id opened a file C:\\Windows\\system32\\user32.dll", kevt.Summary()) + require.Equal(t, "firefox.exe opened a file C:\\Windows\\system32\\user32.dll", evt.Summary()) + evt.PS = nil + require.Equal(t, "process with 859 id opened a file C:\\Windows\\system32\\user32.dll", evt.Summary()) } func TestPartialKey(t *testing.T) { var tests = []struct { - evt *Kevent + evt *Event key uint64 }{ { - &Kevent{Type: ktypes.OpenProcess, PID: 1234, Kparams: Kparams{kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1221)}, kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Uint32, Value: uint32(5)}}}, + &Event{Type: OpenProcess, PID: 1234, Params: Params{params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1221)}, params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Uint32, Value: uint32(5)}}}, 0x99c, }, { - &Kevent{Type: ktypes.OpenThread, PID: 11234, Kparams: Kparams{kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(8452)}, kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Uint32, Value: uint32(15)}}}, + &Event{Type: OpenThread, PID: 11234, Params: Params{params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(8452)}, params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Uint32, Value: uint32(15)}}}, 0x4cf5, }, { - &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.DOSPath, Value: "C:\\Windows\\System32\\kernelbase.dll"}}}, + &Event{Type: CreateFile, PID: 4321, Params: Params{params.FilePath: {Name: params.FilePath, Type: params.DOSPath, Value: "C:\\Windows\\System32\\kernelbase.dll"}}}, 0x7ec254f31df879ec, }, { - &Kevent{Type: ktypes.CreateFile, PID: 4321, Kparams: Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.DOSPath, Value: "C:\\Windows\\System32\\kernel32.dll"}}}, + &Event{Type: CreateFile, PID: 4321, Params: Params{params.FilePath: {Name: params.FilePath, Type: params.DOSPath, Value: "C:\\Windows\\System32\\kernel32.dll"}}}, 0xb6380d9159ccd174, }, } diff --git a/pkg/kevent/ktypes/eventset.go b/pkg/event/eventset.go similarity index 93% rename from pkg/kevent/ktypes/eventset.go rename to pkg/event/eventset.go index a8e62333f..614029027 100644 --- a/pkg/kevent/ktypes/eventset.go +++ b/pkg/event/eventset.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package ktypes +package event import ( "fmt" @@ -34,13 +34,13 @@ type EventsetMasks struct { } // Set puts a new event type into the bitset. -func (e *EventsetMasks) Set(ktype Ktype) { - g := ktype.GUID() +func (e *EventsetMasks) Set(typ Type) { + g := typ.GUID() i := e.bitsetIndex(g) if i < 0 { panic(fmt.Sprintf("invalid event bitset index: %s", g.String())) } - e.masks[e.bitsetIndex(ktype.GUID())].Set(uint(ktype.HookID())) + e.masks[e.bitsetIndex(typ.GUID())].Set(uint(typ.HookID())) } // Test checks if the given provider GUID and diff --git a/pkg/kevent/ktypes/eventset_test.go b/pkg/event/eventset_test.go similarity index 98% rename from pkg/kevent/ktypes/eventset_test.go rename to pkg/event/eventset_test.go index 4d0f35fd3..89d483523 100644 --- a/pkg/kevent/ktypes/eventset_test.go +++ b/pkg/event/eventset_test.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package ktypes +package event import ( "github.com/rabbitstack/fibratus/pkg/sys/etw" @@ -63,7 +63,7 @@ func BenchmarkEventsetMasks(b *testing.B) { func BenchmarkStdlibMap(b *testing.B) { b.ReportAllocs() - evts := make(map[Ktype]bool) + evts := make(map[Type]bool) evts[TerminateThread] = true evts[CreateThread] = true evts[TerminateProcess] = true diff --git a/pkg/kevent/flags.go b/pkg/event/flags.go similarity index 99% rename from pkg/kevent/flags.go rename to pkg/event/flags.go index c2065b57a..cb8b45c1a 100644 --- a/pkg/kevent/flags.go +++ b/pkg/event/flags.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "github.com/rabbitstack/fibratus/pkg/sys" diff --git a/pkg/kevent/flags_test.go b/pkg/event/flags_test.go similarity index 98% rename from pkg/kevent/flags_test.go rename to pkg/event/flags_test.go index 2abd116f0..48e6351dd 100644 --- a/pkg/kevent/flags_test.go +++ b/pkg/event/flags_test.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import "testing" diff --git a/pkg/kevent/formatter.go b/pkg/event/formatter.go similarity index 72% rename from pkg/kevent/formatter.go rename to pkg/event/formatter.go index 0c4c8a8b0..3acd05e6e 100644 --- a/pkg/kevent/formatter.go +++ b/pkg/event/formatter.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "fmt" @@ -33,29 +33,29 @@ const ( // endTag represents the trailing tag surrounding field name endTag = "}}" - seq = ".Seq" - ts = ".Timestamp" - pid = ".Pid" - ppid = ".Ppid" - pexe = ".Pexe" - pcmd = ".Pcmd" - pproc = ".Pname" - cwd = ".Cwd" - exe = ".Exe" - cmd = ".Cmd" - tid = ".Tid" - sid = ".Sid" - proc = ".Process" - cat = ".Category" - desc = ".Description" - cpu = ".CPU" - typ = ".Type" - kparameters = ".Kparams" - meta = ".Meta" - host = ".Host" - pe = ".PE" - kparsAccessor = ".Kparams." - cstack = ".Callstack" + seq = ".Seq" + ts = ".Timestamp" + pid = ".Pid" + ppid = ".Ppid" + pexe = ".Pexe" + pcmd = ".Pcmd" + pproc = ".Pname" + cwd = ".Cwd" + exe = ".Exe" + cmd = ".Cmd" + tid = ".Tid" + sid = ".Sid" + proc = ".Process" + cat = ".Category" + desc = ".Description" + cpu = ".CPU" + typ = ".Type" + parameters = ".Params" + meta = ".Meta" + host = ".Host" + pe = ".PE" + parsAccessor = ".Params." + cstack = ".Callstack" ) var ( @@ -64,38 +64,38 @@ var ( // tmplNormRegepx defines the regular expression for normalizing the template. This basically consists in removing // the brackets and trailing/leading spaces from the field name. tmplNormRegexp = regexp.MustCompile(`({{2}\s*([A-Za-z.]+)\s*}{2})`) - // tmplExpandKparamsRegexp determines whether Kparams. fields are expanded - tmplExpandKparamsRegexp = regexp.MustCompile(`{{\s*.Kparams.\S+}}`) + // tmplExpandKparamsRegexp determines whether Params. fields are expanded + tmplExpandKparamsRegexp = regexp.MustCompile(`{{\s*.Params.\S+}}`) ) -var kfields = map[string]bool{ - seq: true, - ts: true, - pid: true, - ppid: true, - pexe: true, - pcmd: true, - pproc: true, - cwd: true, - exe: true, - cmd: true, - tid: true, - sid: true, - proc: true, - cat: true, - desc: true, - cpu: true, - typ: true, - kparameters: true, - meta: true, - host: true, - pe: true, - cstack: true, +var fields = map[string]bool{ + seq: true, + ts: true, + pid: true, + ppid: true, + pexe: true, + pcmd: true, + pproc: true, + cwd: true, + exe: true, + cmd: true, + tid: true, + sid: true, + proc: true, + cat: true, + desc: true, + cpu: true, + typ: true, + parameters: true, + meta: true, + host: true, + pe: true, + cstack: true, } func hintFields() string { - s := make([]string, 0, len(kfields)) - for field := range kfields { + s := make([]string, 0, len(fields)) + for field := range fields { s = append(s, field) } sort.Slice(s, func(i, j int) bool { return s[i] < s[j] }) @@ -112,23 +112,23 @@ type Formatter struct { func NewFormatter(template string) (*Formatter, error) { // check basic template format and ensure all fields // defined in the template are known to us - fields := tmplRegexp.FindAllStringSubmatch(template, -1) - if len(fields) == 0 { + flds := tmplRegexp.FindAllStringSubmatch(template, -1) + if len(flds) == 0 { return nil, fmt.Errorf("invalid template format: %q", template) } if ok, pos := isTemplateBalanced(template); !ok { return nil, fmt.Errorf("template syntax error near field #%d: %q", pos, template) } - for i, field := range fields { + for i, field := range flds { if len(field) > 0 { name := sanitize(field[0]) - if strings.HasPrefix(name, kparsAccessor) { + if strings.HasPrefix(name, parsAccessor) { continue } if name == "" { return nil, fmt.Errorf("empty field found at position %d", i+1) } - if _, ok := kfields[name]; !ok { + if _, ok := fields[name]; !ok { return nil, fmt.Errorf("%s is not a known field name. Maybe you meant one "+ "of the following fields: %s", name, hintFields()) } diff --git a/pkg/kevent/formatter_test.go b/pkg/event/formatter_test.go similarity index 79% rename from pkg/kevent/formatter_test.go rename to pkg/event/formatter_test.go index 46198f20f..044a4c128 100644 --- a/pkg/kevent/formatter_test.go +++ b/pkg/event/formatter_test.go @@ -16,14 +16,14 @@ * limitations under the License. */ -package kevent +package event import ( htypes "github.com/rabbitstack/fibratus/pkg/handle/types" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/assert" - kpars "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + kpars "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/require" "testing" ) @@ -31,7 +31,7 @@ import ( func TestTemplateUnknownField(t *testing.T) { template := "{{ .Seq }} {{NUllField1}} {{.Type}}" _, err := NewFormatter(template) - require.Error(t, err, "NUllField1 is not a known field name. Maybe you meant one of the following fields: .CPU .Category .Cmd .Cwd .Description .Exe .Handles .Host .Kparams .Meta .Pid .Ppid .Process .Seq .Sid .Tid .Timestamp .Type") + require.Error(t, err, "NUllField1 is not a known field name. Maybe you meant one of the following fields: .CPU .Category .Cmd .Cwd .Description .Exe .Handles .Host .Params .Meta .Pid .Ppid .Process .Seq .Sid .Tid .Timestamp .Type") } func TestTemplateEmptyField(t *testing.T) { @@ -39,7 +39,7 @@ func TestTemplateEmptyField(t *testing.T) { _, err := NewFormatter(template) require.Error(t, err, "empty field found at position 2") - template1 := "{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{}} {{ .Kparams.Pid }} ({{.Kparams}}) {{ .Meta }}" + template1 := "{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{}} {{ .Params.Pid }} ({{.Params}}) {{ .Meta }}" _, err = NewFormatter(template1) require.Error(t, err, "empty field found at position 4") } @@ -51,13 +51,13 @@ func TestTemplateSyntaxError(t *testing.T) { } func TestFormat(t *testing.T) { - template := "{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{ .Kparams.Pid }} ({{.Kparams}}) {{ .Meta }}" + template := "{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{ .Params.Pid }} ({{.Params}}) {{ .Meta }}" f, err := NewFormatter(template) require.NoError(t, err) - params := Kparams{ + params := Params{ kpars.ProcessID: {Name: kpars.ProcessID, Type: kpars.PID, Value: uint32(876)}, } - s := f.Format(&Kevent{CPU: uint8(4), Name: "CreateProcess", Seq: uint64(1999), Kparams: params, Metadata: map[MetadataKey]any{"key1": "value1"}}) + s := f.Format(&Event{CPU: uint8(4), Name: "CreateProcess", Seq: uint64(1999), Params: params, Metadata: map[MetadataKey]any{"key1": "value1"}}) assert.Equal(t, "1999 4 - (CreateProcess) -- pid: 876 (pidâžœ 876) key1: value1", string(s)) } @@ -65,14 +65,14 @@ func TestFormatPS(t *testing.T) { template := "{{ .Seq }} {{ .Process }} ({{ .Cwd }}) {{ .Ppid }} ({{ .Sid }})" f, err := NewFormatter(template) require.NoError(t, err) - params := Kparams{ + params := Params{ kpars.ProcessID: {Name: kpars.ProcessID, Type: kpars.PID, Value: uint32(876)}, } - s := f.Format(&Kevent{ - CPU: uint8(4), - Name: "CreateProcess", - Seq: uint64(1999), - Kparams: params, + s := f.Format(&Event{ + CPU: uint8(4), + Name: "CreateProcess", + Seq: uint64(1999), + Params: params, PS: &pstypes.PS{ Name: "cmd.exe", Cwd: "C:/Windows/System32", @@ -112,15 +112,15 @@ func TestIsTemplateBalanced(t *testing.T) { require.False(t, ok) assert.Equal(t, 2, pos) - ok, pos = isTemplateBalanced("{{{ .Seq }} {{.CPU}} {{} {{ .Kparams }} { .Kparams.pid}}") + ok, pos = isTemplateBalanced("{{{ .Seq }} {{.CPU}} {{} {{ .Params }} { .Params.pid}}") require.False(t, ok) assert.Equal(t, 1, pos) - ok, pos = isTemplateBalanced("{{ .Seq }} {{.CPU}} {{} {{ .Kparams }} { .Kparams.pid}}") + ok, pos = isTemplateBalanced("{{ .Seq }} {{.CPU}} {{} {{ .Params }} { .Params.pid}}") require.False(t, ok) assert.Equal(t, 3, pos) - ok, pos = isTemplateBalanced("({{ .Seq }}) {{.CPU}} {{}} {{ .Kparams }} { .Kparams.pid}}") + ok, pos = isTemplateBalanced("({{ .Seq }}) {{.CPU}} {{}} {{ .Params }} { .Params.pid}}") require.False(t, ok) assert.Equal(t, 5, pos) @@ -132,7 +132,7 @@ func TestIsTemplateBalanced(t *testing.T) { require.False(t, ok) assert.Equal(t, 3, pos) - ok, pos = isTemplateBalanced("{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{]} {{ .Kparams.Pid }} ({{.Kparams}}) {{ .Meta }}") + ok, pos = isTemplateBalanced("{{ .Seq }} {{.CPU}} - ({{.Type}}) -- pid: {{]} {{ .Params.Pid }} ({{.Params}}) {{ .Meta }}") require.False(t, ok) assert.Equal(t, 4, pos) } diff --git a/pkg/kevent/formatter_windows.go b/pkg/event/formatter_windows.go similarity index 66% rename from pkg/kevent/formatter_windows.go rename to pkg/event/formatter_windows.go index 2692fe7d5..7369c0f3e 100644 --- a/pkg/kevent/formatter_windows.go +++ b/pkg/event/formatter_windows.go @@ -16,33 +16,33 @@ * limitations under the License. */ -package kevent +package event import ( "strconv" ) // Format applies the template on the provided kernel event. -func (f *Formatter) Format(kevt *Kevent) []byte { - if kevt == nil { +func (f *Formatter) Format(evt *Event) []byte { + if evt == nil { return []byte{} } values := map[string]interface{}{ - ts: kevt.Timestamp.String(), - pid: strconv.FormatUint(uint64(kevt.PID), 10), - tid: strconv.FormatUint(uint64(kevt.Tid), 10), - seq: strconv.FormatUint(kevt.Seq, 10), - cpu: strconv.FormatUint(uint64(kevt.CPU), 10), - typ: kevt.Name, - cat: kevt.Category, - desc: kevt.Description, - host: kevt.Host, - meta: kevt.Metadata.String(), - kparameters: kevt.Kparams.String(), + ts: evt.Timestamp.String(), + pid: strconv.FormatUint(uint64(evt.PID), 10), + tid: strconv.FormatUint(uint64(evt.Tid), 10), + seq: strconv.FormatUint(evt.Seq, 10), + cpu: strconv.FormatUint(uint64(evt.CPU), 10), + typ: evt.Name, + cat: evt.Category, + desc: evt.Description, + host: evt.Host, + meta: evt.Metadata.String(), + parameters: evt.Params.String(), } // add process metadata - ps := kevt.PS + ps := evt.PS if ps != nil { values[proc] = ps.Name values[ppid] = strconv.FormatUint(uint64(ps.Ppid), 10) @@ -61,15 +61,15 @@ func (f *Formatter) Format(kevt *Kevent) []byte { } } // add callstack summary - if !kevt.Callstack.IsEmpty() { - values[cstack] = kevt.Callstack.String() + if !evt.Callstack.IsEmpty() { + values[cstack] = evt.Callstack.String() } if f.expandKparamsDot { // expand all parameters into the map, so we can ask // for specific parameter names in the template - for _, kpar := range kevt.Kparams { - values[".Kparams."+caser.String(kpar.Name)] = kpar.String() + for _, par := range evt.Params { + values[".Params."+caser.String(par.Name)] = par.String() } } diff --git a/pkg/kevent/marshaller.go b/pkg/event/marshaller.go similarity index 99% rename from pkg/kevent/marshaller.go rename to pkg/event/marshaller.go index d3ed80d89..bcaec4aae 100644 --- a/pkg/kevent/marshaller.go +++ b/pkg/event/marshaller.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "math" diff --git a/pkg/kevent/marshaller_test.go b/pkg/event/marshaller_test.go similarity index 71% rename from pkg/kevent/marshaller_test.go rename to pkg/event/marshaller_test.go index 059266ebb..3e4773906 100644 --- a/pkg/kevent/marshaller_test.go +++ b/pkg/event/marshaller_test.go @@ -16,20 +16,19 @@ * limitations under the License. */ -package kevent +package event import ( "encoding/json" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/util/va" "golang.org/x/sys/windows" "os" "testing" "time" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pex "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/assert" @@ -48,55 +47,55 @@ func TestMarshaller(t *testing.T) { now, err := time.Parse(time.RFC3339Nano, time.Now().Format(time.RFC3339Nano)) require.NoError(t, err) - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: now, - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(1888833888)}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1204)}, - kparams.NetDIPNames: {Name: kparams.NetDIPNames, Type: kparams.Slice, Value: []string{"dns.google.", "github.com."}}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(1888833888)}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1204)}, + params.NetDIPNames: {Name: params.NetDIPNames, Type: params.Slice, Value: []string{"dns.google.", "github.com."}}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - b := kevt.MarshalRaw() + b := evt.MarshalRaw() require.NotEmpty(t, b) - clone, err := NewFromKcap(b, kcapver.KevtSecV2) + clone, err := NewFromCapture(b, capver.EvtSecV2) require.NoError(t, err) assert.Equal(t, uint64(2), clone.Seq) assert.Equal(t, uint32(859), clone.PID) assert.Equal(t, uint32(2484), clone.Tid) - assert.Equal(t, ktypes.CreateFile, clone.Type) + assert.Equal(t, CreateFile, clone.Type) assert.Equal(t, uint8(1), clone.CPU) assert.Equal(t, "CreateFile", clone.Name) - assert.Equal(t, ktypes.File, clone.Category) + assert.Equal(t, File, clone.Category) assert.Equal(t, "Creates or opens a new file, directory, I/O device, pipe, console", clone.Description) assert.Equal(t, "archrabbit", clone.Host) assert.Equal(t, now, clone.Timestamp) - assert.Len(t, clone.Kparams, 10) + assert.Len(t, clone.Params, 10) - filename, err := clone.Kparams.GetString(kparams.FilePath) + filename, err := clone.Params.GetString(params.FilePath) require.NoError(t, err) assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll", filename) - fileobject, err := clone.Kparams.GetUint64(kparams.FileObject) + fileobject, err := clone.Params.GetUint64(params.FileObject) require.NoError(t, err) assert.Equal(t, uint64(12456738026482168384), fileobject) @@ -107,25 +106,25 @@ func TestMarshaller(t *testing.T) { } func TestKeventMarshalJSON(t *testing.T) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.NetDIPNames: {Name: kparams.NetDIPNames, Type: kparams.Slice, Value: []string{"dns.google.", "github.com."}}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, + params.NetDIPNames: {Name: params.NetDIPNames, Type: params.Slice, Value: []string{"dns.google.", "github.com."}}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -195,25 +194,26 @@ func TestKeventMarshalJSON(t *testing.T) { }, }, } - s := kevt.MarshalJSON() - var newKevt Kevent - err := json.Unmarshal(s, &newKevt) + + s := evt.MarshalJSON() + var newEvt Event + err := json.Unmarshal(s, &newEvt) require.NoError(t, err) - assert.Equal(t, uint32(2484), newKevt.Tid) - assert.Equal(t, uint32(859), newKevt.PID) - assert.Equal(t, "archrabbit\\SYSTEM", newKevt.PS.SID) - assert.Len(t, newKevt.PS.Envs, 2) - assert.Len(t, newKevt.PS.Handles, 3) + assert.Equal(t, uint32(2484), newEvt.Tid) + assert.Equal(t, uint32(859), newEvt.PID) + assert.Equal(t, "archrabbit\\SYSTEM", newEvt.PS.SID) + assert.Len(t, newEvt.PS.Envs, 2) + assert.Len(t, newEvt.PS.Handles, 3) - assert.NotNil(t, newKevt.PS.PE) - assert.Equal(t, "explorer.exe", newKevt.PS.Parent.Name) - assert.Equal(t, uint32(10), newKevt.PS.PE.NumberOfSymbols) - assert.Equal(t, uint16(2), newKevt.PS.PE.NumberOfSections) - assert.Len(t, newKevt.PS.PE.Sections, 2) - assert.Len(t, newKevt.PS.PE.Symbols, 5) - assert.Len(t, newKevt.PS.PE.Imports, 4) - assert.Len(t, newKevt.PS.PE.VersionResources, 3) + assert.NotNil(t, newEvt.PS.PE) + assert.Equal(t, "explorer.exe", newEvt.PS.Parent.Name) + assert.Equal(t, uint32(10), newEvt.PS.PE.NumberOfSymbols) + assert.Equal(t, uint16(2), newEvt.PS.PE.NumberOfSections) + assert.Len(t, newEvt.PS.PE.Sections, 2) + assert.Len(t, newEvt.PS.PE.Symbols, 5) + assert.Len(t, newEvt.PS.PE.Imports, 4) + assert.Len(t, newEvt.PS.PE.VersionResources, 3) } func TestUnmarshalHugeHandles(t *testing.T) { @@ -223,24 +223,24 @@ func TestUnmarshalHugeHandles(t *testing.T) { err = json.Unmarshal(b, &handles) require.NoError(t, err) - kevt := &Kevent{ - Type: ktypes.CreateProcess, + evt := &Event{ + Type: CreateProcess, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateProcess", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates a new process", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -276,8 +276,8 @@ func TestUnmarshalHugeHandles(t *testing.T) { }, } - s := kevt.MarshalRaw() - clone, err := NewFromKcap(s, kcapver.KevtSecV2) + s := evt.MarshalRaw() + clone, err := NewFromCapture(s, capver.EvtSecV2) require.NoError(t, err) require.NotNil(t, clone) } @@ -285,24 +285,24 @@ func TestUnmarshalHugeHandles(t *testing.T) { func TestKeventMarshalJSONMultiple(t *testing.T) { for i := 0; i < 10; i++ { seq := uint64(i + 1) - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: seq, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -352,8 +352,8 @@ func TestKeventMarshalJSONMultiple(t *testing.T) { }, }, } - s := kevt.MarshalJSON() - var newKevt Kevent + s := evt.MarshalJSON() + var newKevt Event err := json.Unmarshal(s, &newKevt) require.NoError(t, err) @@ -365,24 +365,24 @@ func TestKeventMarshalJSONMultiple(t *testing.T) { } func BenchmarkKeventMarshalJSON(b *testing.B) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -444,29 +444,29 @@ func BenchmarkKeventMarshalJSON(b *testing.B) { } b.ReportAllocs() for i := 0; i < b.N; i++ { - kevt.MarshalJSON() + evt.MarshalJSON() } } func BenchmarkKeventMarshalJSONStdlib(b *testing.B) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ @@ -528,64 +528,64 @@ func BenchmarkKeventMarshalJSONStdlib(b *testing.B) { } b.ReportAllocs() for i := 0; i < b.N; i++ { - if _, err := json.Marshal(kevt); err != nil { + if _, err := json.Marshal(evt); err != nil { b.Fatal(err) } } } func BenchmarkMarshal(b *testing.B) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "barz"}, } b.ReportAllocs() for i := 0; i < b.N; i++ { - if buf := kevt.MarshalRaw(); len(buf) == 0 { + if buf := evt.MarshalRaw(); len(buf) == 0 { b.Fatal("empty buffer") } } } func BenchmarkUnmarshal(b *testing.B) { - kevt := &Kevent{ - Type: ktypes.CreateFile, + evt := &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, }, Metadata: map[MetadataKey]any{"foo": "bar", "fooz": "barz"}, } - buf := kevt.MarshalRaw() + buf := evt.MarshalRaw() b.ReportAllocs() for i := 0; i < b.N; i++ { - ke, err := NewFromKcap(buf, kcapver.KevtSecV2) + ke, err := NewFromCapture(buf, capver.EvtSecV2) if err != nil { b.Fatal(err) } diff --git a/pkg/kevent/marshaller_windows.go b/pkg/event/marshaller_windows.go similarity index 74% rename from pkg/kevent/marshaller_windows.go rename to pkg/event/marshaller_windows.go index 378f9335d..5566f9329 100644 --- a/pkg/kevent/marshaller_windows.go +++ b/pkg/event/marshaller_windows.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "expvar" @@ -29,33 +29,32 @@ import ( "time" "unsafe" - "github.com/rabbitstack/fibratus/pkg/kcap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/cap/section" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" + "github.com/rabbitstack/fibratus/pkg/event/params" ptypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/bytes" "github.com/rabbitstack/fibratus/pkg/util/ip" ) var ( - // SerializeHandles indicates if handles are serialized as part of the process' state + // SerializeHandles indicates if handles are serialized as part of the process state SerializeHandles bool - // SerializeThreads indicates if threads are serialized as part of the process' state + // SerializeThreads indicates if threads are serialized as part of the process state SerializeThreads bool - // SerializeImages indicates if images are serialized as part of the process' state + // SerializeImages indicates if images are serialized as part of the process state SerializeImages bool - // SerializePE indicates if PE metadata are serialized as part of the process' state + // SerializePE indicates if PE metadata are serialized as part of the process state SerializePE bool - // SerializeEnvs indicates if the environment variables are serialized as part of the process's state + // SerializeEnvs indicates if the environment variables are serialized as part of the process state SerializeEnvs bool ) // unmarshalTimestampErrors counts timestamp unmarshal errors -var unmarshalTimestampErrors = expvar.NewInt("kevent.timestamp.unmarshal.errors") +var unmarshalTimestampErrors = expvar.NewInt("event.timestamp.unmarshal.errors") // MarshalRaw produces a byte stream of the kernel event suitable for writing to disk. -func (e *Kevent) MarshalRaw() []byte { +func (e *Event) MarshalRaw() []byte { b := make([]byte, 0) // write seq, pid, tid fields @@ -90,56 +89,56 @@ func (e *Kevent) MarshalRaw() []byte { b = append(b, timestamp...) // write the number of event parameters followed by each parameter - b = append(b, bytes.WriteUint16(uint16(len(e.Kparams)))...) - for _, kpar := range e.Kparams { + b = append(b, bytes.WriteUint16(uint16(len(e.Params)))...) + for _, par := range e.Params { // append the type, parameter size and name - b = append(b, bytes.WriteUint16(uint16(kpar.KcapType()))...) - b = append(b, bytes.WriteUint16(uint16(len(kpar.Name)))...) - b = append(b, kpar.Name...) - switch kpar.Type { - case kparams.AnsiString, kparams.UnicodeString: - b = append(b, bytes.WriteUint16(uint16(len(kpar.Value.(string))))...) - b = append(b, kpar.Value.(string)...) - case kparams.Key, kparams.Path, kparams.DOSPath, kparams.HandleType: - v := e.GetParamAsString(kpar.Name) + b = append(b, bytes.WriteUint16(uint16(par.CaptureType()))...) + b = append(b, bytes.WriteUint16(uint16(len(par.Name)))...) + b = append(b, par.Name...) + switch par.Type { + case params.AnsiString, params.UnicodeString: + b = append(b, bytes.WriteUint16(uint16(len(par.Value.(string))))...) + b = append(b, par.Value.(string)...) + case params.Key, params.Path, params.DOSPath, params.HandleType: + v := e.GetParamAsString(par.Name) b = append(b, bytes.WriteUint16(uint16(len(v)))...) b = append(b, v...) - case kparams.Uint8: - b = append(b, kpar.Value.(uint8)) - case kparams.Int8: - b = append(b, byte(kpar.Value.(int8))) - case kparams.Uint16, kparams.Port: - b = append(b, bytes.WriteUint16(kpar.Value.(uint16))...) - case kparams.Int16: - b = append(b, bytes.WriteUint16(uint16(kpar.Value.(int16)))...) - case kparams.Uint32, kparams.Status, kparams.Enum, kparams.Flags: - b = append(b, bytes.WriteUint32(kpar.Value.(uint32))...) - case kparams.Int32: - b = append(b, bytes.WriteUint32(uint32(kpar.Value.(int32)))...) - case kparams.Uint64, kparams.Address, kparams.Flags64: - b = append(b, bytes.WriteUint64(kpar.Value.(uint64))...) - case kparams.Int64: - b = append(b, bytes.WriteUint64(uint64(kpar.Value.(int64)))...) - case kparams.Double: - b = append(b, bytes.WriteUint32(math.Float32bits(kpar.Value.(float32)))...) - case kparams.Float: - b = append(b, bytes.WriteUint64(math.Float64bits(kpar.Value.(float64)))...) - case kparams.IPv4: - b = append(b, kpar.Value.(net.IP).To4()...) - case kparams.IPv6: - b = append(b, kpar.Value.(net.IP).To16()...) - case kparams.PID, kparams.TID: - b = append(b, bytes.WriteUint32(kpar.Value.(uint32))...) - case kparams.Bool: - b = append(b, convert.Btoi(kpar.Value.(bool))) - case kparams.Time: - v := kpar.Value.(time.Time) + case params.Uint8: + b = append(b, par.Value.(uint8)) + case params.Int8: + b = append(b, byte(par.Value.(int8))) + case params.Uint16, params.Port: + b = append(b, bytes.WriteUint16(par.Value.(uint16))...) + case params.Int16: + b = append(b, bytes.WriteUint16(uint16(par.Value.(int16)))...) + case params.Uint32, params.Status, params.Enum, params.Flags: + b = append(b, bytes.WriteUint32(par.Value.(uint32))...) + case params.Int32: + b = append(b, bytes.WriteUint32(uint32(par.Value.(int32)))...) + case params.Uint64, params.Address, params.Flags64: + b = append(b, bytes.WriteUint64(par.Value.(uint64))...) + case params.Int64: + b = append(b, bytes.WriteUint64(uint64(par.Value.(int64)))...) + case params.Double: + b = append(b, bytes.WriteUint32(math.Float32bits(par.Value.(float32)))...) + case params.Float: + b = append(b, bytes.WriteUint64(math.Float64bits(par.Value.(float64)))...) + case params.IPv4: + b = append(b, par.Value.(net.IP).To4()...) + case params.IPv6: + b = append(b, par.Value.(net.IP).To16()...) + case params.PID, params.TID: + b = append(b, bytes.WriteUint32(par.Value.(uint32))...) + case params.Bool: + b = append(b, convert.Btoi(par.Value.(bool))) + case params.Time: + v := par.Value.(time.Time) ts := make([]byte, 0) ts = v.AppendFormat(ts, time.RFC3339Nano) b = append(b, bytes.WriteUint16(uint16(len(ts)))...) b = append(b, ts...) - case kparams.Slice: - switch slice := kpar.Value.(type) { + case params.Slice: + switch slice := par.Value.(type) { case []string: // append the type for slice elements b = append(b, uint8('s')) @@ -156,9 +155,9 @@ func (e *Kevent) MarshalRaw() []byte { b = append(b, bytes.WriteUint64(v.Uint64())...) } } - case kparams.Binary, kparams.SID, kparams.WbemSID: - b = append(b, bytes.WriteUint32(uint32(len(kpar.Value.([]byte))))...) - b = append(b, kpar.Value.([]byte)...) + case params.Binary, params.SID, params.WbemSID: + b = append(b, bytes.WriteUint32(uint32(len(par.Value.([]byte))))...) + b = append(b, par.Value.([]byte)...) } } @@ -175,11 +174,11 @@ func (e *Kevent) MarshalRaw() []byte { // write process state if e.PS != nil && (e.IsCreateProcess() || e.IsProcessRundown()) { buf := e.PS.Marshal() - sec := section.New(section.Process, kcapver.ProcessSecV4, 0, uint32(len(buf))) + sec := section.New(section.Process, capver.ProcessSecV4, 0, uint32(len(buf))) b = append(b, sec[:]...) b = append(b, buf...) } else { - sec := section.New(section.Process, kcapver.ProcessSecV4, 0, 0) + sec := section.New(section.Process, capver.ProcessSecV4, 0, 0) b = append(b, sec[:]...) } @@ -191,7 +190,7 @@ func inc(idx, inc uint32) uint32 { } // UnmarshalRaw recovers the state of the kernel event from the byte stream. -func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { +func (e *Event) UnmarshalRaw(b []byte, ver capver.Version) error { if len(b) < 34 { return fmt.Errorf("expected at least 34 bytes but got %d bytes", len(b)) } @@ -202,18 +201,18 @@ func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { e.Tid = bytes.ReadUint32(b[12:]) // read type and CPU - var ktype ktypes.Ktype + var typ Type // set start index depending // on event section version var idx uint32 switch ver { - case kcapver.KevtSecV1: + case capver.EvtSecV1: idx = 33 - case kcapver.KevtSecV2: + case capver.EvtSecV2: idx = 34 } - copy(ktype[:], b[16:idx]) - e.Type = ktype + copy(typ[:], b[16:idx]) + e.Type = typ e.CPU = b[idx : idx+1][0] idx++ // increment index @@ -229,7 +228,7 @@ func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { l = bytes.ReadUint16(b[inc(idx, 2)+offset:]) buf = b[inc(idx, 4)+offset:] offset += uint32(l) - e.Category = ktypes.Category(string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l])) + e.Category = Category(string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l])) // read description l = bytes.ReadUint16(b[inc(idx, 4)+offset:]) @@ -261,91 +260,91 @@ func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { var poffset uint32 for i := 0; i < int(nparams); i++ { - // read kparam type + // read Param type typ := bytes.ReadUint16(b[inc(idx, 12)+offset+poffset:]) - // read kparam name + // read Param name kparamNameLength := uint32(bytes.ReadUint16(b[inc(idx, 14)+offset+poffset:])) buf = b[inc(idx, 16)+offset+poffset:] kparamName := string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:kparamNameLength:kparamNameLength]) pi := inc(idx, 16) // parameter index - var kval kparams.Value - switch kparams.Type(typ) { - case kparams.AnsiString, kparams.UnicodeString, kparams.Path: + var val params.Value + switch params.Type(typ) { + case params.AnsiString, params.UnicodeString, params.Path: // read string parameter l := bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:]) buf = b[inc(idx, 18)+offset+kparamNameLength+poffset:] if len(buf) > 0 { - kval = string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l]) + val = string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l]) } // increment parameter offset by string by type length + name length bytes + length of // the string parameter + string parameter size poffset += kparamNameLength + 6 + uint32(l) - case kparams.Uint64, kparams.Address, kparams.Flags64: - kval = bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:]) + case params.Uint64, params.Address, params.Flags64: + val = bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:]) // increment parameter offset by type length + name length sizes + size of uint64 poffset += kparamNameLength + 4 + 8 - case kparams.Int64: - kval = int64(bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:])) + case params.Int64: + val = int64(bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:])) // increment parameter offset by type length + name length sizes + size of int64 poffset += kparamNameLength + 4 + 8 - case kparams.Double: - kval = float64(bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:])) + case params.Double: + val = float64(bytes.ReadUint64(b[pi+offset+kparamNameLength+poffset:])) poffset += kparamNameLength + 4 + 8 - case kparams.Float: - kval = float32(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) + case params.Float: + val = float32(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) poffset += kparamNameLength + 4 + 4 - case kparams.IPv4: - kval = ip.ToIPv4(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) + case params.IPv4: + val = ip.ToIPv4(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) // // increment by IPv4 length poffset += kparamNameLength + 4 + 4 - case kparams.IPv6: - kval = ip.ToIPv6(b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+16]) + case params.IPv6: + val = ip.ToIPv6(b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+16]) // increment by IPv6 length poffset += kparamNameLength + 4 + 16 - case kparams.PID, kparams.TID: - kval = bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:]) + case params.PID, params.TID: + val = bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:]) poffset += kparamNameLength + 4 + 4 - case kparams.Int32: - kval = int32(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) + case params.Int32: + val = int32(bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:])) poffset += kparamNameLength + 4 + 4 - case kparams.Uint32, kparams.Enum, kparams.Flags, kparams.Status: - kval = bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:]) + case params.Uint32, params.Enum, params.Flags, params.Status: + val = bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:]) poffset += kparamNameLength + 4 + 4 - case kparams.Uint16, kparams.Port: - kval = bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:]) + case params.Uint16, params.Port: + val = bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:]) poffset += kparamNameLength + 4 + 2 - case kparams.Int16: - kval = int16(bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:])) + case params.Int16: + val = int16(bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:])) poffset += kparamNameLength + 4 + 2 - case kparams.Uint8: - kval = b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+1][0] + case params.Uint8: + val = b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+1][0] poffset += kparamNameLength + 4 + 1 - case kparams.Int8: - kval = int8(b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+1][0]) + case params.Int8: + val = int8(b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+1][0]) poffset += kparamNameLength + 4 + 1 - case kparams.Bool: + case params.Bool: v := b[pi+offset+kparamNameLength+poffset : pi+offset+kparamNameLength+poffset+1][0] if v == 1 { - kval = true + val = true } else { - kval = false + val = false } poffset += kparamNameLength + 4 + 1 - case kparams.Time: + case params.Time: // read ts length l := bytes.ReadUint16(b[pi+offset+kparamNameLength+poffset:]) buf = b[inc(idx, 18)+offset+kparamNameLength+poffset:] if len(buf) > 0 { var err error - kval, err = time.Parse(time.RFC3339Nano, string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l])) + val, err = time.Parse(time.RFC3339Nano, string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l])) if err != nil { unmarshalTimestampErrors.Add(1) } } poffset += kparamNameLength + 6 + uint32(l) - case kparams.Slice: + case params.Slice: // read slice element type typ := b[pi+offset+kparamNameLength+poffset] // read slice size @@ -360,27 +359,27 @@ func (e *Kevent) UnmarshalRaw(b []byte, ver kcapver.Version) error { s[i] = string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:size:size]) off += 2 + uint32(size) } - kval = s + val = s case '8': v := make([]uint64, l) for i := 0; i < int(l); i++ { bytes.ReadUint64(b[inc(idx, 22)+offset+kparamNameLength+poffset+off:]) off += 8 } - kval = v + val = v } poffset += kparamNameLength + 4 + 1 + 2 + off - case kparams.Binary, kparams.SID, kparams.WbemSID: + case params.Binary, params.SID, params.WbemSID: l := bytes.ReadUint32(b[pi+offset+kparamNameLength+poffset:]) buf = b[inc(idx, 18)+offset+kparamNameLength+poffset:] if len(buf) > 0 { - kval = buf[:l] + val = buf[:l] } poffset += kparamNameLength + 8 + l } - if kval != nil { - e.Kparams.AppendFromKcap(kparamName, kparams.Type(typ), kval, e.Type) + if val != nil { + e.Params.AppendFromCapture(kparamName, params.Type(typ), val, e.Type) } } @@ -427,8 +426,8 @@ func writePsResources() bool { return SerializeHandles || SerializeThreads || SerializeImages || SerializePE } -// MarshalJSON produces a JSON payload for this kevent. -func (e *Kevent) MarshalJSON() []byte { +// MarshalJSON produces a JSON payload for this event. +func (e *Event) MarshalJSON() []byte { if e == nil { return []byte{} } @@ -450,50 +449,50 @@ func (e *Kevent) MarshalJSON() []byte { timestamp = e.Timestamp.AppendFormat(timestamp, time.RFC3339Nano) js.writeObjectField("timestamp").writeString(string(timestamp)).writeMore() - // start kparams - js.writeObjectField("kparams") + // start params + js.writeObjectField("params") js.writeObjectStart() - pars := make([]*Kparam, 0, len(e.Kparams)) - for _, kpar := range e.Kparams { - pars = append(pars, kpar) + pars := make([]*Param, 0, len(e.Params)) + for _, par := range e.Params { + pars = append(pars, par) } sort.Slice(pars, func(i, j int) bool { return pars[i].Name < pars[j].Name }) - for i, kpar := range pars { + for i, par := range pars { writeMore := js.shouldWriteMore(i, len(pars)) - js.writeObjectField(kpar.Name) - switch kpar.Type { - case kparams.Int64: - js.writeInt64(kpar.Value.(int64)) - case kparams.Uint64: - js.writeUint64(kpar.Value.(uint64)) - case kparams.Int32: - js.writeInt32(kpar.Value.(int32)) - case kparams.Uint32: - js.writeUint32(kpar.Value.(uint32)) - case kparams.Int16: - js.writeInt16(kpar.Value.(int16)) - case kparams.Uint16, kparams.Port: - js.writeUint16(kpar.Value.(uint16)) - case kparams.Int8: - js.writeInt8(kpar.Value.(int8)) - case kparams.Uint8: - js.writeUint8(kpar.Value.(uint8)) - case kparams.Float: - js.writeFloat32(kpar.Value.(float32)) - case kparams.Double: - js.writeFloat64(kpar.Value.(float64)) - case kparams.PID, kparams.TID: - js.writeUint32(kpar.Value.(uint32)) - case kparams.IPv4, kparams.IPv6: - js.writeString(kpar.Value.(net.IP).String()) - case kparams.Bool: - js.writeBool(kpar.Value.(bool)) - case kparams.Time: - js.writeString(kpar.Value.(time.Time).String()) - case kparams.Slice: - switch slice := kpar.Value.(type) { + js.writeObjectField(par.Name) + switch par.Type { + case params.Int64: + js.writeInt64(par.Value.(int64)) + case params.Uint64: + js.writeUint64(par.Value.(uint64)) + case params.Int32: + js.writeInt32(par.Value.(int32)) + case params.Uint32: + js.writeUint32(par.Value.(uint32)) + case params.Int16: + js.writeInt16(par.Value.(int16)) + case params.Uint16, params.Port: + js.writeUint16(par.Value.(uint16)) + case params.Int8: + js.writeInt8(par.Value.(int8)) + case params.Uint8: + js.writeUint8(par.Value.(uint8)) + case params.Float: + js.writeFloat32(par.Value.(float32)) + case params.Double: + js.writeFloat64(par.Value.(float64)) + case params.PID, params.TID: + js.writeUint32(par.Value.(uint32)) + case params.IPv4, params.IPv6: + js.writeString(par.Value.(net.IP).String()) + case params.Bool: + js.writeBool(par.Value.(bool)) + case params.Time: + js.writeString(par.Value.(time.Time).String()) + case params.Slice: + switch slice := par.Value.(type) { case []string: js.writeArrayStart() for i, s := range slice { @@ -506,13 +505,13 @@ func (e *Kevent) MarshalJSON() []byte { js.writeArrayEnd() } default: - js.writeEscapeString(e.GetParamAsString(kpar.Name)) + js.writeEscapeString(e.GetParamAsString(par.Name)) } if writeMore { js.writeMore() } } - // end kparams + // end params js.writeObjectEnd().writeMore() // start metadata diff --git a/pkg/kevent/ktypes/metainfo_windows.go b/pkg/event/metainfo_windows.go similarity index 74% rename from pkg/kevent/ktypes/metainfo_windows.go rename to pkg/event/metainfo_windows.go index db2c7cc22..a052be00c 100644 --- a/pkg/kevent/ktypes/metainfo_windows.go +++ b/pkg/event/metainfo_windows.go @@ -16,16 +16,15 @@ * limitations under the License. */ -package ktypes +package event import ( "cmp" "slices" ) -// KeventInfo describes the kernel event meta info such as human-readable name, category -// and event's description. -type KeventInfo struct { +// Info describes the event meta info such as human-readable name, category and description. +type Info struct { // Name is the human-readable representation of the event (e.g. CreateProcess, DeleteFile). Name string // Category designates the category to which event pertains. (e.g. process, net) @@ -34,7 +33,7 @@ type KeventInfo struct { Description string } -var kevents = map[Ktype]KeventInfo{ +var events = map[Type]Info{ CreateProcess: {"CreateProcess", Process, "Creates a new process and its primary thread"}, TerminateProcess: {"TerminateProcess", Process, "Terminates the process and all of its threads"}, OpenProcess: {"OpenProcess", Process, "Opens the process handle"}, @@ -93,7 +92,7 @@ var kevents = map[Ktype]KeventInfo{ SetThreadpoolTimer: {"SetThreadpoolTimer", Threadpool, "Sets the thread pool timer object"}, } -var ktypes = map[string]Ktype{ +var types = map[string]Type{ "CreateProcess": CreateProcess, "TerminateProcess": TerminateProcess, "OpenProcess": OpenProcess, @@ -152,135 +151,135 @@ var ktypes = map[string]Ktype{ "SetThreadpoolTimer": SetThreadpoolTimer, } -// indexedKevents keeps the slice of event infos. When the +// indexedEvents keeps the slice of event infos. When the // new event type is added, MAKE SURE TO ADD the event info // at the END of the slice. This way the event index is guaranteed // to remain static which is important for eventlog message identifiers. -var indexedKevents = []KeventInfo{ - kevents[CreateProcess], - kevents[TerminateProcess], - kevents[OpenProcess], - kevents[CreateThread], - kevents[TerminateThread], - kevents[OpenThread], - kevents[SetThreadContext], - kevents[LoadImage], - kevents[UnloadImage], - kevents[CreateFile], - kevents[CloseFile], - kevents[ReadFile], - kevents[WriteFile], - kevents[SetFileInformation], - kevents[DeleteFile], - kevents[RenameFile], - kevents[EnumDirectory], - kevents[RegCreateKey], - kevents[RegOpenKey], - kevents[RegSetValue], - kevents[RegQueryValue], - kevents[RegQueryKey], - kevents[RegDeleteKey], - kevents[RegDeleteValue], - kevents[AcceptTCPv4], - kevents[AcceptTCPv6], - kevents[SendTCPv4], - kevents[SendTCPv6], - kevents[SendUDPv4], - kevents[SendUDPv6], - kevents[RecvTCPv4], - kevents[RecvTCPv6], - kevents[RecvUDPv4], - kevents[RecvUDPv6], - kevents[ConnectTCPv4], - kevents[ConnectTCPv6], - kevents[ReconnectTCPv4], - kevents[ReconnectTCPv6], - kevents[DisconnectTCPv4], - kevents[DisconnectTCPv6], - kevents[RetransmitTCPv4], - kevents[RetransmitTCPv6], - kevents[CreateHandle], - kevents[CloseHandle], - kevents[DuplicateHandle], - kevents[VirtualAlloc], - kevents[VirtualFree], - kevents[MapViewFile], - kevents[UnmapViewFile], - kevents[QueryDNS], - kevents[ReplyDNS], - kevents[CreateSymbolicLinkObject], - kevents[SubmitThreadpoolWork], - kevents[SubmitThreadpoolCallback], - kevents[SetThreadpoolTimer], +var indexedEvents = []Info{ + events[CreateProcess], + events[TerminateProcess], + events[OpenProcess], + events[CreateThread], + events[TerminateThread], + events[OpenThread], + events[SetThreadContext], + events[LoadImage], + events[UnloadImage], + events[CreateFile], + events[CloseFile], + events[ReadFile], + events[WriteFile], + events[SetFileInformation], + events[DeleteFile], + events[RenameFile], + events[EnumDirectory], + events[RegCreateKey], + events[RegOpenKey], + events[RegSetValue], + events[RegQueryValue], + events[RegQueryKey], + events[RegDeleteKey], + events[RegDeleteValue], + events[AcceptTCPv4], + events[AcceptTCPv6], + events[SendTCPv4], + events[SendTCPv6], + events[SendUDPv4], + events[SendUDPv6], + events[RecvTCPv4], + events[RecvTCPv6], + events[RecvUDPv4], + events[RecvUDPv6], + events[ConnectTCPv4], + events[ConnectTCPv6], + events[ReconnectTCPv4], + events[ReconnectTCPv6], + events[DisconnectTCPv4], + events[DisconnectTCPv6], + events[RetransmitTCPv4], + events[RetransmitTCPv6], + events[CreateHandle], + events[CloseHandle], + events[DuplicateHandle], + events[VirtualAlloc], + events[VirtualFree], + events[MapViewFile], + events[UnmapViewFile], + events[QueryDNS], + events[ReplyDNS], + events[CreateSymbolicLinkObject], + events[SubmitThreadpoolWork], + events[SubmitThreadpoolCallback], + events[SetThreadpoolTimer], } // All returns all event types. -func All() []Ktype { - s := make([]Ktype, 0, len(ktypes)) - for _, ktype := range ktypes { - s = append(s, ktype) +func All() []Type { + s := make([]Type, 0, len(types)) + for _, Type := range types { + s = append(s, Type) } return s } -// KtypeToKeventInfo maps the event type to the structure storing detailed information about the event. -func KtypeToKeventInfo(ktype Ktype) KeventInfo { - if kinfo, ok := kevents[ktype]; ok { - return kinfo +// TypeToEventInfo maps the event type to the structure storing detailed information about the event. +func TypeToEventInfo(typ Type) Info { + if info, ok := events[typ]; ok { + return info } - return KeventInfo{Name: "N/A", Category: Unknown} + return Info{Name: "N/A", Category: Unknown} } -// KeventNameToKtype converts a human-readable event name to its internal type representation. -func KeventNameToKtype(name string) Ktype { - if ktype, ok := ktypes[name]; ok { - return ktype +// NameToType converts a human-readable event name to its internal type representation. +func NameToType(name string) Type { + if typ, ok := types[name]; ok { + return typ } - return UnknownKtype + return UnknownType } -// KeventNameToKtypes maps the event name to internal type representations, specifically, network -// events that have multiple internal types for a single event name. For example, Accept event name -// have AcceptTCP4 and AcceptTCP6 types. -func KeventNameToKtypes(name string) []Ktype { +// NameToTypes maps the event name to internal type representations, specifically, network +// events that have multiple internal types for a single event name. For example, the Accept +// event name has AcceptTCP4 and AcceptTCP6 types. +func NameToTypes(name string) []Type { switch name { case "Accept": - return []Ktype{AcceptTCPv4, AcceptTCPv6} + return []Type{AcceptTCPv4, AcceptTCPv6} case "Send": - return []Ktype{SendTCPv4, SendTCPv6, SendUDPv4, SendUDPv6} + return []Type{SendTCPv4, SendTCPv6, SendUDPv4, SendUDPv6} case "Recv": - return []Ktype{RecvTCPv4, RecvTCPv6, RecvUDPv4, RecvUDPv6} + return []Type{RecvTCPv4, RecvTCPv6, RecvUDPv4, RecvUDPv6} case "Connect": - return []Ktype{ConnectTCPv4, ConnectTCPv6} + return []Type{ConnectTCPv4, ConnectTCPv6} case "Reconnect": - return []Ktype{ReconnectTCPv4, ReconnectTCPv6} + return []Type{ReconnectTCPv4, ReconnectTCPv6} case "Disconnect": - return []Ktype{DisconnectTCPv4, DisconnectTCPv6} + return []Type{DisconnectTCPv4, DisconnectTCPv6} case "Retransmit": - return []Ktype{RetransmitTCPv4, RetransmitTCPv6} + return []Type{RetransmitTCPv4, RetransmitTCPv6} default: - return []Ktype{KeventNameToKtype(name)} + return []Type{NameToType(name)} } } -// GetKtypesMeta returns event types metadata. -func GetKtypesMeta() []KeventInfo { - ktypes := make([]KeventInfo, 0) +// GetTypesMeta returns event types metadata. +func GetTypesMeta() []Info { + typs := make([]Info, 0) outer: - for _, ktyp := range kevents { - for _, typ := range ktypes { - if typ.Name == ktyp.Name { + for _, ev := range events { + for _, typ := range typs { + if typ.Name == ev.Name { continue outer } } - ktypes = append(ktypes, ktyp) + typs = append(typs, ev) } - slices.SortFunc(ktypes, func(a, b KeventInfo) int { + slices.SortFunc(typs, func(a, b Info) int { return cmp.Or(cmp.Compare(a.Category, b.Category), cmp.Compare(a.Name, b.Name)) }) - return ktypes + return typs } -// GetKtypesMetaIndexed returns indexed event types metadata +// GetTypesMetaIndexed returns indexed event types metadata // that is guaranteed to always return the same event indices. -func GetKtypesMetaIndexed() []KeventInfo { return indexedKevents } +func GetTypesMetaIndexed() []Info { return indexedEvents } diff --git a/pkg/kevent/ktypes/metainfo_windows_test.go b/pkg/event/metainfo_windows_test.go similarity index 57% rename from pkg/kevent/ktypes/metainfo_windows_test.go rename to pkg/event/metainfo_windows_test.go index 7750174fa..e23be0d5c 100644 --- a/pkg/kevent/ktypes/metainfo_windows_test.go +++ b/pkg/event/metainfo_windows_test.go @@ -16,31 +16,31 @@ * limitations under the License. */ -package ktypes +package event import ( "github.com/stretchr/testify/assert" "testing" ) -func TestKeventNameToKtype(t *testing.T) { - ktype := KeventNameToKtype("CreateProcess") +func TestEventNameToType(t *testing.T) { + typ := NameToType("CreateProcess") - assert.Equal(t, CreateProcess, ktype) + assert.Equal(t, CreateProcess, typ) - ktype = KeventNameToKtype("CreateRemoteThread") - assert.Equal(t, UnknownKtype, ktype) + typ = NameToType("CreateRemoteThread") + assert.Equal(t, UnknownType, typ) } -func TestKtypeToKeventInfo(t *testing.T) { - kinfo := KtypeToKeventInfo(CreateProcess) +func TestEventToEventInfo(t *testing.T) { + info := TypeToEventInfo(CreateProcess) - assert.Equal(t, "CreateProcess", kinfo.Name) - assert.Equal(t, Process, kinfo.Category) - assert.Equal(t, "Creates a new process and its primary thread", kinfo.Description) + assert.Equal(t, "CreateProcess", info.Name) + assert.Equal(t, Process, info.Category) + assert.Equal(t, "Creates a new process and its primary thread", info.Description) - kinfo = KtypeToKeventInfo(UnknownKtype) - assert.Equal(t, "N/A", kinfo.Name) - assert.Equal(t, Unknown, kinfo.Category) - assert.Empty(t, kinfo.Description) + info = TypeToEventInfo(UnknownType) + assert.Equal(t, "N/A", info.Name) + assert.Equal(t, Unknown, info.Category) + assert.Empty(t, info.Description) } diff --git a/pkg/kevent/kparam.go b/pkg/event/param.go similarity index 61% rename from pkg/kevent/kparam.go rename to pkg/event/param.go index 147d0e15a..62e5209c2 100644 --- a/pkg/kevent/kparam.go +++ b/pkg/event/param.go @@ -16,12 +16,11 @@ * limitations under the License. */ -package kevent +package event import ( "fmt" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/network" "github.com/rabbitstack/fibratus/pkg/util/key" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -33,8 +32,8 @@ import ( "strings" "time" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/errors" + "github.com/rabbitstack/fibratus/pkg/event/params" ) var caser = cases.Title(language.English) @@ -53,7 +52,7 @@ const ( CamelCase ParamCaseStyle = 4 ) -// ParamNameCaseStyle designates the case style for kernel parameter names +// ParamNameCaseStyle designates the case style for the parameter names var ParamNameCaseStyle = SnakeCase // ParamKVDelimiter specifies the character that delimits parameter's key from its value @@ -85,13 +84,13 @@ func WithEnum(enum ParamEnum) ParamOption { } } -// Kparam defines the layout of the kernel event parameter. -type Kparam struct { +// Param defines the layout of the event parameter. +type Param struct { // Type is the type of the parameter. For example, `sport` parameter has the `Port` type although its value // is the uint16 numeric type. - Type kparams.Type `json:"-"` + Type params.Type `json:"-"` // Value is the container for parameter values. To access the underlying value use the appropriate `Get` methods. - Value kparams.Value `json:"value"` + Value params.Value `json:"value"` // Name represents the name of the parameter (e.g. pid, sport). Name string `json:"name"` // Flags represents parameter flags @@ -100,149 +99,149 @@ type Kparam struct { Enum ParamEnum `json:"enum"` } -// KcapType returns the event type saved inside the capture file. +// CaptureType returns the event type saved inside the capture file. // Captures usually override the type of the parameter to provide // consistent replay experience. For example, the file path param // type is converted to string param type, as drive mapping is performed // on the target where the capture is being taken. -func (k Kparam) KcapType() kparams.Type { - switch k.Type { - case kparams.HandleType, kparams.DOSPath, kparams.Key: - return kparams.UnicodeString +func (p Param) CaptureType() params.Type { + switch p.Type { + case params.HandleType, params.DOSPath, params.Key: + return params.UnicodeString default: - return k.Type + return p.Type } } -// Kparams is the type that represents the sequence of kernel event parameters -type Kparams map[string]*Kparam +// Params is the type that represents the sequence of event parameters +type Params map[string]*Param -// NewKparamFromKcap builds a kparam instance from the restored state. -func NewKparamFromKcap(name string, typ kparams.Type, value kparams.Value, ktype ktypes.Ktype) *Kparam { +// NewParamFromCapture builds a parameter instance from the restored capture state. +func NewParamFromCapture(name string, typ params.Type, value params.Value, etype Type) *Param { var enum ParamEnum var flags ParamFlags switch name { - case kparams.FileOperation: + case params.FileOperation: enum = fs.FileCreateDispositions - case kparams.FileCreateOptions: + case params.FileCreateOptions: flags = FileCreateOptionsFlags - case kparams.FileAttributes: + case params.FileAttributes: flags = FileAttributeFlags - case kparams.FileShareMask: + case params.FileShareMask: flags = FileShareModeFlags - case kparams.FileInfoClass: + case params.FileInfoClass: enum = fs.FileInfoClasses - case kparams.FileType: + case params.FileType: enum = fs.FileTypes - case kparams.NetL4Proto: + case params.NetL4Proto: enum = network.ProtoNames - case kparams.RegValueType: + case params.RegValueType: enum = key.RegistryValueTypes - case kparams.MemAllocType: + case params.MemAllocType: flags = MemAllocationFlags - case kparams.FileViewSectionType: + case params.FileViewSectionType: enum = ViewSectionTypes - case kparams.DNSOpts: + case params.DNSOpts: flags = DNSOptsFlags - case kparams.DNSRR: + case params.DNSRR: enum = DNSRecordTypes - case kparams.DNSRcode: + case params.DNSRcode: enum = DNSResponseCodes - case kparams.DesiredAccess: - if ktype == ktypes.OpenProcess { + case params.DesiredAccess: + if etype == OpenProcess { flags = PsAccessRightFlags } else { flags = ThreadAccessRightFlags } - case kparams.MemProtect: - if ktype == ktypes.VirtualAlloc || ktype == ktypes.VirtualFree { + case params.MemProtect: + if etype == VirtualAlloc || etype == VirtualFree { flags = MemProtectionFlags } else { flags = ViewProtectionFlags } } - return &Kparam{Name: name, Type: typ, Value: value, Enum: enum, Flags: flags} + return &Param{Name: name, Type: typ, Value: value, Enum: enum, Flags: flags} } // Append adds a new parameter with the specified name, type and value. -func (kpars Kparams) Append(name string, typ kparams.Type, value kparams.Value, opts ...ParamOption) Kparams { - kpars[name] = NewKparam(name, typ, value, opts...) - return kpars +func (pars Params) Append(name string, typ params.Type, value params.Value, opts ...ParamOption) Params { + pars[name] = NewParam(name, typ, value, opts...) + return pars } -// AppendFromKcap adds a new parameter with the specified name, type and value from the kcap state. -func (kpars Kparams) AppendFromKcap(name string, typ kparams.Type, value kparams.Value, ktype ktypes.Ktype) Kparams { - kpars[name] = NewKparamFromKcap(name, typ, value, ktype) - return kpars +// AppendFromCapture adds a new parameter with the specified name, type and value from the cap state. +func (pars Params) AppendFromCapture(name string, typ params.Type, value params.Value, etype Type) Params { + pars[name] = NewParamFromCapture(name, typ, value, etype) + return pars } // Contains determines whether the specified parameter name exists. -func (kpars Kparams) Contains(name string) bool { - _, err := kpars.findParam(name) +func (pars Params) Contains(name string) bool { + _, err := pars.findParam(name) return err == nil } // Remove deletes the specified parameter from the map. -func (kpars Kparams) Remove(name string) { - delete(kpars, name) +func (pars Params) Remove(name string) { + delete(pars, name) } // Get returns the event parameter with specified name. -func (kpars Kparams) Get(name string) (*Kparam, error) { - return kpars.findParam(name) +func (pars Params) Get(name string) (*Param, error) { + return pars.findParam(name) } // Len returns the number of parameters. -func (kpars Kparams) Len() int { return len(kpars) } +func (pars Params) Len() int { return len(pars) } // Set replaces the value that is indexed at existing parameter name. It will return an error // if the supplied parameter is not present. -func (kpars Kparams) Set(name string, value kparams.Value, typ kparams.Type) error { - _, err := kpars.findParam(name) +func (pars Params) Set(name string, value params.Value, typ params.Type) error { + _, err := pars.findParam(name) if err != nil { return fmt.Errorf("setting the value on a missing %q parameter is not allowed", name) } - kpars[name] = &Kparam{Name: name, Value: value, Type: typ} + pars[name] = &Param{Name: name, Value: value, Type: typ} return nil } // SetValue replaces the value for the given parameter name. It will return an error // if the supplied parameter is not present in the parameter map. -func (kpars Kparams) SetValue(name string, value kparams.Value) error { - _, err := kpars.findParam(name) +func (pars Params) SetValue(name string, value params.Value) error { + _, err := pars.findParam(name) if err != nil { return fmt.Errorf("setting the value on a missing %q parameter is not allowed", name) } - kpars[name].Value = value + pars[name].Value = value return nil } // GetRaw returns the raw value for given parameter name. It is the responsibility of the caller to probe type assertion // on the value before yielding its underlying type. -func (kpars Kparams) GetRaw(name string) (kparams.Value, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetRaw(name string) (params.Value, error) { + par, err := pars.findParam(name) if err != nil { return "", err } - return kpar.Value, nil + return par.Value, nil } // GetString returns the underlying string value from the parameter. -func (kpars Kparams) GetString(name string) (string, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetString(name string) (string, error) { + par, err := pars.findParam(name) if err != nil { return "", err } - if _, ok := kpar.Value.(string); !ok { + if _, ok := par.Value.(string); !ok { return "", fmt.Errorf("unable to type cast %q parameter to string value", name) } - return kpar.Value.(string), nil + return par.Value.(string), nil } // MustGetString returns the string parameter or panics // if an error occurs while trying to get the parameter. -func (kpars Kparams) MustGetString(name string) string { - s, err := kpars.GetString(name) +func (pars Params) MustGetString(name string) string { + s, err := pars.GetString(name) if err != nil { panic(err) } @@ -250,14 +249,14 @@ func (kpars Kparams) MustGetString(name string) string { } // GetPid returns the pid from the parameter. -func (kpars Kparams) GetPid() (uint32, error) { - return kpars.getPid(kparams.ProcessID) +func (pars Params) GetPid() (uint32, error) { + return pars.getPid(params.ProcessID) } // MustGetPid returns the pid parameter. It panics if // an error occurs while trying to get the pid parameter. -func (kpars Kparams) MustGetPid() uint32 { - pid, err := kpars.GetPid() +func (pars Params) MustGetPid() uint32 { + pid, err := pars.GetPid() if err != nil { panic(err) } @@ -265,29 +264,29 @@ func (kpars Kparams) MustGetPid() uint32 { } // GetPpid returns the parent pid from the parameter. -func (kpars Kparams) GetPpid() (uint32, error) { - return kpars.getPid(kparams.ProcessParentID) +func (pars Params) GetPpid() (uint32, error) { + return pars.getPid(params.ProcessParentID) } // MustGetPpid returns the parent pid parameter. It panics if // an error occurs while trying to get the pid parameter. -func (kpars Kparams) MustGetPpid() uint32 { - ppid, err := kpars.GetPpid() +func (pars Params) MustGetPpid() uint32 { + ppid, err := pars.GetPpid() if err != nil { panic(err) } return ppid } -func (kpars Kparams) getPid(name string) (uint32, error) { - kpar, err := kpars.findParam(name) +func (pars Params) getPid(name string) (uint32, error) { + par, err := pars.findParam(name) if err != nil { return uint32(0), err } - if kpar.Type != kparams.PID { + if par.Type != params.PID { return uint32(0), fmt.Errorf("%q parameter is not a PID", name) } - v, ok := kpar.Value.(uint32) + v, ok := par.Value.(uint32) if !ok { return uint32(0), fmt.Errorf("unable to type cast %q parameter to uint32 value from pid", name) } @@ -295,44 +294,44 @@ func (kpars Kparams) getPid(name string) (uint32, error) { } // GetTid returns the thread id from the parameter. -func (kpars Kparams) GetTid() (uint32, error) { - kpar, err := kpars.findParam(kparams.ThreadID) +func (pars Params) GetTid() (uint32, error) { + par, err := pars.findParam(params.ThreadID) if err != nil { return uint32(0), err } - if kpar.Type != kparams.TID { - return uint32(0), fmt.Errorf("%q parameter is not a TID", kparams.ThreadID) + if par.Type != params.TID { + return uint32(0), fmt.Errorf("%q parameter is not a TID", params.ThreadID) } - v, ok := kpar.Value.(uint32) + v, ok := par.Value.(uint32) if !ok { - return uint32(0), fmt.Errorf("unable to type cast %q parameter to uint32 value from tid", kparams.ThreadID) + return uint32(0), fmt.Errorf("unable to type cast %q parameter to uint32 value from tid", params.ThreadID) } return v, nil } // MustGetTid returns the thread id from the parameter or panics if an error occurs. -func (kpars Kparams) MustGetTid() uint32 { - kpar, err := kpars.findParam(kparams.ThreadID) +func (pars Params) MustGetTid() uint32 { + par, err := pars.findParam(params.ThreadID) if err != nil { panic(err) } - if kpar.Type != kparams.TID { - panic(fmt.Errorf("%q parameter is not a TID", kparams.ThreadID)) + if par.Type != params.TID { + panic(fmt.Errorf("%q parameter is not a TID", params.ThreadID)) } - v, ok := kpar.Value.(uint32) + v, ok := par.Value.(uint32) if !ok { - panic(fmt.Errorf("unable to type cast %q parameter to uint32 value from tid", kparams.ThreadID)) + panic(fmt.Errorf("unable to type cast %q parameter to uint32 value from tid", params.ThreadID)) } return v } // GetUint8 returns the underlying uint8 value from the parameter. -func (kpars Kparams) GetUint8(name string) (uint8, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetUint8(name string) (uint8, error) { + par, err := pars.findParam(name) if err != nil { return uint8(0), err } - v, ok := kpar.Value.(uint8) + v, ok := par.Value.(uint8) if !ok { return uint8(0), fmt.Errorf("unable to type cast %q parameter to uint8 value", name) } @@ -340,12 +339,12 @@ func (kpars Kparams) GetUint8(name string) (uint8, error) { } // GetBool returns the underlying boolean value from the parameter. -func (kpars Kparams) GetBool(name string) (bool, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetBool(name string) (bool, error) { + par, err := pars.findParam(name) if err != nil { return false, err } - v, ok := kpar.Value.(bool) + v, ok := par.Value.(bool) if !ok { return false, fmt.Errorf("unable to type cast %q parameter to bool value", name) } @@ -354,8 +353,8 @@ func (kpars Kparams) GetBool(name string) (bool, error) { // MustGetBool returns the underlying boolean value from the parameter or // panics if the parameter can't be retrieved. -func (kpars Kparams) MustGetBool(name string) bool { - val, err := kpars.GetBool(name) +func (pars Params) MustGetBool(name string) bool { + val, err := pars.GetBool(name) if err != nil { panic(err) } @@ -364,8 +363,8 @@ func (kpars Kparams) MustGetBool(name string) bool { // TryGetBool tries to retrieve the boolean value from the parameter. // Returns the underlying value on success, or false otherwise. -func (kpars Kparams) TryGetBool(name string) bool { - val, err := kpars.GetBool(name) +func (pars Params) TryGetBool(name string) bool { + val, err := pars.GetBool(name) if err != nil { return false } @@ -373,12 +372,12 @@ func (kpars Kparams) TryGetBool(name string) bool { } // GetInt8 returns the underlying int8 value from the parameter. -func (kpars Kparams) GetInt8(name string) (int8, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetInt8(name string) (int8, error) { + par, err := pars.findParam(name) if err != nil { return int8(0), err } - v, ok := kpar.Value.(int8) + v, ok := par.Value.(int8) if !ok { return int8(0), fmt.Errorf("unable to type cast %q parameter to int8 value", name) } @@ -386,12 +385,12 @@ func (kpars Kparams) GetInt8(name string) (int8, error) { } // GetUint16 returns the underlying int16 value from the parameter. -func (kpars Kparams) GetUint16(name string) (uint16, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetUint16(name string) (uint16, error) { + par, err := pars.findParam(name) if err != nil { return uint16(0), err } - v, ok := kpar.Value.(uint16) + v, ok := par.Value.(uint16) if !ok { return uint16(0), fmt.Errorf("unable to type cast %q parameter to uint16 value", name) } @@ -400,8 +399,8 @@ func (kpars Kparams) GetUint16(name string) (uint16, error) { // MustGetUint16 returns the underlying uint16 value parameter. It panics if // an error occurs while trying to get the parameter. -func (kpars Kparams) MustGetUint16(name string) uint16 { - v, err := kpars.GetUint16(name) +func (pars Params) MustGetUint16(name string) uint16 { + v, err := pars.GetUint16(name) if err != nil { panic(err) } @@ -410,8 +409,8 @@ func (kpars Kparams) MustGetUint16(name string) uint16 { // TryGetUint16 tries to retrieve the uint16 value from the parameter. // Returns the underlying value on success, or zero otherwise. -func (kpars Kparams) TryGetUint16(name string) uint16 { - val, err := kpars.GetUint16(name) +func (pars Params) TryGetUint16(name string) uint16 { + val, err := pars.GetUint16(name) if err != nil { return 0 } @@ -419,12 +418,12 @@ func (kpars Kparams) TryGetUint16(name string) uint16 { } // GetInt16 returns the underlying int16 value from the parameter. -func (kpars Kparams) GetInt16(name string) (int16, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetInt16(name string) (int16, error) { + par, err := pars.findParam(name) if err != nil { return int16(0), err } - v, ok := kpar.Value.(int16) + v, ok := par.Value.(int16) if !ok { return int16(0), fmt.Errorf("unable to type cast %q parameter to int16 value", name) } @@ -432,12 +431,12 @@ func (kpars Kparams) GetInt16(name string) (int16, error) { } // GetUint32 returns the underlying uint32 value from the parameter. -func (kpars Kparams) GetUint32(name string) (uint32, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetUint32(name string) (uint32, error) { + par, err := pars.findParam(name) if err != nil { return uint32(0), err } - v, ok := kpar.Value.(uint32) + v, ok := par.Value.(uint32) if !ok { return uint32(0), fmt.Errorf("unable to type cast %q parameter to uint32 value", name) } @@ -446,8 +445,8 @@ func (kpars Kparams) GetUint32(name string) (uint32, error) { // MustGetUint32 returns the underlying uint32 value parameter. It panics if // an error occurs while trying to get the parameter. -func (kpars Kparams) MustGetUint32(name string) uint32 { - v, err := kpars.GetUint32(name) +func (pars Params) MustGetUint32(name string) uint32 { + v, err := pars.GetUint32(name) if err != nil { panic(err) } @@ -456,8 +455,8 @@ func (kpars Kparams) MustGetUint32(name string) uint32 { // TryGetUint32 tries to retrieve the uint32 value from the parameter. // Returns the underlying value on success, or zero otherwise. -func (kpars Kparams) TryGetUint32(name string) uint32 { - val, err := kpars.GetUint32(name) +func (pars Params) TryGetUint32(name string) uint32 { + val, err := pars.GetUint32(name) if err != nil { return 0 } @@ -465,12 +464,12 @@ func (kpars Kparams) TryGetUint32(name string) uint32 { } // GetInt32 returns the underlying int32 value from the parameter. -func (kpars Kparams) GetInt32(name string) (int32, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetInt32(name string) (int32, error) { + par, err := pars.findParam(name) if err != nil { return int32(0), err } - v, ok := kpar.Value.(int32) + v, ok := par.Value.(int32) if !ok { return int32(0), fmt.Errorf("unable to type cast %q parameter to int32 value", name) } @@ -478,12 +477,12 @@ func (kpars Kparams) GetInt32(name string) (int32, error) { } // GetUint64 returns the underlying uint64 value from the parameter. -func (kpars Kparams) GetUint64(name string) (uint64, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetUint64(name string) (uint64, error) { + par, err := pars.findParam(name) if err != nil { return uint64(0), err } - v, ok := kpar.Value.(uint64) + v, ok := par.Value.(uint64) if !ok { return uint64(0), fmt.Errorf("unable to type cast %q parameter to uint64 value", name) } @@ -492,8 +491,8 @@ func (kpars Kparams) GetUint64(name string) (uint64, error) { // MustGetUint64 returns the underlying uint64 value parameter. It panics if // an error occurs while trying to get the parameter. -func (kpars Kparams) MustGetUint64(name string) uint64 { - v, err := kpars.GetUint64(name) +func (pars Params) MustGetUint64(name string) uint64 { + v, err := pars.GetUint64(name) if err != nil { panic(err) } @@ -502,8 +501,8 @@ func (kpars Kparams) MustGetUint64(name string) uint64 { // TryGetUint64 tries to retrieve the uint64 value from the parameter. // Returns the underlying value on success, or zero otherwise. -func (kpars Kparams) TryGetUint64(name string) uint64 { - val, err := kpars.GetUint64(name) +func (pars Params) TryGetUint64(name string) uint64 { + val, err := pars.GetUint64(name) if err != nil { return 0 } @@ -511,12 +510,12 @@ func (kpars Kparams) TryGetUint64(name string) uint64 { } // GetInt64 returns the underlying int64 value from the parameter. -func (kpars Kparams) GetInt64(name string) (int64, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetInt64(name string) (int64, error) { + par, err := pars.findParam(name) if err != nil { return int64(0), err } - v, ok := kpar.Value.(int64) + v, ok := par.Value.(int64) if !ok { return int64(0), fmt.Errorf("unable to type cast %q parameter to int64 value", name) } @@ -524,12 +523,12 @@ func (kpars Kparams) GetInt64(name string) (int64, error) { } // GetFloat returns the underlying float value from the parameter. -func (kpars Kparams) GetFloat(name string) (float32, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetFloat(name string) (float32, error) { + par, err := pars.findParam(name) if err != nil { return float32(0), err } - v, ok := kpar.Value.(float32) + v, ok := par.Value.(float32) if !ok { return float32(0), fmt.Errorf("unable to type cast %q parameter to float32 value", name) } @@ -537,12 +536,12 @@ func (kpars Kparams) GetFloat(name string) (float32, error) { } // GetDouble returns the underlying double (float64) value from the parameter. -func (kpars Kparams) GetDouble(name string) (float64, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetDouble(name string) (float64, error) { + par, err := pars.findParam(name) if err != nil { return float64(0), err } - v, ok := kpar.Value.(float64) + v, ok := par.Value.(float64) if !ok { return float64(0), fmt.Errorf("unable to type cast %q parameter to float64 value", name) } @@ -550,12 +549,12 @@ func (kpars Kparams) GetDouble(name string) (float64, error) { } // TryGetAddress attempts to convert the underlying type to address. -func (kpars Kparams) TryGetAddress(name string) va.Address { - kpar, err := kpars.findParam(name) +func (pars Params) TryGetAddress(name string) va.Address { + par, err := pars.findParam(name) if err != nil { return 0 } - v, ok := kpar.Value.(uint64) + v, ok := par.Value.(uint64) if !ok { return 0 } @@ -563,15 +562,15 @@ func (kpars Kparams) TryGetAddress(name string) va.Address { } // GetIPv4 returns the underlying IPv4 address from the parameter. -func (kpars Kparams) GetIPv4(name string) (net.IP, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetIPv4(name string) (net.IP, error) { + par, err := pars.findParam(name) if err != nil { return net.IP{}, err } - if kpar.Type != kparams.IPv4 { + if par.Type != params.IPv4 { return net.IP{}, fmt.Errorf("%q parameter is not an IPv4 address", name) } - v, ok := kpar.Value.(net.IP) + v, ok := par.Value.(net.IP) if !ok { return net.IP{}, fmt.Errorf("unable to type cast %q parameter to net.IP value", name) } @@ -579,15 +578,15 @@ func (kpars Kparams) GetIPv4(name string) (net.IP, error) { } // GetIPv6 returns the underlying IPv6 address from the parameter. -func (kpars Kparams) GetIPv6(name string) (net.IP, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetIPv6(name string) (net.IP, error) { + par, err := pars.findParam(name) if err != nil { return net.IP{}, err } - if kpar.Type != kparams.IPv6 { + if par.Type != params.IPv6 { return net.IP{}, fmt.Errorf("%q parameter is not an IPv6 address", name) } - v, ok := kpar.Value.(net.IP) + v, ok := par.Value.(net.IP) if !ok { return net.IP{}, fmt.Errorf("unable to type cast %q parameter to net.IP value", name) } @@ -595,15 +594,15 @@ func (kpars Kparams) GetIPv6(name string) (net.IP, error) { } // GetIP returns either the IPv4 or IPv6 address from the parameter. -func (kpars Kparams) GetIP(name string) (net.IP, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetIP(name string) (net.IP, error) { + par, err := pars.findParam(name) if err != nil { return net.IP{}, err } - if kpar.Type != kparams.IPv4 && kpar.Type != kparams.IPv6 { + if par.Type != params.IPv4 && par.Type != params.IPv6 { return net.IP{}, fmt.Errorf("%q parameter is not an IP address", name) } - v, ok := kpar.Value.(net.IP) + v, ok := par.Value.(net.IP) if !ok { return net.IP{}, fmt.Errorf("unable to type cast %q parameter to net.IP value", name) } @@ -611,8 +610,8 @@ func (kpars Kparams) GetIP(name string) (net.IP, error) { } // MustGetIP returns the IP address parameter or panics if an error occurs. -func (kpars Kparams) MustGetIP(name string) net.IP { - ip, err := kpars.GetIP(name) +func (pars Params) MustGetIP(name string) net.IP { + ip, err := pars.GetIP(name) if err != nil { panic(err) } @@ -620,12 +619,12 @@ func (kpars Kparams) MustGetIP(name string) net.IP { } // GetTime returns the underlying time structure from the parameter. -func (kpars Kparams) GetTime(name string) (time.Time, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetTime(name string) (time.Time, error) { + par, err := pars.findParam(name) if err != nil { return time.Unix(0, 0), err } - v, ok := kpar.Value.(time.Time) + v, ok := par.Value.(time.Time) if !ok { return time.Unix(0, 0), fmt.Errorf("unable to type cast %q parameter to Time value", name) } @@ -634,12 +633,12 @@ func (kpars Kparams) GetTime(name string) (time.Time, error) { // MustGetTime returns the underlying time structure from the parameter or panics // if any errors occur. -func (kpars Kparams) MustGetTime(name string) time.Time { - kpar, err := kpars.findParam(name) +func (pars Params) MustGetTime(name string) time.Time { + par, err := pars.findParam(name) if err != nil { panic(err) } - v, ok := kpar.Value.(time.Time) + v, ok := par.Value.(time.Time) if !ok { panic(fmt.Errorf("unable to type cast %q parameter to Time value", name)) } @@ -647,12 +646,12 @@ func (kpars Kparams) MustGetTime(name string) time.Time { } // GetStringSlice returns the string slice from the event parameter. -func (kpars Kparams) GetStringSlice(name string) ([]string, error) { - kpar, err := kpars.GetSlice(name) +func (pars Params) GetStringSlice(name string) ([]string, error) { + par, err := pars.GetSlice(name) if err != nil { return nil, err } - v, ok := kpar.([]string) + v, ok := par.([]string) if !ok { return nil, fmt.Errorf("unable to type cast %q parameter to string slice", name) } @@ -660,31 +659,31 @@ func (kpars Kparams) GetStringSlice(name string) ([]string, error) { } // GetSlice returns the slice of generic values from the parameter. -func (kpars Kparams) GetSlice(name string) (kparams.Value, error) { - kpar, err := kpars.findParam(name) +func (pars Params) GetSlice(name string) (params.Value, error) { + par, err := pars.findParam(name) if err != nil { return nil, err } - if reflect.TypeOf(kpar.Value).Kind() != reflect.Slice { + if reflect.TypeOf(par.Value).Kind() != reflect.Slice { return nil, fmt.Errorf("%q parameter is not a slice", name) } - return kpar.Value, nil + return par.Value, nil } // MustGetSlice returns the slice of generic values from the parameter or // panics if the parameter cannot be found. -func (kpars Kparams) MustGetSlice(name string) kparams.Value { - kpar, err := kpars.findParam(name) +func (pars Params) MustGetSlice(name string) params.Value { + par, err := pars.findParam(name) if err != nil { panic(err) } - return kpar.Value + return par.Value } // MustGetSliceAddrs returns the slice of addresses or panics if the parameter // is not found, or either a parameter is not a slice of addresses. -func (kpars Kparams) MustGetSliceAddrs(name string) []va.Address { - val := kpars.MustGetSlice(name) +func (pars Params) MustGetSliceAddrs(name string) []va.Address { + val := pars.MustGetSlice(name) addrs, ok := val.([]va.Address) if !ok { panic("must be a slice of addresses") @@ -694,22 +693,22 @@ func (kpars Kparams) MustGetSliceAddrs(name string) []va.Address { // String returns the string representation of the event parameters. Parameter names are rendered according // to the currently active parameter style case. -func (kpars Kparams) String() string { +func (pars Params) String() string { var sb strings.Builder // sort parameters by name - pars := make([]*Kparam, 0, len(kpars)) - for _, kpar := range kpars { - pars = append(pars, kpar) + s := make([]*Param, 0, len(pars)) + for _, par := range pars { + s = append(s, par) } - sort.Slice(pars, func(i, j int) bool { return pars[i].Name < pars[j].Name }) - for i, kpar := range pars { + sort.Slice(s, func(i, j int) bool { return s[i].Name < s[j].Name }) + for i, par := range s { switch ParamNameCaseStyle { case SnakeCase: - sb.WriteString(kpar.Name + ParamKVDelimiter + kpar.String()) + sb.WriteString(par.Name + ParamKVDelimiter + par.String()) case DotCase: - sb.WriteString(strings.Replace(kpar.Name, "_", ".", -1) + ParamKVDelimiter + kpar.String()) + sb.WriteString(strings.Replace(par.Name, "_", ".", -1) + ParamKVDelimiter + par.String()) case PascalCase: - sb.WriteString(strings.Replace(caser.String(strings.Replace(kpar.Name, "_", " ", -1)), " ", "", -1) + ParamKVDelimiter + kpar.String()) + sb.WriteString(strings.Replace(caser.String(strings.Replace(par.Name, "_", " ", -1)), " ", "", -1) + ParamKVDelimiter + par.String()) case CamelCase: } if i != len(pars)-1 { @@ -719,19 +718,19 @@ func (kpars Kparams) String() string { return sb.String() } -// Find returns the kparam with specified name. If it is not found, nil value is returned. -func (kpars Kparams) Find(name string) *Kparam { - kpar, err := kpars.findParam(name) +// Find returns the parameter with the specified name. If it is not found, nil value is returned. +func (pars Params) Find(name string) *Param { + par, err := pars.findParam(name) if err != nil { return nil } - return kpar + return par } // findParam lookups a parameter in the map and returns an error if it doesn't exist. -func (kpars Kparams) findParam(name string) (*Kparam, error) { - if _, ok := kpars[name]; !ok { - return nil, &kerrors.ErrKparamNotFound{Name: name} +func (pars Params) findParam(name string) (*Param, error) { + if _, ok := pars[name]; !ok { + return nil, &errors.ErrParamNotFound{Name: name} } - return kpars[name], nil + return pars[name], nil } diff --git a/pkg/event/param_test.go b/pkg/event/param_test.go new file mode 100644 index 000000000..a47b18dcb --- /dev/null +++ b/pkg/event/param_test.go @@ -0,0 +1,60 @@ +/* + * Copyright 2019-2020 by Nedim Sabic Sabic + * https://www.fibratus.io + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package event + +import ( + "github.com/rabbitstack/fibratus/pkg/event/params" + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + "testing" +) + +func TestParams(t *testing.T) { + pars := Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(18446738026482168384)}, + params.ThreadID: {Name: params.ThreadID, Type: params.Uint32, Value: uint32(1484)}, + params.FileCreateOptions: {Name: params.FileCreateOptions, Type: params.Uint32, Value: uint32(1223456)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll"}, + params.FileShareMask: {Name: params.FileShareMask, Type: params.Uint32, Value: uint32(5)}, + } + + assert.True(t, pars.Contains(params.FileObject)) + assert.False(t, pars.Contains(params.FileOffset)) + + filename, err := pars.GetString(params.FilePath) + require.NoError(t, err) + assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll", filename) + + _, err = pars.GetString(params.FileObject) + require.Error(t, err) + + assert.Equal(t, 5, pars.Len()) + + pars.Remove(params.ThreadID) + + assert.False(t, pars.Contains(params.ThreadID)) + assert.Equal(t, 4, pars.Len()) + + require.NoError(t, pars.Set(params.FileShareMask, uint32(5), params.Enum)) + + require.NoError(t, pars.SetValue(params.FilePath, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll")) + filename1, err := pars.GetString(params.FilePath) + require.NoError(t, err) + assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll", filename1) +} diff --git a/pkg/kevent/kparam_windows.go b/pkg/event/param_windows.go similarity index 50% rename from pkg/kevent/kparam_windows.go rename to pkg/event/param_windows.go index 5907d9224..021c04bb2 100644 --- a/pkg/kevent/kparam_windows.go +++ b/pkg/event/param_windows.go @@ -16,15 +16,14 @@ * limitations under the License. */ -package kevent +package event import ( "expvar" "fmt" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/sys/etw" "github.com/rabbitstack/fibratus/pkg/util/ip" "github.com/rabbitstack/fibratus/pkg/util/key" @@ -42,47 +41,47 @@ import ( // unknownKeysCount counts the number of times the registry key failed to convert from native format var unknownKeysCount = expvar.NewInt("registry.unknown.keys.count") -// NewKparam creates a new event parameter. Since the parameter type is already categorized, +// NewParam creates a new event parameter. Since the parameter type is already categorized, // we can coerce the value to the appropriate representation (e.g. hex, IP address) -func NewKparam(name string, typ kparams.Type, value kparams.Value, options ...ParamOption) *Kparam { +func NewParam(name string, typ params.Type, value params.Value, options ...ParamOption) *Param { var opts paramOpts for _, opt := range options { opt(&opts) } - var v kparams.Value + var v params.Value switch typ { - case kparams.IPv4: + case params.IPv4: v = ip.ToIPv4(value.(uint32)) - case kparams.IPv6: + case params.IPv6: v = ip.ToIPv6(value.([]byte)) - case kparams.Port: + case params.Port: v = windows.Ntohs(value.(uint16)) default: v = value } - return &Kparam{Name: name, Type: typ, Value: v, Flags: opts.flags, Enum: opts.enum} + return &Param{Name: name, Type: typ, Value: v, Flags: opts.flags, Enum: opts.enum} } var devMapper = fs.NewDevMapper() // String returns the string representation of the parameter value. -func (k Kparam) String() string { - if k.Value == nil { +func (p Param) String() string { + if p.Value == nil { return "" } - switch k.Type { - case kparams.UnicodeString, kparams.AnsiString, kparams.Path: - return k.Value.(string) - case kparams.SID, kparams.WbemSID: - sid, err := getSID(&k) + switch p.Type { + case params.UnicodeString, params.AnsiString, params.Path: + return p.Value.(string) + case params.SID, params.WbemSID: + sid, err := getSID(&p) if err != nil { return "" } return sid.String() - case kparams.DOSPath: - return devMapper.Convert(k.Value.(string)) - case kparams.Key: - rootKey, keyName := key.Format(k.Value.(string)) + case params.DOSPath: + return devMapper.Convert(p.Value.(string)) + case params.Key: + rootKey, keyName := key.Format(p.Value.(string)) if keyName != "" && rootKey != key.Invalid { return rootKey.String() + "\\" + keyName } @@ -91,100 +90,100 @@ func (k Kparam) String() string { } unknownKeysCount.Add(1) return keyName - case kparams.HandleType: - return htypes.ConvertTypeIDToName(k.Value.(uint16)) - case kparams.Status: - v, ok := k.Value.(uint32) + case params.HandleType: + return htypes.ConvertTypeIDToName(p.Value.(uint16)) + case params.Status: + v, ok := p.Value.(uint32) if !ok { return "" } return ntstatus.FormatMessage(v) - case kparams.Address: - v, ok := k.Value.(uint64) + case params.Address: + v, ok := p.Value.(uint64) if !ok { return "" } return va.Address(v).String() - case kparams.Int8: - return strconv.Itoa(int(k.Value.(int8))) - case kparams.Uint8: - return strconv.Itoa(int(k.Value.(uint8))) - case kparams.Int16: - return strconv.Itoa(int(k.Value.(int16))) - case kparams.Uint16, kparams.Port: - return strconv.Itoa(int(k.Value.(uint16))) - case kparams.Uint32, kparams.PID, kparams.TID: - return strconv.Itoa(int(k.Value.(uint32))) - case kparams.Int32: - return strconv.Itoa(int(k.Value.(int32))) - case kparams.Uint64: - return strconv.FormatUint(k.Value.(uint64), 10) - case kparams.Int64: - return strconv.Itoa(int(k.Value.(int64))) - case kparams.IPv4, kparams.IPv6: - return k.Value.(net.IP).String() - case kparams.Bool: - return strconv.FormatBool(k.Value.(bool)) - case kparams.Float: - return strconv.FormatFloat(float64(k.Value.(float32)), 'f', 6, 32) - case kparams.Double: - return strconv.FormatFloat(k.Value.(float64), 'f', 6, 64) - case kparams.Time: - return k.Value.(time.Time).String() - case kparams.Enum: - if k.Enum == nil { + case params.Int8: + return strconv.Itoa(int(p.Value.(int8))) + case params.Uint8: + return strconv.Itoa(int(p.Value.(uint8))) + case params.Int16: + return strconv.Itoa(int(p.Value.(int16))) + case params.Uint16, params.Port: + return strconv.Itoa(int(p.Value.(uint16))) + case params.Uint32, params.PID, params.TID: + return strconv.Itoa(int(p.Value.(uint32))) + case params.Int32: + return strconv.Itoa(int(p.Value.(int32))) + case params.Uint64: + return strconv.FormatUint(p.Value.(uint64), 10) + case params.Int64: + return strconv.Itoa(int(p.Value.(int64))) + case params.IPv4, params.IPv6: + return p.Value.(net.IP).String() + case params.Bool: + return strconv.FormatBool(p.Value.(bool)) + case params.Float: + return strconv.FormatFloat(float64(p.Value.(float32)), 'f', 6, 32) + case params.Double: + return strconv.FormatFloat(p.Value.(float64), 'f', 6, 64) + case params.Time: + return p.Value.(time.Time).String() + case params.Enum: + if p.Enum == nil { return "" } - e := k.Value + e := p.Value v, ok := e.(uint32) if !ok { return "" } - return k.Enum[v] - case kparams.Flags, kparams.Flags64: - if k.Flags == nil { + return p.Enum[v] + case params.Flags, params.Flags64: + if p.Flags == nil { return "" } - f := k.Value + f := p.Value switch v := f.(type) { case uint32: - return k.Flags.String(uint64(v)) + return p.Flags.String(uint64(v)) case uint64: - return k.Flags.String(v) + return p.Flags.String(v) default: return "" } - case kparams.Slice: - switch slice := k.Value.(type) { + case params.Slice: + switch slice := p.Value.(type) { case []string: return strings.Join(slice, ",") default: return fmt.Sprintf("%v", slice) } - case kparams.Binary: - return string(k.Value.([]byte)) + case params.Binary: + return string(p.Value.([]byte)) } - return fmt.Sprintf("%v", k.Value) + return fmt.Sprintf("%v", p.Value) } // GetSID returns the raw SID (Security Identifier) parameter as // typed representation on which various operations can be performed, // such as converting the SID to string or resolving username/domain. -func (kpars Kparams) GetSID() (*windows.SID, error) { - kpar, err := kpars.findParam(kparams.UserSID) +func (pars Params) GetSID() (*windows.SID, error) { + par, err := pars.findParam(params.UserSID) if err != nil { return nil, err } - return getSID(kpar) + return getSID(par) } -func getSID(kpar *Kparam) (*windows.SID, error) { - sid, ok := kpar.Value.([]byte) +func getSID(param *Param) (*windows.SID, error) { + sid, ok := param.Value.([]byte) if !ok { - return nil, fmt.Errorf("unable to type cast %q parameter to []byte value", kparams.UserSID) + return nil, fmt.Errorf("unable to type cast %q parameter to []byte value", params.UserSID) } b := uintptr(unsafe.Pointer(&sid[0])) - if kpar.Type == kparams.WbemSID { + if param.Type == params.WbemSID { // a WBEM SID is actually a TOKEN_USER structure followed // by the SID, so we have to double the pointer size b += uintptr(8 * 2) @@ -194,8 +193,8 @@ func getSID(kpar *Kparam) (*windows.SID, error) { // MustGetSID returns the SID (Security Identifier) event parameter // or panics if an error occurs. -func (kpars Kparams) MustGetSID() *windows.SID { - sid, err := kpars.GetSID() +func (pars Params) MustGetSID() *windows.SID { + sid, err := pars.GetSID() if err != nil { panic(err) } @@ -206,11 +205,11 @@ func (kpars Kparams) MustGetSID() *windows.SID { // the parameters. Each event is annotated with the schema // version number which helps us determine when the event // schema changes in order to parse new fields. -func (e *Kevent) produceParams(evt *etw.EventRecord) { +func (e *Event) produceParams(evt *etw.EventRecord) { switch e.Type { - case ktypes.ProcessRundown, - ktypes.CreateProcess, - ktypes.TerminateProcess: + case ProcessRundown, + CreateProcess, + TerminateProcess: var ( kproc uint64 pid, ppid uint32 @@ -251,35 +250,35 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { sid, soffset = evt.ReadSID(offset) name, noffset = evt.ReadAnsiString(soffset) cmdline, _ = evt.ReadUTF16String(soffset + noffset) - e.AppendParam(kparams.ProcessObject, kparams.Address, kproc) - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.ProcessParentID, kparams.PID, ppid) - e.AppendParam(kparams.ProcessRealParentID, kparams.PID, evt.Header.ProcessID) - e.AppendParam(kparams.SessionID, kparams.Uint32, sessionID) - e.AppendParam(kparams.ExitStatus, kparams.Status, exitStatus) - e.AppendParam(kparams.DTB, kparams.Address, dtb) - e.AppendParam(kparams.ProcessFlags, kparams.Flags, flags, WithFlags(PsCreationFlags)) - e.AppendParam(kparams.UserSID, kparams.WbemSID, sid) - e.AppendParam(kparams.ProcessName, kparams.AnsiString, name) - e.AppendParam(kparams.Cmdline, kparams.UnicodeString, cmdline) - case ktypes.OpenProcess: + e.AppendParam(params.ProcessObject, params.Address, kproc) + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.ProcessParentID, params.PID, ppid) + e.AppendParam(params.ProcessRealParentID, params.PID, evt.Header.ProcessID) + e.AppendParam(params.SessionID, params.Uint32, sessionID) + e.AppendParam(params.ExitStatus, params.Status, exitStatus) + e.AppendParam(params.DTB, params.Address, dtb) + e.AppendParam(params.ProcessFlags, params.Flags, flags, WithFlags(PsCreationFlags)) + e.AppendParam(params.UserSID, params.WbemSID, sid) + e.AppendParam(params.ProcessName, params.AnsiString, name) + e.AppendParam(params.Cmdline, params.UnicodeString, cmdline) + case OpenProcess: processID := evt.ReadUint32(0) desiredAccess := evt.ReadUint32(4) status := evt.ReadUint32(8) - e.AppendParam(kparams.ProcessID, kparams.PID, processID) - e.AppendParam(kparams.DesiredAccess, kparams.Flags, desiredAccess, WithFlags(PsAccessRightFlags)) - e.AppendParam(kparams.NTStatus, kparams.Status, status) + e.AppendParam(params.ProcessID, params.PID, processID) + e.AppendParam(params.DesiredAccess, params.Flags, desiredAccess, WithFlags(PsAccessRightFlags)) + e.AppendParam(params.NTStatus, params.Status, status) // append callstack for interested flags if desiredAccess == AllAccess || ((desiredAccess & windows.PROCESS_VM_READ) != 0) || ((desiredAccess & windows.PROCESS_VM_WRITE) != 0) || ((desiredAccess & windows.PROCESS_VM_OPERATION) != 0) || ((desiredAccess & windows.PROCESS_DUP_HANDLE) != 0) || ((desiredAccess & windows.PROCESS_TERMINATE) != 0) || ((desiredAccess & windows.PROCESS_CREATE_PROCESS) != 0) || ((desiredAccess & windows.PROCESS_CREATE_THREAD) != 0) || ((desiredAccess & windows.PROCESS_SET_INFORMATION) != 0) { - e.AppendParam(kparams.Callstack, kparams.Slice, evt.Callstack()) + e.AppendParam(params.Callstack, params.Slice, evt.Callstack()) } - case ktypes.CreateThread, - ktypes.TerminateThread, - ktypes.ThreadRundown: + case CreateThread, + TerminateThread, + ThreadRundown: var ( pid uint32 tid uint32 @@ -311,41 +310,41 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { pagePrio = evt.ReadByte(70) ioPrio = evt.ReadByte(71) } - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - e.AppendParam(kparams.KstackBase, kparams.Address, kstack) - e.AppendParam(kparams.KstackLimit, kparams.Address, klimit) - e.AppendParam(kparams.UstackBase, kparams.Address, ustack) - e.AppendParam(kparams.UstackLimit, kparams.Address, ulimit) - e.AppendParam(kparams.StartAddress, kparams.Address, startAddress) - e.AppendParam(kparams.TEB, kparams.Address, teb) - e.AppendParam(kparams.BasePrio, kparams.Uint8, basePrio) - e.AppendParam(kparams.PagePrio, kparams.Uint8, pagePrio) - e.AppendParam(kparams.IOPrio, kparams.Uint8, ioPrio) - case ktypes.OpenThread: + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.ThreadID, params.TID, tid) + e.AppendParam(params.KstackBase, params.Address, kstack) + e.AppendParam(params.KstackLimit, params.Address, klimit) + e.AppendParam(params.UstackBase, params.Address, ustack) + e.AppendParam(params.UstackLimit, params.Address, ulimit) + e.AppendParam(params.StartAddress, params.Address, startAddress) + e.AppendParam(params.TEB, params.Address, teb) + e.AppendParam(params.BasePrio, params.Uint8, basePrio) + e.AppendParam(params.PagePrio, params.Uint8, pagePrio) + e.AppendParam(params.IOPrio, params.Uint8, ioPrio) + case OpenThread: processID := evt.ReadUint32(0) threadID := evt.ReadUint32(4) desiredAccess := evt.ReadUint32(8) status := evt.ReadUint32(12) - e.AppendParam(kparams.ProcessID, kparams.PID, processID) - e.AppendParam(kparams.ThreadID, kparams.TID, threadID) - e.AppendParam(kparams.DesiredAccess, kparams.Flags, desiredAccess, WithFlags(ThreadAccessRightFlags)) - e.AppendParam(kparams.NTStatus, kparams.Status, status) + e.AppendParam(params.ProcessID, params.PID, processID) + e.AppendParam(params.ThreadID, params.TID, threadID) + e.AppendParam(params.DesiredAccess, params.Flags, desiredAccess, WithFlags(ThreadAccessRightFlags)) + e.AppendParam(params.NTStatus, params.Status, status) // append callstack for interested flags if desiredAccess == AllAccess || ((desiredAccess & windows.THREAD_SET_CONTEXT) != 0) || ((desiredAccess & windows.THREAD_SET_THREAD_TOKEN) != 0) || ((desiredAccess & windows.THREAD_IMPERSONATE) != 0) || ((desiredAccess & windows.THREAD_DIRECT_IMPERSONATION) != 0) || ((desiredAccess & windows.THREAD_SUSPEND_RESUME) != 0) || ((desiredAccess & windows.THREAD_TERMINATE) != 0) || ((desiredAccess & windows.THREAD_SET_INFORMATION) != 0) { - e.AppendParam(kparams.Callstack, kparams.Slice, evt.Callstack()) + e.AppendParam(params.Callstack, params.Slice, evt.Callstack()) } - case ktypes.SetThreadContext: + case SetThreadContext: status := evt.ReadUint32(0) - e.AppendParam(kparams.NTStatus, kparams.Status, status) + e.AppendParam(params.NTStatus, params.Status, status) if evt.HasStackTrace() { - e.AppendParam(kparams.Callstack, kparams.Slice, evt.Callstack()) + e.AppendParam(params.Callstack, params.Slice, evt.Callstack()) } - case ktypes.CreateHandle, ktypes.CloseHandle: + case CreateHandle, CloseHandle: object := evt.ReadUint64(0) handleID := evt.ReadUint32(8) typeID := evt.ReadUint16(12) @@ -353,26 +352,26 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { if evt.BufferLen >= 16 { handleName = evt.ConsumeUTF16String(14) } - e.AppendParam(kparams.HandleObject, kparams.Address, object) - e.AppendParam(kparams.HandleID, kparams.Uint32, handleID) - e.AppendParam(kparams.HandleObjectTypeID, kparams.HandleType, typeID) - e.AppendParam(kparams.HandleObjectName, kparams.UnicodeString, handleName) - case ktypes.DuplicateHandle: + e.AppendParam(params.HandleObject, params.Address, object) + e.AppendParam(params.HandleID, params.Uint32, handleID) + e.AppendParam(params.HandleObjectTypeID, params.HandleType, typeID) + e.AppendParam(params.HandleObjectName, params.UnicodeString, handleName) + case DuplicateHandle: object := evt.ReadUint64(0) srcHandleID := evt.ReadUint32(8) dstHandleID := evt.ReadUint32(12) targetPID := evt.ReadUint32(16) typeID := evt.ReadUint16(20) sourcePID := evt.ReadUint32(22) - e.AppendParam(kparams.HandleObject, kparams.Address, object) - e.AppendParam(kparams.HandleID, kparams.Uint32, dstHandleID) - e.AppendParam(kparams.HandleSourceID, kparams.Uint32, srcHandleID) - e.AppendParam(kparams.HandleObjectTypeID, kparams.HandleType, typeID) - e.AppendParam(kparams.ProcessID, kparams.PID, sourcePID) - e.AppendParam(kparams.TargetProcessID, kparams.PID, targetPID) - case ktypes.LoadImage, - ktypes.UnloadImage, - ktypes.ImageRundown: + e.AppendParam(params.HandleObject, params.Address, object) + e.AppendParam(params.HandleID, params.Uint32, dstHandleID) + e.AppendParam(params.HandleSourceID, params.Uint32, srcHandleID) + e.AppendParam(params.HandleObjectTypeID, params.HandleType, typeID) + e.AppendParam(params.ProcessID, params.PID, sourcePID) + e.AppendParam(params.TargetProcessID, params.PID, targetPID) + case LoadImage, + UnloadImage, + ImageRundown: var ( pid uint32 checksum uint32 @@ -406,20 +405,20 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { offset = 16 } filename = evt.ConsumeUTF16String(offset) - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.ImageCheckSum, kparams.Uint32, checksum) - e.AppendParam(kparams.ImageDefaultBase, kparams.Address, defaultBase) - e.AppendParam(kparams.ImageBase, kparams.Address, imageBase) - e.AppendParam(kparams.ImageSize, kparams.Uint64, imageSize) - e.AppendParam(kparams.ImagePath, kparams.DOSPath, filename) - e.AppendParam(kparams.ImageSignatureLevel, kparams.Enum, uint32(sigLevel), WithEnum(signature.Levels)) - e.AppendParam(kparams.ImageSignatureType, kparams.Enum, uint32(sigType), WithEnum(signature.Types)) - case ktypes.RegOpenKey, ktypes.RegCloseKey, - ktypes.RegCreateKCB, ktypes.RegDeleteKCB, - ktypes.RegKCBRundown, ktypes.RegCreateKey, - ktypes.RegDeleteKey, ktypes.RegDeleteValue, - ktypes.RegQueryKey, ktypes.RegQueryValue, - ktypes.RegSetValue: + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.ImageCheckSum, params.Uint32, checksum) + e.AppendParam(params.ImageDefaultBase, params.Address, defaultBase) + e.AppendParam(params.ImageBase, params.Address, imageBase) + e.AppendParam(params.ImageSize, params.Uint64, imageSize) + e.AppendParam(params.ImagePath, params.DOSPath, filename) + e.AppendParam(params.ImageSignatureLevel, params.Enum, uint32(sigLevel), WithEnum(signature.Levels)) + e.AppendParam(params.ImageSignatureType, params.Enum, uint32(sigType), WithEnum(signature.Types)) + case RegOpenKey, RegCloseKey, + RegCreateKCB, RegDeleteKCB, + RegKCBRundown, RegCreateKey, + RegDeleteKey, RegDeleteValue, + RegQueryKey, RegQueryValue, + RegSetValue: var ( status uint32 keyHandle uint64 @@ -437,10 +436,10 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { } else { keyName = evt.ConsumeUTF16String(20) } - e.AppendParam(kparams.RegKeyHandle, kparams.Address, keyHandle) - e.AppendParam(kparams.RegPath, kparams.Key, keyName) - e.AppendParam(kparams.NTStatus, kparams.Status, status) - case ktypes.CreateFile: + e.AppendParam(params.RegKeyHandle, params.Address, keyHandle) + e.AppendParam(params.RegPath, params.Key, keyName) + e.AppendParam(params.NTStatus, params.Status, status) + case CreateFile: var ( irp uint64 fileObject uint64 @@ -462,14 +461,14 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileObject = evt.ReadUint64(0) filename = evt.ConsumeUTF16String(8) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - e.AppendParam(kparams.FileShareMask, kparams.Flags, shareAccess, WithFlags(FileShareModeFlags)) - e.AppendParam(kparams.FileAttributes, kparams.Flags, fileAttributes, WithFlags(FileAttributeFlags)) - e.AppendParam(kparams.FileCreateOptions, kparams.Flags, createOptions, WithFlags(FileCreateOptionsFlags)) - e.AppendParam(kparams.FilePath, kparams.DOSPath, filename) - case ktypes.FileOpEnd: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.ThreadID, params.TID, tid) + e.AppendParam(params.FileShareMask, params.Flags, shareAccess, WithFlags(FileShareModeFlags)) + e.AppendParam(params.FileAttributes, params.Flags, fileAttributes, WithFlags(FileAttributeFlags)) + e.AppendParam(params.FileCreateOptions, params.Flags, createOptions, WithFlags(FileCreateOptionsFlags)) + e.AppendParam(params.FilePath, params.DOSPath, filename) + case FileOpEnd: var ( irp uint64 extraInfo uint64 @@ -480,10 +479,10 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { extraInfo = evt.ReadUint64(8) status = evt.ReadUint32(16) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileExtraInfo, kparams.Address, extraInfo) - e.AppendParam(kparams.NTStatus, kparams.Status, status) - case ktypes.FileRundown: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileExtraInfo, params.Address, extraInfo) + e.AppendParam(params.NTStatus, params.Status, status) + case FileRundown: var ( fileObject uint64 filename string @@ -492,9 +491,9 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileObject = evt.ReadUint64(0) filename = evt.ConsumeUTF16String(8) } - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.FilePath, kparams.DOSPath, filename) - case ktypes.ReleaseFile, ktypes.CloseFile: + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.FilePath, params.DOSPath, filename) + case ReleaseFile, CloseFile: var ( irp uint64 fileObject uint64 @@ -509,13 +508,13 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileKey = evt.ReadUint64(16) tid = evt.ReadUint32(24) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - case ktypes.DeleteFile, - ktypes.RenameFile, - ktypes.SetFileInformation: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.FileKey, params.Address, fileKey) + e.AppendParam(params.ThreadID, params.TID, tid) + case DeleteFile, + RenameFile, + SetFileInformation: var ( irp uint64 fileObject uint64 @@ -539,13 +538,13 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileKey = evt.ReadUint64(18) extraInfo = evt.ReadUint64(28) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - e.AppendParam(kparams.FileExtraInfo, kparams.Uint64, extraInfo) - e.AppendParam(kparams.FileInfoClass, kparams.Enum, infoClass, WithEnum(fs.FileInfoClasses)) - case ktypes.ReadFile, ktypes.WriteFile: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.FileKey, params.Address, fileKey) + e.AppendParam(params.ThreadID, params.TID, tid) + e.AppendParam(params.FileExtraInfo, params.Uint64, extraInfo) + e.AppendParam(params.FileInfoClass, params.Enum, infoClass, WithEnum(fs.FileInfoClasses)) + case ReadFile, WriteFile: var ( irp uint64 offset uint64 @@ -568,13 +567,13 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileKey = evt.ReadUint64(28) tid = evt.ReadUint32(16) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - e.AppendParam(kparams.FileOffset, kparams.Uint64, offset) - e.AppendParam(kparams.FileIoSize, kparams.Uint32, size) - case ktypes.EnumDirectory: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.FileKey, params.Address, fileKey) + e.AppendParam(params.ThreadID, params.TID, tid) + e.AppendParam(params.FileOffset, params.Uint64, offset) + e.AppendParam(params.FileIoSize, params.Uint32, size) + case EnumDirectory: var ( irp uint64 fileObject uint64 @@ -597,13 +596,13 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { fileObject = evt.ReadUint64(12) fileKey = evt.ReadUint64(20) } - e.AppendParam(kparams.FileIrpPtr, kparams.Address, irp) - e.AppendParam(kparams.FileObject, kparams.Address, fileObject) - e.AppendParam(kparams.ThreadID, kparams.TID, tid) - e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.FilePath, kparams.UnicodeString, filename) - e.AppendParam(kparams.FileInfoClass, kparams.Enum, infoClass, WithEnum(fs.FileInfoClasses)) - case ktypes.MapViewFile, ktypes.UnmapViewFile, ktypes.MapFileRundown: + e.AppendParam(params.FileIrpPtr, params.Address, irp) + e.AppendParam(params.FileObject, params.Address, fileObject) + e.AppendParam(params.ThreadID, params.TID, tid) + e.AppendParam(params.FileKey, params.Address, fileKey) + e.AppendParam(params.FilePath, params.UnicodeString, filename) + e.AppendParam(params.FileInfoClass, params.Enum, infoClass, WithEnum(fs.FileInfoClasses)) + case MapViewFile, UnmapViewFile, MapFileRundown: var ( viewBase uint64 fileKey uint64 @@ -626,22 +625,22 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { } protect := uint32(extraInfo >> 32) section := uint32(extraInfo >> 52) - e.AppendParam(kparams.FileViewBase, kparams.Address, viewBase) - e.AppendParam(kparams.FileKey, kparams.Address, fileKey) - e.AppendParam(kparams.FileViewSize, kparams.Uint64, viewSize) - e.AppendParam(kparams.FileOffset, kparams.Uint64, offset) - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.MemProtect, kparams.Flags, protect, WithFlags(ViewProtectionFlags)) - e.AppendParam(kparams.FileViewSectionType, kparams.Enum, section, WithEnum(ViewSectionTypes)) - case ktypes.SendTCPv4, - ktypes.SendUDPv4, - ktypes.RecvTCPv4, - ktypes.RecvUDPv4, - ktypes.DisconnectTCPv4, - ktypes.RetransmitTCPv4, - ktypes.ReconnectTCPv4, - ktypes.ConnectTCPv4, - ktypes.AcceptTCPv4: + e.AppendParam(params.FileViewBase, params.Address, viewBase) + e.AppendParam(params.FileKey, params.Address, fileKey) + e.AppendParam(params.FileViewSize, params.Uint64, viewSize) + e.AppendParam(params.FileOffset, params.Uint64, offset) + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.MemProtect, params.Flags, protect, WithFlags(ViewProtectionFlags)) + e.AppendParam(params.FileViewSectionType, params.Enum, section, WithEnum(ViewSectionTypes)) + case SendTCPv4, + SendUDPv4, + RecvTCPv4, + RecvUDPv4, + DisconnectTCPv4, + RetransmitTCPv4, + ReconnectTCPv4, + ConnectTCPv4, + AcceptTCPv4: var ( pid uint32 size uint32 @@ -665,21 +664,21 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { size = evt.ReadUint32(12) pid = evt.ReadUint32(16) } - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.NetSize, kparams.Uint32, size) - e.AppendParam(kparams.NetDIP, kparams.IPv4, dip) - e.AppendParam(kparams.NetSIP, kparams.IPv4, sip) - e.AppendParam(kparams.NetDport, kparams.Port, dport) - e.AppendParam(kparams.NetSport, kparams.Port, sport) - case ktypes.SendTCPv6, - ktypes.SendUDPv6, - ktypes.RecvTCPv6, - ktypes.RecvUDPv6, - ktypes.DisconnectTCPv6, - ktypes.RetransmitTCPv6, - ktypes.ReconnectTCPv6, - ktypes.ConnectTCPv6, - ktypes.AcceptTCPv6: + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.NetSize, params.Uint32, size) + e.AppendParam(params.NetDIP, params.IPv4, dip) + e.AppendParam(params.NetSIP, params.IPv4, sip) + e.AppendParam(params.NetDport, params.Port, dport) + e.AppendParam(params.NetSport, params.Port, sport) + case SendTCPv6, + SendUDPv6, + RecvTCPv6, + RecvUDPv6, + DisconnectTCPv6, + RetransmitTCPv6, + ReconnectTCPv6, + ConnectTCPv6, + AcceptTCPv6: var ( pid uint32 size uint32 @@ -696,13 +695,13 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { dport = evt.ReadUint16(40) sport = evt.ReadUint16(42) } - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.NetSize, kparams.Uint32, size) - e.AppendParam(kparams.NetDIP, kparams.IPv6, dip) - e.AppendParam(kparams.NetSIP, kparams.IPv6, sip) - e.AppendParam(kparams.NetDport, kparams.Port, dport) - e.AppendParam(kparams.NetSport, kparams.Port, sport) - case ktypes.VirtualAlloc, ktypes.VirtualFree: + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.NetSize, params.Uint32, size) + e.AppendParam(params.NetDIP, params.IPv6, dip) + e.AppendParam(params.NetSIP, params.IPv6, sip) + e.AppendParam(params.NetDport, params.Port, dport) + e.AppendParam(params.NetSport, params.Port, sport) + case VirtualAlloc, VirtualFree: var ( baseAddress uint64 regionSize uint64 @@ -715,11 +714,11 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { pid = evt.ReadUint32(16) flags = evt.ReadUint32(20) } - e.AppendParam(kparams.MemBaseAddress, kparams.Address, baseAddress) - e.AppendParam(kparams.MemRegionSize, kparams.Uint64, regionSize) - e.AppendParam(kparams.ProcessID, kparams.PID, pid) - e.AppendParam(kparams.MemAllocType, kparams.Flags, flags, WithFlags(MemAllocationFlags)) - case ktypes.QueryDNS, ktypes.ReplyDNS: + e.AppendParam(params.MemBaseAddress, params.Address, baseAddress) + e.AppendParam(params.MemRegionSize, params.Uint64, regionSize) + e.AppendParam(params.ProcessID, params.PID, pid) + e.AppendParam(params.MemAllocType, params.Flags, flags, WithFlags(MemAllocationFlags)) + case QueryDNS, ReplyDNS: var ( name string rr uint32 @@ -729,18 +728,18 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { name, offset = evt.ReadUTF16String(0) rr = evt.ReadUint32(offset) opts = evt.ReadUint64(offset + 4) - e.AppendParam(kparams.DNSName, kparams.UnicodeString, name) - e.AppendParam(kparams.DNSRR, kparams.Enum, rr, WithEnum(DNSRecordTypes)) - e.AppendParam(kparams.DNSOpts, kparams.Flags64, opts, WithFlags(DNSOptsFlags)) - if e.Type == ktypes.ReplyDNS { + e.AppendParam(params.DNSName, params.UnicodeString, name) + e.AppendParam(params.DNSRR, params.Enum, rr, WithEnum(DNSRecordTypes)) + e.AppendParam(params.DNSOpts, params.Flags64, opts, WithFlags(DNSOptsFlags)) + if e.Type == ReplyDNS { rcode := evt.ReadUint32(offset + 12) answers := evt.ConsumeUTF16String(offset + 16) - e.AppendParam(kparams.DNSRcode, kparams.Enum, rcode, WithEnum(DNSResponseCodes)) - e.AppendParam(kparams.DNSAnswers, kparams.Slice, strings.Split(sanitizeDNSAnswers(answers), ";")) + e.AppendParam(params.DNSRcode, params.Enum, rcode, WithEnum(DNSResponseCodes)) + e.AppendParam(params.DNSAnswers, params.Slice, strings.Split(sanitizeDNSAnswers(answers), ";")) } - case ktypes.StackWalk: - e.AppendParam(kparams.ProcessID, kparams.PID, evt.ReadUint32(8)) - e.AppendParam(kparams.ThreadID, kparams.TID, evt.ReadUint32(12)) + case StackWalk: + e.AppendParam(params.ProcessID, params.PID, evt.ReadUint32(8)) + e.AppendParam(params.ThreadID, params.TID, evt.ReadUint32(12)) var n uint16 var offset uint16 = 16 frames := (evt.BufferLen - offset) / 8 @@ -750,43 +749,43 @@ func (e *Kevent) produceParams(evt *etw.EventRecord) { offset += 8 n++ } - e.AppendParam(kparams.Callstack, kparams.Slice, callstack) - case ktypes.CreateSymbolicLinkObject: + e.AppendParam(params.Callstack, params.Slice, callstack) + case CreateSymbolicLinkObject: source, offset := evt.ReadUTF16String(0) target, offset := evt.ReadUTF16String(offset) desiredAccess := evt.ReadUint32(offset) status := evt.ReadUint32(offset + 4) - e.AppendParam(kparams.LinkSource, kparams.UnicodeString, source) - e.AppendParam(kparams.LinkTarget, kparams.UnicodeString, target) - e.AppendParam(kparams.DesiredAccess, kparams.Flags, desiredAccess, WithFlags(AccessMaskFlags)) - e.AppendParam(kparams.NTStatus, kparams.Status, status) + e.AppendParam(params.LinkSource, params.UnicodeString, source) + e.AppendParam(params.LinkTarget, params.UnicodeString, target) + e.AppendParam(params.DesiredAccess, params.Flags, desiredAccess, WithFlags(AccessMaskFlags)) + e.AppendParam(params.NTStatus, params.Status, status) if evt.HasStackTrace() { - e.AppendParam(kparams.Callstack, kparams.Slice, evt.Callstack()) + e.AppendParam(params.Callstack, params.Slice, evt.Callstack()) } - case ktypes.SubmitThreadpoolWork, ktypes.SubmitThreadpoolCallback: + case SubmitThreadpoolWork, SubmitThreadpoolCallback: poolID := evt.ReadUint64(0) taskID := evt.ReadUint64(8) callback := evt.ReadUint64(16) ctx := evt.ReadUint64(24) tag := evt.ReadUint64(32) - e.AppendParam(kparams.ThreadpoolPoolID, kparams.Address, poolID) - e.AppendParam(kparams.ThreadpoolTaskID, kparams.Address, taskID) - e.AppendParam(kparams.ThreadpoolCallback, kparams.Address, callback) - e.AppendParam(kparams.ThreadpoolContext, kparams.Address, ctx) - e.AppendParam(kparams.ThreadpoolSubprocessTag, kparams.Address, tag) - case ktypes.SetThreadpoolTimer: + e.AppendParam(params.ThreadpoolPoolID, params.Address, poolID) + e.AppendParam(params.ThreadpoolTaskID, params.Address, taskID) + e.AppendParam(params.ThreadpoolCallback, params.Address, callback) + e.AppendParam(params.ThreadpoolContext, params.Address, ctx) + e.AppendParam(params.ThreadpoolSubprocessTag, params.Address, tag) + case SetThreadpoolTimer: duetime := evt.ReadUint64(0) subqueue := evt.ReadUint64(8) timer := evt.ReadUint64(16) period := evt.ReadUint32(24) window := evt.ReadUint32(28) absolute := evt.ReadUint32(32) - e.AppendParam(kparams.ThreadpoolTimerDuetime, kparams.Uint64, duetime) - e.AppendParam(kparams.ThreadpoolTimerSubqueue, kparams.Address, subqueue) - e.AppendParam(kparams.ThreadpoolTimer, kparams.Address, timer) - e.AppendParam(kparams.ThreadpoolTimerPeriod, kparams.Uint32, period) - e.AppendParam(kparams.ThreadpoolTimerWindow, kparams.Uint32, window) - e.AppendParam(kparams.ThreadpoolTimerAbsolute, kparams.Bool, absolute > 0) + e.AppendParam(params.ThreadpoolTimerDuetime, params.Uint64, duetime) + e.AppendParam(params.ThreadpoolTimerSubqueue, params.Address, subqueue) + e.AppendParam(params.ThreadpoolTimer, params.Address, timer) + e.AppendParam(params.ThreadpoolTimerPeriod, params.Uint32, period) + e.AppendParam(params.ThreadpoolTimerWindow, params.Uint32, window) + e.AppendParam(params.ThreadpoolTimerAbsolute, params.Bool, absolute > 0) } } diff --git a/pkg/kevent/kparams/fields_windows.go b/pkg/event/params/params_windows.go similarity index 99% rename from pkg/kevent/kparams/fields_windows.go rename to pkg/event/params/params_windows.go index e692394d1..afed096c0 100644 --- a/pkg/kevent/kparams/fields_windows.go +++ b/pkg/event/params/params_windows.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kparams +package params const ( // NTStatus is the parameter that identifies the NTSTATUS value. diff --git a/pkg/event/params/types.go b/pkg/event/params/types.go new file mode 100644 index 000000000..e492cb3e6 --- /dev/null +++ b/pkg/event/params/types.go @@ -0,0 +1,27 @@ +/* + * Copyright 2021-present by Nedim Sabic Sabic + * https://www.fibratus.io + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package params + +const ( + // NA defines absent parameter's value + NA = "na" +) + +// Value defines the container for parameter values +type Value interface{} diff --git a/pkg/kevent/kparams/types_windows.go b/pkg/event/params/types_windows.go similarity index 93% rename from pkg/kevent/kparams/types_windows.go rename to pkg/event/params/types_windows.go index 441cfa1f6..aec8c363d 100644 --- a/pkg/kevent/kparams/types_windows.go +++ b/pkg/event/params/types_windows.go @@ -1,5 +1,5 @@ /* - * Copyright 2019-2020 by Nedim Sabic Sabic + * Copyright 2021-present by Nedim Sabic Sabic * https://www.fibratus.io * All Rights Reserved. * @@ -16,17 +16,9 @@ * limitations under the License. */ -package kparams +package params -const ( - // NA defines absent parameter's value - NA = "na" -) - -// Value defines the container for parameter values -type Value interface{} - -// Type defines kernel event parameter type +// Type defines event parameter type type Type uint16 const ( diff --git a/pkg/kevent/queue.go b/pkg/event/queue.go similarity index 90% rename from pkg/kevent/queue.go rename to pkg/event/queue.go index 9a9a801e4..cf185f4ee 100644 --- a/pkg/kevent/queue.go +++ b/pkg/event/queue.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "expvar" @@ -38,7 +38,7 @@ type Listener interface { // indicating if the event should continue the processing journey. // In case any errors occur during processing, this method returns // the error and stops further event processing. - ProcessEvent(*Kevent) (bool, error) + ProcessEvent(*Event) (bool, error) // CanEnqueue indicates if the event listener is capable of // submitting the event to the output queue if the ProcessEvent // method returns true. In general, processors that merely @@ -50,7 +50,7 @@ type Listener interface { // Queue is the channel-backed data structure for // pushing captured events and invoking listeners. type Queue struct { - q chan *Kevent + q chan *Event listeners []Listener backlog *backlog decorator *StackwalkDecorator @@ -61,7 +61,7 @@ type Queue struct { // NewQueue constructs a new queue with the given channel size. func NewQueue(size int, stackEnrichment bool, enqueueAlways bool) *Queue { q := &Queue{ - q: make(chan *Kevent, size), + q: make(chan *Event, size), listeners: make([]Listener, 0), backlog: newBacklog(backlogCacheSize), stackEnrichment: stackEnrichment, @@ -72,7 +72,7 @@ func NewQueue(size int, stackEnrichment bool, enqueueAlways bool) *Queue { } // NewQueueWithChannel constructs a new queue with a custom channel. -func NewQueueWithChannel(ch chan *Kevent, stackEnrichment bool, enqueueAlways bool) *Queue { +func NewQueueWithChannel(ch chan *Event, stackEnrichment bool, enqueueAlways bool) *Queue { q := &Queue{ q: ch, listeners: make([]Listener, 0), @@ -91,7 +91,7 @@ func (q *Queue) RegisterListener(listener Listener) { } // Events returns the channel with all queued events. -func (q *Queue) Events() <-chan *Kevent { return q.q } +func (q *Queue) Events() <-chan *Event { return q.q } // Close closes the queue disposing allocated resources. func (q *Queue) Close() { q.decorator.Stop() } @@ -116,7 +116,7 @@ func (q *Queue) Close() { q.decorator.Stop() } // Then, the originating event is popped from the queue, // enriched with callstack parameter and forwarded to the // event queue. -func (q *Queue) Push(e *Kevent) error { +func (q *Queue) Push(e *Event) error { if q.stackEnrichment { // store pending event for callstack enrichment if e.Type.CanEnrichStack() { @@ -143,7 +143,7 @@ func (q *Queue) Push(e *Kevent) error { return q.push(e) } -func (q *Queue) push(e *Kevent) error { +func (q *Queue) push(e *Event) error { var enqueue bool if q.enqueueAlways { enqueue = true @@ -158,7 +158,7 @@ func (q *Queue) push(e *Kevent) error { } } if q.stackEnrichment && e.IsTerminateThread() { - id := uint64(e.Kparams.MustGetPid() + e.Kparams.MustGetTid()) + id := uint64(e.Params.MustGetPid() + e.Params.MustGetTid()) q.decorator.RemoveBucket(id) } if enqueue || len(q.listeners) == 0 { @@ -168,7 +168,7 @@ func (q *Queue) push(e *Kevent) error { return nil } -func isEventDelayed(e *Kevent) bool { +func isEventDelayed(e *Event) bool { return e.IsCreateHandle() } @@ -180,7 +180,7 @@ func newBacklog(size int) *backlog { return &backlog{cache: lru.New(size)} } -func (b *backlog) put(evt *Kevent) { +func (b *backlog) put(evt *Event) { if b.cache.Len() > backlogCacheSize { b.cache.RemoveOldest() } @@ -190,7 +190,7 @@ func (b *backlog) put(evt *Kevent) { } } -func (b *backlog) pop(evt *Kevent) *Kevent { +func (b *backlog) pop(evt *Event) *Event { key := evt.BacklogKey() if key == 0 { return nil @@ -200,7 +200,7 @@ func (b *backlog) pop(evt *Kevent) *Kevent { return nil } b.cache.Remove(key) - e := ev.(*Kevent) + e := ev.(*Event) e.CopyState(evt) return e } diff --git a/pkg/kevent/queue_test.go b/pkg/event/queue_test.go similarity index 51% rename from pkg/kevent/queue_test.go rename to pkg/event/queue_test.go index bc4ebf310..56dea2d83 100644 --- a/pkg/kevent/queue_test.go +++ b/pkg/event/queue_test.go @@ -16,13 +16,12 @@ * limitations under the License. */ -package kevent +package event import ( "errors" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" @@ -38,9 +37,9 @@ type AddParamListener struct { func (l *AddParamListener) CanEnqueue() bool { return true } -func (l *AddParamListener) ProcessEvent(e *Kevent) (bool, error) { +func (l *AddParamListener) ProcessEvent(e *Event) (bool, error) { args := l.Called(e) - e.AppendParam(kparams.FileAttributes, kparams.AnsiString, "HIDDEN") + e.AppendParam(params.FileAttributes, params.AnsiString, "HIDDEN") return args.Bool(0), args.Error(1) } @@ -49,7 +48,7 @@ type DummyListener struct{} func (l *DummyListener) CanEnqueue() bool { return true } -func (l *DummyListener) ProcessEvent(e *Kevent) (bool, error) { +func (l *DummyListener) ProcessEvent(e *Event) (bool, error) { return true, nil } @@ -58,7 +57,7 @@ var ErrCantEnqueue = errors.New("cannot push event into the queue") func TestQueuePush(t *testing.T) { var tests = []struct { name string - e *Kevent + e *Event err error listeners func() []Listener enqueueAlways bool @@ -66,20 +65,20 @@ func TestQueuePush(t *testing.T) { }{ { "push event ok", - &Kevent{ - Type: ktypes.CreateFile, + &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, }, nil, @@ -93,20 +92,20 @@ func TestQueuePush(t *testing.T) { }, { "push event listener error", - &Kevent{ - Type: ktypes.CreateFile, + &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, }, ErrCantEnqueue, @@ -120,20 +119,20 @@ func TestQueuePush(t *testing.T) { }, { "push event one listener allows", - &Kevent{ - Type: ktypes.CreateFile, + &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, }, nil, @@ -148,20 +147,20 @@ func TestQueuePush(t *testing.T) { }, { "push event listeners deny", - &Kevent{ - Type: ktypes.CreateFile, + &Event{ + Type: CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, }, }, nil, @@ -185,7 +184,7 @@ func TestQueuePush(t *testing.T) { err := q.Push(tt.e) assert.Equal(t, err, tt.err) if tt.isEnqueued { - assert.True(t, tt.e.Kparams.Contains(kparams.FileAttributes)) + assert.True(t, tt.e.Params.Contains(params.FileAttributes)) } assert.True(t, len(q.Events()) > 0 == tt.isEnqueued) }) @@ -193,16 +192,16 @@ func TestQueuePush(t *testing.T) { } func TestPushBacklog(t *testing.T) { - e := &Kevent{ - Type: ktypes.CreateHandle, + e := &Event{ + Type: CreateHandle, Tid: 2484, PID: 859, - Category: ktypes.Handle, - Kparams: Kparams{ - kparams.HandleID: {Name: kparams.HandleID, Type: kparams.Uint32, Value: uint32(21)}, - kparams.HandleObjectTypeID: {Name: kparams.HandleObjectTypeID, Type: kparams.AnsiString, Value: "Key"}, - kparams.HandleObject: {Name: kparams.HandleObject, Type: kparams.Uint64, Value: uint64(18446692422059208560)}, - kparams.HandleObjectName: {Name: kparams.HandleObjectName, Type: kparams.UnicodeString, Value: ""}, + Category: Handle, + Params: Params{ + params.HandleID: {Name: params.HandleID, Type: params.Uint32, Value: uint32(21)}, + params.HandleObjectTypeID: {Name: params.HandleObjectTypeID, Type: params.AnsiString, Value: "Key"}, + params.HandleObject: {Name: params.HandleObject, Type: params.Uint64, Value: uint64(18446692422059208560)}, + params.HandleObjectName: {Name: params.HandleObjectName, Type: params.UnicodeString, Value: ""}, }, Metadata: make(Metadata), } @@ -214,16 +213,16 @@ func TestPushBacklog(t *testing.T) { require.Len(t, q.Events(), 0) require.False(t, q.backlog.empty()) - e1 := &Kevent{ - Type: ktypes.CloseHandle, + e1 := &Event{ + Type: CloseHandle, Tid: 2484, PID: 859, - Category: ktypes.Handle, - Kparams: Kparams{ - kparams.HandleID: {Name: kparams.HandleID, Type: kparams.Uint32, Value: uint32(21)}, - kparams.HandleObjectTypeID: {Name: kparams.HandleObjectTypeID, Type: kparams.AnsiString, Value: "Key"}, - kparams.HandleObject: {Name: kparams.HandleObject, Type: kparams.Uint64, Value: uint64(18446692422059208560)}, - kparams.HandleObjectName: {Name: kparams.HandleObjectName, Type: kparams.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`}, + Category: Handle, + Params: Params{ + params.HandleID: {Name: params.HandleID, Type: params.Uint32, Value: uint32(21)}, + params.HandleObjectTypeID: {Name: params.HandleObjectTypeID, Type: params.AnsiString, Value: "Key"}, + params.HandleObject: {Name: params.HandleObject, Type: params.Uint64, Value: uint64(18446692422059208560)}, + params.HandleObjectName: {Name: params.HandleObjectName, Type: params.UnicodeString, Value: `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`}, }, Metadata: make(Metadata), } @@ -233,7 +232,7 @@ func TestPushBacklog(t *testing.T) { ev := <-q.Events() require.NotNil(t, ev) - assert.Equal(t, `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`, ev.GetParamAsString(kparams.HandleObjectName)) + assert.Equal(t, `\REGISTRY\MACHINE\SYSTEM\ControlSet001\Services\Tcpip\Parameters\Interfaces\{b677c565-6ca5-45d3-b618-736b4e09b036}`, ev.GetParamAsString(params.HandleObjectName)) require.True(t, reflect.DeepEqual(e1, <-q.Events())) } diff --git a/pkg/kevent/sequencer_windows.go b/pkg/event/sequencer_windows.go similarity index 92% rename from pkg/kevent/sequencer_windows.go rename to pkg/event/sequencer_windows.go index 4aa593fb6..faf0594b5 100644 --- a/pkg/kevent/sequencer_windows.go +++ b/pkg/event/sequencer_windows.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "errors" @@ -36,18 +36,18 @@ const ( invalidKey = registry.Key(syscall.InvalidHandle) ) -var seqStoreErrors = expvar.NewInt("kevent.seq.store.errors") -var seqInitErrors = expvar.NewMap("kevent.seq.init.errors") +var seqStoreErrors = expvar.NewInt("event.seq.store.errors") +var seqInitErrors = expvar.NewMap("event.seq.init.errors") var errInvalidVolatileKey = errors.New("couldn't open HKCU/Volatile Environment key") -// Sequencer is responsible for incrementing, getting and persisting the kevent sequence number in the Windows registry. +// Sequencer is responsible for incrementing, getting and persisting the event sequence number in the Windows registry. type Sequencer struct { key registry.Key quit chan struct{} seq uint64 } -// NewSequencer creates a fresh kevent sequencer. If the `KeventSeq` value is present under the volatile key, the current +// NewSequencer creates a fresh event sequencer. If the `EventSequence` value is present under the volatile key, the current // sequence number is initialized to the last stored sequence. The sequencer schedules a ticker that periodically dumps // the current sequence number into the registry value. func NewSequencer() *Sequencer { diff --git a/pkg/kevent/sequencer_windows_test.go b/pkg/event/sequencer_windows_test.go similarity index 99% rename from pkg/kevent/sequencer_windows_test.go rename to pkg/event/sequencer_windows_test.go index bb2aff59b..f815b4767 100644 --- a/pkg/kevent/sequencer_windows_test.go +++ b/pkg/event/sequencer_windows_test.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "github.com/stretchr/testify/assert" diff --git a/pkg/kevent/stackwalk.go b/pkg/event/stackwalk.go similarity index 92% rename from pkg/kevent/stackwalk.go rename to pkg/event/stackwalk.go index 6cc9a388d..bdf86795b 100644 --- a/pkg/kevent/stackwalk.go +++ b/pkg/event/stackwalk.go @@ -16,11 +16,11 @@ * limitations under the License. */ -package kevent +package event import ( "expvar" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/util/multierror" log "github.com/sirupsen/logrus" "sync" @@ -55,7 +55,7 @@ var stackwalkBuckets = expvar.NewInt("stackwalk.buckets") // popped from the queue and enriched with return addresses // which are later subject to symbolization. type StackwalkDecorator struct { - buckets map[uint64][]*Kevent + buckets map[uint64][]*Event q *Queue mux sync.Mutex @@ -69,7 +69,7 @@ type StackwalkDecorator struct { func NewStackwalkDecorator(q *Queue) *StackwalkDecorator { s := &StackwalkDecorator{ q: q, - buckets: make(map[uint64][]*Kevent), + buckets: make(map[uint64][]*Event), flusher: time.NewTicker(flusherInterval), quit: make(chan struct{}, 1), } @@ -80,7 +80,7 @@ func NewStackwalkDecorator(q *Queue) *StackwalkDecorator { } // Push pushes a new event to the queue. -func (s *StackwalkDecorator) Push(e *Kevent) { +func (s *StackwalkDecorator) Push(e *Event) { s.mux.Lock() defer s.mux.Unlock() @@ -88,7 +88,7 @@ func (s *StackwalkDecorator) Push(e *Kevent) { id := e.StackID() q, ok := s.buckets[id] if !ok { - s.buckets[id] = []*Kevent{e} + s.buckets[id] = []*Event{e} } else { s.buckets[id] = append(q, e) } @@ -101,7 +101,7 @@ func (s *StackwalkDecorator) Push(e *Kevent) { // originating event with the same pid,tid tuple formerly // coined as stack identifier. The originating event is then // decorated with callstack return addresses. -func (s *StackwalkDecorator) Pop(e *Kevent) *Kevent { +func (s *StackwalkDecorator) Pop(e *Event) *Event { s.mux.Lock() defer s.mux.Unlock() @@ -111,7 +111,7 @@ func (s *StackwalkDecorator) Pop(e *Kevent) *Kevent { return e } - var evt *Kevent + var evt *Event if len(q) > 0 { evt, s.buckets[id] = q[0], q[1:] stackwalkEnqueued.Add(-int64(len(s.buckets[id]))) @@ -121,8 +121,8 @@ func (s *StackwalkDecorator) Pop(e *Kevent) *Kevent { return e } - callstack := e.Kparams.MustGetSlice(kparams.Callstack) - evt.AppendParam(kparams.Callstack, kparams.Slice, callstack) + callstack := e.Params.MustGetSlice(params.Callstack) + evt.AppendParam(params.Callstack, params.Slice, callstack) return evt } diff --git a/pkg/event/stackwalk_test.go b/pkg/event/stackwalk_test.go new file mode 100644 index 000000000..2275b1005 --- /dev/null +++ b/pkg/event/stackwalk_test.go @@ -0,0 +1,129 @@ +/* + * Copyright 2021-present by Nedim Sabic Sabic + * https://www.fibratus.io + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package event + +import ( + "github.com/rabbitstack/fibratus/pkg/event/params" + "github.com/rabbitstack/fibratus/pkg/fs" + "github.com/rabbitstack/fibratus/pkg/util/va" + "github.com/stretchr/testify/assert" + "testing" + "time" +) + +func TestStackwalkDecorator(t *testing.T) { + q := NewQueue(50, false, true) + cd := NewStackwalkDecorator(q) + + e := &Event{ + Type: CreateFile, + Tid: 2484, + PID: 859, + CPU: 1, + Seq: 2, + Name: "CreateFile", + Timestamp: time.Now(), + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + }, + } + + e1 := &Event{ + Type: CreateFile, + Tid: 2484, + PID: 859, + CPU: 1, + Seq: 3, + Name: "CreateFile", + Timestamp: time.Now(), + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + }, + } + + cd.Push(e) + cd.Push(e1) + + assert.Len(t, cd.buckets[e.StackID()], 2) + + sw := &Event{ + Type: StackWalk, + Tid: 2484, + PID: 859, + CPU: 1, + Seq: 4, + Name: "StackWalk", + Timestamp: time.Now(), + Params: Params{ + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5eb70dc4, 0x7ffb5c191deb, 0x7ffb3138592e}}, + }, + } + + evt := cd.Pop(sw) + assert.Len(t, cd.buckets[e.StackID()], 1) + assert.Equal(t, CreateFile, evt.Type) + assert.True(t, evt.Params.Contains(params.Callstack)) + assert.Equal(t, "C:\\Windows\\system32\\user32.dll", evt.GetParamAsString(params.FilePath)) +} + +func init() { + maxQueueTTLPeriod = time.Second * 2 + flusherInterval = time.Second +} + +func TestStackwalkDecoratorFlush(t *testing.T) { + q := NewQueue(50, false, true) + q.RegisterListener(&DummyListener{}) + cd := NewStackwalkDecorator(q) + defer cd.Stop() + + e := &Event{ + Type: CreateFile, + Tid: 2484, + PID: 859, + CPU: 1, + Seq: 2, + Name: "CreateFile", + Timestamp: time.Now(), + Category: File, + Params: Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, + }, + } + + cd.Push(e) + assert.Len(t, cd.buckets[e.StackID()], 1) + time.Sleep(time.Millisecond * 3100) + + evt := <-q.Events() + assert.Len(t, cd.buckets[e.StackID()], 0) + assert.Equal(t, CreateFile, evt.Type) + assert.False(t, evt.Params.Contains(params.Callstack)) +} diff --git a/pkg/kevent/template.go b/pkg/event/template.go similarity index 59% rename from pkg/kevent/template.go rename to pkg/event/template.go index f487fe69a..8f349b653 100644 --- a/pkg/kevent/template.go +++ b/pkg/event/template.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package kevent +package event import ( "bytes" @@ -25,28 +25,28 @@ import ( ) // Template is the default Go template used for formatting events in textual format. -var Template = `Name: {{ .Kevt.Name }} -Sequence: {{ .Kevt.Seq }} -Description: {{ .Kevt.Description }} -Process ID: {{ .Kevt.PID }} -Thread ID: {{ .Kevt.Tid }} -Params: {{ .Kevt.Kparams }} +var Template = `Name: {{ .Evt.Name }} +Sequence: {{ .Evt.Seq }} +Description: {{ .Evt.Description }} +Process ID: {{ .Evt.PID }} +Thread ID: {{ .Evt.Tid }} +Params: {{ .Evt.Params }} -{{- if .Kevt.PS }} +{{- if .Evt.PS }} -Process: {{ .Kevt.PS.Name }} -Exe: {{ .Kevt.PS.Exe }} -Pid: {{ .Kevt.PS.PID }} -Ppid: {{ .Kevt.PS.Ppid }} -Cmdline: {{ .Kevt.PS.Cmdline }} -Cwd: {{ .Kevt.PS.Cwd }} -SID: {{ .Kevt.PS.SID }} -User: {{ .Kevt.PS.Username }} -Domain: {{ .Kevt.PS.Domain }} -Session ID: {{ .Kevt.PS.SessionID }} -{{ if and (.SerializeEnvs) (.Kevt.PS.Envs) }} +Process: {{ .Evt.PS.Name }} +Exe: {{ .Evt.PS.Exe }} +Pid: {{ .Evt.PS.PID }} +Ppid: {{ .Evt.PS.Ppid }} +Cmdline: {{ .Evt.PS.Cmdline }} +Cwd: {{ .Evt.PS.Cwd }} +SID: {{ .Evt.PS.SID }} +User: {{ .Evt.PS.Username }} +Domain: {{ .Evt.PS.Domain }} +Session ID: {{ .Evt.PS.SessionID }} +{{ if and (.SerializeEnvs) (.Evt.PS.Envs) }} Env: - {{- with .Kevt.PS.Envs }} + {{- with .Evt.PS.Envs }} {{- range $k, $v := . }} {{ $k }}: {{ $v }} {{- end }} @@ -54,7 +54,7 @@ Env: {{ end }} {{ if .SerializeThreads }} Threads: - {{- with .Kevt.PS.Threads }} + {{- with .Evt.PS.Threads }} {{- range . }} {{ . }} {{- end }} @@ -62,54 +62,54 @@ Threads: {{ end }} {{ if .SerializeImages }} Modules: - {{- with .Kevt.PS.Modules }} + {{- with .Evt.PS.Modules }} {{- range . }} {{ . }} {{- end }} {{- end }} {{ end }} -{{ if and (.SerializeHandles) (.Kevt.PS.Handles) }} +{{ if and (.SerializeHandles) (.Evt.PS.Handles) }} Handles: - {{- with .Kevt.PS.Handles }} + {{- with .Evt.PS.Handles }} {{- range . }} {{ . }} {{- end }} {{- end }} {{ end }} -{{ if and (.SerializePE) (.Kevt.PS.PE) }} -Entrypoint: {{ .Kevt.PS.PE.EntryPoint }} -Image base: {{ .Kevt.PS.PE.ImageBase }} -Build date: {{ .Kevt.PS.PE.LinkTime }} +{{ if and (.SerializePE) (.Evt.PS.PE) }} +Entrypoint: {{ .Evt.PS.PE.EntryPoint }} +Image base: {{ .Evt.PS.PE.ImageBase }} +Build date: {{ .Evt.PS.PE.LinkTime }} -Number of symbols: {{ .Kevt.PS.PE.NumberOfSymbols }} -Number of sections: {{ .Kevt.PS.PE.NumberOfSections }} +Number of symbols: {{ .Evt.PS.PE.NumberOfSymbols }} +Number of sections: {{ .Evt.PS.PE.NumberOfSections }} Sections: - {{- with .Kevt.PS.PE.Sections }} + {{- with .Evt.PS.PE.Sections }} {{- range . }} {{ . }} {{- end }} {{- end }} -{{ if .Kevt.PS.PE.Symbols }} +{{ if .Evt.PS.PE.Symbols }} Symbols: - {{- with .Kevt.PS.PE.Symbols }} + {{- with .Evt.PS.PE.Symbols }} {{- range . }} {{ . }} {{- end }} {{- end }} {{ end }} -{{ if .Kevt.PS.PE.Imports }} +{{ if .Evt.PS.PE.Imports }} Imports: - {{- with .Kevt.PS.PE.Imports }} + {{- with .Evt.PS.PE.Imports }} {{- range . }} {{ . }} {{- end }} {{- end }} {{ end }} -{{ if .Kevt.PS.PE.VersionResources }} +{{ if .Evt.PS.PE.VersionResources }} Resources: - {{- with .Kevt.PS.PE.VersionResources }} + {{- with .Evt.PS.PE.VersionResources }} {{- range $k, $v := . }} {{ $k }}: {{ $v }} {{- end }} @@ -121,7 +121,7 @@ Resources: // RenderDefaultTemplate returns the event string representation // after applying the default Go template. -func (e *Kevent) RenderDefaultTemplate() ([]byte, error) { +func (e *Event) RenderDefaultTemplate() ([]byte, error) { tmpl, err := template.New("event").Parse(Template) if err != nil { return nil, err @@ -131,21 +131,21 @@ func (e *Kevent) RenderDefaultTemplate() ([]byte, error) { // RenderCustomTemplate returns the event string representation // after applying the given Go template. -func (e *Kevent) RenderCustomTemplate(tmpl *template.Template) ([]byte, error) { +func (e *Event) RenderCustomTemplate(tmpl *template.Template) ([]byte, error) { return renderTemplate(e, tmpl) } -func renderTemplate(kevt *Kevent, tmpl *template.Template) ([]byte, error) { +func renderTemplate(evt *Event, tmpl *template.Template) ([]byte, error) { var writer bytes.Buffer data := struct { - Kevt *Kevent + Evt *Event SerializeHandles bool SerializeThreads bool SerializeImages bool SerializeEnvs bool SerializePE bool }{ - kevt, + evt, SerializeHandles, SerializeThreads, SerializeImages, diff --git a/pkg/kevent/ktypes/ktypes_windows.go b/pkg/event/types_windows.go similarity index 92% rename from pkg/kevent/ktypes/ktypes_windows.go rename to pkg/event/types_windows.go index 1eb62e2b3..db44c512e 100644 --- a/pkg/kevent/ktypes/ktypes_windows.go +++ b/pkg/event/types_windows.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package ktypes +package event import ( "encoding/binary" @@ -43,8 +43,8 @@ const ( ThreadpoolLogger ) -// Ktype identifies an event type. It comprises the event GUID + hook ID to uniquely identify the event -type Ktype [18]byte +// Type identifies an event type. It comprises the event GUID + hook ID to uniquely identify the event +type Type [18]byte var ( // ProcessEventGUID represents process provider event GUID @@ -221,19 +221,19 @@ var ( // SetThreadpoolTimer represents the event that sets the thread pool timer object SetThreadpoolTimer = pack(ThreadpoolGUID, 44) - // UnknownKtype designates unknown kernel event type - UnknownKtype = pack(windows.GUID{}, 0) + // UnknownType designates unknown event type + UnknownType = pack(windows.GUID{}, 0) ) // NewFromEventRecord creates a new event type from ETW event record. -func NewFromEventRecord(ev *etw.EventRecord) Ktype { +func NewFromEventRecord(ev *etw.EventRecord) Type { return pack(ev.Header.ProviderID, ev.HookID()) } // String returns the string representation of the event type. Returns an empty string // if the event type is not recognized. -func (k Ktype) String() string { - switch k { +func (t Type) String() string { + switch t { case CreateProcess: return "CreateProcess" case TerminateProcess: @@ -350,8 +350,8 @@ func (k Ktype) String() string { } // Category determines the category to which the event type pertains. -func (k Ktype) Category() Category { - switch k { +func (t Type) Category() Category { + switch t { case CreateProcess, TerminateProcess, OpenProcess, ProcessRundown: return Process case CreateThread, TerminateThread, OpenThread, SetThreadContext, ThreadRundown, StackWalk: @@ -387,8 +387,8 @@ func (k Ktype) Category() Category { } // Subcategory determines the event subcategory, if any. -func (k Ktype) Subcategory() Subcategory { - switch k { +func (t Type) Subcategory() Subcategory { + switch t { case QueryDNS, ReplyDNS: return DNS default: @@ -397,8 +397,8 @@ func (k Ktype) Subcategory() Subcategory { } // Description returns a brief description of the event type. -func (k Ktype) Description() string { - switch k { +func (t Type) Description() string { + switch t { case CreateProcess: return "Creates a new process and its primary thread" case TerminateProcess: @@ -495,21 +495,21 @@ func (k Ktype) Description() string { } // Hash calculates the hash number of the event type. -func (k Ktype) Hash() uint32 { - if k == UnknownKtype { +func (t Type) Hash() uint32 { + if t == UnknownType { return 0 } - return hashers.FnvUint32([]byte(k.String())) + return hashers.FnvUint32([]byte(t.String())) } // Exists determines whether particular event type exists. -func (k Ktype) Exists() bool { - return k.String() != "" +func (t Type) Exists() bool { + return t.String() != "" } // OnlyState determines whether the event type is solely used for state management. -func (k Ktype) OnlyState() bool { - switch k { +func (t Type) OnlyState() bool { + switch t { case ProcessRundown, ThreadRundown, ImageRundown, @@ -527,8 +527,8 @@ func (k Ktype) OnlyState() bool { } // CanEnrichStack determines if the event can be enriched with a callstack. -func (k Ktype) CanEnrichStack() bool { - switch k { +func (t Type) CanEnrichStack() bool { + switch t { case CreateProcess, CreateThread, TerminateThread, @@ -549,35 +549,35 @@ func (k Ktype) CanEnrichStack() bool { } } -// UnmarshalYAML converts the ktype name to ktype array type. -func (k *Ktype) UnmarshalYAML(unmarshal func(interface{}) error) error { - var ktyp string - err := unmarshal(&ktyp) +// UnmarshalYAML converts the Type name to Type array type. +func (t *Type) UnmarshalYAML(unmarshal func(interface{}) error) error { + var typ string + err := unmarshal(&typ) if err != nil { return err } - *k = KeventNameToKtype(ktyp) + *t = NameToType(typ) return nil } -// GUID returns the event GUID from the raw ktype. -func (k *Ktype) GUID() windows.GUID { +// GUID returns the event GUID from the raw event type. +func (t *Type) GUID() windows.GUID { return windows.GUID{ - Data1: binary.BigEndian.Uint32(k[0:4]), - Data2: binary.BigEndian.Uint16(k[4:6]), - Data3: binary.BigEndian.Uint16(k[6:8]), - Data4: [8]byte{k[8], k[9], k[10], k[11], k[12], k[13], k[14], k[15]}, + Data1: binary.BigEndian.Uint32(t[0:4]), + Data2: binary.BigEndian.Uint16(t[4:6]), + Data3: binary.BigEndian.Uint16(t[6:8]), + Data4: [8]byte{t[8], t[9], t[10], t[11], t[12], t[13], t[14], t[15]}, } } -// HookID returns the event operation code (hook ID) from the raw ktype. -func (k *Ktype) HookID() uint16 { - return binary.BigEndian.Uint16(k[16:]) +// HookID returns the event operation code (hook ID) from the raw event type. +func (t *Type) HookID() uint16 { + return binary.BigEndian.Uint16(t[16:]) } // Source designates the provenance of this event type. -func (k Ktype) Source() EventSource { - switch k { +func (t Type) Source() EventSource { + switch t { case OpenProcess, OpenThread, SetThreadContext, CreateSymbolicLinkObject: return AuditAPICallsLogger case QueryDNS, ReplyDNS: @@ -594,17 +594,17 @@ func (k Ktype) Source() EventSource { // its timestamp is perfectly aligned in relation to other // events, but it appears first on the consumer callback // before other events published before it. -func (k Ktype) CanArriveOutOfOrder() bool { - return k.Category() == Threadpool || k.Subcategory() == DNS || - k == OpenProcess || k == OpenThread || k == SetThreadContext || k == CreateSymbolicLinkObject +func (t Type) CanArriveOutOfOrder() bool { + return t.Category() == Threadpool || t.Subcategory() == DNS || + t == OpenProcess || t == OpenThread || t == SetThreadContext || t == CreateSymbolicLinkObject } -// FromParts builds ktype from provider GUID and hook ID. -func FromParts(g windows.GUID, id uint16) Ktype { return pack(g, id) } +// TypeFromParts builds the event type from provider GUID and hook ID. +func TypeFromParts(g windows.GUID, id uint16) Type { return pack(g, id) } -// pack merges event provider GUID and the hook ID into `Ktype` array. +// pack merges event provider GUID and the hook ID into `Type` array. // The type provides a convenient way for comparing event types. -func pack(g windows.GUID, id uint16) Ktype { +func pack(g windows.GUID, id uint16) Type { return [18]byte{ byte(g.Data1 >> 24), byte(g.Data1 >> 16), byte(g.Data1 >> 8), byte(g.Data1), byte(g.Data2 >> 8), byte(g.Data2), diff --git a/pkg/kevent/ktypes/ktypes_windows_test.go b/pkg/event/types_windows_test.go similarity index 89% rename from pkg/kevent/ktypes/ktypes_windows_test.go rename to pkg/event/types_windows_test.go index 2f6b1da56..a93c15b5a 100644 --- a/pkg/kevent/ktypes/ktypes_windows_test.go +++ b/pkg/event/types_windows_test.go @@ -16,7 +16,7 @@ * limitations under the License. */ -package ktypes +package event import ( "github.com/rabbitstack/fibratus/pkg/sys/etw" @@ -26,7 +26,7 @@ import ( "testing" ) -func TestPackAllBytes(t *testing.T) { +func TestEventTypePackAllBytes(t *testing.T) { assert.Equal(t, byte(0x3d), CreateProcess[0]) assert.Equal(t, byte(0x6f), CreateProcess[1]) assert.Equal(t, byte(0xa8), CreateProcess[2]) @@ -53,11 +53,11 @@ func TestPackAllBytes(t *testing.T) { assert.Equal(t, byte(0xbe), QueryDNS[17]) } -func TestKtypeComparision(t *testing.T) { +func TestEventTypeComparison(t *testing.T) { var tests = []struct { name string - ktyp Ktype - wants Ktype + ktyp Type + wants Type }{ { "equals CreateProcess", @@ -79,7 +79,7 @@ func TestKtypeComparision(t *testing.T) { } } -func TestNewFromEventRecord(t *testing.T) { +func TestNewEventTypeFromEventRecord(t *testing.T) { assert.Equal(t, CreateProcess, NewFromEventRecord(&etw.EventRecord{ Header: etw.EventHeader{ ProviderID: windows.GUID{Data1: 0x3d6fa8d0, Data2: 0xfe05, Data3: 0x11d0, Data4: [8]byte{0x9d, 0xda, 0x0, 0xc0, 0x4f, 0xd7, 0xba, 0x7c}}, @@ -98,14 +98,14 @@ func TestNewFromEventRecord(t *testing.T) { })) } -func TestKtypeExists(t *testing.T) { +func TestEventTypeExists(t *testing.T) { require.True(t, AcceptTCPv4.Exists()) require.True(t, AcceptTCPv6.Exists()) } -func TestGUIDAndHookIDFromKtype(t *testing.T) { +func TestGUIDAndHookIDFromEventType(t *testing.T) { var tests = []struct { - ktype Ktype + Type Type opcode uint16 guid windows.GUID }{ @@ -122,9 +122,9 @@ func TestGUIDAndHookIDFromKtype(t *testing.T) { } for _, tt := range tests { - t.Run(tt.ktype.String(), func(t *testing.T) { - assert.Equal(t, tt.guid.String(), tt.ktype.GUID().String()) - assert.Equal(t, tt.opcode, tt.ktype.HookID()) + t.Run(tt.Type.String(), func(t *testing.T) { + assert.Equal(t, tt.guid.String(), tt.Type.GUID().String()) + assert.Equal(t, tt.opcode, tt.Type.HookID()) }) } } diff --git a/pkg/filament/_fixtures/test_filter.py b/pkg/filament/_fixtures/test_filter.py index 33c1afbbb..2211180a9 100644 --- a/pkg/filament/_fixtures/test_filter.py +++ b/pkg/filament/_fixtures/test_filter.py @@ -23,5 +23,5 @@ def on_init(): kfilter('ps.name in (%s)' % ','.join(["'svchost.exe'", "'cmd.exe'", "'mimikatz.exe'"])) -def on_next_kevent(kevent): +def on_next_kevent(Event): pass \ No newline at end of file diff --git a/pkg/filament/_fixtures/test_on_next_kevent.py b/pkg/filament/_fixtures/test_on_next_kevent.py index 07b490f96..080ae9132 100644 --- a/pkg/filament/_fixtures/test_on_next_kevent.py +++ b/pkg/filament/_fixtures/test_on_next_kevent.py @@ -25,8 +25,8 @@ def on_init(): columns(['Key', '#Seq']) sort_by('#Seq') -def on_next_kevent(kevent): - kevents.append({'key_name': kevent['kparams']['key_name'], 'seq': kevent['seq'], 'dip': kevent['kparams']['dip']}) +def on_next_kevent(Event): + kevents.append({'key_name': Event['params']['key_name'], 'seq': Event['seq'], 'dip': Event['params']['dip']}) def on_interval(): for key in kevents: diff --git a/pkg/filament/_fixtures/top_hives_io.py b/pkg/filament/_fixtures/top_hives_io.py index b58fcc640..7855e5922 100644 --- a/pkg/filament/_fixtures/top_hives_io.py +++ b/pkg/filament/_fixtures/top_hives_io.py @@ -29,6 +29,6 @@ def on_init(): sort_by("1") -def on_next_kevent(kevent): +def on_next_kevent(Event): pass diff --git a/pkg/filament/_fixtures/top_keys_io_table.py b/pkg/filament/_fixtures/top_keys_io_table.py index 104e3cdb8..ae039b73f 100644 --- a/pkg/filament/_fixtures/top_keys_io_table.py +++ b/pkg/filament/_fixtures/top_keys_io_table.py @@ -29,7 +29,7 @@ def on_init(): sort_by('#Ops') -def on_next_kevent(kevent): +def on_next_kevent(Event): pass diff --git a/pkg/filament/cpython/_fixtures/top_hives_io.py b/pkg/filament/cpython/_fixtures/top_hives_io.py index 9695ab4fe..5621a4cb1 100644 --- a/pkg/filament/cpython/_fixtures/top_hives_io.py +++ b/pkg/filament/cpython/_fixtures/top_hives_io.py @@ -32,8 +32,8 @@ def on_init(): #set_interval(1) -def on_next_kevent(kevent): - print("KEVENT\n", kevent["kparams"]) +def on_next_kevent(Event): + print("Event\n", Event["params"]) #raise Exception('eggs', 'eggs') def on_interval(): diff --git a/pkg/filament/dict.go b/pkg/filament/dict.go new file mode 100644 index 000000000..307261e1c --- /dev/null +++ b/pkg/filament/dict.go @@ -0,0 +1,114 @@ +//go:build filament && windows +// +build filament,windows + +/* + * Copyright 2019-2020 by Nedim Sabic Sabic + * https://www.fibratus.io + * All Rights Reserved. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package filament + +import ( + "errors" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" + "github.com/rabbitstack/fibratus/pkg/filament/cpython" +) + +var ( + seq = cpython.PyUnicodeFromString("seq") + pid = cpython.PyUnicodeFromString("pid") + ppid = cpython.PyUnicodeFromString("ppid") + cwd = cpython.PyUnicodeFromString("cwd") + exec = cpython.PyUnicodeFromString("exe") + comm = cpython.PyUnicodeFromString("comm") + sid = cpython.PyUnicodeFromString("sid") + tid = cpython.PyUnicodeFromString("tid") + cpu = cpython.PyUnicodeFromString("cpu") + name = cpython.PyUnicodeFromString("name") + cat = cpython.PyUnicodeFromString("category") + desc = cpython.PyUnicodeFromString("description") + host = cpython.PyUnicodeFromString("host") + ts = cpython.PyUnicodeFromString("timestamp") + parameters = cpython.PyUnicodeFromString("params") + + errDictAllocate = errors.New("couldn't allocate a new dict") +) + +// newEventDict constructs a Python dictionary object from event structure. This dictionary object is +// passed to the event dispatching function in the filament. +func newEventDict(evt *event.Event) (*cpython.Dict, error) { + dict := cpython.NewDict() + if dict.IsNull() { + return nil, errDictAllocate + } + + // insert canonical event fields + dict.Insert(seq, cpython.NewPyObjectFromValue(evt.Seq)) + dict.Insert(pid, cpython.NewPyObjectFromValue(evt.PID)) + dict.Insert(tid, cpython.NewPyObjectFromValue(evt.Tid)) + dict.Insert(cpu, cpython.NewPyObjectFromValue(evt.CPU)) + dict.Insert(name, cpython.NewPyObjectFromValue(evt.Name)) + dict.Insert(cat, cpython.NewPyObjectFromValue(string(evt.Category))) + dict.Insert(desc, cpython.NewPyObjectFromValue(evt.Description)) + dict.Insert(host, cpython.NewPyObjectFromValue(evt.Host)) + dict.Insert(ts, cpython.NewPyObjectFromValue(evt.Timestamp)) + + // insert process state fields + ps := evt.PS + if ps != nil { + dict.Insert(ppid, cpython.NewPyObjectFromValue(ps.Ppid)) + dict.Insert(cwd, cpython.NewPyObjectFromValue(ps.Cwd)) + dict.Insert(exec, cpython.NewPyObjectFromValue(ps.Name)) + dict.Insert(comm, cpython.NewPyObjectFromValue(ps.Cmdline)) + dict.Insert(sid, cpython.NewPyObjectFromValue(ps.SID)) + } + + // insert event parameters + pars := cpython.NewDict() + for _, par := range evt.Params { + var val interface{} + var err error + switch par.Type { + case params.Uint8: + val, err = evt.Params.GetUint8(par.Name) + case params.Uint16, params.Port: + val, err = evt.Params.GetUint16(par.Name) + case params.Uint32, params.PID, params.TID: + val, err = evt.Params.GetUint32(par.Name) + case params.Uint64: + val, err = evt.Params.GetUint64(par.Name) + case params.Time: + val, err = evt.Params.GetTime(par.Name) + case params.IP: + val, err = evt.Params.GetIP(par.Name) + default: + val = evt.GetParamAsString(par.Name) + } + if err != nil { + continue + } + param := cpython.NewPyObjectFromValue(val) + if param.IsNull() { + continue + } + pars.Insert(cpython.PyUnicodeFromString(par.Name), param) + } + + dict.Insert(parameters, pars.Object()) + + return dict, nil +} diff --git a/pkg/filament/kdict_test.go b/pkg/filament/dict_test.go similarity index 76% rename from pkg/filament/kdict_test.go rename to pkg/filament/dict_test.go index 22c184ca4..069f72c26 100644 --- a/pkg/filament/kdict_test.go +++ b/pkg/filament/dict_test.go @@ -22,10 +22,9 @@ package filament import ( + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filament/cpython" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" @@ -33,7 +32,7 @@ import ( "time" ) -func TestProduceKdict(t *testing.T) { +func TestProduceEventDict(t *testing.T) { // this test crashes in the CI. Reenable once // we investigate why this happens t.SkipNow() @@ -41,18 +40,18 @@ func TestProduceKdict(t *testing.T) { require.NoError(t, err) defer cpython.Finalize() now := time.Now() - kevt := &kevent.Kevent{ + evt := &event.Event{ Seq: uint64(12456738026482168384), Tid: 2484, PID: 859, CPU: 1, Name: "CreateFile", Timestamp: now, - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", } - dict, err := newKDict(kevt) + dict, err := newEventDict(evt) require.NoError(t, err) require.NotNil(t, dict) @@ -72,7 +71,7 @@ func TestProduceKdict(t *testing.T) { assert.Equal(t, timestamp.Second(), now.Second()) } -func TestProduceKdictWithIPAddresses(t *testing.T) { +func TestProduceEventDictWithIPAddresses(t *testing.T) { // this test crashes in the CI. Reenable once // we investigate why this happens t.SkipNow() @@ -80,30 +79,30 @@ func TestProduceKdictWithIPAddresses(t *testing.T) { require.NoError(t, err) defer cpython.Finalize() - kevt := &kevent.Kevent{ + evt := &event.Event{ Name: "Send", Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv6, Value: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv6, Value: net.ParseIP("2001:0db8:85a3:0000:0000:8a2e:0370:7334")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - dict, err := newKDict(kevt) + dict, err := newEventDict(evt) require.NoError(t, err) require.NotNil(t, dict) - kpars := dict.Get(cpython.PyUnicodeFromString("kparams")) + kpars := dict.Get(cpython.PyUnicodeFromString("params")) kparamsDict := cpython.NewDictFromObject(kpars) assert.Equal(t, "216.58.201.174", kparamsDict.Get(cpython.PyUnicodeFromString("dip")).String()) assert.Equal(t, "2001:db8:85a3::8a2e:370:7334", kparamsDict.Get(cpython.PyUnicodeFromString("sip")).String()) } -func BenchmarkTestProduceKdict(b *testing.B) { +func BenchmarkTestProduceEventDict(b *testing.B) { // this crashes in the CI. Reenable once // we investigate why this happens b.SkipNow() @@ -112,20 +111,20 @@ func BenchmarkTestProduceKdict(b *testing.B) { require.NoError(b, err) defer cpython.Finalize() - kevt := &kevent.Kevent{ + evt := &event.Event{ Seq: uint64(12456738026482168384), Tid: 2484, PID: 859, CPU: 1, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", } for i := 0; i < b.N; i++ { - dict, err := newKDict(kevt) + dict, err := newEventDict(evt) if err != nil || dict.IsNull() { b.Fatal("invalid dict produced") } diff --git a/pkg/filament/filament.go b/pkg/filament/filament.go index 54bb978a6..2a2c5f7a8 100644 --- a/pkg/filament/filament.go +++ b/pkg/filament/filament.go @@ -27,10 +27,10 @@ import ( "fmt" "github.com/rabbitstack/fibratus/pkg/alertsender" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filament/cpython" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/handle" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/multierror" "github.com/rabbitstack/fibratus/pkg/util/term" @@ -55,7 +55,7 @@ const ( intervalFn = "interval" columnsFn = "columns" sortbyFn = "sort_by" - kfilterFn = "kfilter" + setFilterFn = "set_filter" addRowFn = "add_row" maxRowsFn = "max_rows" titleFn = "title" @@ -66,37 +66,37 @@ const ( findProcessesFn = "find_processes" emitAlertFn = "emit_alert" - onInitFn = "on_init" - onStopFn = "on_stop" - onNextKeventFn = "on_next_kevent" - onIntervalFn = "on_interval" - doc = "__doc__" + onInitFn = "on_init" + onStopFn = "on_stop" + onNextEventFn = "on_next_event" + onIntervalFn = "on_interval" + doc = "__doc__" ) var ( - keventErrors = expvar.NewMap("filament.kevent.errors") - keventProcessErrors = expvar.NewInt("filament.kevent.process.errors") + keventErrors = expvar.NewMap("filament.event.errors") + keventProcessErrors = expvar.NewInt("filament.event.process.errors") kdictErrors = expvar.NewInt("filament.kdict.errors") - batchFlushes = expvar.NewInt("filament.kevent.batch.flushes") + batchFlushes = expvar.NewInt("filament.event.batch.flushes") errFilamentsDir = func(path string) error { return fmt.Errorf("%s does not exist or is not a directory", path) } - errNoDoc = errors.New("filament description is required") - errNoOnNextKevent = errors.New("required on_next_kevent function is not defined") - errOnNextKeventNotCallable = errors.New("on_next_kevent is not callable") - errOnNextKeventMismatchArgs = func(c uint32) error { return fmt.Errorf("expected 1 argument for on_next_kevent but found %d args", c) } - errEmptyName = errors.New("filament name is empty") + errNoDoc = errors.New("filament description is required") + errNoOnNextEvent = errors.New("required on_next_event function is not defined") + errOnNextEventNotCallable = errors.New("on_next_event is not callable") + errOnNextEventMismatchArgs = func(c uint32) error { return fmt.Errorf("expected 1 argument for on_next_event but found %d args", c) } + errEmptyName = errors.New("filament name is empty") tableOutput io.Writer ) -type kbatch []*kevent.Kevent +type kbatch []*event.Event -func (k *kbatch) append(kevt *kevent.Kevent) { +func (k *kbatch) append(evt *event.Event) { if *k == nil { - *k = make([]*kevent.Kevent, 0) + *k = make([]*event.Event, 0) } - *k = append(*k, kevt) + *k = append(*k, evt) } func (k *kbatch) reset() { *k = nil } @@ -205,26 +205,26 @@ func New( // ensure required attributes are present before proceeding with // further initialization. For instance, if the documentation - // string is not provided, on_next_kevent function is missing + // string is not provided, on_next_event function is missing // or has a wrong signature we won't run the filament doc, err := mod.GetAttrString(doc) if err != nil || doc.IsNull() { return nil, errNoDoc } defer doc.DecRef() - if !mod.HasAttr(onNextKeventFn) { - return nil, errNoOnNextKevent + if !mod.HasAttr(onNextEventFn) { + return nil, errNoOnNextEvent } - onNextKevent, err := mod.GetAttrString(onNextKeventFn) - if err != nil || onNextKevent.IsNull() { - return nil, errNoOnNextKevent + onNextEvent, err := mod.GetAttrString(onNextEventFn) + if err != nil || onNextEvent.IsNull() { + return nil, errNoOnNextEvent } - if !onNextKevent.IsCallable() { - return nil, errOnNextKeventNotCallable + if !onNextEvent.IsCallable() { + return nil, errOnNextEventNotCallable } - argCount := onNextKevent.CallableArgCount() + argCount := onNextEvent.CallableArgCount() if argCount != 1 { - return nil, errOnNextKeventMismatchArgs(argCount) + return nil, errOnNextEventMismatchArgs(argCount) } f := &filament{ @@ -237,7 +237,7 @@ func New( fnerrs: make(chan error, 100), gil: cpython.NewGIL(), columns: make([]string, 0), - onNextKevent: onNextKevent, + onNextKevent: onNextEvent, interval: time.Second, initErrors: make([]error, 0), table: newTable(), @@ -272,7 +272,7 @@ func New( if err != nil { return nil, err } - err = f.mod.RegisterFn(kfilterFn, f.kfilterFn, cpython.DefaultMethFlags) + err = f.mod.RegisterFn(setFilterFn, f.setFilterFn, cpython.DefaultMethFlags) if err != nil { return nil, err } @@ -368,7 +368,7 @@ func New( return f, nil } -func (f *filament) Run(kevents <-chan *kevent.Kevent, errs <-chan error) error { +func (f *filament) Run(kevents <-chan *event.Event, errs <-chan error) error { var batch kbatch var flusher = time.NewTicker(time.Second) for { @@ -380,14 +380,14 @@ func (f *filament) Run(kevents <-chan *kevent.Kevent, errs <-chan error) error { } select { - case kevt := <-kevents: - batch.append(kevt) + case evt := <-kevents: + batch.append(evt) case err := <-errs: keventErrors.Add(err.Error(), 1) case <-flusher.C: batchFlushes.Add(1) if batch.len() > 0 { - err := f.pushKevents(batch) + err := f.pushEvents(batch) if err != nil { log.Warnf("on_next_kevent failed: %v", err) keventProcessErrors.Add(1) @@ -403,21 +403,21 @@ func (f *filament) Run(kevents <-chan *kevent.Kevent, errs <-chan error) error { } } -func (f *filament) pushKevents(b kbatch) error { +func (f *filament) pushEvents(b kbatch) error { f.gil.Lock() defer f.gil.Unlock() - for _, kevt := range b { - kdict, err := newKDict(kevt) + for _, evt := range b { + dict, err := newEventDict(evt) if err != nil { - kdict.DecRef() + dict.DecRef() kdictErrors.Add(1) continue } - r := f.onNextKevent.Call(kdict.Object()) + r := f.onNextKevent.Call(dict.Object()) if r != nil { r.DecRef() } - kdict.DecRef() + dict.DecRef() if err := cpython.FetchErr(); err != nil { return err } @@ -472,7 +472,7 @@ func (f *filament) columnsFn(_, args cpython.PyArgs) cpython.PyRawObject { return cpython.NewPyNone() } -func (f *filament) kfilterFn(_, args cpython.PyArgs) cpython.PyRawObject { +func (f *filament) setFilterFn(_, args cpython.PyArgs) cpython.PyRawObject { f.fexpr = args.GetString(1) return cpython.NewPyNone() } diff --git a/pkg/filament/filament_test.go b/pkg/filament/filament_test.go index c61c9751f..862238fd6 100644 --- a/pkg/filament/filament_test.go +++ b/pkg/filament/filament_test.go @@ -25,9 +25,8 @@ import ( "bufio" "bytes" "github.com/rabbitstack/fibratus/pkg/config" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "net" @@ -65,26 +64,26 @@ func TestOnNextKevent(t *testing.T) { filament.Close() }) - kevents := make(chan *kevent.Kevent, 100) + kevents := make(chan *event.Event, 100) errs := make(chan error, 10) for i := 1; i <= 100; i++ { - kevt := &kevent.Kevent{ - Type: ktypes.RegCreateKey, + evt := &event.Event{ + Type: event.RegCreateKey, Tid: 2484, PID: 859, Name: "RegCreateKey", Host: "archrabbit", CPU: uint8(i / 2), - Category: ktypes.Registry, + Category: event.Registry, Seq: uint64(i), Timestamp: time.Now(), - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup`}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Address, Value: uint64(18446666033449935464)}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup`}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Address, Value: uint64(18446666033449935464)}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - kevents <- kevt + kevents <- evt } err = filament.Run(kevents, errs) require.Nil(t, err) @@ -105,18 +104,18 @@ func TestFilamentFilter(t *testing.T) { require.NotNil(t, filament) defer filament.Close() require.NotNil(t, filament.Filter()) - kpars := kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "svchost.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(1234)}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.Uint32, Value: uint32(345)}, + kpars := event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "svchost.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(1234)}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.Uint32, Value: uint32(345)}, } - kevt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kpars, - Name: "CreateProcess", + evt := &event.Event{ + Type: event.CreateProcess, + Params: kpars, + Name: "CreateProcess", } - require.True(t, filament.Filter().Run(kevt)) + require.True(t, filament.Filter().Run(evt)) } diff --git a/pkg/filament/filament_unsupported.go b/pkg/filament/filament_unsupported.go index fd5f83b0d..24fadfc11 100644 --- a/pkg/filament/filament_unsupported.go +++ b/pkg/filament/filament_unsupported.go @@ -23,7 +23,7 @@ package filament import ( "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/handle" "github.com/rabbitstack/fibratus/pkg/ps" ) @@ -35,5 +35,5 @@ func New( hsnap handle.Snapshotter, config *config.Config, ) (Filament, error) { - return nil, kerrors.ErrFeatureUnsupported("filament") + return nil, errs.ErrFeatureUnsupported("filament") } diff --git a/pkg/filament/kdict.go b/pkg/filament/kdict.go deleted file mode 100644 index fd39f108a..000000000 --- a/pkg/filament/kdict.go +++ /dev/null @@ -1,114 +0,0 @@ -//go:build filament && windows -// +build filament,windows - -/* - * Copyright 2019-2020 by Nedim Sabic Sabic - * https://www.fibratus.io - * All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package filament - -import ( - "errors" - "github.com/rabbitstack/fibratus/pkg/filament/cpython" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" -) - -var ( - seq = cpython.PyUnicodeFromString("seq") - pid = cpython.PyUnicodeFromString("pid") - ppid = cpython.PyUnicodeFromString("ppid") - cwd = cpython.PyUnicodeFromString("cwd") - exec = cpython.PyUnicodeFromString("exe") - comm = cpython.PyUnicodeFromString("comm") - sid = cpython.PyUnicodeFromString("sid") - tid = cpython.PyUnicodeFromString("tid") - cpu = cpython.PyUnicodeFromString("cpu") - name = cpython.PyUnicodeFromString("name") - cat = cpython.PyUnicodeFromString("category") - desc = cpython.PyUnicodeFromString("description") - host = cpython.PyUnicodeFromString("host") - ts = cpython.PyUnicodeFromString("timestamp") - kparamsk = cpython.PyUnicodeFromString("kparams") - - errDictAllocate = errors.New("couldn't allocate a new dict") -) - -// newKDict constructs a Python dictionary object from the kernel event structure. This dictionary object is -// passed to the event dispatching function in the filament. -func newKDict(kevt *kevent.Kevent) (*cpython.Dict, error) { - kdict := cpython.NewDict() - if kdict.IsNull() { - return nil, errDictAllocate - } - - // insert canonical kevent fields - kdict.Insert(seq, cpython.NewPyObjectFromValue(kevt.Seq)) - kdict.Insert(pid, cpython.NewPyObjectFromValue(kevt.PID)) - kdict.Insert(tid, cpython.NewPyObjectFromValue(kevt.Tid)) - kdict.Insert(cpu, cpython.NewPyObjectFromValue(kevt.CPU)) - kdict.Insert(name, cpython.NewPyObjectFromValue(kevt.Name)) - kdict.Insert(cat, cpython.NewPyObjectFromValue(string(kevt.Category))) - kdict.Insert(desc, cpython.NewPyObjectFromValue(kevt.Description)) - kdict.Insert(host, cpython.NewPyObjectFromValue(kevt.Host)) - kdict.Insert(ts, cpython.NewPyObjectFromValue(kevt.Timestamp)) - - // insert process state fields - ps := kevt.PS - if ps != nil { - kdict.Insert(ppid, cpython.NewPyObjectFromValue(ps.Ppid)) - kdict.Insert(cwd, cpython.NewPyObjectFromValue(ps.Cwd)) - kdict.Insert(exec, cpython.NewPyObjectFromValue(ps.Name)) - kdict.Insert(comm, cpython.NewPyObjectFromValue(ps.Cmdline)) - kdict.Insert(sid, cpython.NewPyObjectFromValue(ps.SID)) - } - - // insert kevent parameters - kpars := cpython.NewDict() - for _, kpar := range kevt.Kparams { - var val interface{} - var err error - switch kpar.Type { - case kparams.Uint8: - val, err = kevt.Kparams.GetUint8(kpar.Name) - case kparams.Uint16, kparams.Port: - val, err = kevt.Kparams.GetUint16(kpar.Name) - case kparams.Uint32, kparams.PID, kparams.TID: - val, err = kevt.Kparams.GetUint32(kpar.Name) - case kparams.Uint64: - val, err = kevt.Kparams.GetUint64(kpar.Name) - case kparams.Time: - val, err = kevt.Kparams.GetTime(kpar.Name) - case kparams.IP: - val, err = kevt.Kparams.GetIP(kpar.Name) - default: - val = kevt.GetParamAsString(kpar.Name) - } - if err != nil { - continue - } - kparam := cpython.NewPyObjectFromValue(val) - if kparam.IsNull() { - continue - } - kpars.Insert(cpython.PyUnicodeFromString(kpar.Name), kparam) - } - - kdict.Insert(kparamsk, kpars.Object()) - - return kdict, nil -} diff --git a/pkg/filament/types.go b/pkg/filament/types.go index b23a5f8a5..8e2087b1b 100644 --- a/pkg/filament/types.go +++ b/pkg/filament/types.go @@ -19,15 +19,15 @@ package filament import ( + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" - "github.com/rabbitstack/fibratus/pkg/kevent" ) // Filament defines the set of operations all filaments have to satisfy. Filament represents a full-fledged // Python interpreter that runs the modules given by users. type Filament interface { // Run consumes all events from the kernel event stream and dispatches them to the filament. - Run(<-chan *kevent.Kevent, <-chan error) error + Run(<-chan *event.Event, <-chan error) error // Close shutdowns the filament by releasing all allocated resources. Close() error // Filter returns the filter compiled from filament. diff --git a/pkg/filter/accessor.go b/pkg/filter/accessor.go index 49ea069bd..27124c495 100644 --- a/pkg/filter/accessor.go +++ b/pkg/filter/accessor.go @@ -20,9 +20,9 @@ package filter import ( "errors" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" "reflect" ) @@ -36,7 +36,7 @@ var ( // from the non-params constructs such as process' state or PE metadata. type Accessor interface { // Get fetches the parameter value for the specified filter field. - Get(f Field, evt *kevent.Kevent) (kparams.Value, error) + Get(f Field, evt *event.Event) (params.Value, error) // SetFields sets all fields declared in the expression. SetFields(fields []Field) // SetSegments sets all segments utilized in the function predicate expression. @@ -45,94 +45,94 @@ type Accessor interface { // given event. The condition is usually based on the event category, // but it can also include different circumstances, like the presence // of the process state or callstacks. - IsFieldAccessible(evt *kevent.Kevent) bool + IsFieldAccessible(evt *event.Event) bool } -// kevtAccessor extracts generic event values. -type kevtAccessor struct{} +// evtAccessor extracts generic event values. +type evtAccessor struct{} -func (kevtAccessor) SetFields([]Field) {} -func (kevtAccessor) SetSegments([]fields.Segment) {} -func (kevtAccessor) IsFieldAccessible(*kevent.Kevent) bool { return true } +func (evtAccessor) SetFields([]Field) {} +func (evtAccessor) SetSegments([]fields.Segment) {} +func (evtAccessor) IsFieldAccessible(*event.Event) bool { return true } -func newKevtAccessor() Accessor { - return &kevtAccessor{} +func newEventAccessor() Accessor { + return &evtAccessor{} } const timeFmt = "15:04:05" const dateFmt = "2006-01-02" -func (k *kevtAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (k *evtAccessor) Get(f Field, evt *event.Event) (params.Value, error) { switch f.Name { case fields.KevtSeq: - return kevt.Seq, nil + return evt.Seq, nil case fields.KevtPID: - return kevt.PID, nil + return evt.PID, nil case fields.KevtTID: - return kevt.Tid, nil + return evt.Tid, nil case fields.KevtCPU: - return kevt.CPU, nil + return evt.CPU, nil case fields.KevtName: - return kevt.Name, nil + return evt.Name, nil case fields.KevtCategory: - return string(kevt.Category), nil + return string(evt.Category), nil case fields.KevtDesc: - return kevt.Description, nil + return evt.Description, nil case fields.KevtHost: - return kevt.Host, nil + return evt.Host, nil case fields.KevtTime: - return kevt.Timestamp.Format(timeFmt), nil + return evt.Timestamp.Format(timeFmt), nil case fields.KevtTimeHour: - return uint8(kevt.Timestamp.Hour()), nil + return uint8(evt.Timestamp.Hour()), nil case fields.KevtTimeMin: - return uint8(kevt.Timestamp.Minute()), nil + return uint8(evt.Timestamp.Minute()), nil case fields.KevtTimeSec: - return uint8(kevt.Timestamp.Second()), nil + return uint8(evt.Timestamp.Second()), nil case fields.KevtTimeNs: - return kevt.Timestamp.UnixNano(), nil + return evt.Timestamp.UnixNano(), nil case fields.KevtDate: - return kevt.Timestamp.Format(dateFmt), nil + return evt.Timestamp.Format(dateFmt), nil case fields.KevtDateDay: - return uint8(kevt.Timestamp.Day()), nil + return uint8(evt.Timestamp.Day()), nil case fields.KevtDateMonth: - return uint8(kevt.Timestamp.Month()), nil + return uint8(evt.Timestamp.Month()), nil case fields.KevtDateTz: - tz, _ := kevt.Timestamp.Zone() + tz, _ := evt.Timestamp.Zone() return tz, nil case fields.KevtDateYear: - return uint32(kevt.Timestamp.Year()), nil + return uint32(evt.Timestamp.Year()), nil case fields.KevtDateWeek: - _, week := kevt.Timestamp.ISOWeek() + _, week := evt.Timestamp.ISOWeek() return uint8(week), nil case fields.KevtDateWeekday: - return kevt.Timestamp.Weekday().String(), nil + return evt.Timestamp.Weekday().String(), nil case fields.KevtNparams: - return uint64(kevt.Kparams.Len()), nil + return uint64(evt.Params.Len()), nil case fields.KevtArg: // lookup the parameter from the field argument // and depending on the parameter type, return // the respective value. The field format is - // expressed as kevt.arg[cmdline] where the string + // expressed as evt.arg[cmdline] where the string // inside brackets represents the parameter name name := f.Arg - par, err := kevt.Kparams.Get(name) + par, err := evt.Params.Get(name) if err != nil { return nil, err } switch par.Type { - case kparams.Uint8: - return kevt.Kparams.GetUint8(name) - case kparams.Uint16, kparams.Port: - return kevt.Kparams.GetUint16(name) - case kparams.Uint32, kparams.PID, kparams.TID: - return kevt.Kparams.GetUint32(name) - case kparams.Uint64: - return kevt.Kparams.GetUint64(name) - case kparams.Time: - return kevt.Kparams.GetTime(name) + case params.Uint8: + return evt.Params.GetUint8(name) + case params.Uint16, params.Port: + return evt.Params.GetUint16(name) + case params.Uint32, params.PID, params.TID: + return evt.Params.GetUint32(name) + case params.Uint64: + return evt.Params.GetUint64(name) + case params.Time: + return evt.Params.GetTime(name) default: - return kevt.GetParamAsString(name), nil + return evt.GetParamAsString(name), nil } } @@ -189,7 +189,7 @@ func (f *filter) narrowAccessors() { } if removeKevtAccessor { - f.removeAccessor(&kevtAccessor{}) + f.removeAccessor(&evtAccessor{}) } if removePsAccessor { f.removeAccessor(&psAccessor{}) diff --git a/pkg/filter/accessor_windows.go b/pkg/filter/accessor_windows.go index 5ad8d5969..e3069ee59 100644 --- a/pkg/filter/accessor_windows.go +++ b/pkg/filter/accessor_windows.go @@ -22,7 +22,6 @@ import ( "errors" "expvar" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/network" psnap "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/cmdline" @@ -33,9 +32,9 @@ import ( "strings" "time" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" ) @@ -59,7 +58,7 @@ func GetAccessors() []Accessor { newMemAccessor(), newDNSAccessor(), newFileAccessor(), - newKevtAccessor(), + newEventAccessor(), newImageAccessor(), newThreadAccessor(), newHandleAccessor(), @@ -69,11 +68,11 @@ func GetAccessors() []Accessor { } } -func getParentPs(kevt *kevent.Kevent) *pstypes.PS { - if kevt.PS == nil { +func getParentPs(e *event.Event) *pstypes.PS { + if e.PS == nil { return nil } - return kevt.PS.Parent + return e.PS.Parent } // psAccessor extracts process's state or event specific values. @@ -83,181 +82,181 @@ type psAccessor struct { func (psAccessor) SetFields([]Field) {} func (psAccessor) SetSegments([]fields.Segment) {} -func (psAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.PS != nil || kevt.Category == ktypes.Process +func (psAccessor) IsFieldAccessible(e *event.Event) bool { + return e.PS != nil || e.Category == event.Process } func newPSAccessor(psnap psnap.Snapshotter) Accessor { return &psAccessor{psnap: psnap} } -func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (ps *psAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.PsPid: // identifier of the process that is generating the event - return kevt.PID, nil + return e.PID, nil case fields.PsSiblingPid, fields.PsChildPid: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - // the id of a created child process. `kevt.PID` is the parent process id - return kevt.Kparams.GetPid() + // the id of a created child process. `e.PID` is the parent process id + return e.Params.GetPid() case fields.PsPpid: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Ppid, nil case fields.PsName: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Name, nil case fields.PsSiblingName, fields.PsChildName: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetString(kparams.ProcessName) + return e.Params.GetString(params.ProcessName) case fields.PsComm, fields.PsCmdline: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Cmdline, nil case fields.PsSiblingComm, fields.PsChildCmdline: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetString(kparams.Cmdline) + return e.Params.GetString(params.Cmdline) case fields.PsExe: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Exe, nil case fields.PsSiblingExe, fields.PsChildExe: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetString(kparams.Exe) + return e.Params.GetString(params.Exe) case fields.PsArgs: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Args, nil case fields.PsSiblingArgs, fields.PsChildArgs: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - cmndline, err := kevt.Kparams.GetString(kparams.Cmdline) + cmndline, err := e.Params.GetString(params.Cmdline) if err != nil { return nil, err } return cmdline.Split(cmndline), nil case fields.PsCwd: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Cwd, nil case fields.PsSID: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.SID, nil case fields.PsSiblingSID, fields.PsChildSID: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - sid, err := kevt.Kparams.GetSID() + sid, err := e.Params.GetSID() if err != nil { return nil, err } return sid.String(), nil case fields.PsSiblingDomain, fields.PsChildDomain: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetString(kparams.Domain) + return e.Params.GetString(params.Domain) case fields.PsSiblingUsername, fields.PsChildUsername: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetString(kparams.Username) + return e.Params.GetString(params.Username) case fields.PsChildIsWOW64Field: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return (kevt.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsWOW64) != 0, nil + return (e.Params.MustGetUint32(params.ProcessFlags) & event.PsWOW64) != 0, nil case fields.PsChildIsPackagedField: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return (kevt.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsPackaged) != 0, nil + return (e.Params.MustGetUint32(params.ProcessFlags) & event.PsPackaged) != 0, nil case fields.PsChildIsProtectedField: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return (kevt.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsProtected) != 0, nil + return (e.Params.MustGetUint32(params.ProcessFlags) & event.PsProtected) != 0, nil case fields.PsIsWOW64Field: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.IsWOW64, nil case fields.PsIsPackagedField: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.IsPackaged, nil case fields.PsIsProtectedField: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.IsProtected, nil case fields.PsDomain: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Domain, nil case fields.PsUsername: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.Username, nil case fields.PsSessionID: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, nil } return ps.SessionID, nil case fields.PsAccessMask: - if kevt.Type != ktypes.OpenProcess { + if e.Type != event.OpenProcess { return nil, nil } - return kevt.Kparams.GetString(kparams.DesiredAccess) + return e.Params.GetString(params.DesiredAccess) case fields.PsAccessMaskNames: - if kevt.Type != ktypes.OpenProcess { + if e.Type != event.OpenProcess { return nil, nil } - return kevt.GetFlagsAsSlice(kparams.DesiredAccess), nil + return e.GetFlagsAsSlice(params.DesiredAccess), nil case fields.PsAccessStatus: - if kevt.Type != ktypes.OpenProcess { + if e.Type != event.OpenProcess { return nil, nil } - return kevt.GetParamAsString(kparams.NTStatus), nil + return e.GetParamAsString(params.NTStatus), nil case fields.PsSiblingSessionID, fields.PsChildSessionID: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - return kevt.Kparams.GetUint32(kparams.SessionID) + return e.Params.GetUint32(params.SessionID) case fields.PsModuleNames: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } @@ -267,23 +266,23 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return mods, nil case fields.PsUUID: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } return ps.UUID(), nil case fields.PsParentUUID: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.UUID(), nil case fields.PsChildUUID: - if kevt.Category != ktypes.Process { + if e.Category != event.Process { return nil, nil } - pid, err := kevt.Kparams.GetPid() + pid, err := e.Params.GetPid() if err != nil { return nil, err } @@ -298,7 +297,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { return proc.UUID(), nil case fields.PsHandleNames: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } @@ -308,7 +307,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return handles, nil case fields.PsHandleTypes: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } @@ -321,67 +320,67 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return types, nil case fields.PsParentPid: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.PID, nil case fields.PsParentName: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.Name, nil case fields.PsParentComm, fields.PsParentCmdline: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.Cmdline, nil case fields.PsParentExe: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.Exe, nil case fields.PsParentArgs: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.Args, nil case fields.PsParentCwd: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.Cwd, nil case fields.PsParentSID: - parent := getParentPs(kevt) + parent := getParentPs(e) if parent == nil { return nil, ErrPsNil } return parent.SID, nil case fields.PsParentDomain: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.Domain, nil case fields.PsParentUsername: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.Username, nil case fields.PsParentSessionID: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.SessionID, nil case fields.PsParentEnvs: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } @@ -391,7 +390,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return envs, nil case fields.PsParentHandles: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } @@ -401,7 +400,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return handles, nil case fields.PsParentHandleTypes: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } @@ -414,51 +413,51 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return types, nil case fields.PsParentIsWOW64Field: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.IsWOW64, nil case fields.PsParentIsPackagedField: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.IsPackaged, nil case fields.PsParentIsProtectedField: - ps := getParentPs(kevt) + ps := getParentPs(e) if ps == nil { return nil, ErrPsNil } return ps.IsProtected, nil case fields.PsAncestors: - if kevt.PS != nil { + if e.PS != nil { ancestors := make([]*pstypes.PS, 0) walk := func(proc *pstypes.PS) { ancestors = append(ancestors, proc) } - pstypes.Walk(walk, kevt.PS) + pstypes.Walk(walk, e.PS) return ancestors, nil } return nil, ErrPsNil case fields.PsModules: - if kevt.PS != nil { - return kevt.PS.Modules, nil + if e.PS != nil { + return e.PS.Modules, nil } return nil, ErrPsNil case fields.PsThreads: - if kevt.PS != nil { - return kevt.PS.Threads, nil + if e.PS != nil { + return e.PS.Threads, nil } return nil, ErrPsNil case fields.PsMmaps: - if kevt.PS != nil { - return kevt.PS.Mmaps, nil + if e.PS != nil { + return e.PS.Mmaps, nil } return nil, ErrPsNil case fields.PsAncestor: - if kevt.PS != nil { + if e.PS != nil { n := -1 // if the index is given try to parse it // to access the ancestor at the given level. @@ -477,7 +476,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { walk := func(proc *pstypes.PS) { ancestors = append(ancestors, proc.Name) } - pstypes.Walk(walk, kevt.PS) + pstypes.Walk(walk, e.PS) if n >= 0 { // return a single ancestor indicated by the index @@ -493,7 +492,7 @@ func (ps *psAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return nil, ErrPsNil case fields.PsEnvs: - ps := kevt.PS + ps := e.PS if ps == nil { return nil, ErrPsNil } @@ -531,51 +530,51 @@ type threadAccessor struct{} func (threadAccessor) SetFields([]Field) {} func (threadAccessor) SetSegments([]fields.Segment) {} -func (threadAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return !kevt.Callstack.IsEmpty() || kevt.Category == ktypes.Thread +func (threadAccessor) IsFieldAccessible(e *event.Event) bool { + return !e.Callstack.IsEmpty() || e.Category == event.Thread } func newThreadAccessor() Accessor { return &threadAccessor{} } -func (t *threadAccessor) Get(f Field, e *kevent.Kevent) (kparams.Value, error) { +func (t *threadAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.ThreadBasePrio: - return e.Kparams.GetUint8(kparams.BasePrio) + return e.Params.GetUint8(params.BasePrio) case fields.ThreadIOPrio: - return e.Kparams.GetUint8(kparams.IOPrio) + return e.Params.GetUint8(params.IOPrio) case fields.ThreadPagePrio: - return e.Kparams.GetUint8(kparams.PagePrio) + return e.Params.GetUint8(params.PagePrio) case fields.ThreadKstackBase: - return e.GetParamAsString(kparams.KstackBase), nil + return e.GetParamAsString(params.KstackBase), nil case fields.ThreadKstackLimit: - return e.GetParamAsString(kparams.KstackLimit), nil + return e.GetParamAsString(params.KstackLimit), nil case fields.ThreadUstackBase: - return e.GetParamAsString(kparams.UstackBase), nil + return e.GetParamAsString(params.UstackBase), nil case fields.ThreadUstackLimit: - return e.GetParamAsString(kparams.UstackLimit), nil + return e.GetParamAsString(params.UstackLimit), nil case fields.ThreadEntrypoint, fields.ThreadStartAddress: - return e.GetParamAsString(kparams.StartAddress), nil + return e.GetParamAsString(params.StartAddress), nil case fields.ThreadPID: - return e.Kparams.GetUint32(kparams.ProcessID) + return e.Params.GetUint32(params.ProcessID) case fields.ThreadTEB: - return e.GetParamAsString(kparams.TEB), nil + return e.GetParamAsString(params.TEB), nil case fields.ThreadAccessMask: - if e.Type != ktypes.OpenThread { + if e.Type != event.OpenThread { return nil, nil } - return e.Kparams.GetString(kparams.DesiredAccess) + return e.Params.GetString(params.DesiredAccess) case fields.ThreadAccessMaskNames: - if e.Type != ktypes.OpenThread { + if e.Type != event.OpenThread { return nil, nil } - return e.GetFlagsAsSlice(kparams.DesiredAccess), nil + return e.GetFlagsAsSlice(params.DesiredAccess), nil case fields.ThreadAccessStatus: - if e.Type != ktypes.OpenThread { + if e.Type != event.OpenThread { return nil, nil } - return e.GetParamAsString(kparams.NTStatus), nil + return e.GetParamAsString(params.NTStatus), nil case fields.ThreadCallstackSummary: return e.Callstack.Summary(), nil case fields.ThreadCallstackDetail: @@ -625,15 +624,15 @@ func (t *threadAccessor) Get(f Field, e *kevent.Kevent) (kparams.Value, error) { case fields.ThreadCallstack: return e.Callstack, nil case fields.ThreadStartAddressSymbol: - if e.Type != ktypes.CreateThread { + if e.Type != event.CreateThread { return nil, nil } - return e.GetParamAsString(kparams.StartAddressSymbol), nil + return e.GetParamAsString(params.StartAddressSymbol), nil case fields.ThreadStartAddressModule: - if e.Type != ktypes.CreateThread { + if e.Type != event.CreateThread { return nil, nil } - return e.GetParamAsString(kparams.StartAddressModule), nil + return e.GetParamAsString(params.StartAddressModule), nil case fields.ThreadCallstackAddresses: return e.Callstack.Addresses(), nil case fields.ThreadCallstackFinalUserModuleName, fields.ThreadCallstackFinalUserModulePath: @@ -713,75 +712,75 @@ func (fileAccessor) SetFields(fields []Field) { } func (fileAccessor) SetSegments([]fields.Segment) {} -func (fileAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { return kevt.Category == ktypes.File } +func (fileAccessor) IsFieldAccessible(e *event.Event) bool { return e.Category == event.File } func newFileAccessor() Accessor { return &fileAccessor{} } -func (l *fileAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (l *fileAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.FilePath: - return kevt.GetParamAsString(kparams.FilePath), nil + return e.GetParamAsString(params.FilePath), nil case fields.FileName: - return filepath.Base(kevt.GetParamAsString(kparams.FilePath)), nil + return filepath.Base(e.GetParamAsString(params.FilePath)), nil case fields.FileExtension: - return filepath.Ext(kevt.GetParamAsString(kparams.FilePath)), nil + return filepath.Ext(e.GetParamAsString(params.FilePath)), nil case fields.FileOffset: - return kevt.Kparams.GetUint64(kparams.FileOffset) + return e.Params.GetUint64(params.FileOffset) case fields.FileIOSize: - return kevt.Kparams.GetUint32(kparams.FileIoSize) + return e.Params.GetUint32(params.FileIoSize) case fields.FileShareMask: - return kevt.GetParamAsString(kparams.FileShareMask), nil + return e.GetParamAsString(params.FileShareMask), nil case fields.FileOperation: - return kevt.GetParamAsString(kparams.FileOperation), nil + return e.GetParamAsString(params.FileOperation), nil case fields.FileObject: - return kevt.Kparams.GetUint64(kparams.FileObject) + return e.Params.GetUint64(params.FileObject) case fields.FileType: - return kevt.GetParamAsString(kparams.FileType), nil + return e.GetParamAsString(params.FileType), nil case fields.FileAttributes: - return kevt.GetFlagsAsSlice(kparams.FileAttributes), nil + return e.GetFlagsAsSlice(params.FileAttributes), nil case fields.FileStatus: - if kevt.Type != ktypes.CreateFile { + if e.Type != event.CreateFile { return nil, nil } - return kevt.GetParamAsString(kparams.NTStatus), nil + return e.GetParamAsString(params.NTStatus), nil case fields.FileViewBase: - return kevt.GetParamAsString(kparams.FileViewBase), nil + return e.GetParamAsString(params.FileViewBase), nil case fields.FileViewSize: - return kevt.Kparams.GetUint64(kparams.FileViewSize) + return e.Params.GetUint64(params.FileViewSize) case fields.FileViewType: - return kevt.GetParamAsString(kparams.FileViewSectionType), nil + return e.GetParamAsString(params.FileViewSectionType), nil case fields.FileViewProtection: - return kevt.GetParamAsString(kparams.MemProtect), nil + return e.GetParamAsString(params.MemProtect), nil case fields.FileIsDriverVulnerable, fields.FileIsDriverMalicious: - if kevt.IsCreateDisposition() && kevt.IsSuccess() { - return isLOLDriver(f.Name, kevt) + if e.IsCreateDisposition() && e.IsSuccess() { + return isLOLDriver(f.Name, e) } return false, nil case fields.FileIsDLL: - return kevt.Kparams.GetBool(kparams.FileIsDLL) + return e.Params.GetBool(params.FileIsDLL) case fields.FileIsDriver: - return kevt.Kparams.GetBool(kparams.FileIsDriver) + return e.Params.GetBool(params.FileIsDriver) case fields.FileIsExecutable: - return kevt.Kparams.GetBool(kparams.FileIsExecutable) + return e.Params.GetBool(params.FileIsExecutable) case fields.FilePID: - return kevt.Kparams.GetPid() + return e.Params.GetPid() case fields.FileKey: - return kevt.Kparams.GetUint64(kparams.FileKey) + return e.Params.GetUint64(params.FileKey) case fields.FileInfoClass: - return kevt.GetParamAsString(kparams.FileInfoClass), nil + return e.GetParamAsString(params.FileInfoClass), nil case fields.FileInfoAllocationSize: - if kevt.Kparams.TryGetUint32(kparams.FileInfoClass) == fs.AllocationClass { - return kevt.Kparams.GetUint64(kparams.FileExtraInfo) + if e.Params.TryGetUint32(params.FileInfoClass) == fs.AllocationClass { + return e.Params.GetUint64(params.FileExtraInfo) } case fields.FileInfoEOFSize: - if kevt.Kparams.TryGetUint32(kparams.FileInfoClass) == fs.EOFClass { - return kevt.Kparams.GetUint64(kparams.FileExtraInfo) + if e.Params.TryGetUint32(params.FileInfoClass) == fs.EOFClass { + return e.Params.GetUint64(params.FileExtraInfo) } case fields.FileInfoIsDispositionDeleteFile: - return kevt.Kparams.TryGetUint32(kparams.FileInfoClass) == fs.DispositionClass && - kevt.Kparams.TryGetUint64(kparams.FileExtraInfo) > 0, nil + return e.Params.TryGetUint32(params.FileInfoClass) == fs.DispositionClass && + e.Params.TryGetUint64(params.FileExtraInfo) > 0, nil } return nil, nil @@ -795,20 +794,20 @@ func (imageAccessor) SetFields(fields []Field) { } func (imageAccessor) SetSegments([]fields.Segment) {} -func (imageAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.Category == ktypes.Image +func (imageAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Category == event.Image } func newImageAccessor() Accessor { return &imageAccessor{} } -func (i *imageAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { - if kevt.IsLoadImage() && (f.Name == fields.ImageSignatureType || f.Name == fields.ImageSignatureLevel || f.Name.IsImageCert()) { - filename := kevt.GetParamAsString(kparams.ImagePath) - addr := kevt.Kparams.MustGetUint64(kparams.ImageBase) - typ := kevt.Kparams.MustGetUint32(kparams.ImageSignatureType) - level := kevt.Kparams.MustGetUint32(kparams.ImageSignatureLevel) +func (i *imageAccessor) Get(f Field, e *event.Event) (params.Value, error) { + if e.IsLoadImage() && (f.Name == fields.ImageSignatureType || f.Name == fields.ImageSignatureLevel || f.Name.IsImageCert()) { + filename := e.GetParamAsString(params.ImagePath) + addr := e.Params.MustGetUint64(params.ImageBase) + typ := e.Params.MustGetUint32(params.ImageSignatureType) + level := e.Params.MustGetUint32(params.ImageSignatureLevel) sign := signature.GetSignatures().GetSignature(addr) @@ -854,62 +853,62 @@ func (i *imageAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) signature.GetSignatures().PutSignature(addr, sign) } // reset signature type/level parameters - _ = kevt.Kparams.SetValue(kparams.ImageSignatureType, sign.Type) - _ = kevt.Kparams.SetValue(kparams.ImageSignatureLevel, sign.Level) + _ = e.Params.SetValue(params.ImageSignatureType, sign.Type) + _ = e.Params.SetValue(params.ImageSignatureLevel, sign.Level) } // append certificate parameters if sign.HasCertificate() { - kevt.AppendParam(kparams.ImageCertIssuer, kparams.UnicodeString, sign.Cert.Issuer) - kevt.AppendParam(kparams.ImageCertSubject, kparams.UnicodeString, sign.Cert.Subject) - kevt.AppendParam(kparams.ImageCertSerial, kparams.UnicodeString, sign.Cert.SerialNumber) - kevt.AppendParam(kparams.ImageCertNotAfter, kparams.Time, sign.Cert.NotAfter) - kevt.AppendParam(kparams.ImageCertNotBefore, kparams.Time, sign.Cert.NotBefore) + e.AppendParam(params.ImageCertIssuer, params.UnicodeString, sign.Cert.Issuer) + e.AppendParam(params.ImageCertSubject, params.UnicodeString, sign.Cert.Subject) + e.AppendParam(params.ImageCertSerial, params.UnicodeString, sign.Cert.SerialNumber) + e.AppendParam(params.ImageCertNotAfter, params.Time, sign.Cert.NotAfter) + e.AppendParam(params.ImageCertNotBefore, params.Time, sign.Cert.NotBefore) } } switch f.Name { case fields.ImagePath: - return kevt.GetParamAsString(kparams.ImagePath), nil + return e.GetParamAsString(params.ImagePath), nil case fields.ImageName: - return filepath.Base(kevt.GetParamAsString(kparams.ImagePath)), nil + return filepath.Base(e.GetParamAsString(params.ImagePath)), nil case fields.ImageDefaultAddress: - return kevt.GetParamAsString(kparams.ImageDefaultBase), nil + return e.GetParamAsString(params.ImageDefaultBase), nil case fields.ImageBase: - return kevt.GetParamAsString(kparams.ImageBase), nil + return e.GetParamAsString(params.ImageBase), nil case fields.ImageSize: - return kevt.Kparams.GetUint64(kparams.ImageSize) + return e.Params.GetUint64(params.ImageSize) case fields.ImageChecksum: - return kevt.Kparams.GetUint32(kparams.ImageCheckSum) + return e.Params.GetUint32(params.ImageCheckSum) case fields.ImagePID: - return kevt.Kparams.GetPid() + return e.Params.GetPid() case fields.ImageSignatureType: - return kevt.GetParamAsString(kparams.ImageSignatureType), nil + return e.GetParamAsString(params.ImageSignatureType), nil case fields.ImageSignatureLevel: - return kevt.GetParamAsString(kparams.ImageSignatureLevel), nil + return e.GetParamAsString(params.ImageSignatureLevel), nil case fields.ImageCertSubject: - return kevt.GetParamAsString(kparams.ImageCertSubject), nil + return e.GetParamAsString(params.ImageCertSubject), nil case fields.ImageCertIssuer: - return kevt.GetParamAsString(kparams.ImageCertIssuer), nil + return e.GetParamAsString(params.ImageCertIssuer), nil case fields.ImageCertSerial: - return kevt.GetParamAsString(kparams.ImageCertSerial), nil + return e.GetParamAsString(params.ImageCertSerial), nil case fields.ImageCertBefore: - return kevt.Kparams.GetTime(kparams.ImageCertNotBefore) + return e.Params.GetTime(params.ImageCertNotBefore) case fields.ImageCertAfter: - return kevt.Kparams.GetTime(kparams.ImageCertNotAfter) + return e.Params.GetTime(params.ImageCertNotAfter) case fields.ImageIsDriverVulnerable, fields.ImageIsDriverMalicious: - if kevt.IsLoadImage() { - return isLOLDriver(f.Name, kevt) + if e.IsLoadImage() { + return isLOLDriver(f.Name, e) } return false, nil case fields.ImageIsDLL: - return kevt.Kparams.GetBool(kparams.FileIsDLL) + return e.Params.GetBool(params.FileIsDLL) case fields.ImageIsDriver: - return kevt.Kparams.GetBool(kparams.FileIsDriver) + return e.Params.GetBool(params.FileIsDriver) case fields.ImageIsExecutable: - return kevt.Kparams.GetBool(kparams.FileIsExecutable) + return e.Params.GetBool(params.FileIsExecutable) case fields.ImageIsDotnet: - return kevt.Kparams.GetBool(kparams.FileIsDotnet) + return e.Params.GetBool(params.FileIsDotnet) } return nil, nil @@ -920,32 +919,32 @@ type registryAccessor struct{} func (registryAccessor) SetFields([]Field) {} func (registryAccessor) SetSegments([]fields.Segment) {} -func (registryAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.Category == ktypes.Registry +func (registryAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Category == event.Registry } func newRegistryAccessor() Accessor { return ®istryAccessor{} } -func (r *registryAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (r *registryAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.RegistryPath: - return kevt.GetParamAsString(kparams.RegPath), nil + return e.GetParamAsString(params.RegPath), nil case fields.RegistryKeyName: - if kevt.IsRegSetValue() { - return filepath.Base(filepath.Dir(kevt.GetParamAsString(kparams.RegPath))), nil + if e.IsRegSetValue() { + return filepath.Base(filepath.Dir(e.GetParamAsString(params.RegPath))), nil } else { - return filepath.Base(kevt.GetParamAsString(kparams.RegPath)), nil + return filepath.Base(e.GetParamAsString(params.RegPath)), nil } case fields.RegistryKeyHandle: - return kevt.GetParamAsString(kparams.RegKeyHandle), nil + return e.GetParamAsString(params.RegKeyHandle), nil case fields.RegistryValue: - return kevt.Kparams.GetRaw(kparams.RegValue) + return e.Params.GetRaw(params.RegValue) case fields.RegistryValueType: - return kevt.Kparams.GetString(kparams.RegValueType) + return e.Params.GetString(params.RegValueType) case fields.RegistryStatus: - return kevt.GetParamAsString(kparams.NTStatus), nil + return e.GetParamAsString(params.NTStatus), nil } return nil, nil @@ -967,34 +966,34 @@ func (n *networkAccessor) SetFields(flds []Field) { func (networkAccessor) SetSegments([]fields.Segment) {} -func (networkAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.Category == ktypes.Net +func (networkAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Category == event.Net } func newNetworkAccessor() Accessor { return &networkAccessor{} } -func (n *networkAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (n *networkAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.NetDIP: - return kevt.Kparams.GetIP(kparams.NetDIP) + return e.Params.GetIP(params.NetDIP) case fields.NetSIP: - return kevt.Kparams.GetIP(kparams.NetSIP) + return e.Params.GetIP(params.NetSIP) case fields.NetDport: - return kevt.Kparams.GetUint16(kparams.NetDport) + return e.Params.GetUint16(params.NetDport) case fields.NetSport: - return kevt.Kparams.GetUint16(kparams.NetSport) + return e.Params.GetUint16(params.NetSport) case fields.NetDportName: - return kevt.Kparams.GetString(kparams.NetDportName) + return e.Params.GetString(params.NetDportName) case fields.NetSportName: - return kevt.Kparams.GetString(kparams.NetSportName) + return e.Params.GetString(params.NetSportName) case fields.NetL4Proto: - return kevt.GetParamAsString(kparams.NetL4Proto), nil + return e.GetParamAsString(params.NetL4Proto), nil case fields.NetPacketSize: - return kevt.Kparams.GetUint32(kparams.NetSize) + return e.Params.GetUint32(params.NetSize) case fields.NetDIPNames: - return n.resolveNamesForIP(kevt.Kparams.MustGetIP(kparams.NetDIP)) + return n.resolveNamesForIP(e.Params.MustGetIP(params.NetDIP)) case fields.NetSIPNames: - return n.resolveNamesForIP(kevt.Kparams.MustGetIP(kparams.NetSIP)) + return n.resolveNamesForIP(e.Params.MustGetIP(params.NetSIP)) } return nil, nil @@ -1016,22 +1015,22 @@ type handleAccessor struct{} func (handleAccessor) SetFields([]Field) {} func (handleAccessor) SetSegments([]fields.Segment) {} -func (handleAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.Category == ktypes.Handle +func (handleAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Category == event.Handle } func newHandleAccessor() Accessor { return &handleAccessor{} } -func (h *handleAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (h *handleAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.HandleID: - return kevt.Kparams.GetUint32(kparams.HandleID) + return e.Params.GetUint32(params.HandleID) case fields.HandleType: - return kevt.GetParamAsString(kparams.HandleObjectTypeID), nil + return e.GetParamAsString(params.HandleObjectTypeID), nil case fields.HandleName: - return kevt.Kparams.GetString(kparams.HandleObjectName) + return e.Params.GetString(params.HandleObjectName) case fields.HandleObject: - return kevt.Kparams.GetUint64(kparams.HandleObject) + return e.Params.GetUint64(params.HandleObject) } return nil, nil @@ -1050,8 +1049,8 @@ func (pa *peAccessor) SetSegments(segments []fields.Segment) { pa.segments = segments } -func (peAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.PS != nil || kevt.IsLoadImage() +func (peAccessor) IsFieldAccessible(e *event.Event) bool { + return e.PS != nil || e.IsLoadImage() } // parserOpts traverses all fields/segments declared in the expression and @@ -1103,10 +1102,10 @@ func newPEAccessor() Accessor { return &peAccessor{} } -func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (pa *peAccessor) Get(f Field, e *event.Event) (params.Value, error) { var p *pe.PE - if kevt.PS != nil && kevt.PS.PE != nil { - p = kevt.PS.PE + if e.PS != nil && e.PS.PE != nil { + p = e.PS.PE } // PE enrichment is likely disabled. Load PE data lazily @@ -1116,13 +1115,13 @@ func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { // original file name as part of the CreateProcess event, // then the parser obtains the PE metadata for the executable // path parameter - if (kevt.PS != nil && kevt.PS.Exe != "" && p == nil) || f.Name == fields.PePsChildFileName || f.Name == fields.PsChildPeFilename { + if (e.PS != nil && e.PS.Exe != "" && p == nil) || f.Name == fields.PePsChildFileName || f.Name == fields.PsChildPeFilename { var err error var exe string - if (f.Name == fields.PePsChildFileName || f.Name == fields.PsChildPeFilename) && kevt.IsCreateProcess() { - exe = kevt.GetParamAsString(kparams.Exe) + if (f.Name == fields.PePsChildFileName || f.Name == fields.PsChildPeFilename) && e.IsCreateProcess() { + exe = e.GetParamAsString(params.Exe) } else { - exe = kevt.PS.Exe + exe = e.PS.Exe } p, err = pe.ParseFile(exe, pa.parserOpts()...) if err != nil { @@ -1135,15 +1134,15 @@ func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { // PE for loaded executables followed by fetching the PE // from process' memory at the base address of the loaded // executable image - if kevt.IsLoadImage() && f.Name.IsPeModified() { - filename := kevt.GetParamAsString(kparams.ImagePath) - isExecutable := filepath.Ext(filename) == ".exe" || kevt.Kparams.TryGetBool(kparams.FileIsExecutable) + if e.IsLoadImage() && f.Name.IsPeModified() { + filename := e.GetParamAsString(params.ImagePath) + isExecutable := filepath.Ext(filename) == ".exe" || e.Params.TryGetBool(params.FileIsExecutable) if !isExecutable { return nil, nil } - pid := kevt.Kparams.MustGetPid() - addr := kevt.Kparams.MustGetUint64(kparams.ImageBase) + pid := e.Params.MustGetPid() + addr := e.Params.MustGetUint64(params.ImageBase) file, err := pe.ParseFile(filename, pa.parserOpts()...) if err != nil { @@ -1170,7 +1169,7 @@ func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } if f.Name != fields.PePsChildFileName { - kevt.PS.PE = p + e.PS.PE = p } switch f.Name { @@ -1224,11 +1223,11 @@ func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { } return p.Cert.NotBefore, nil case fields.PeIsDLL: - return kevt.Kparams.GetBool(kparams.FileIsDLL) + return e.Params.GetBool(params.FileIsDLL) case fields.PeIsDriver: - return kevt.Kparams.GetBool(kparams.FileIsDriver) + return e.Params.GetBool(params.FileIsDriver) case fields.PeIsExecutable: - return kevt.Kparams.GetBool(kparams.FileIsExecutable) + return e.Params.GetBool(params.FileIsExecutable) case fields.PeCompany: return p.VersionResources[pe.Company], nil case fields.PeCopyright: @@ -1278,28 +1277,28 @@ func (pa *peAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { // memAccessor extracts parameters from memory alloc/free events. type memAccessor struct{} -func (memAccessor) SetFields([]Field) {} -func (memAccessor) SetSegments([]fields.Segment) {} -func (memAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { return kevt.Category == ktypes.Mem } +func (memAccessor) SetFields([]Field) {} +func (memAccessor) SetSegments([]fields.Segment) {} +func (memAccessor) IsFieldAccessible(e *event.Event) bool { return e.Category == event.Mem } func newMemAccessor() Accessor { return &memAccessor{} } -func (*memAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (*memAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.MemPageType: - return kevt.GetParamAsString(kparams.MemPageType), nil + return e.GetParamAsString(params.MemPageType), nil case fields.MemAllocType: - return kevt.GetParamAsString(kparams.MemAllocType), nil + return e.GetParamAsString(params.MemAllocType), nil case fields.MemProtection: - return kevt.GetParamAsString(kparams.MemProtect), nil + return e.GetParamAsString(params.MemProtect), nil case fields.MemBaseAddress: - return kevt.Kparams.GetUint64(kparams.MemBaseAddress) + return e.Params.GetUint64(params.MemBaseAddress) case fields.MemRegionSize: - return kevt.Kparams.GetUint64(kparams.MemRegionSize) + return e.Params.GetUint64(params.MemRegionSize) case fields.MemProtectionMask: - return kevt.Kparams.GetString(kparams.MemProtectMask) + return e.Params.GetString(params.MemProtectMask) } return nil, nil @@ -1310,26 +1309,26 @@ type dnsAccessor struct{} func (dnsAccessor) SetFields([]Field) {} func (dnsAccessor) SetSegments([]fields.Segment) {} -func (dnsAccessor) IsFieldAccessible(kevt *kevent.Kevent) bool { - return kevt.Type.Subcategory() == ktypes.DNS +func (dnsAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Type.Subcategory() == event.DNS } func newDNSAccessor() Accessor { return &dnsAccessor{} } -func (*dnsAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error) { +func (*dnsAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.DNSName: - return kevt.GetParamAsString(kparams.DNSName), nil + return e.GetParamAsString(params.DNSName), nil case fields.DNSRR: - return kevt.GetParamAsString(kparams.DNSRR), nil + return e.GetParamAsString(params.DNSRR), nil case fields.DNSRcode: - return kevt.GetParamAsString(kparams.DNSRcode), nil + return e.GetParamAsString(params.DNSRcode), nil case fields.DNSOptions: - return kevt.GetFlagsAsSlice(kparams.DNSOpts), nil + return e.GetFlagsAsSlice(params.DNSOpts), nil case fields.DNSAnswers: - return kevt.Kparams.GetSlice(kparams.DNSAnswers) + return e.Params.GetSlice(params.DNSAnswers) } return nil, nil @@ -1340,48 +1339,48 @@ type threadpoolAccessor struct{} func (threadpoolAccessor) SetFields([]Field) {} func (threadpoolAccessor) SetSegments([]fields.Segment) {} -func (threadpoolAccessor) IsFieldAccessible(e *kevent.Kevent) bool { - return e.Category == ktypes.Threadpool +func (threadpoolAccessor) IsFieldAccessible(e *event.Event) bool { + return e.Category == event.Threadpool } func newThreadpoolAccessor() Accessor { return &threadpoolAccessor{} } -func (*threadpoolAccessor) Get(f Field, e *kevent.Kevent) (kparams.Value, error) { +func (*threadpoolAccessor) Get(f Field, e *event.Event) (params.Value, error) { switch f.Name { case fields.ThreadpoolPoolID: - return e.GetParamAsString(kparams.ThreadpoolPoolID), nil + return e.GetParamAsString(params.ThreadpoolPoolID), nil case fields.ThreadpoolTaskID: - return e.GetParamAsString(kparams.ThreadpoolTaskID), nil + return e.GetParamAsString(params.ThreadpoolTaskID), nil case fields.ThreadpoolCallbackAddress: - return e.GetParamAsString(kparams.ThreadpoolCallback), nil + return e.GetParamAsString(params.ThreadpoolCallback), nil case fields.ThreadpoolCallbackSymbol: - return e.GetParamAsString(kparams.ThreadpoolCallbackSymbol), nil + return e.GetParamAsString(params.ThreadpoolCallbackSymbol), nil case fields.ThreadpoolCallbackModule: - return e.GetParamAsString(kparams.ThreadpoolCallbackModule), nil + return e.GetParamAsString(params.ThreadpoolCallbackModule), nil case fields.ThreadpoolCallbackContext: - return e.GetParamAsString(kparams.ThreadpoolContext), nil + return e.GetParamAsString(params.ThreadpoolContext), nil case fields.ThreadpoolCallbackContextRip: - return e.GetParamAsString(kparams.ThreadpoolContextRip), nil + return e.GetParamAsString(params.ThreadpoolContextRip), nil case fields.ThreadpoolCallbackContextRipSymbol: - return e.GetParamAsString(kparams.ThreadpoolContextRipSymbol), nil + return e.GetParamAsString(params.ThreadpoolContextRipSymbol), nil case fields.ThreadpoolCallbackContextRipModule: - return e.GetParamAsString(kparams.ThreadpoolContextRipModule), nil + return e.GetParamAsString(params.ThreadpoolContextRipModule), nil case fields.ThreadpoolSubprocessTag: - return e.GetParamAsString(kparams.ThreadpoolSubprocessTag), nil + return e.GetParamAsString(params.ThreadpoolSubprocessTag), nil case fields.ThreadpoolTimer: - return e.GetParamAsString(kparams.ThreadpoolTimer), nil + return e.GetParamAsString(params.ThreadpoolTimer), nil case fields.ThreadpoolTimerSubqueue: - return e.GetParamAsString(kparams.ThreadpoolTimerSubqueue), nil + return e.GetParamAsString(params.ThreadpoolTimerSubqueue), nil case fields.ThreadpoolTimerDuetime: - return e.Kparams.GetUint64(kparams.ThreadpoolTimerDuetime) + return e.Params.GetUint64(params.ThreadpoolTimerDuetime) case fields.ThreadpoolTimerPeriod: - return e.Kparams.GetUint32(kparams.ThreadpoolTimerPeriod) + return e.Params.GetUint32(params.ThreadpoolTimerPeriod) case fields.ThreadpoolTimerWindow: - return e.Kparams.GetUint32(kparams.ThreadpoolTimerWindow) + return e.Params.GetUint32(params.ThreadpoolTimerWindow) case fields.ThreadpoolTimerAbsolute: - return e.Kparams.GetBool(kparams.ThreadpoolTimerAbsolute) + return e.Params.GetBool(params.ThreadpoolTimerAbsolute) } return nil, nil diff --git a/pkg/filter/accessor_windows_test.go b/pkg/filter/accessor_windows_test.go index bf8bb7bba..949077f27 100644 --- a/pkg/filter/accessor_windows_test.go +++ b/pkg/filter/accessor_windows_test.go @@ -20,8 +20,7 @@ package filter import ( "github.com/rabbitstack/fibratus/pkg/callstack" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" ptypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -35,7 +34,7 @@ func TestNarrowAccessors(t *testing.T) { expectedAccessors int }{ { - New(`ps.name = 'cmd.exe' and kevt.name = 'CreateProcess' or kevt.name in ('TerminateProcess', 'CreateFile')`, cfg), + New(`ps.name = 'cmd.exe' and evt.name = 'CreateProcess' or evt.name in ('TerminateProcess', 'CreateFile')`, cfg), 2, }, { @@ -43,11 +42,11 @@ func TestNarrowAccessors(t *testing.T) { 1, }, { - New(`handle.type = 'Section' and pe.nsections > 1 and kevt.name = 'CreateHandle'`, cfg), + New(`handle.type = 'Section' and pe.nsections > 1 and evt.name = 'CreateHandle'`, cfg), 3, }, { - New(`sequence |kevt.name = 'CreateProcess'| as e1 |kevt.name = 'CreateFile' and file.name = $e1.ps.exe |`, cfg), + New(`sequence |evt.name = 'CreateProcess'| as e1 |evt.name = 'CreateFile' and file.name = $e1.ps.exe |`, cfg), 3, }, { @@ -78,72 +77,72 @@ func TestNarrowAccessors(t *testing.T) { func TestIsFieldAccessible(t *testing.T) { var tests = []struct { a Accessor - e *kevent.Kevent + e *event.Event isAccessible bool }{ { - newKevtAccessor(), - &kevent.Kevent{Type: ktypes.QueryDNS, Category: ktypes.Net}, + newEventAccessor(), + &event.Event{Type: event.QueryDNS, Category: event.Net}, true, }, { newPSAccessor(nil), - &kevent.Kevent{Type: ktypes.CreateProcess, Category: ktypes.Process}, + &event.Event{Type: event.CreateProcess, Category: event.Process}, true, }, { newPSAccessor(nil), - &kevent.Kevent{PS: &ptypes.PS{}, Type: ktypes.CreateFile, Category: ktypes.File}, + &event.Event{PS: &ptypes.PS{}, Type: event.CreateFile, Category: event.File}, true, }, { newPSAccessor(nil), - &kevent.Kevent{Type: ktypes.SetThreadContext, Category: ktypes.Thread}, + &event.Event{Type: event.SetThreadContext, Category: event.Thread}, false, }, { newThreadAccessor(), - &kevent.Kevent{Type: ktypes.SetThreadContext, Category: ktypes.Thread}, + &event.Event{Type: event.SetThreadContext, Category: event.Thread}, true, }, { newThreadAccessor(), - &kevent.Kevent{Type: ktypes.CreateProcess, Category: ktypes.Process, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, + &event.Event{Type: event.CreateProcess, Category: event.Process, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, true, }, { newThreadAccessor(), - &kevent.Kevent{Type: ktypes.RegSetValue, Category: ktypes.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, + &event.Event{Type: event.RegSetValue, Category: event.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, true, }, { newRegistryAccessor(), - &kevent.Kevent{Type: ktypes.RegSetValue, Category: ktypes.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, + &event.Event{Type: event.RegSetValue, Category: event.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, true, }, { newNetworkAccessor(), - &kevent.Kevent{Type: ktypes.RegSetValue, Category: ktypes.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, + &event.Event{Type: event.RegSetValue, Category: event.Registry, Callstack: []callstack.Frame{{Addr: 0x7ffb5c1d0396, Offset: 0x61, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}}}, false, }, { newNetworkAccessor(), - &kevent.Kevent{Type: ktypes.ConnectTCPv6, Category: ktypes.Net}, + &event.Event{Type: event.ConnectTCPv6, Category: event.Net}, true, }, { newDNSAccessor(), - &kevent.Kevent{Type: ktypes.ReplyDNS, Category: ktypes.Net}, + &event.Event{Type: event.ReplyDNS, Category: event.Net}, true, }, { newImageAccessor(), - &kevent.Kevent{Type: ktypes.LoadImage, Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Category: event.Image}, true, }, { newMemAccessor(), - &kevent.Kevent{Type: ktypes.VirtualAlloc, Category: ktypes.Mem}, + &event.Event{Type: event.VirtualAlloc, Category: event.Mem}, true, }, } diff --git a/pkg/filter/fields/fields.go b/pkg/filter/fields/fields.go index 717f7525a..56c920a89 100644 --- a/pkg/filter/fields/fields.go +++ b/pkg/filter/fields/fields.go @@ -19,7 +19,7 @@ package fields import ( - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/event/params" "sort" "unicode" ) @@ -28,7 +28,7 @@ import ( type FieldInfo struct { Field Field Desc string - Type kparams.Type + Type params.Type Examples []string Deprecation *Deprecation Argument *Argument @@ -99,5 +99,5 @@ func IsDeprecated(f Field) (bool, *Deprecation) { // IsBoolean determines if the given field has the bool type. func IsBoolean(f Field) bool { - return fields[f].Type == kparams.Bool + return fields[f].Type == params.Bool } diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index 3cee4fe7a..4970397cb 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -22,7 +22,7 @@ import ( "strings" "unicode" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/event/params" ) // Field represents the type alias for the field @@ -301,51 +301,51 @@ const ( PePsChildFileName Field = "pe.ps.child.file.name" // KevtSeq is the event sequence number - KevtSeq Field = "kevt.seq" + KevtSeq Field = "evt.seq" // KevtPID is the process identifier that generated the event - KevtPID Field = "kevt.pid" + KevtPID Field = "evt.pid" // KevtTID is the thread identifier that generated the event - KevtTID Field = "kevt.tid" + KevtTID Field = "evt.tid" // KevtCPU is the CPU core where the event was generated - KevtCPU Field = "kevt.cpu" + KevtCPU Field = "evt.cpu" // KevtDesc represents the event description - KevtDesc Field = "kevt.desc" + KevtDesc Field = "evt.desc" // KevtHost represents the host where the event was produced - KevtHost Field = "kevt.host" + KevtHost Field = "evt.host" // KevtTime is the event time - KevtTime Field = "kevt.time" + KevtTime Field = "evt.time" // KevtTimeHour is the hour part of the event time - KevtTimeHour Field = "kevt.time.h" + KevtTimeHour Field = "evt.time.h" // KevtTimeMin is the minute part of the event time - KevtTimeMin Field = "kevt.time.m" + KevtTimeMin Field = "evt.time.m" // KevtTimeSec is the second part of the event time - KevtTimeSec Field = "kevt.time.s" + KevtTimeSec Field = "evt.time.s" // KevtTimeNs is the nanosecond part of the event time - KevtTimeNs Field = "kevt.time.ns" + KevtTimeNs Field = "evt.time.ns" // KevtDate is the event date - KevtDate Field = "kevt.date" + KevtDate Field = "evt.date" // KevtDateDay is the day of event date - KevtDateDay Field = "kevt.date.d" + KevtDateDay Field = "evt.date.d" // KevtDateMonth is the month of event date - KevtDateMonth Field = "kevt.date.m" + KevtDateMonth Field = "evt.date.m" // KevtDateYear is the year of event date - KevtDateYear Field = "kevt.date.y" + KevtDateYear Field = "evt.date.y" // KevtDateTz is the time zone of event timestamp - KevtDateTz Field = "kevt.date.tz" + KevtDateTz Field = "evt.date.tz" // KevtDateWeek is the event week number - KevtDateWeek Field = "kevt.date.week" + KevtDateWeek Field = "evt.date.week" // KevtDateWeekday is the event week day - KevtDateWeekday Field = "kevt.date.weekday" + KevtDateWeekday Field = "evt.date.weekday" // KevtName is the event name - KevtName Field = "kevt.name" + KevtName Field = "evt.name" // KevtCategory is the event category - KevtCategory Field = "kevt.category" + KevtCategory Field = "evt.category" // KevtMeta is the event metadata - KevtMeta Field = "kevt.meta" + KevtMeta Field = "evt.meta" // KevtNparams is the number of event parameters - KevtNparams Field = "kevt.nparams" + KevtNparams Field = "evt.nparams" // KevtArg represents the field sequence for generic argument access - KevtArg Field = "kevt.arg" + KevtArg Field = "evt.arg" // HandleID represents the handle identifier within the process address space HandleID Field = "handle.id" @@ -547,7 +547,7 @@ const ( func (f Field) String() string { return string(f) } func (f Field) IsPsField() bool { return strings.HasPrefix(string(f), "ps.") } -func (f Field) IsKevtField() bool { return strings.HasPrefix(string(f), "kevt.") } +func (f Field) IsKevtField() bool { return strings.HasPrefix(string(f), "evt.") } func (f Field) IsThreadField() bool { return strings.HasPrefix(string(f), "thread.") } func (f Field) IsImageField() bool { return strings.HasPrefix(string(f), "image.") } func (f Field) IsFileField() bool { return strings.HasPrefix(string(f), "file.") } @@ -734,28 +734,28 @@ func IsPseudoField(f Field) bool { func (f Field) IsPeSectionsPseudo() bool { return f == PeSections } var fields = map[Field]FieldInfo{ - KevtSeq: {KevtSeq, "event sequence number", kparams.Uint64, []string{"kevt.seq > 666"}, nil, nil}, - KevtPID: {KevtPID, "process identifier generating the kernel event", kparams.Uint32, []string{"kevt.pid = 6"}, nil, nil}, - KevtTID: {KevtTID, "thread identifier generating the kernel event", kparams.Uint32, []string{"kevt.tid = 1024"}, nil, nil}, - KevtCPU: {KevtCPU, "logical processor core where the event was generated", kparams.Uint8, []string{"kevt.cpu = 2"}, nil, nil}, - KevtName: {KevtName, "symbolical kernel event name", kparams.AnsiString, []string{"kevt.name = 'CreateThread'"}, nil, nil}, - KevtCategory: {KevtCategory, "event category", kparams.AnsiString, []string{"kevt.category = 'registry'"}, nil, nil}, - KevtDesc: {KevtDesc, "event description", kparams.AnsiString, []string{"kevt.desc contains 'Creates a new process'"}, nil, nil}, - KevtHost: {KevtHost, "host name on which the event was produced", kparams.UnicodeString, []string{"kevt.host contains 'kitty'"}, nil, nil}, - KevtTime: {KevtTime, "event timestamp as a time string", kparams.Time, []string{"kevt.time = '17:05:32'"}, nil, nil}, - KevtTimeHour: {KevtTimeHour, "hour within the day on which the event occurred", kparams.Time, []string{"kevt.time.h = 23"}, nil, nil}, - KevtTimeMin: {KevtTimeMin, "minute offset within the hour on which the event occurred", kparams.Time, []string{"kevt.time.m = 54"}, nil, nil}, - KevtTimeSec: {KevtTimeSec, "second offset within the minute on which the event occurred", kparams.Time, []string{"kevt.time.s = 0"}, nil, nil}, - KevtTimeNs: {KevtTimeNs, "nanoseconds specified by event timestamp", kparams.Int64, []string{"kevt.time.ns > 1591191629102337000"}, nil, nil}, - KevtDate: {KevtDate, "event timestamp as a date string", kparams.Time, []string{"kevt.date = '2018-03-03'"}, nil, nil}, - KevtDateDay: {KevtDateDay, "day of the month on which the event occurred", kparams.Time, []string{"kevt.date.d = 12"}, nil, nil}, - KevtDateMonth: {KevtDateMonth, "month of the year on which the event occurred", kparams.Time, []string{"kevt.date.m = 11"}, nil, nil}, - KevtDateYear: {KevtDateYear, "year on which the event occurred", kparams.Uint32, []string{"kevt.date.y = 2020"}, nil, nil}, - KevtDateTz: {KevtDateTz, "time zone associated with the event timestamp", kparams.AnsiString, []string{"kevt.date.tz = 'UTC'"}, nil, nil}, - KevtDateWeek: {KevtDateWeek, "week number within the year on which the event occurred", kparams.Uint8, []string{"kevt.date.week = 2"}, nil, nil}, - KevtDateWeekday: {KevtDateWeekday, "week day on which the event occurred", kparams.AnsiString, []string{"kevt.date.weekday = 'Monday'"}, nil, nil}, - KevtNparams: {KevtNparams, "number of parameters", kparams.Int8, []string{"kevt.nparams > 2"}, nil, nil}, - KevtArg: {KevtArg, "event parameter", kparams.Object, []string{"kevt.arg[cmdline] istartswith 'C:\\Windows'"}, nil, &Argument{Optional: false, Pattern: "[a-z0-9_]+", ValidationFunc: func(s string) bool { + KevtSeq: {KevtSeq, "event sequence number", params.Uint64, []string{"evt.seq > 666"}, nil, nil}, + KevtPID: {KevtPID, "process identifier generating the kernel event", params.Uint32, []string{"evt.pid = 6"}, nil, nil}, + KevtTID: {KevtTID, "thread identifier generating the kernel event", params.Uint32, []string{"evt.tid = 1024"}, nil, nil}, + KevtCPU: {KevtCPU, "logical processor core where the event was generated", params.Uint8, []string{"evt.cpu = 2"}, nil, nil}, + KevtName: {KevtName, "symbolical kernel event name", params.AnsiString, []string{"evt.name = 'CreateThread'"}, nil, nil}, + KevtCategory: {KevtCategory, "event category", params.AnsiString, []string{"evt.category = 'registry'"}, nil, nil}, + KevtDesc: {KevtDesc, "event description", params.AnsiString, []string{"evt.desc contains 'Creates a new process'"}, nil, nil}, + KevtHost: {KevtHost, "host name on which the event was produced", params.UnicodeString, []string{"evt.host contains 'kitty'"}, nil, nil}, + KevtTime: {KevtTime, "event timestamp as a time string", params.Time, []string{"evt.time = '17:05:32'"}, nil, nil}, + KevtTimeHour: {KevtTimeHour, "hour within the day on which the event occurred", params.Time, []string{"evt.time.h = 23"}, nil, nil}, + KevtTimeMin: {KevtTimeMin, "minute offset within the hour on which the event occurred", params.Time, []string{"evt.time.m = 54"}, nil, nil}, + KevtTimeSec: {KevtTimeSec, "second offset within the minute on which the event occurred", params.Time, []string{"evt.time.s = 0"}, nil, nil}, + KevtTimeNs: {KevtTimeNs, "nanoseconds specified by event timestamp", params.Int64, []string{"evt.time.ns > 1591191629102337000"}, nil, nil}, + KevtDate: {KevtDate, "event timestamp as a date string", params.Time, []string{"evt.date = '2018-03-03'"}, nil, nil}, + KevtDateDay: {KevtDateDay, "day of the month on which the event occurred", params.Time, []string{"evt.date.d = 12"}, nil, nil}, + KevtDateMonth: {KevtDateMonth, "month of the year on which the event occurred", params.Time, []string{"evt.date.m = 11"}, nil, nil}, + KevtDateYear: {KevtDateYear, "year on which the event occurred", params.Uint32, []string{"evt.date.y = 2020"}, nil, nil}, + KevtDateTz: {KevtDateTz, "time zone associated with the event timestamp", params.AnsiString, []string{"evt.date.tz = 'UTC'"}, nil, nil}, + KevtDateWeek: {KevtDateWeek, "week number within the year on which the event occurred", params.Uint8, []string{"evt.date.week = 2"}, nil, nil}, + KevtDateWeekday: {KevtDateWeekday, "week day on which the event occurred", params.AnsiString, []string{"evt.date.weekday = 'Monday'"}, nil, nil}, + KevtNparams: {KevtNparams, "number of parameters", params.Int8, []string{"evt.nparams > 2"}, nil, nil}, + KevtArg: {KevtArg, "event parameter", params.Object, []string{"evt.arg[cmdline] istartswith 'C:\\Windows'"}, nil, &Argument{Optional: false, Pattern: "[a-z0-9_]+", ValidationFunc: func(s string) bool { for _, c := range s { switch { case unicode.IsLower(c): @@ -768,190 +768,190 @@ var fields = map[Field]FieldInfo{ return true }}}, - PsPid: {PsPid, "process identifier", kparams.PID, []string{"ps.pid = 1024"}, nil, nil}, - PsPpid: {PsPpid, "parent process identifier", kparams.PID, []string{"ps.ppid = 45"}, nil, nil}, - PsName: {PsName, "process image name including the file extension", kparams.UnicodeString, []string{"ps.name contains 'firefox'"}, nil, nil}, - PsComm: {PsComm, "process command line", kparams.UnicodeString, []string{"ps.comm contains 'java'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsCmdline}}, nil}, - PsCmdline: {PsCmdline, "process command line", kparams.UnicodeString, []string{"ps.cmdline contains 'java'"}, nil, nil}, - PsExe: {PsExe, "full name of the process' executable", kparams.UnicodeString, []string{"ps.exe = 'C:\\Windows\\system32\\cmd.exe'"}, nil, nil}, - PsArgs: {PsArgs, "process command line arguments", kparams.Slice, []string{"ps.args in ('/cdir', '/-C')"}, nil, nil}, - PsCwd: {PsCwd, "process current working directory", kparams.UnicodeString, []string{"ps.cwd = 'C:\\Users\\Default'"}, nil, nil}, - PsSID: {PsSID, "security identifier under which this process is run", kparams.UnicodeString, []string{"ps.sid contains 'SYSTEM'"}, nil, nil}, - PsSessionID: {PsSessionID, "unique identifier for the current session", kparams.Int16, []string{"ps.sessionid = 1"}, nil, nil}, - PsDomain: {PsDomain, "process domain", kparams.UnicodeString, []string{"ps.domain contains 'SERVICE'"}, nil, nil}, - PsUsername: {PsUsername, "process username", kparams.UnicodeString, []string{"ps.username contains 'system'"}, nil, nil}, - PsEnvs: {PsEnvs, "process environment variables", kparams.Slice, []string{"ps.envs in ('SystemRoot:C:\\WINDOWS')", "ps.envs[windir] = 'C:\\WINDOWS'"}, nil, &Argument{Optional: true, ValidationFunc: func(arg string) bool { return true }}}, - PsHandleNames: {PsHandleNames, "allocated process handle names", kparams.Slice, []string{"ps.handles in ('\\BaseNamedObjects\\__ComCatalogCache__')"}, nil, nil}, - PsHandleTypes: {PsHandleTypes, "allocated process handle types", kparams.Slice, []string{"ps.handle.types in ('Key', 'Mutant', 'Section')"}, nil, nil}, - PsDTB: {PsDTB, "process directory table base address", kparams.Address, []string{"ps.dtb = '7ffe0000'"}, nil, nil}, - PsModuleNames: {PsModuleNames, "modules loaded by the process", kparams.Slice, []string{"ps.modules in ('crypt32.dll', 'xul.dll')"}, nil, nil}, - PsParentName: {PsParentName, "parent process image name including the file extension", kparams.UnicodeString, []string{"ps.parent.name contains 'cmd.exe'"}, nil, nil}, - PsParentPid: {PsParentPid, "parent process id", kparams.Uint32, []string{"ps.parent.pid = 4"}, nil, nil}, - PsParentComm: {PsParentComm, "parent process command line", kparams.UnicodeString, []string{"ps.parent.comm contains 'java'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsParentCmdline}}, nil}, - PsParentCmdline: {PsParentCmdline, "parent process command line", kparams.UnicodeString, []string{"ps.parent.cmdline contains 'java'"}, nil, nil}, - PsParentExe: {PsParentExe, "full name of the parent process' executable", kparams.UnicodeString, []string{"ps.parent.exe = 'C:\\Windows\\system32\\explorer.exe'"}, nil, nil}, - PsParentArgs: {PsParentArgs, "parent process command line arguments", kparams.Slice, []string{"ps.parent.args in ('/cdir', '/-C')"}, nil, nil}, - PsParentCwd: {PsParentCwd, "parent process current working directory", kparams.UnicodeString, []string{"ps.parent.cwd = 'C:\\Temp'"}, nil, nil}, - PsParentSID: {PsParentSID, "security identifier under which the parent process is run", kparams.UnicodeString, []string{"ps.parent.sid contains 'SYSTEM'"}, nil, nil}, - PsParentDomain: {PsParentDomain, "parent process domain", kparams.UnicodeString, []string{"ps.parent.domain contains 'SERVICE'"}, nil, nil}, - PsParentUsername: {PsParentUsername, "parent process username", kparams.UnicodeString, []string{"ps.parent.username contains 'system'"}, nil, nil}, - PsParentSessionID: {PsParentSessionID, "unique identifier for the current session of parent process", kparams.Int16, []string{"ps.parent.sessionid = 1"}, nil, nil}, - PsParentEnvs: {PsParentEnvs, "parent process environment variables", kparams.Slice, []string{"ps.parent.envs in ('MOZ_CRASHREPORTER_DATA_DIRECTORY')"}, nil, nil}, - PsParentHandles: {PsParentHandles, "allocated parent process handle names", kparams.Slice, []string{"ps.parent.handles in ('\\BaseNamedObjects\\__ComCatalogCache__')"}, nil, nil}, - PsParentHandleTypes: {PsParentHandleTypes, "allocated parent process handle types", kparams.Slice, []string{"ps.parent.handle.types in ('File', 'SymbolicLink')"}, nil, nil}, - PsParentDTB: {PsParentDTB, "parent process directory table base address", kparams.Address, []string{"ps.parent.dtb = '7ffe0000'"}, nil, nil}, - PsAccessMask: {PsAccessMask, "process desired access rights", kparams.AnsiString, []string{"ps.access.mask = '0x1400'"}, nil, nil}, - PsAccessMaskNames: {PsAccessMaskNames, "process desired access rights as a string list", kparams.Slice, []string{"ps.access.mask.names in ('SUSPEND_RESUME')"}, nil, nil}, - PsAccessStatus: {PsAccessStatus, "process access status", kparams.UnicodeString, []string{"ps.access.status = 'access is denied.'"}, nil, nil}, - PsSiblingPid: {PsSiblingPid, "created or terminated process identifier", kparams.PID, []string{"ps.sibling.pid = 320"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildPid}}, nil}, - PsChildPid: {PsChildPid, "created or terminated process identifier", kparams.PID, []string{"ps.child.pid = 320"}, nil, nil}, - PsSiblingName: {PsSiblingName, "created or terminated process name", kparams.UnicodeString, []string{"ps.sibling.name = 'notepad.exe'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildName}}, nil}, - PsChildName: {PsChildName, "created or terminated process name", kparams.UnicodeString, []string{"ps.child.name = 'notepad.exe'"}, nil, nil}, - PsSiblingComm: {PsSiblingComm, "created or terminated process command line", kparams.UnicodeString, []string{"ps.sibling.comm contains '\\k \\v'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildCmdline}}, nil}, - PsChildCmdline: {PsChildCmdline, "created or terminated process command line", kparams.UnicodeString, []string{"ps.child.cmdline contains '\\k \\v'"}, nil, nil}, - PsSiblingArgs: {PsSiblingArgs, "created process command line arguments", kparams.Slice, []string{"ps.sibling.args in ('/cdir', '/-C')"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildArgs}}, nil}, - PsChildArgs: {PsChildArgs, "created process command line arguments", kparams.Slice, []string{"ps.child.args in ('/cdir', '/-C')"}, nil, nil}, - PsSiblingExe: {PsSiblingExe, "created, terminated, or opened process id", kparams.UnicodeString, []string{"ps.sibling.exe contains '\\Windows\\cmd.exe'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildExe}}, nil}, - PsChildExe: {PsChildExe, "created, terminated, or opened process id", kparams.UnicodeString, []string{"ps.child.exe contains '\\Windows\\cmd.exe'"}, nil, nil}, - PsSiblingSID: {PsSiblingSID, "created or terminated process security identifier", kparams.UnicodeString, []string{"ps.sibling.sid contains 'SERVICE'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildSID}}, nil}, - PsChildSID: {PsChildSID, "created or terminated process security identifier", kparams.UnicodeString, []string{"ps.child.sid contains 'SERVICE'"}, nil, nil}, - PsSiblingSessionID: {PsSiblingSessionID, "created or terminated process session identifier", kparams.Int16, []string{"ps.sibling.sessionid == 1"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildSessionID}}, nil}, - PsChildSessionID: {PsChildSessionID, "created or terminated process session identifier", kparams.Int16, []string{"ps.child.sessionid == 1"}, nil, nil}, - PsSiblingDomain: {PsSiblingDomain, "created or terminated process domain", kparams.UnicodeString, []string{"ps.sibling.domain contains 'SERVICE'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildDomain}}, nil}, - PsChildDomain: {PsChildDomain, "created or terminated process domain", kparams.UnicodeString, []string{"ps.child.domain contains 'SERVICE'"}, nil, nil}, - PsSiblingUsername: {PsSiblingUsername, "created or terminated process username", kparams.UnicodeString, []string{"ps.sibling.username contains 'system'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildUsername}}, nil}, - PsChildUsername: {PsChildUsername, "created or terminated process username", kparams.UnicodeString, []string{"ps.child.username contains 'system'"}, nil, nil}, - PsUUID: {PsUUID, "unique process identifier", kparams.Uint64, []string{"ps.uuid > 6000054355"}, nil, nil}, - PsParentUUID: {PsParentUUID, "unique parent process identifier", kparams.Uint64, []string{"ps.parent.uuid > 6000054355"}, nil, nil}, - PsChildUUID: {PsChildUUID, "unique child process identifier", kparams.Uint64, []string{"ps.child.uuid > 6000054355"}, nil, nil}, - PsChildPeFilename: {PsChildPeFilename, "original file name of the child process executable supplied at compile-time", kparams.UnicodeString, []string{"ps.child.pe.file.name = 'NOTEPAD.EXE'"}, nil, nil}, - PsChildIsWOW64Field: {PsChildIsWOW64Field, "indicates if the 32-bit child process is created in 64-bit Windows system", kparams.Bool, []string{"ps.child.is_wow64"}, nil, nil}, - PsChildIsPackagedField: {PsChildIsPackagedField, "indicates if the child process is packaged with the MSIX technology", kparams.Bool, []string{"ps.child.is_packaged"}, nil, nil}, - PsChildIsProtectedField: {PsChildIsProtectedField, "indicates if the child process is a protected process", kparams.Bool, []string{"ps.child.is_protected"}, nil, nil}, - PsIsWOW64Field: {PsIsWOW64Field, "indicates if the process generating the event is a 32-bit process created in 64-bit Windows system", kparams.Bool, []string{"ps.is_wow64"}, nil, nil}, - PsIsPackagedField: {PsIsPackagedField, "indicates if the process generating the event is packaged with the MSIX technology", kparams.Bool, []string{"ps.is_packaged"}, nil, nil}, - PsIsProtectedField: {PsIsProtectedField, "indicates if the process generating the event is a protected process", kparams.Bool, []string{"ps.is_protected"}, nil, nil}, - PsParentIsWOW64Field: {PsParentIsWOW64Field, "indicates if the parent process generating the event is a 32-bit process created in 64-bit Windows system", kparams.Bool, []string{"ps.parent.is_wow64"}, nil, nil}, - PsParentIsPackagedField: {PsParentIsPackagedField, "indicates if the parent process generating the event is packaged with the MSIX technology", kparams.Bool, []string{"ps.parent.is_packaged"}, nil, nil}, - PsParentIsProtectedField: {PsParentIsProtectedField, "indicates if the the parent process generating the event is a protected process", kparams.Bool, []string{"ps.parent.is_protected"}, nil, nil}, - PsAncestor: {PsAncestor, "the process ancestor name", kparams.UnicodeString, []string{"ps.ancestor[1] = 'svchost.exe'", "ps.ancestor in ('winword.exe')"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, + PsPid: {PsPid, "process identifier", params.PID, []string{"ps.pid = 1024"}, nil, nil}, + PsPpid: {PsPpid, "parent process identifier", params.PID, []string{"ps.ppid = 45"}, nil, nil}, + PsName: {PsName, "process image name including the file extension", params.UnicodeString, []string{"ps.name contains 'firefox'"}, nil, nil}, + PsComm: {PsComm, "process command line", params.UnicodeString, []string{"ps.comm contains 'java'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsCmdline}}, nil}, + PsCmdline: {PsCmdline, "process command line", params.UnicodeString, []string{"ps.cmdline contains 'java'"}, nil, nil}, + PsExe: {PsExe, "full name of the process' executable", params.UnicodeString, []string{"ps.exe = 'C:\\Windows\\system32\\cmd.exe'"}, nil, nil}, + PsArgs: {PsArgs, "process command line arguments", params.Slice, []string{"ps.args in ('/cdir', '/-C')"}, nil, nil}, + PsCwd: {PsCwd, "process current working directory", params.UnicodeString, []string{"ps.cwd = 'C:\\Users\\Default'"}, nil, nil}, + PsSID: {PsSID, "security identifier under which this process is run", params.UnicodeString, []string{"ps.sid contains 'SYSTEM'"}, nil, nil}, + PsSessionID: {PsSessionID, "unique identifier for the current session", params.Int16, []string{"ps.sessionid = 1"}, nil, nil}, + PsDomain: {PsDomain, "process domain", params.UnicodeString, []string{"ps.domain contains 'SERVICE'"}, nil, nil}, + PsUsername: {PsUsername, "process username", params.UnicodeString, []string{"ps.username contains 'system'"}, nil, nil}, + PsEnvs: {PsEnvs, "process environment variables", params.Slice, []string{"ps.envs in ('SystemRoot:C:\\WINDOWS')", "ps.envs[windir] = 'C:\\WINDOWS'"}, nil, &Argument{Optional: true, ValidationFunc: func(arg string) bool { return true }}}, + PsHandleNames: {PsHandleNames, "allocated process handle names", params.Slice, []string{"ps.handles in ('\\BaseNamedObjects\\__ComCatalogCache__')"}, nil, nil}, + PsHandleTypes: {PsHandleTypes, "allocated process handle types", params.Slice, []string{"ps.handle.types in ('Key', 'Mutant', 'Section')"}, nil, nil}, + PsDTB: {PsDTB, "process directory table base address", params.Address, []string{"ps.dtb = '7ffe0000'"}, nil, nil}, + PsModuleNames: {PsModuleNames, "modules loaded by the process", params.Slice, []string{"ps.modules in ('crypt32.dll', 'xul.dll')"}, nil, nil}, + PsParentName: {PsParentName, "parent process image name including the file extension", params.UnicodeString, []string{"ps.parent.name contains 'cmd.exe'"}, nil, nil}, + PsParentPid: {PsParentPid, "parent process id", params.Uint32, []string{"ps.parent.pid = 4"}, nil, nil}, + PsParentComm: {PsParentComm, "parent process command line", params.UnicodeString, []string{"ps.parent.comm contains 'java'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsParentCmdline}}, nil}, + PsParentCmdline: {PsParentCmdline, "parent process command line", params.UnicodeString, []string{"ps.parent.cmdline contains 'java'"}, nil, nil}, + PsParentExe: {PsParentExe, "full name of the parent process' executable", params.UnicodeString, []string{"ps.parent.exe = 'C:\\Windows\\system32\\explorer.exe'"}, nil, nil}, + PsParentArgs: {PsParentArgs, "parent process command line arguments", params.Slice, []string{"ps.parent.args in ('/cdir', '/-C')"}, nil, nil}, + PsParentCwd: {PsParentCwd, "parent process current working directory", params.UnicodeString, []string{"ps.parent.cwd = 'C:\\Temp'"}, nil, nil}, + PsParentSID: {PsParentSID, "security identifier under which the parent process is run", params.UnicodeString, []string{"ps.parent.sid contains 'SYSTEM'"}, nil, nil}, + PsParentDomain: {PsParentDomain, "parent process domain", params.UnicodeString, []string{"ps.parent.domain contains 'SERVICE'"}, nil, nil}, + PsParentUsername: {PsParentUsername, "parent process username", params.UnicodeString, []string{"ps.parent.username contains 'system'"}, nil, nil}, + PsParentSessionID: {PsParentSessionID, "unique identifier for the current session of parent process", params.Int16, []string{"ps.parent.sessionid = 1"}, nil, nil}, + PsParentEnvs: {PsParentEnvs, "parent process environment variables", params.Slice, []string{"ps.parent.envs in ('MOZ_CRASHREPORTER_DATA_DIRECTORY')"}, nil, nil}, + PsParentHandles: {PsParentHandles, "allocated parent process handle names", params.Slice, []string{"ps.parent.handles in ('\\BaseNamedObjects\\__ComCatalogCache__')"}, nil, nil}, + PsParentHandleTypes: {PsParentHandleTypes, "allocated parent process handle types", params.Slice, []string{"ps.parent.handle.types in ('File', 'SymbolicLink')"}, nil, nil}, + PsParentDTB: {PsParentDTB, "parent process directory table base address", params.Address, []string{"ps.parent.dtb = '7ffe0000'"}, nil, nil}, + PsAccessMask: {PsAccessMask, "process desired access rights", params.AnsiString, []string{"ps.access.mask = '0x1400'"}, nil, nil}, + PsAccessMaskNames: {PsAccessMaskNames, "process desired access rights as a string list", params.Slice, []string{"ps.access.mask.names in ('SUSPEND_RESUME')"}, nil, nil}, + PsAccessStatus: {PsAccessStatus, "process access status", params.UnicodeString, []string{"ps.access.status = 'access is denied.'"}, nil, nil}, + PsSiblingPid: {PsSiblingPid, "created or terminated process identifier", params.PID, []string{"ps.sibling.pid = 320"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildPid}}, nil}, + PsChildPid: {PsChildPid, "created or terminated process identifier", params.PID, []string{"ps.child.pid = 320"}, nil, nil}, + PsSiblingName: {PsSiblingName, "created or terminated process name", params.UnicodeString, []string{"ps.sibling.name = 'notepad.exe'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildName}}, nil}, + PsChildName: {PsChildName, "created or terminated process name", params.UnicodeString, []string{"ps.child.name = 'notepad.exe'"}, nil, nil}, + PsSiblingComm: {PsSiblingComm, "created or terminated process command line", params.UnicodeString, []string{"ps.sibling.comm contains '\\k \\v'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildCmdline}}, nil}, + PsChildCmdline: {PsChildCmdline, "created or terminated process command line", params.UnicodeString, []string{"ps.child.cmdline contains '\\k \\v'"}, nil, nil}, + PsSiblingArgs: {PsSiblingArgs, "created process command line arguments", params.Slice, []string{"ps.sibling.args in ('/cdir', '/-C')"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildArgs}}, nil}, + PsChildArgs: {PsChildArgs, "created process command line arguments", params.Slice, []string{"ps.child.args in ('/cdir', '/-C')"}, nil, nil}, + PsSiblingExe: {PsSiblingExe, "created, terminated, or opened process id", params.UnicodeString, []string{"ps.sibling.exe contains '\\Windows\\cmd.exe'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildExe}}, nil}, + PsChildExe: {PsChildExe, "created, terminated, or opened process id", params.UnicodeString, []string{"ps.child.exe contains '\\Windows\\cmd.exe'"}, nil, nil}, + PsSiblingSID: {PsSiblingSID, "created or terminated process security identifier", params.UnicodeString, []string{"ps.sibling.sid contains 'SERVICE'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildSID}}, nil}, + PsChildSID: {PsChildSID, "created or terminated process security identifier", params.UnicodeString, []string{"ps.child.sid contains 'SERVICE'"}, nil, nil}, + PsSiblingSessionID: {PsSiblingSessionID, "created or terminated process session identifier", params.Int16, []string{"ps.sibling.sessionid == 1"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildSessionID}}, nil}, + PsChildSessionID: {PsChildSessionID, "created or terminated process session identifier", params.Int16, []string{"ps.child.sessionid == 1"}, nil, nil}, + PsSiblingDomain: {PsSiblingDomain, "created or terminated process domain", params.UnicodeString, []string{"ps.sibling.domain contains 'SERVICE'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildDomain}}, nil}, + PsChildDomain: {PsChildDomain, "created or terminated process domain", params.UnicodeString, []string{"ps.child.domain contains 'SERVICE'"}, nil, nil}, + PsSiblingUsername: {PsSiblingUsername, "created or terminated process username", params.UnicodeString, []string{"ps.sibling.username contains 'system'"}, &Deprecation{Since: "1.10.0", Fields: []Field{PsChildUsername}}, nil}, + PsChildUsername: {PsChildUsername, "created or terminated process username", params.UnicodeString, []string{"ps.child.username contains 'system'"}, nil, nil}, + PsUUID: {PsUUID, "unique process identifier", params.Uint64, []string{"ps.uuid > 6000054355"}, nil, nil}, + PsParentUUID: {PsParentUUID, "unique parent process identifier", params.Uint64, []string{"ps.parent.uuid > 6000054355"}, nil, nil}, + PsChildUUID: {PsChildUUID, "unique child process identifier", params.Uint64, []string{"ps.child.uuid > 6000054355"}, nil, nil}, + PsChildPeFilename: {PsChildPeFilename, "original file name of the child process executable supplied at compile-time", params.UnicodeString, []string{"ps.child.pe.file.name = 'NOTEPAD.EXE'"}, nil, nil}, + PsChildIsWOW64Field: {PsChildIsWOW64Field, "indicates if the 32-bit child process is created in 64-bit Windows system", params.Bool, []string{"ps.child.is_wow64"}, nil, nil}, + PsChildIsPackagedField: {PsChildIsPackagedField, "indicates if the child process is packaged with the MSIX technology", params.Bool, []string{"ps.child.is_packaged"}, nil, nil}, + PsChildIsProtectedField: {PsChildIsProtectedField, "indicates if the child process is a protected process", params.Bool, []string{"ps.child.is_protected"}, nil, nil}, + PsIsWOW64Field: {PsIsWOW64Field, "indicates if the process generating the event is a 32-bit process created in 64-bit Windows system", params.Bool, []string{"ps.is_wow64"}, nil, nil}, + PsIsPackagedField: {PsIsPackagedField, "indicates if the process generating the event is packaged with the MSIX technology", params.Bool, []string{"ps.is_packaged"}, nil, nil}, + PsIsProtectedField: {PsIsProtectedField, "indicates if the process generating the event is a protected process", params.Bool, []string{"ps.is_protected"}, nil, nil}, + PsParentIsWOW64Field: {PsParentIsWOW64Field, "indicates if the parent process generating the event is a 32-bit process created in 64-bit Windows system", params.Bool, []string{"ps.parent.is_wow64"}, nil, nil}, + PsParentIsPackagedField: {PsParentIsPackagedField, "indicates if the parent process generating the event is packaged with the MSIX technology", params.Bool, []string{"ps.parent.is_packaged"}, nil, nil}, + PsParentIsProtectedField: {PsParentIsProtectedField, "indicates if the the parent process generating the event is a protected process", params.Bool, []string{"ps.parent.is_protected"}, nil, nil}, + PsAncestor: {PsAncestor, "the process ancestor name", params.UnicodeString, []string{"ps.ancestor[1] = 'svchost.exe'", "ps.ancestor in ('winword.exe')"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, - ThreadBasePrio: {ThreadBasePrio, "scheduler priority of the thread", kparams.Int8, []string{"thread.prio = 5"}, nil, nil}, - ThreadIOPrio: {ThreadIOPrio, "I/O priority hint for scheduling I/O operations", kparams.Int8, []string{"thread.io.prio = 4"}, nil, nil}, - ThreadPagePrio: {ThreadPagePrio, "memory page priority hint for memory pages accessed by the thread", kparams.Int8, []string{"thread.page.prio = 12"}, nil, nil}, - ThreadKstackBase: {ThreadKstackBase, "base address of the thread's kernel space stack", kparams.Address, []string{"thread.kstack.base = 'a65d800000'"}, nil, nil}, - ThreadKstackLimit: {ThreadKstackLimit, "limit of the thread's kernel space stack", kparams.Address, []string{"thread.kstack.limit = 'a85d800000'"}, nil, nil}, - ThreadUstackBase: {ThreadUstackBase, "base address of the thread's user space stack", kparams.Address, []string{"thread.ustack.base = '7ffe0000'"}, nil, nil}, - ThreadUstackLimit: {ThreadUstackLimit, "limit of the thread's user space stack", kparams.Address, []string{"thread.ustack.limit = '8ffe0000'"}, nil, nil}, - ThreadEntrypoint: {ThreadEntrypoint, "starting address of the function to be executed by the thread", kparams.Address, []string{"thread.entrypoint = '7efe0000'"}, &Deprecation{Since: "2.3.0", Fields: []Field{ThreadStartAddress}}, nil}, - ThreadStartAddress: {ThreadStartAddress, "thread start address", kparams.Address, []string{"thread.start_address = '7efe0000'"}, nil, nil}, - ThreadStartAddressSymbol: {ThreadStartAddressSymbol, "thread start address symbol", kparams.UnicodeString, []string{"thread.start_address.symbol = 'LoadImage'"}, nil, nil}, - ThreadStartAddressModule: {ThreadStartAddressModule, "thread start address module", kparams.UnicodeString, []string{"thread.start_address.module endswith 'kernel32.dll'"}, nil, nil}, - ThreadPID: {ThreadPID, "the process identifier where the thread is created", kparams.Uint32, []string{"kevt.pid != thread.pid"}, nil, nil}, - ThreadTEB: {ThreadTEB, "the base address of the thread environment block", kparams.Address, []string{"thread.teb_address = '8f30893000'"}, nil, nil}, - ThreadAccessMask: {ThreadAccessMask, "thread desired access rights", kparams.AnsiString, []string{"thread.access.mask = '0x1fffff'"}, nil, nil}, - ThreadAccessMaskNames: {ThreadAccessMaskNames, "thread desired access rights as a string list", kparams.Slice, []string{"thread.access.mask.names in ('IMPERSONATE')"}, nil, nil}, - ThreadAccessStatus: {ThreadAccessStatus, "thread access status", kparams.UnicodeString, []string{"thread.access.status = 'success'"}, nil, nil}, - ThreadCallstackSummary: {ThreadCallstackSummary, "callstack summary", kparams.UnicodeString, []string{"thread.callstack.summary contains 'ntdll.dll|KERNELBASE.dll'"}, nil, nil}, - ThreadCallstackDetail: {ThreadCallstackDetail, "detailed information of each stack frame", kparams.UnicodeString, []string{"thread.callstack.detail contains 'KERNELBASE.dll!CreateProcessW'"}, nil, nil}, - ThreadCallstackModules: {ThreadCallstackModules, "list of modules comprising the callstack", kparams.Slice, []string{"thread.callstack.modules in ('C:\\WINDOWS\\System32\\KERNELBASE.dll')", "base(thread.callstack.modules[7]) = 'ntdll.dll'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, - ThreadCallstackSymbols: {ThreadCallstackSymbols, "list of symbols comprising the callstack", kparams.Slice, []string{"thread.callstack.symbols in ('ntdll.dll!NtCreateProcess')", "thread.callstack.symbols[3] = 'ntdll!NtCreateProcess'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, - ThreadCallstackAllocationSizes: {ThreadCallstackAllocationSizes, "allocation sizes of private pages", kparams.Slice, []string{"thread.callstack.allocation_sizes > 10000"}, nil, nil}, - ThreadCallstackProtections: {ThreadCallstackProtections, "page protections masks of each frame", kparams.Slice, []string{"thread.callstack.protections in ('RWX', 'WX')"}, nil, nil}, - ThreadCallstackCallsiteLeadingAssembly: {ThreadCallstackCallsiteLeadingAssembly, "callsite leading assembly instructions", kparams.Slice, []string{"thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')"}, nil, nil}, - ThreadCallstackCallsiteTrailingAssembly: {ThreadCallstackCallsiteTrailingAssembly, "callsite trailing assembly instructions", kparams.Slice, []string{"thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')"}, nil, nil}, - ThreadCallstackIsUnbacked: {ThreadCallstackIsUnbacked, "indicates if the callstack contains unbacked regions", kparams.Bool, []string{"thread.callstack.is_unbacked"}, nil, nil}, - ThreadCallstackAddresses: {ThreadCallstackAddresses, "list of all stack return addresses", kparams.Slice, []string{"thread.callstack.addresses in ('7ffb5c1d0396')"}, nil, nil}, - ThreadCallstackFinalUserModuleName: {ThreadCallstackFinalUserModuleName, "final user space stack frame module name", kparams.UnicodeString, []string{"thread.callstack.final_user_module.name != 'ntdll.dll'"}, nil, nil}, - ThreadCallstackFinalUserModulePath: {ThreadCallstackFinalUserModulePath, "final user space stack frame module path", kparams.UnicodeString, []string{"thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'"}, nil, nil}, - ThreadCallstackFinalUserSymbolName: {ThreadCallstackFinalUserSymbolName, "final user space stack symbol name", kparams.UnicodeString, []string{"thread.callstack.final_user_symbol.name imatches 'CreateProcess*'"}, nil, nil}, - ThreadCallstackFinalKernelModuleName: {ThreadCallstackFinalKernelModuleName, "final kernel space stack frame module name", kparams.UnicodeString, []string{"thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'"}, nil, nil}, - ThreadCallstackFinalKernelModulePath: {ThreadCallstackFinalKernelModulePath, "final kernel space stack frame module path", kparams.UnicodeString, []string{"thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'"}, nil, nil}, - ThreadCallstackFinalKernelSymbolName: {ThreadCallstackFinalKernelSymbolName, "final kernel space stack symbol name", kparams.UnicodeString, []string{"thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureIsSigned: {ThreadCallstackFinalUserModuleSignatureIsSigned, "signature status of the final user space stack frame module", kparams.Bool, []string{"thread.callstack.final_user_module.signature.is_signed = true"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureIsTrusted: {ThreadCallstackFinalUserModuleSignatureIsTrusted, "signature trust status of the final user space stack frame module", kparams.Bool, []string{"thread.callstack.final_user_module.signature.is_trusted = true"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureCertIssuer: {ThreadCallstackFinalUserModuleSignatureCertIssuer, "final user space stack frame module signature certificate issuer", kparams.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.issuer imatches '*Microsoft Corporation*'"}, nil, nil}, - ThreadCallstackFinalUserModuleSignatureCertSubject: {ThreadCallstackFinalUserModuleSignatureCertSubject, "final user space stack frame module signature certificate subject", kparams.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.subject imatches '*Microsoft Windows*'"}, nil, nil}, + ThreadBasePrio: {ThreadBasePrio, "scheduler priority of the thread", params.Int8, []string{"thread.prio = 5"}, nil, nil}, + ThreadIOPrio: {ThreadIOPrio, "I/O priority hint for scheduling I/O operations", params.Int8, []string{"thread.io.prio = 4"}, nil, nil}, + ThreadPagePrio: {ThreadPagePrio, "memory page priority hint for memory pages accessed by the thread", params.Int8, []string{"thread.page.prio = 12"}, nil, nil}, + ThreadKstackBase: {ThreadKstackBase, "base address of the thread's kernel space stack", params.Address, []string{"thread.kstack.base = 'a65d800000'"}, nil, nil}, + ThreadKstackLimit: {ThreadKstackLimit, "limit of the thread's kernel space stack", params.Address, []string{"thread.kstack.limit = 'a85d800000'"}, nil, nil}, + ThreadUstackBase: {ThreadUstackBase, "base address of the thread's user space stack", params.Address, []string{"thread.ustack.base = '7ffe0000'"}, nil, nil}, + ThreadUstackLimit: {ThreadUstackLimit, "limit of the thread's user space stack", params.Address, []string{"thread.ustack.limit = '8ffe0000'"}, nil, nil}, + ThreadEntrypoint: {ThreadEntrypoint, "starting address of the function to be executed by the thread", params.Address, []string{"thread.entrypoint = '7efe0000'"}, &Deprecation{Since: "2.3.0", Fields: []Field{ThreadStartAddress}}, nil}, + ThreadStartAddress: {ThreadStartAddress, "thread start address", params.Address, []string{"thread.start_address = '7efe0000'"}, nil, nil}, + ThreadStartAddressSymbol: {ThreadStartAddressSymbol, "thread start address symbol", params.UnicodeString, []string{"thread.start_address.symbol = 'LoadImage'"}, nil, nil}, + ThreadStartAddressModule: {ThreadStartAddressModule, "thread start address module", params.UnicodeString, []string{"thread.start_address.module endswith 'kernel32.dll'"}, nil, nil}, + ThreadPID: {ThreadPID, "the process identifier where the thread is created", params.Uint32, []string{"evt.pid != thread.pid"}, nil, nil}, + ThreadTEB: {ThreadTEB, "the base address of the thread environment block", params.Address, []string{"thread.teb_address = '8f30893000'"}, nil, nil}, + ThreadAccessMask: {ThreadAccessMask, "thread desired access rights", params.AnsiString, []string{"thread.access.mask = '0x1fffff'"}, nil, nil}, + ThreadAccessMaskNames: {ThreadAccessMaskNames, "thread desired access rights as a string list", params.Slice, []string{"thread.access.mask.names in ('IMPERSONATE')"}, nil, nil}, + ThreadAccessStatus: {ThreadAccessStatus, "thread access status", params.UnicodeString, []string{"thread.access.status = 'success'"}, nil, nil}, + ThreadCallstackSummary: {ThreadCallstackSummary, "callstack summary", params.UnicodeString, []string{"thread.callstack.summary contains 'ntdll.dll|KERNELBASE.dll'"}, nil, nil}, + ThreadCallstackDetail: {ThreadCallstackDetail, "detailed information of each stack frame", params.UnicodeString, []string{"thread.callstack.detail contains 'KERNELBASE.dll!CreateProcessW'"}, nil, nil}, + ThreadCallstackModules: {ThreadCallstackModules, "list of modules comprising the callstack", params.Slice, []string{"thread.callstack.modules in ('C:\\WINDOWS\\System32\\KERNELBASE.dll')", "base(thread.callstack.modules[7]) = 'ntdll.dll'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, + ThreadCallstackSymbols: {ThreadCallstackSymbols, "list of symbols comprising the callstack", params.Slice, []string{"thread.callstack.symbols in ('ntdll.dll!NtCreateProcess')", "thread.callstack.symbols[3] = 'ntdll!NtCreateProcess'"}, nil, &Argument{Optional: true, Pattern: "[0-9]+", ValidationFunc: isNumber}}, + ThreadCallstackAllocationSizes: {ThreadCallstackAllocationSizes, "allocation sizes of private pages", params.Slice, []string{"thread.callstack.allocation_sizes > 10000"}, nil, nil}, + ThreadCallstackProtections: {ThreadCallstackProtections, "page protections masks of each frame", params.Slice, []string{"thread.callstack.protections in ('RWX', 'WX')"}, nil, nil}, + ThreadCallstackCallsiteLeadingAssembly: {ThreadCallstackCallsiteLeadingAssembly, "callsite leading assembly instructions", params.Slice, []string{"thread.callstack.callsite_leading_assembly in ('mov r10,rcx', 'syscall')"}, nil, nil}, + ThreadCallstackCallsiteTrailingAssembly: {ThreadCallstackCallsiteTrailingAssembly, "callsite trailing assembly instructions", params.Slice, []string{"thread.callstack.callsite_trailing_assembly in ('add esp, 0xab')"}, nil, nil}, + ThreadCallstackIsUnbacked: {ThreadCallstackIsUnbacked, "indicates if the callstack contains unbacked regions", params.Bool, []string{"thread.callstack.is_unbacked"}, nil, nil}, + ThreadCallstackAddresses: {ThreadCallstackAddresses, "list of all stack return addresses", params.Slice, []string{"thread.callstack.addresses in ('7ffb5c1d0396')"}, nil, nil}, + ThreadCallstackFinalUserModuleName: {ThreadCallstackFinalUserModuleName, "final user space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_user_module.name != 'ntdll.dll'"}, nil, nil}, + ThreadCallstackFinalUserModulePath: {ThreadCallstackFinalUserModulePath, "final user space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_user_module.path imatches '?:\\Windows\\System32\\ntdll.dll'"}, nil, nil}, + ThreadCallstackFinalUserSymbolName: {ThreadCallstackFinalUserSymbolName, "final user space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_user_symbol.name imatches 'CreateProcess*'"}, nil, nil}, + ThreadCallstackFinalKernelModuleName: {ThreadCallstackFinalKernelModuleName, "final kernel space stack frame module name", params.UnicodeString, []string{"thread.callstack.final_kernel_module.name = 'FLTMGR.SYS'"}, nil, nil}, + ThreadCallstackFinalKernelModulePath: {ThreadCallstackFinalKernelModulePath, "final kernel space stack frame module path", params.UnicodeString, []string{"thread.callstack.final_kernel_module.path imatches '?:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS'"}, nil, nil}, + ThreadCallstackFinalKernelSymbolName: {ThreadCallstackFinalKernelSymbolName, "final kernel space stack symbol name", params.UnicodeString, []string{"thread.callstack.final_kernel_symbol.name = 'FltGetStreamContext'"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureIsSigned: {ThreadCallstackFinalUserModuleSignatureIsSigned, "signature status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.is_signed = true"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureIsTrusted: {ThreadCallstackFinalUserModuleSignatureIsTrusted, "signature trust status of the final user space stack frame module", params.Bool, []string{"thread.callstack.final_user_module.signature.is_trusted = true"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureCertIssuer: {ThreadCallstackFinalUserModuleSignatureCertIssuer, "final user space stack frame module signature certificate issuer", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.issuer imatches '*Microsoft Corporation*'"}, nil, nil}, + ThreadCallstackFinalUserModuleSignatureCertSubject: {ThreadCallstackFinalUserModuleSignatureCertSubject, "final user space stack frame module signature certificate subject", params.UnicodeString, []string{"thread.callstack.final_user_module.signature.cert.subject imatches '*Microsoft Windows*'"}, nil, nil}, - ImagePath: {ImagePath, "full image path", kparams.UnicodeString, []string{"image.patj = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil}, - ImageName: {ImageName, "image name", kparams.UnicodeString, []string{"image.name = 'advapi32.dll'"}, nil, nil}, - ImageBase: {ImageBase, "the base address of process in which the image is loaded", kparams.Address, []string{"image.base.address = 'a65d800000'"}, nil, nil}, - ImageChecksum: {ImageChecksum, "image checksum", kparams.Uint32, []string{"image.checksum = 746424"}, nil, nil}, - ImageSize: {ImageSize, "image size", kparams.Uint32, []string{"image.size > 1024"}, nil, nil}, - ImageDefaultAddress: {ImageDefaultAddress, "default image address", kparams.Address, []string{"image.default.address = '7efe0000'"}, nil, nil}, - ImagePID: {ImagePID, "target process identifier", kparams.Uint32, []string{"image.pid = 80"}, nil, nil}, - ImageSignatureType: {ImageSignatureType, "image signature type", kparams.AnsiString, []string{"image.signature.type != 'NONE'"}, nil, nil}, - ImageSignatureLevel: {ImageSignatureLevel, "image signature level", kparams.AnsiString, []string{"image.signature.level = 'AUTHENTICODE'"}, nil, nil}, - ImageCertSerial: {ImageCertSerial, "image certificate serial number", kparams.UnicodeString, []string{"image.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, - ImageCertSubject: {ImageCertSubject, "image certificate subject", kparams.UnicodeString, []string{"image.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - ImageCertIssuer: {ImageCertIssuer, "image certificate CA", kparams.UnicodeString, []string{"image.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - ImageCertAfter: {ImageCertAfter, "image certificate expiration date", kparams.Time, []string{"image.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - ImageCertBefore: {ImageCertBefore, "image certificate enrollment date", kparams.Time, []string{"image.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - ImageIsDriverMalicious: {ImageIsDriverMalicious, "indicates if the loaded driver is malicious", kparams.Bool, []string{"image.is_driver_malicious"}, nil, nil}, - ImageIsDriverVulnerable: {ImageIsDriverVulnerable, "indicates if the loaded driver is vulnerable", kparams.Bool, []string{"image.is_driver_vulnerable"}, nil, nil}, - ImageIsDLL: {ImageIsDLL, "indicates if the loaded image is a DLL", kparams.Bool, []string{"image.is_dll'"}, nil, nil}, - ImageIsDriver: {ImageIsDriver, "indicates if the loaded image is a driver", kparams.Bool, []string{"image.is_driver'"}, nil, nil}, - ImageIsExecutable: {ImageIsExecutable, "indicates if the loaded image is an executable", kparams.Bool, []string{"image.is_exec'"}, nil, nil}, - ImageIsDotnet: {ImageIsDotnet, "indicates if the loaded image is a .NET assembly", kparams.Bool, []string{"image.is_dotnet'"}, nil, nil}, + ImagePath: {ImagePath, "full image path", params.UnicodeString, []string{"image.patj = 'C:\\Windows\\System32\\advapi32.dll'"}, nil, nil}, + ImageName: {ImageName, "image name", params.UnicodeString, []string{"image.name = 'advapi32.dll'"}, nil, nil}, + ImageBase: {ImageBase, "the base address of process in which the image is loaded", params.Address, []string{"image.base.address = 'a65d800000'"}, nil, nil}, + ImageChecksum: {ImageChecksum, "image checksum", params.Uint32, []string{"image.checksum = 746424"}, nil, nil}, + ImageSize: {ImageSize, "image size", params.Uint32, []string{"image.size > 1024"}, nil, nil}, + ImageDefaultAddress: {ImageDefaultAddress, "default image address", params.Address, []string{"image.default.address = '7efe0000'"}, nil, nil}, + ImagePID: {ImagePID, "target process identifier", params.Uint32, []string{"image.pid = 80"}, nil, nil}, + ImageSignatureType: {ImageSignatureType, "image signature type", params.AnsiString, []string{"image.signature.type != 'NONE'"}, nil, nil}, + ImageSignatureLevel: {ImageSignatureLevel, "image signature level", params.AnsiString, []string{"image.signature.level = 'AUTHENTICODE'"}, nil, nil}, + ImageCertSerial: {ImageCertSerial, "image certificate serial number", params.UnicodeString, []string{"image.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, + ImageCertSubject: {ImageCertSubject, "image certificate subject", params.UnicodeString, []string{"image.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + ImageCertIssuer: {ImageCertIssuer, "image certificate CA", params.UnicodeString, []string{"image.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + ImageCertAfter: {ImageCertAfter, "image certificate expiration date", params.Time, []string{"image.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + ImageCertBefore: {ImageCertBefore, "image certificate enrollment date", params.Time, []string{"image.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + ImageIsDriverMalicious: {ImageIsDriverMalicious, "indicates if the loaded driver is malicious", params.Bool, []string{"image.is_driver_malicious"}, nil, nil}, + ImageIsDriverVulnerable: {ImageIsDriverVulnerable, "indicates if the loaded driver is vulnerable", params.Bool, []string{"image.is_driver_vulnerable"}, nil, nil}, + ImageIsDLL: {ImageIsDLL, "indicates if the loaded image is a DLL", params.Bool, []string{"image.is_dll'"}, nil, nil}, + ImageIsDriver: {ImageIsDriver, "indicates if the loaded image is a driver", params.Bool, []string{"image.is_driver'"}, nil, nil}, + ImageIsExecutable: {ImageIsExecutable, "indicates if the loaded image is an executable", params.Bool, []string{"image.is_exec'"}, nil, nil}, + ImageIsDotnet: {ImageIsDotnet, "indicates if the loaded image is a .NET assembly", params.Bool, []string{"image.is_dotnet'"}, nil, nil}, - FileObject: {FileObject, "file object address", kparams.Uint64, []string{"file.object = 18446738026482168384"}, nil, nil}, - FilePath: {FilePath, "full file path", kparams.UnicodeString, []string{"file.path = 'C:\\Windows\\System32'"}, nil, nil}, - FileName: {FileName, "full file name", kparams.UnicodeString, []string{"file.name contains 'mimikatz'"}, nil, nil}, - FileOperation: {FileOperation, "file operation", kparams.AnsiString, []string{"file.operation = 'open'"}, nil, nil}, - FileShareMask: {FileShareMask, "file share mask", kparams.AnsiString, []string{"file.share.mask = 'rw-'"}, nil, nil}, - FileIOSize: {FileIOSize, "file I/O size", kparams.Uint32, []string{"file.io.size > 512"}, nil, nil}, - FileOffset: {FileOffset, "file offset", kparams.Uint64, []string{"file.offset = 1024"}, nil, nil}, - FileType: {FileType, "file type", kparams.AnsiString, []string{"file.type = 'directory'"}, nil, nil}, - FileExtension: {FileExtension, "file extension", kparams.AnsiString, []string{"file.extension = '.dll'"}, nil, nil}, - FileAttributes: {FileAttributes, "file attributes", kparams.Slice, []string{"file.attributes in ('archive', 'hidden')"}, nil, nil}, - FileStatus: {FileStatus, "file operation status message", kparams.UnicodeString, []string{"file.status != 'success'"}, nil, nil}, - FileViewBase: {FileViewBase, "view base address", kparams.Address, []string{"file.view.base = '25d42170000'"}, nil, nil}, - FileViewSize: {FileViewSize, "size of the mapped view", kparams.Uint64, []string{"file.view.size > 1024"}, nil, nil}, - FileViewType: {FileViewType, "type of the mapped view section", kparams.Enum, []string{"file.view.type = 'IMAGE'"}, nil, nil}, - FileViewProtection: {FileViewProtection, "protection rights of the section view", kparams.AnsiString, []string{"file.view.protection = 'READONLY'"}, nil, nil}, - FileIsDriverMalicious: {FileIsDriverMalicious, "indicates if the dropped driver is malicious", kparams.Bool, []string{"file.is_driver_malicious"}, nil, nil}, - FileIsDriverVulnerable: {FileIsDriverVulnerable, "indicates if the dropped driver is vulnerable", kparams.Bool, []string{"file.is_driver_vulnerable"}, nil, nil}, - FileIsDLL: {FileIsDLL, "indicates if the created file is a DLL", kparams.Bool, []string{"file.is_dll'"}, nil, nil}, - FileIsDriver: {FileIsDriver, "indicates if the created file is a driver", kparams.Bool, []string{"file.is_driver'"}, nil, nil}, - FileIsExecutable: {FileIsExecutable, "indicates if the created file is an executable", kparams.Bool, []string{"file.is_exec'"}, nil, nil}, - FilePID: {FilePID, "denotes the process id performing file operation", kparams.PID, []string{"file.pid = 4"}, nil, nil}, - FileKey: {FileKey, "uniquely identifies the file object", kparams.Uint64, []string{"file.key = 12446738026482168384"}, nil, nil}, - FileInfoClass: {FileInfoClass, "identifies the file information class", kparams.Enum, []string{"file.info_class = 'Allocation'"}, nil, nil}, - FileInfoAllocationSize: {FileInfoAllocationSize, "file allocation size", kparams.Uint64, []string{"file.info.allocation_size > 645400"}, nil, nil}, - FileInfoEOFSize: {FileInfoEOFSize, "file EOF size", kparams.Uint64, []string{"file.info.eof_size > 1000"}, nil, nil}, - FileInfoIsDispositionDeleteFile: {FileInfoIsDispositionDeleteFile, "indicates if the file is deleted when its handle is closed", kparams.Bool, []string{"file.info.is_disposition_file_delete = true"}, nil, nil}, + FileObject: {FileObject, "file object address", params.Uint64, []string{"file.object = 18446738026482168384"}, nil, nil}, + FilePath: {FilePath, "full file path", params.UnicodeString, []string{"file.path = 'C:\\Windows\\System32'"}, nil, nil}, + FileName: {FileName, "full file name", params.UnicodeString, []string{"file.name contains 'mimikatz'"}, nil, nil}, + FileOperation: {FileOperation, "file operation", params.AnsiString, []string{"file.operation = 'open'"}, nil, nil}, + FileShareMask: {FileShareMask, "file share mask", params.AnsiString, []string{"file.share.mask = 'rw-'"}, nil, nil}, + FileIOSize: {FileIOSize, "file I/O size", params.Uint32, []string{"file.io.size > 512"}, nil, nil}, + FileOffset: {FileOffset, "file offset", params.Uint64, []string{"file.offset = 1024"}, nil, nil}, + FileType: {FileType, "file type", params.AnsiString, []string{"file.type = 'directory'"}, nil, nil}, + FileExtension: {FileExtension, "file extension", params.AnsiString, []string{"file.extension = '.dll'"}, nil, nil}, + FileAttributes: {FileAttributes, "file attributes", params.Slice, []string{"file.attributes in ('archive', 'hidden')"}, nil, nil}, + FileStatus: {FileStatus, "file operation status message", params.UnicodeString, []string{"file.status != 'success'"}, nil, nil}, + FileViewBase: {FileViewBase, "view base address", params.Address, []string{"file.view.base = '25d42170000'"}, nil, nil}, + FileViewSize: {FileViewSize, "size of the mapped view", params.Uint64, []string{"file.view.size > 1024"}, nil, nil}, + FileViewType: {FileViewType, "type of the mapped view section", params.Enum, []string{"file.view.type = 'IMAGE'"}, nil, nil}, + FileViewProtection: {FileViewProtection, "protection rights of the section view", params.AnsiString, []string{"file.view.protection = 'READONLY'"}, nil, nil}, + FileIsDriverMalicious: {FileIsDriverMalicious, "indicates if the dropped driver is malicious", params.Bool, []string{"file.is_driver_malicious"}, nil, nil}, + FileIsDriverVulnerable: {FileIsDriverVulnerable, "indicates if the dropped driver is vulnerable", params.Bool, []string{"file.is_driver_vulnerable"}, nil, nil}, + FileIsDLL: {FileIsDLL, "indicates if the created file is a DLL", params.Bool, []string{"file.is_dll'"}, nil, nil}, + FileIsDriver: {FileIsDriver, "indicates if the created file is a driver", params.Bool, []string{"file.is_driver'"}, nil, nil}, + FileIsExecutable: {FileIsExecutable, "indicates if the created file is an executable", params.Bool, []string{"file.is_exec'"}, nil, nil}, + FilePID: {FilePID, "denotes the process id performing file operation", params.PID, []string{"file.pid = 4"}, nil, nil}, + FileKey: {FileKey, "uniquely identifies the file object", params.Uint64, []string{"file.key = 12446738026482168384"}, nil, nil}, + FileInfoClass: {FileInfoClass, "identifies the file information class", params.Enum, []string{"file.info_class = 'Allocation'"}, nil, nil}, + FileInfoAllocationSize: {FileInfoAllocationSize, "file allocation size", params.Uint64, []string{"file.info.allocation_size > 645400"}, nil, nil}, + FileInfoEOFSize: {FileInfoEOFSize, "file EOF size", params.Uint64, []string{"file.info.eof_size > 1000"}, nil, nil}, + FileInfoIsDispositionDeleteFile: {FileInfoIsDispositionDeleteFile, "indicates if the file is deleted when its handle is closed", params.Bool, []string{"file.info.is_disposition_file_delete = true"}, nil, nil}, - RegistryPath: {RegistryPath, "fully qualified registry path", kparams.UnicodeString, []string{"registry.path = 'HKEY_LOCAL_MACHINE\\SYSTEM'"}, nil, nil}, - RegistryKeyName: {RegistryKeyName, "registry key name", kparams.UnicodeString, []string{"registry.key.name = 'CurrentControlSet'"}, nil, nil}, - RegistryKeyHandle: {RegistryKeyHandle, "registry key object address", kparams.Address, []string{"registry.key.handle = 'FFFFB905D60C2268'"}, nil, nil}, - RegistryValue: {RegistryValue, "registry value content", kparams.UnicodeString, []string{"registry.value = '%SystemRoot%\\system32'"}, nil, nil}, - RegistryValueType: {RegistryValueType, "type of registry value", kparams.UnicodeString, []string{"registry.value.type = 'REG_SZ'"}, nil, nil}, - RegistryStatus: {RegistryStatus, "status of registry operation", kparams.UnicodeString, []string{"registry.status != 'success'"}, nil, nil}, + RegistryPath: {RegistryPath, "fully qualified registry path", params.UnicodeString, []string{"registry.path = 'HKEY_LOCAL_MACHINE\\SYSTEM'"}, nil, nil}, + RegistryKeyName: {RegistryKeyName, "registry key name", params.UnicodeString, []string{"registry.key.name = 'CurrentControlSet'"}, nil, nil}, + RegistryKeyHandle: {RegistryKeyHandle, "registry key object address", params.Address, []string{"registry.key.handle = 'FFFFB905D60C2268'"}, nil, nil}, + RegistryValue: {RegistryValue, "registry value content", params.UnicodeString, []string{"registry.value = '%SystemRoot%\\system32'"}, nil, nil}, + RegistryValueType: {RegistryValueType, "type of registry value", params.UnicodeString, []string{"registry.value.type = 'REG_SZ'"}, nil, nil}, + RegistryStatus: {RegistryStatus, "status of registry operation", params.UnicodeString, []string{"registry.status != 'success'"}, nil, nil}, - NetDIP: {NetDIP, "destination IP address", kparams.IP, []string{"net.dip = 172.17.0.3"}, nil, nil}, - NetSIP: {NetSIP, "source IP address", kparams.IP, []string{"net.sip = 127.0.0.1"}, nil, nil}, - NetDport: {NetDport, "destination port", kparams.Uint16, []string{"net.dport in (80, 443, 8080)"}, nil, nil}, - NetSport: {NetSport, "source port", kparams.Uint16, []string{"net.sport != 3306"}, nil, nil}, - NetDportName: {NetDportName, "destination port name", kparams.AnsiString, []string{"net.dport.name = 'dns'"}, nil, nil}, - NetSportName: {NetSportName, "source port name", kparams.AnsiString, []string{"net.sport.name = 'http'"}, nil, nil}, - NetL4Proto: {NetL4Proto, "layer 4 protocol name", kparams.AnsiString, []string{"net.l4.proto = 'TCP"}, nil, nil}, - NetPacketSize: {NetPacketSize, "packet size", kparams.Uint32, []string{"net.size > 512"}, nil, nil}, - NetSIPNames: {NetSIPNames, "source IP names", kparams.Slice, []string{"net.sip.names in ('github.com.')"}, nil, nil}, - NetDIPNames: {NetDIPNames, "destination IP names", kparams.Slice, []string{"net.dip.names in ('github.com.')"}, nil, nil}, + NetDIP: {NetDIP, "destination IP address", params.IP, []string{"net.dip = 172.17.0.3"}, nil, nil}, + NetSIP: {NetSIP, "source IP address", params.IP, []string{"net.sip = 127.0.0.1"}, nil, nil}, + NetDport: {NetDport, "destination port", params.Uint16, []string{"net.dport in (80, 443, 8080)"}, nil, nil}, + NetSport: {NetSport, "source port", params.Uint16, []string{"net.sport != 3306"}, nil, nil}, + NetDportName: {NetDportName, "destination port name", params.AnsiString, []string{"net.dport.name = 'dns'"}, nil, nil}, + NetSportName: {NetSportName, "source port name", params.AnsiString, []string{"net.sport.name = 'http'"}, nil, nil}, + NetL4Proto: {NetL4Proto, "layer 4 protocol name", params.AnsiString, []string{"net.l4.proto = 'TCP"}, nil, nil}, + NetPacketSize: {NetPacketSize, "packet size", params.Uint32, []string{"net.size > 512"}, nil, nil}, + NetSIPNames: {NetSIPNames, "source IP names", params.Slice, []string{"net.sip.names in ('github.com.')"}, nil, nil}, + NetDIPNames: {NetDIPNames, "destination IP names", params.Slice, []string{"net.dip.names in ('github.com.')"}, nil, nil}, - HandleID: {HandleID, "handle identifier", kparams.Uint16, []string{"handle.id = 24"}, nil, nil}, - HandleObject: {HandleObject, "handle object address", kparams.Address, []string{"handle.object = 'FFFFB905DBF61988'"}, nil, nil}, - HandleName: {HandleName, "handle name", kparams.UnicodeString, []string{"handle.name = '\\Device\\NamedPipe\\chrome.12644.28.105826381'"}, nil, nil}, - HandleType: {HandleType, "handle type", kparams.AnsiString, []string{"handle.type = 'Mutant'"}, nil, nil}, + HandleID: {HandleID, "handle identifier", params.Uint16, []string{"handle.id = 24"}, nil, nil}, + HandleObject: {HandleObject, "handle object address", params.Address, []string{"handle.object = 'FFFFB905DBF61988'"}, nil, nil}, + HandleName: {HandleName, "handle name", params.UnicodeString, []string{"handle.name = '\\Device\\NamedPipe\\chrome.12644.28.105826381'"}, nil, nil}, + HandleType: {HandleType, "handle type", params.AnsiString, []string{"handle.type = 'Mutant'"}, nil, nil}, - PeNumSections: {PeNumSections, "number of sections", kparams.Uint16, []string{"pe.nsections < 5"}, nil, nil}, - PeNumSymbols: {PeNumSymbols, "number of entries in the symbol table", kparams.Uint32, []string{"pe.nsymbols > 230"}, nil, nil}, - PeBaseAddress: {PeBaseAddress, "image base address", kparams.Address, []string{"pe.address.base = '140000000'"}, nil, nil}, - PeEntrypoint: {PeEntrypoint, "address of the entrypoint function", kparams.Address, []string{"pe.address.entrypoint = '20110'"}, nil, nil}, - PeSymbols: {PeSymbols, "imported symbols", kparams.Slice, []string{"pe.symbols in ('GetTextFaceW', 'GetProcessHeap')"}, nil, nil}, - PeImports: {PeImports, "imported dynamic linked libraries", kparams.Slice, []string{"pe.imports in ('msvcrt.dll', 'GDI32.dll'"}, nil, nil}, + PeNumSections: {PeNumSections, "number of sections", params.Uint16, []string{"pe.nsections < 5"}, nil, nil}, + PeNumSymbols: {PeNumSymbols, "number of entries in the symbol table", params.Uint32, []string{"pe.nsymbols > 230"}, nil, nil}, + PeBaseAddress: {PeBaseAddress, "image base address", params.Address, []string{"pe.address.base = '140000000'"}, nil, nil}, + PeEntrypoint: {PeEntrypoint, "address of the entrypoint function", params.Address, []string{"pe.address.entrypoint = '20110'"}, nil, nil}, + PeSymbols: {PeSymbols, "imported symbols", params.Slice, []string{"pe.symbols in ('GetTextFaceW', 'GetProcessHeap')"}, nil, nil}, + PeImports: {PeImports, "imported dynamic linked libraries", params.Slice, []string{"pe.imports in ('msvcrt.dll', 'GDI32.dll'"}, nil, nil}, - PeResources: {PeResources, "version resources", kparams.Map, []string{"pe.resources[FileDescription] = 'Notepad'"}, nil, &Argument{Optional: true, Pattern: "[a-zA-Z0-9_]+", ValidationFunc: func(s string) bool { + PeResources: {PeResources, "version resources", params.Map, []string{"pe.resources[FileDescription] = 'Notepad'"}, nil, &Argument{Optional: true, Pattern: "[a-zA-Z0-9_]+", ValidationFunc: func(s string) bool { for _, c := range s { switch { case unicode.IsLower(c): @@ -965,58 +965,58 @@ var fields = map[Field]FieldInfo{ return true }}}, - PeCompany: {PeCompany, "internal company name of the file provided at compile-time", kparams.UnicodeString, []string{"pe.company = 'Microsoft Corporation'"}, nil, nil}, - PeCopyright: {PeCopyright, "copyright notice for the file emitted at compile-time", kparams.UnicodeString, []string{"pe.copyright = '© Microsoft Corporation'"}, nil, nil}, - PeDescription: {PeDescription, "internal description of the file provided at compile-time", kparams.UnicodeString, []string{"pe.description = 'Notepad'"}, nil, nil}, - PeFileName: {PeFileName, "original file name supplied at compile-time", kparams.UnicodeString, []string{"pe.file.name = 'NOTEPAD.EXE'"}, nil, nil}, - PeFileVersion: {PeFileVersion, "file version supplied at compile-time", kparams.UnicodeString, []string{"pe.file.version = '10.0.18362.693 (WinBuild.160101.0800)'"}, nil, nil}, - PeProduct: {PeProduct, "internal product name of the file provided at compile-time", kparams.UnicodeString, []string{"pe.product = 'Microsoft® Windows® Operating System'"}, nil, nil}, - PeProductVersion: {PeProductVersion, "internal product version of the file provided at compile-time", kparams.UnicodeString, []string{"pe.product.version = '10.0.18362.693'"}, nil, nil}, - PeIsDLL: {PeIsDLL, "indicates if the loaded image or created file is a DLL", kparams.Bool, []string{"pe.is_dll'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsDLL, ImageIsDLL}}, nil}, - PeIsDriver: {PeIsDriver, "indicates if the loaded image or created file is a driver", kparams.Bool, []string{"pe.is_driver'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsDriver, ImageIsDriver}}, nil}, - PeIsExecutable: {PeIsExecutable, "indicates if the loaded image or created file is an executable", kparams.Bool, []string{"pe.is_exec'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsExecutable, ImageIsExecutable}}, nil}, - PeImphash: {PeImphash, "import hash", kparams.AnsiString, []string{"pe.impash = '5d3861c5c547f8a34e471ba273a732b2'"}, nil, nil}, - PeIsDotnet: {PeIsDotnet, "indicates if PE contains CLR data", kparams.Bool, []string{"pe.is_dotnet"}, nil, nil}, - PeAnomalies: {PeAnomalies, "contains PE anomalies detected during parsing", kparams.Slice, []string{"pe.anomalies in ('number of sections is 0')"}, nil, nil}, - PeIsSigned: {PeIsSigned, "indicates if the PE has embedded or catalog signature", kparams.Bool, []string{"pe.is_signed"}, nil, nil}, - PeIsTrusted: {PeIsTrusted, "indicates if the PE certificate chain is trusted", kparams.Bool, []string{"pe.is_trusted"}, nil, nil}, - PeCertSerial: {PeCertSerial, "PE certificate serial number", kparams.UnicodeString, []string{"pe.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, - PeCertSubject: {PeCertSubject, "PE certificate subject", kparams.UnicodeString, []string{"pe.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - PeCertIssuer: {PeCertIssuer, "PE certificate CA", kparams.UnicodeString, []string{"pe.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, - PeCertAfter: {PeCertAfter, "PE certificate expiration date", kparams.Time, []string{"pe.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - PeCertBefore: {PeCertBefore, "PE certificate enrollment date", kparams.Time, []string{"pe.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, - PeIsModified: {PeIsModified, "indicates if disk and in-memory PE headers differ", kparams.Bool, []string{"pe.is_modified"}, nil, nil}, - PePsChildFileName: {PePsChildFileName, "original file name of the child process executable supplied at compile-time", kparams.UnicodeString, []string{"pe.ps.child.file.name = 'NOTEPAD.EXE'"}, &Deprecation{Since: "2.3.0", Fields: []Field{PsChildPeFilename}}, nil}, + PeCompany: {PeCompany, "internal company name of the file provided at compile-time", params.UnicodeString, []string{"pe.company = 'Microsoft Corporation'"}, nil, nil}, + PeCopyright: {PeCopyright, "copyright notice for the file emitted at compile-time", params.UnicodeString, []string{"pe.copyright = '© Microsoft Corporation'"}, nil, nil}, + PeDescription: {PeDescription, "internal description of the file provided at compile-time", params.UnicodeString, []string{"pe.description = 'Notepad'"}, nil, nil}, + PeFileName: {PeFileName, "original file name supplied at compile-time", params.UnicodeString, []string{"pe.file.name = 'NOTEPAD.EXE'"}, nil, nil}, + PeFileVersion: {PeFileVersion, "file version supplied at compile-time", params.UnicodeString, []string{"pe.file.version = '10.0.18362.693 (WinBuild.160101.0800)'"}, nil, nil}, + PeProduct: {PeProduct, "internal product name of the file provided at compile-time", params.UnicodeString, []string{"pe.product = 'Microsoft® Windows® Operating System'"}, nil, nil}, + PeProductVersion: {PeProductVersion, "internal product version of the file provided at compile-time", params.UnicodeString, []string{"pe.product.version = '10.0.18362.693'"}, nil, nil}, + PeIsDLL: {PeIsDLL, "indicates if the loaded image or created file is a DLL", params.Bool, []string{"pe.is_dll'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsDLL, ImageIsDLL}}, nil}, + PeIsDriver: {PeIsDriver, "indicates if the loaded image or created file is a driver", params.Bool, []string{"pe.is_driver'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsDriver, ImageIsDriver}}, nil}, + PeIsExecutable: {PeIsExecutable, "indicates if the loaded image or created file is an executable", params.Bool, []string{"pe.is_exec'"}, &Deprecation{Since: "2.0.0", Fields: []Field{FileIsExecutable, ImageIsExecutable}}, nil}, + PeImphash: {PeImphash, "import hash", params.AnsiString, []string{"pe.impash = '5d3861c5c547f8a34e471ba273a732b2'"}, nil, nil}, + PeIsDotnet: {PeIsDotnet, "indicates if PE contains CLR data", params.Bool, []string{"pe.is_dotnet"}, nil, nil}, + PeAnomalies: {PeAnomalies, "contains PE anomalies detected during parsing", params.Slice, []string{"pe.anomalies in ('number of sections is 0')"}, nil, nil}, + PeIsSigned: {PeIsSigned, "indicates if the PE has embedded or catalog signature", params.Bool, []string{"pe.is_signed"}, nil, nil}, + PeIsTrusted: {PeIsTrusted, "indicates if the PE certificate chain is trusted", params.Bool, []string{"pe.is_trusted"}, nil, nil}, + PeCertSerial: {PeCertSerial, "PE certificate serial number", params.UnicodeString, []string{"pe.cert.serial = '330000023241fb59996dcc4dff000000000232'"}, nil, nil}, + PeCertSubject: {PeCertSubject, "PE certificate subject", params.UnicodeString, []string{"pe.cert.subject contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + PeCertIssuer: {PeCertIssuer, "PE certificate CA", params.UnicodeString, []string{"pe.cert.issuer contains 'Washington, Redmond, Microsoft Corporation'"}, nil, nil}, + PeCertAfter: {PeCertAfter, "PE certificate expiration date", params.Time, []string{"pe.cert.after contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + PeCertBefore: {PeCertBefore, "PE certificate enrollment date", params.Time, []string{"pe.cert.before contains '2024-02-01 00:05:42 +0000 UTC'"}, nil, nil}, + PeIsModified: {PeIsModified, "indicates if disk and in-memory PE headers differ", params.Bool, []string{"pe.is_modified"}, nil, nil}, + PePsChildFileName: {PePsChildFileName, "original file name of the child process executable supplied at compile-time", params.UnicodeString, []string{"pe.ps.child.file.name = 'NOTEPAD.EXE'"}, &Deprecation{Since: "2.3.0", Fields: []Field{PsChildPeFilename}}, nil}, - MemBaseAddress: {MemBaseAddress, "region base address", kparams.Address, []string{"mem.address = '211d13f2000'"}, nil, nil}, - MemRegionSize: {MemRegionSize, "region size", kparams.Uint64, []string{"mem.size > 438272"}, nil, nil}, - MemAllocType: {MemAllocType, "region allocation or release type", kparams.Flags, []string{"mem.alloc = 'COMMIT'"}, nil, nil}, - MemPageType: {MemPageType, "page type of the allocated region", kparams.Enum, []string{"mem.type = 'PRIVATE'"}, nil, nil}, - MemProtection: {MemProtection, "allocated region protection type", kparams.Enum, []string{"mem.protection = 'READWRITE'"}, nil, nil}, - MemProtectionMask: {MemProtectionMask, "allocated region protection in mask notation", kparams.Enum, []string{"mem.protection.mask = 'RWX'"}, nil, nil}, + MemBaseAddress: {MemBaseAddress, "region base address", params.Address, []string{"mem.address = '211d13f2000'"}, nil, nil}, + MemRegionSize: {MemRegionSize, "region size", params.Uint64, []string{"mem.size > 438272"}, nil, nil}, + MemAllocType: {MemAllocType, "region allocation or release type", params.Flags, []string{"mem.alloc = 'COMMIT'"}, nil, nil}, + MemPageType: {MemPageType, "page type of the allocated region", params.Enum, []string{"mem.type = 'PRIVATE'"}, nil, nil}, + MemProtection: {MemProtection, "allocated region protection type", params.Enum, []string{"mem.protection = 'READWRITE'"}, nil, nil}, + MemProtectionMask: {MemProtectionMask, "allocated region protection in mask notation", params.Enum, []string{"mem.protection.mask = 'RWX'"}, nil, nil}, - DNSName: {DNSName, "dns query name", kparams.UnicodeString, []string{"dns.name = 'example.org'"}, nil, nil}, - DNSRR: {DNSRR, "dns resource record type", kparams.AnsiString, []string{"dns.rr = 'AA'"}, nil, nil}, - DNSOptions: {DNSOptions, "dns query options", kparams.Flags64, []string{"dns.options in ('ADDRCONFIG', 'DUAL_ADDR')"}, nil, nil}, - DNSRcode: {DNSRR, "dns response status", kparams.AnsiString, []string{"dns.rcode = 'NXDOMAIN'"}, nil, nil}, - DNSAnswers: {DNSAnswers, "dns response answers", kparams.Slice, []string{"dns.answers in ('o.lencr.edgesuite.net', 'a1887.dscq.akamai.net')"}, nil, nil}, + DNSName: {DNSName, "dns query name", params.UnicodeString, []string{"dns.name = 'example.org'"}, nil, nil}, + DNSRR: {DNSRR, "dns resource record type", params.AnsiString, []string{"dns.rr = 'AA'"}, nil, nil}, + DNSOptions: {DNSOptions, "dns query options", params.Flags64, []string{"dns.options in ('ADDRCONFIG', 'DUAL_ADDR')"}, nil, nil}, + DNSRcode: {DNSRR, "dns response status", params.AnsiString, []string{"dns.rcode = 'NXDOMAIN'"}, nil, nil}, + DNSAnswers: {DNSAnswers, "dns response answers", params.Slice, []string{"dns.answers in ('o.lencr.edgesuite.net', 'a1887.dscq.akamai.net')"}, nil, nil}, - ThreadpoolPoolID: {ThreadpoolPoolID, "thread pool identifier", kparams.Address, []string{"threadpool.id = '20f5fc02440'"}, nil, nil}, - ThreadpoolTaskID: {ThreadpoolTaskID, "thread pool task identifier", kparams.Address, []string{"threadpool.task.id = '20f7ecd21f8'"}, nil, nil}, - ThreadpoolCallbackAddress: {ThreadpoolCallbackAddress, "thread pool callback address", kparams.Address, []string{"threadpool.callback.address = '7ff868739ed0'"}, nil, nil}, - ThreadpoolCallbackSymbol: {ThreadpoolCallbackSymbol, "thread pool callback symbol", kparams.UnicodeString, []string{"threadpool.callback.symbol = 'RtlDestroyQueryDebugBuffer'"}, nil, nil}, - ThreadpoolCallbackModule: {ThreadpoolCallbackModule, "thread pool module containing the callback symbol", kparams.UnicodeString, []string{"threadpool.callback.module contains 'ntdll.dll'"}, nil, nil}, - ThreadpoolCallbackContext: {ThreadpoolCallbackContext, "thread pool callback context address", kparams.Address, []string{"threadpool.callback.context = '1df41e07bd0'"}, nil, nil}, - ThreadpoolCallbackContextRip: {ThreadpoolCallbackContextRip, "thread pool callback thread context instruction pointer", kparams.Address, []string{"threadpool.callback.context.rip = '1df42ffc1f8'"}, nil, nil}, - ThreadpoolCallbackContextRipSymbol: {ThreadpoolCallbackContextRipSymbol, "thread pool callback thread context instruction pointer symbol", kparams.UnicodeString, []string{"threadpool.callback.context.rip.symbol = 'VirtualProtect'"}, nil, nil}, - ThreadpoolCallbackContextRipModule: {ThreadpoolCallbackContextRipModule, "thread pool callback thread context instruction pointer symbol module", kparams.UnicodeString, []string{"threadpool.callback.context.rip.module contains 'ntdll.dll'"}, nil, nil}, - ThreadpoolSubprocessTag: {ThreadpoolSubprocessTag, "thread pool service identifier", kparams.Address, []string{"threadpool.subprocess_tag = '10d'"}, nil, nil}, - ThreadpoolTimerDuetime: {ThreadpoolTimerDuetime, "thread pool timer due time", kparams.Uint64, []string{"threadpool.timer.duetime > 10"}, nil, nil}, - ThreadpoolTimerSubqueue: {ThreadpoolTimerSubqueue, "thread pool timer subqueue address", kparams.Address, []string{"threadpool.timer.subqueue = '1db401703e8'"}, nil, nil}, - ThreadpoolTimer: {ThreadpoolTimer, "thread pool timer address", kparams.Address, []string{"threadpool.timer.address = '3e8'"}, nil, nil}, - ThreadpoolTimerPeriod: {ThreadpoolTimerPeriod, "thread pool timer period", kparams.Uint32, []string{"threadpool.timer.period = 0'"}, nil, nil}, - ThreadpoolTimerWindow: {ThreadpoolTimerWindow, "thread pool timer tolerate period", kparams.Uint32, []string{"threadpool.timer.window = 0'"}, nil, nil}, - ThreadpoolTimerAbsolute: {ThreadpoolTimerAbsolute, "indicates if the thread pool timer is absolute or relative", kparams.Bool, []string{"threadpool.timer.is_absolute = true'"}, nil, nil}, + ThreadpoolPoolID: {ThreadpoolPoolID, "thread pool identifier", params.Address, []string{"threadpool.id = '20f5fc02440'"}, nil, nil}, + ThreadpoolTaskID: {ThreadpoolTaskID, "thread pool task identifier", params.Address, []string{"threadpool.task.id = '20f7ecd21f8'"}, nil, nil}, + ThreadpoolCallbackAddress: {ThreadpoolCallbackAddress, "thread pool callback address", params.Address, []string{"threadpool.callback.address = '7ff868739ed0'"}, nil, nil}, + ThreadpoolCallbackSymbol: {ThreadpoolCallbackSymbol, "thread pool callback symbol", params.UnicodeString, []string{"threadpool.callback.symbol = 'RtlDestroyQueryDebugBuffer'"}, nil, nil}, + ThreadpoolCallbackModule: {ThreadpoolCallbackModule, "thread pool module containing the callback symbol", params.UnicodeString, []string{"threadpool.callback.module contains 'ntdll.dll'"}, nil, nil}, + ThreadpoolCallbackContext: {ThreadpoolCallbackContext, "thread pool callback context address", params.Address, []string{"threadpool.callback.context = '1df41e07bd0'"}, nil, nil}, + ThreadpoolCallbackContextRip: {ThreadpoolCallbackContextRip, "thread pool callback thread context instruction pointer", params.Address, []string{"threadpool.callback.context.rip = '1df42ffc1f8'"}, nil, nil}, + ThreadpoolCallbackContextRipSymbol: {ThreadpoolCallbackContextRipSymbol, "thread pool callback thread context instruction pointer symbol", params.UnicodeString, []string{"threadpool.callback.context.rip.symbol = 'VirtualProtect'"}, nil, nil}, + ThreadpoolCallbackContextRipModule: {ThreadpoolCallbackContextRipModule, "thread pool callback thread context instruction pointer symbol module", params.UnicodeString, []string{"threadpool.callback.context.rip.module contains 'ntdll.dll'"}, nil, nil}, + ThreadpoolSubprocessTag: {ThreadpoolSubprocessTag, "thread pool service identifier", params.Address, []string{"threadpool.subprocess_tag = '10d'"}, nil, nil}, + ThreadpoolTimerDuetime: {ThreadpoolTimerDuetime, "thread pool timer due time", params.Uint64, []string{"threadpool.timer.duetime > 10"}, nil, nil}, + ThreadpoolTimerSubqueue: {ThreadpoolTimerSubqueue, "thread pool timer subqueue address", params.Address, []string{"threadpool.timer.subqueue = '1db401703e8'"}, nil, nil}, + ThreadpoolTimer: {ThreadpoolTimer, "thread pool timer address", params.Address, []string{"threadpool.timer.address = '3e8'"}, nil, nil}, + ThreadpoolTimerPeriod: {ThreadpoolTimerPeriod, "thread pool timer period", params.Uint32, []string{"threadpool.timer.period = 0'"}, nil, nil}, + ThreadpoolTimerWindow: {ThreadpoolTimerWindow, "thread pool timer tolerate period", params.Uint32, []string{"threadpool.timer.window = 0'"}, nil, nil}, + ThreadpoolTimerAbsolute: {ThreadpoolTimerAbsolute, "indicates if the thread pool timer is absolute or relative", params.Bool, []string{"threadpool.timer.is_absolute = true'"}, nil, nil}, } // ArgumentOf returns argument data for the specified field. diff --git a/pkg/filter/fields/fields_windows_test.go b/pkg/filter/fields/fields_windows_test.go index 4359593ff..af082f1f4 100644 --- a/pkg/filter/fields/fields_windows_test.go +++ b/pkg/filter/fields/fields_windows_test.go @@ -31,9 +31,9 @@ func TestIsField(t *testing.T) { {"ps.pid", true}, {"ps.none", false}, {"ps.envs[ALLUSERSPROFILE]", false}, - {"kevt.arg", true}, + {"evt.arg", true}, {"thread._callstack", true}, - {"kevt._callstack", false}, + {"evt._callstack", false}, } for _, tt := range tests { diff --git a/pkg/filter/filter.go b/pkg/filter/filter.go index bb38ada64..ed92de1c4 100644 --- a/pkg/filter/filter.go +++ b/pkg/filter/filter.go @@ -22,10 +22,10 @@ import ( "errors" "expvar" "fmt" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter/fields" "github.com/rabbitstack/fibratus/pkg/filter/ql" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/rabbitstack/fibratus/pkg/util/bytes" "github.com/rabbitstack/fibratus/pkg/util/hashers" "net" @@ -49,11 +49,11 @@ type Filter interface { Compile() error // Run runs a filter with a single expression. The return value decides // if the incoming event has successfully matched the filter expression. - Run(evt *kevent.Kevent) bool + Run(evt *event.Event) bool // RunSequence runs a filter with sequence expressions. Sequence rules depend // on the state machine transitions and partial matches to decide whether the // rule is fired. - RunSequence(evt *kevent.Kevent, seqID int, partials map[int][]*kevent.Kevent, rawMatch bool) bool + RunSequence(evt *event.Event, seqID int, partials map[int][]*event.Event, rawMatch bool) bool // GetStringFields returns field names mapped to their string values. GetStringFields() map[fields.Field][]string // GetFields returns all fields used in the filter expression. @@ -182,14 +182,14 @@ func (f *filter) Compile() error { return f.checkBoundRefs() } -func (f *filter) Run(e *kevent.Kevent) bool { +func (f *filter) Run(e *event.Event) bool { if f.expr == nil { return false } return ql.Eval(f.expr, f.mapValuer(e), f.hasFunctions) } -func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*kevent.Kevent, rawMatch bool) bool { +func (f *filter) RunSequence(e *event.Event, seqID int, partials map[int][]*event.Event, rawMatch bool) bool { if f.seq == nil { return false } @@ -211,7 +211,7 @@ func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*ke // if a sequence expression contains references to // bound fields we map all partials to their sequence // aliases - p := make(map[string][]*kevent.Kevent) + p := make(map[string][]*event.Event) nslots := len(partials[seqID]) for i := 0; i < seqID; i++ { alias := f.seq.Expressions[i].Alias @@ -234,7 +234,7 @@ func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*ke hash := make([]byte, 0) for nslots > 0 { nslots-- - var evt *kevent.Kevent + var evt *event.Event for _, field := range flds { // get all events pertaining to the bounded event evts := p[field.BoundVar] @@ -252,7 +252,7 @@ func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*ke continue } v, err := accessor.Get(field.Field, evt) - if err != nil && !kerrors.IsKparamNotFound(err) { + if err != nil && !errs.IsParamNotFound(err) { accessorErrors.Add(err.Error(), 1) continue } @@ -292,8 +292,8 @@ func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*ke match = ql.Eval(expr.Expr, valuer, f.hasFunctions) if match { // compute sequence key hash to tie the events - evt.AddMeta(kevent.RuleSequenceLink, hashers.FnvUint64(hash)) - e.AddMeta(kevent.RuleSequenceLink, hashers.FnvUint64(hash)) + evt.AddMeta(event.RuleSequenceLink, hashers.FnvUint64(hash)) + e.AddMeta(event.RuleSequenceLink, hashers.FnvUint64(hash)) break } } @@ -323,7 +323,7 @@ func (f *filter) RunSequence(e *kevent.Kevent, seqID int, partials map[int][]*ke if match && by != nil { if v := valuer[by.Value]; v != nil { - e.AddMeta(kevent.RuleSequenceLink, v) + e.AddMeta(event.RuleSequenceLink, v) } } } @@ -349,7 +349,7 @@ func (f *filter) GetSequence() *ql.Sequence { return f.seq } // with values extracted from the event. Field modifiers may contain a leading ordinal // which refers to the event in particular sequence stage. Otherwise, the modifier is // a well-known field name prepended with the `%` symbol. -func InterpolateFields(s string, evts []*kevent.Kevent) string { +func InterpolateFields(s string, evts []*event.Event) string { var fieldsReplRegexp = regexp.MustCompile(`%([1-9]?)\.?([a-z0-9A-Z\[\]._]+)`) matches := fieldsReplRegexp.FindAllStringSubmatch(s, -1) r := s @@ -384,14 +384,14 @@ func InterpolateFields(s string, evts []*kevent.Kevent) string { if i-1 > len(evts)-1 { continue } - kevt := evts[i-1] + evt := evts[i-1] // extract field value from the event and replace in string var val any for _, accessor := range GetAccessors() { name, arg := split(m[2]) f := Field{Value: m[2], Name: fields.Field(name), Arg: arg} var err error - val, err = accessor.Get(f, kevt) + val, err = accessor.Get(f, evt) if err != nil { continue } @@ -415,7 +415,7 @@ func InterpolateFields(s string, evts []*kevent.Kevent) string { // accessors and extract the field values that are // supplied to the valuer. The valuer feeds the // expression with correct values. -func (f *filter) mapValuer(evt *kevent.Kevent) map[string]interface{} { +func (f *filter) mapValuer(evt *event.Event) map[string]interface{} { valuer := make(map[string]interface{}, len(f.fields)) for _, field := range f.fields { for _, accessor := range f.accessors { @@ -423,7 +423,7 @@ func (f *filter) mapValuer(evt *kevent.Kevent) map[string]interface{} { continue } v, err := accessor.Get(field, evt) - if err != nil && !kerrors.IsKparamNotFound(err) { + if err != nil && !errs.IsParamNotFound(err) { accessorErrors.Add(err.Error(), 1) continue } diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index cc7c5c917..aefce2002 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -22,11 +22,10 @@ import ( "github.com/rabbitstack/fibratus/internal/etw/processors" "github.com/rabbitstack/fibratus/pkg/callstack" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter/fields" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" @@ -78,8 +77,8 @@ func TestFilterCompile(t *testing.T) { func TestSeqFilterCompile(t *testing.T) { f := New(`sequence -|kevt.name = 'CreateProcess'| by ps.exe -|kevt.name = 'CreateFile' and file.operation = 'create'| by file.name +|evt.name = 'CreateProcess'| by ps.exe +|evt.name = 'CreateFile' and file.operation = 'create'| by file.name `, cfg) require.NoError(t, f.Compile()) require.NotNil(t, f.GetSequence()) @@ -90,19 +89,19 @@ func TestSeqFilterCompile(t *testing.T) { func TestSeqFilterInvalidBoundRefs(t *testing.T) { f := New(`sequence -|kevt.name = 'CreateProcess'| as e1 -|kevt.name = 'CreateFile' and file.name = $e.ps.exe | +|evt.name = 'CreateProcess'| as e1 +|evt.name = 'CreateFile' and file.name = $e.ps.exe | `, cfg) require.Error(t, f.Compile()) f1 := New(`sequence -|kevt.name = 'CreateProcess'| as e1 -|kevt.name = 'CreateFile' and file.name = $e1.ps.exe | +|evt.name = 'CreateProcess'| as e1 +|evt.name = 'CreateFile' and file.name = $e1.ps.exe | `, cfg) require.NoError(t, f1.Compile()) } func TestStringFields(t *testing.T) { - f := New(`ps.name = 'cmd.exe' and kevt.name = 'CreateProcess' or kevt.name in ('TerminateProcess', 'CreateFile')`, cfg) + f := New(`ps.name = 'cmd.exe' and evt.name = 'CreateProcess' or evt.name in ('TerminateProcess', 'CreateFile')`, cfg) require.NoError(t, f.Compile()) assert.Len(t, f.GetStringFields(), 2) assert.Len(t, f.GetStringFields()[fields.KevtName], 3) @@ -110,19 +109,19 @@ func TestStringFields(t *testing.T) { } func TestProcFilter(t *testing.T) { - kpars := kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "svchost-fake.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1234)}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(345)}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.Username: {Name: kparams.Username, Type: kparams.UnicodeString, Value: "loki"}, - kparams.Domain: {Name: kparams.Domain, Type: kparams.UnicodeString, Value: "TITAN"}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x000000E)}, + pars := event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-fake.exe -k RPCSS"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "svchost-fake.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1234)}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(345)}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.Username: {Name: params.Username, Type: params.UnicodeString, Value: "loki"}, + params.Domain: {Name: params.Domain, Type: params.UnicodeString, Value: "TITAN"}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x000000E)}, } - kpars1 := kevent.Kparams{ - kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Flags, Value: uint32(0x1400), Flags: kevent.PsAccessRightFlags}, + pars1 := event.Params{ + params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Flags, Value: uint32(0x1400), Flags: event.PsAccessRightFlags}, } ps1 := &pstypes.PS{ @@ -144,10 +143,10 @@ func TestProcFilter(t *testing.T) { IsPackaged: false, } - kevt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Category: ktypes.Process, - Kparams: kpars, + evt := &event.Event{ + Type: event.CreateProcess, + Category: event.Process, + Params: pars, Name: "CreateProcess", PID: 1023, PS: &pstypes.PS{ @@ -177,12 +176,12 @@ func TestProcFilter(t *testing.T) { IsWOW64: false, }, } - kevt.Timestamp, _ = time.Parse(time.RFC3339, "2011-05-03T15:04:05.323Z") + evt.Timestamp, _ = time.Parse(time.RFC3339, "2011-05-03T15:04:05.323Z") - kevt1 := &kevent.Kevent{ - Type: ktypes.OpenProcess, - Category: ktypes.Process, - Kparams: kpars1, + evt1 := &event.Event{ + Type: event.OpenProcess, + Category: event.Process, + Params: pars1, Name: "OpenProcess", PID: 1023, PS: &pstypes.PS{ @@ -241,10 +240,10 @@ func TestProcFilter(t *testing.T) { {`ps.parent.is_wow64`, false}, {`ps.parent.is_packaged`, false}, {`ps.parent.is_protected`, true}, - {`kevt.name = 'CreateProcess' and ps.name contains 'svchost'`, true}, + {`evt.name = 'CreateProcess' and ps.name contains 'svchost'`, true}, {`ps.modules IN ('kernel32.dll')`, true}, - {`kevt.name = 'CreateProcess' and kevt.pid != ps.ppid`, true}, + {`evt.name = 'CreateProcess' and evt.pid != ps.ppid`, true}, {`ps.parent.name = 'wininit.exe'`, true}, {`ps.ancestor[0] = 'svchost.exe'`, false}, @@ -299,7 +298,7 @@ func TestProcFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q ps filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -320,7 +319,7 @@ func TestProcFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt1) + matches := f.Run(evt1) if matches != tt.matches { t.Errorf("%d. %q ps filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -328,27 +327,27 @@ func TestProcFilter(t *testing.T) { } func TestThreadFilter(t *testing.T) { - kpars := kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(3453)}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Uint8, Value: uint8(13)}, - kparams.StartAddress: {Name: kparams.StartAddress, Type: kparams.Address, Value: uint64(140729524944768)}, - kparams.TEB: {Name: kparams.TEB, Type: kparams.Address, Value: uint64(614994620416)}, - kparams.IOPrio: {Name: kparams.IOPrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackBase: {Name: kparams.KstackBase, Type: kparams.Address, Value: uint64(18446677035730165760)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(18446677035730137088)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(5)}, - kparams.UstackBase: {Name: kparams.UstackBase, Type: kparams.Address, Value: uint64(86376448)}, - kparams.UstackLimit: {Name: kparams.UstackLimit, Type: kparams.Address, Value: uint64(86372352)}, - kparams.StartAddressSymbol: {Name: kparams.StartAddressSymbol, Type: kparams.UnicodeString, Value: "LoadImage"}, - kparams.StartAddressModule: {Name: kparams.StartAddressModule, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\kernel32.dll"}, - } - kevt := &kevent.Kevent{ - Type: ktypes.CreateThread, - Kparams: kpars, + pars := event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(3453)}, + params.BasePrio: {Name: params.BasePrio, Type: params.Uint8, Value: uint8(13)}, + params.StartAddress: {Name: params.StartAddress, Type: params.Address, Value: uint64(140729524944768)}, + params.TEB: {Name: params.TEB, Type: params.Address, Value: uint64(614994620416)}, + params.IOPrio: {Name: params.IOPrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackBase: {Name: params.KstackBase, Type: params.Address, Value: uint64(18446677035730165760)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(18446677035730137088)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(5)}, + params.UstackBase: {Name: params.UstackBase, Type: params.Address, Value: uint64(86376448)}, + params.UstackLimit: {Name: params.UstackLimit, Type: params.Address, Value: uint64(86372352)}, + params.StartAddressSymbol: {Name: params.StartAddressSymbol, Type: params.UnicodeString, Value: "LoadImage"}, + params.StartAddressModule: {Name: params.StartAddressModule, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\kernel32.dll"}, + } + evt := &event.Event{ + Type: event.CreateThread, + Params: pars, Name: "CreateThread", PID: windows.GetCurrentProcessId(), - Category: ktypes.Thread, + Category: event.Thread, PS: &pstypes.PS{ Name: "svchost.exe", Envs: map[string]string{"ALLUSERSPROFILE": "C:\\ProgramData", "OS": "Windows_NT", "ProgramFiles(x86)": "C:\\Program Files (x86)"}, @@ -379,15 +378,15 @@ func TestThreadFilter(t *testing.T) { } require.NoError(t, windows.WriteProcessMemory(windows.CurrentProcess(), base, &insns[0], uintptr(len(insns)), nil)) - kevt.Callstack.Init(8) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0x2638e59e0a5, Offset: 0, Symbol: "?", Module: "unbacked"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: va.Address(base), Offset: 0, Symbol: "?", Module: "unbacked"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0x7ffb313853b2, Offset: 0x10a, Symbol: "Java_java_lang_ProcessImpl_create", Module: "C:\\Program Files\\JetBrains\\GoLand 2021.2.3\\jbr\\bin\\java.dll"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0x7ffb3138592e, ModuleAddress: 0x7ffb3138592e, Offset: 0x3a2, Symbol: "Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly", Module: "C:\\Program Files\\JetBrains\\GoLand 2021.2.3\\jbr\\bin\\java.dll"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0x7ffb5d8e61f4, Offset: 0x54, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNEL32.DLL"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0x7ffb5c1d0396, Offset: 0x66, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0xfffff8072ebc1f6f, Offset: 0x4ef, Symbol: "FltRequestFileInfoOnCreateCompletion", Module: "C:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS"}) - kevt.Callstack.PushFrame(callstack.Frame{PID: kevt.PID, Addr: 0xfffff8072eb8961b, Offset: 0x20cb, Symbol: "FltGetStreamContext", Module: "C:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS"}) + evt.Callstack.Init(8) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0x2638e59e0a5, Offset: 0, Symbol: "?", Module: "unbacked"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: va.Address(base), Offset: 0, Symbol: "?", Module: "unbacked"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0x7ffb313853b2, Offset: 0x10a, Symbol: "Java_java_lang_ProcessImpl_create", Module: "C:\\Program Files\\JetBrains\\GoLand 2021.2.3\\jbr\\bin\\java.dll"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0x7ffb3138592e, ModuleAddress: 0x7ffb3138592e, Offset: 0x3a2, Symbol: "Java_java_lang_ProcessImpl_waitForTimeoutInterruptibly", Module: "C:\\Program Files\\JetBrains\\GoLand 2021.2.3\\jbr\\bin\\java.dll"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0x7ffb5d8e61f4, Offset: 0x54, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNEL32.DLL"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0x7ffb5c1d0396, Offset: 0x66, Symbol: "CreateProcessW", Module: "C:\\WINDOWS\\System32\\KERNELBASE.dll"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0xfffff8072ebc1f6f, Offset: 0x4ef, Symbol: "FltRequestFileInfoOnCreateCompletion", Module: "C:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS"}) + evt.Callstack.PushFrame(callstack.Frame{PID: evt.PID, Addr: 0xfffff8072eb8961b, Offset: 0x20cb, Symbol: "FltGetStreamContext", Module: "C:\\WINDOWS\\System32\\drivers\\FLTMGR.SYS"}) var tests = []struct { filter string @@ -452,7 +451,7 @@ func TestThreadFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q thread filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -487,7 +486,7 @@ func TestThreadFilter(t *testing.T) { } defer windows.TerminateProcess(pi.Process, 0) - kevt.PID = pi.ProcessId + evt.PID = pi.ProcessId // try until a valid address is returned // or fail if max attempts are exhausted @@ -507,7 +506,7 @@ func TestThreadFilter(t *testing.T) { var n uintptr require.NoError(t, windows.WriteProcessMemory(pi.Process, ntdll, &insns[0], uintptr(len(insns)), &n)) - kevt.Callstack[0] = callstack.Frame{PID: kevt.PID, Addr: va.Address(ntdll), Offset: 0, Symbol: "?", Module: "C:\\Windows\\System32\\ntdll.dll"} + evt.Callstack[0] = callstack.Frame{PID: evt.PID, Addr: va.Address(ntdll), Offset: 0, Symbol: "?", Module: "C:\\Windows\\System32\\ntdll.dll"} var tests1 = []struct { filter string @@ -524,7 +523,7 @@ func TestThreadFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q thread filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -532,23 +531,23 @@ func TestThreadFilter(t *testing.T) { } func TestFileFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } var tests = []struct { @@ -600,7 +599,7 @@ func TestFileFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q file filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -610,69 +609,69 @@ func TestFileFilter(t *testing.T) { func TestFileInfoFilter(t *testing.T) { var tests = []struct { f string - e *kevent.Kevent + e *event.Event matches bool }{ { `file.info_class = 'Allocation'`, - &kevent.Kevent{ - Category: ktypes.File, - Type: ktypes.SetFileInformation, + &event.Event{ + Category: event.File, + Type: event.SetFileInformation, Name: "SetFileInformation", - Kparams: kevent.Kparams{ - kparams.FileInfoClass: {Name: kparams.FileInfoClass, Type: kparams.Enum, Value: fs.AllocationClass, Enum: fs.FileInfoClasses}, + Params: event.Params{ + params.FileInfoClass: {Name: params.FileInfoClass, Type: params.Enum, Value: fs.AllocationClass, Enum: fs.FileInfoClasses}, }, }, true, }, { `file.info.allocation_size = 64500`, - &kevent.Kevent{ - Category: ktypes.File, - Type: ktypes.SetFileInformation, + &event.Event{ + Category: event.File, + Type: event.SetFileInformation, Name: "SetFileInformation", - Kparams: kevent.Kparams{ - kparams.FileInfoClass: {Name: kparams.FileInfoClass, Type: kparams.Enum, Value: fs.AllocationClass, Enum: fs.FileInfoClasses}, - kparams.FileExtraInfo: {Name: kparams.FileExtraInfo, Type: kparams.Uint64, Value: uint64(64500)}, + Params: event.Params{ + params.FileInfoClass: {Name: params.FileInfoClass, Type: params.Enum, Value: fs.AllocationClass, Enum: fs.FileInfoClasses}, + params.FileExtraInfo: {Name: params.FileExtraInfo, Type: params.Uint64, Value: uint64(64500)}, }, }, true, }, { `file.info.eof_size = 64500`, - &kevent.Kevent{ - Category: ktypes.File, - Type: ktypes.SetFileInformation, + &event.Event{ + Category: event.File, + Type: event.SetFileInformation, Name: "SetFileInformation", - Kparams: kevent.Kparams{ - kparams.FileInfoClass: {Name: kparams.FileInfoClass, Type: kparams.Enum, Value: fs.EOFClass, Enum: fs.FileInfoClasses}, - kparams.FileExtraInfo: {Name: kparams.FileExtraInfo, Type: kparams.Uint64, Value: uint64(64500)}, + Params: event.Params{ + params.FileInfoClass: {Name: params.FileInfoClass, Type: params.Enum, Value: fs.EOFClass, Enum: fs.FileInfoClasses}, + params.FileExtraInfo: {Name: params.FileExtraInfo, Type: params.Uint64, Value: uint64(64500)}, }, }, true, }, { `file.info.eof_size = 64500`, - &kevent.Kevent{ - Category: ktypes.File, - Type: ktypes.SetFileInformation, + &event.Event{ + Category: event.File, + Type: event.SetFileInformation, Name: "SetFileInformation", - Kparams: kevent.Kparams{ - kparams.FileInfoClass: {Name: kparams.FileInfoClass, Type: kparams.Enum, Value: fs.DispositionClass, Enum: fs.FileInfoClasses}, - kparams.FileExtraInfo: {Name: kparams.FileExtraInfo, Type: kparams.Uint64, Value: uint64(1)}, + Params: event.Params{ + params.FileInfoClass: {Name: params.FileInfoClass, Type: params.Enum, Value: fs.DispositionClass, Enum: fs.FileInfoClasses}, + params.FileExtraInfo: {Name: params.FileExtraInfo, Type: params.Uint64, Value: uint64(1)}, }, }, false, }, { `file.info.is_disposition_delete_file = true`, - &kevent.Kevent{ - Category: ktypes.File, - Type: ktypes.DeleteFile, + &event.Event{ + Category: event.File, + Type: event.DeleteFile, Name: "DeleteFile", - Kparams: kevent.Kparams{ - kparams.FileInfoClass: {Name: kparams.FileInfoClass, Type: kparams.Enum, Value: fs.DispositionClass, Enum: fs.FileInfoClasses}, - kparams.FileExtraInfo: {Name: kparams.FileExtraInfo, Type: kparams.Uint64, Value: uint64(1)}, + Params: event.Params{ + params.FileInfoClass: {Name: params.FileInfoClass, Type: params.Enum, Value: fs.DispositionClass, Enum: fs.FileInfoClasses}, + params.FileExtraInfo: {Name: params.FileExtraInfo, Type: params.Uint64, Value: uint64(1)}, }, }, true, @@ -692,63 +691,63 @@ func TestFileInfoFilter(t *testing.T) { } func TestKeventFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(3434)}, - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(3434)}, + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barz"}, } - kevt.Timestamp, _ = time.Parse(time.RFC3339, "2011-05-03T15:04:05.323Z") + evt.Timestamp, _ = time.Parse(time.RFC3339, "2011-05-03T15:04:05.323Z") var tests = []struct { filter string matches bool }{ - {`kevt.seq = 2`, true}, - {`kevt.pid = 859`, true}, - {`kevt.tid = 2484`, true}, - {`kevt.cpu = 1`, true}, - {`kevt.name = 'CreateFile'`, true}, - {`kevt.category = 'file'`, true}, - {`kevt.host = 'archrabbit'`, true}, - {`kevt.nparams = 5`, true}, - {`kevt.arg[file_path] = '\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll'`, true}, - {`kevt.arg[type] = 'file'`, true}, - {`kevt.arg[pid] = 3434`, true}, - - {`kevt.desc contains 'Creates or opens a new file'`, true}, - - {`kevt.date.d = 3 AND kevt.date.m = 5 AND kevt.time.s = 5 AND kevt.time.m = 4 and kevt.time.h = 15`, true}, - {`kevt.time = '15:04:05'`, true}, - {`concat(kevt.name, kevt.host, kevt.nparams) = 'CreateFilearchrabbit5'`, true}, - {`ltrim(kevt.host, 'arch') = 'rabbit'`, true}, - {`concat(ltrim(kevt.name, 'Create'), kevt.host) = 'Filearchrabbit'`, true}, - {`lower(rtrim(kevt.name, 'File')) = 'create'`, true}, - {`upper(rtrim(kevt.name, 'File')) = 'CREATE'`, true}, - {`replace(kevt.host, 'rabbit', '_bunny') = 'arch_bunny'`, true}, - {`replace(kevt.host, 'rabbit', '_bunny', '_bunny', 'bunny') = 'archbunny'`, true}, + {`evt.seq = 2`, true}, + {`evt.pid = 859`, true}, + {`evt.tid = 2484`, true}, + {`evt.cpu = 1`, true}, + {`evt.name = 'CreateFile'`, true}, + {`evt.category = 'file'`, true}, + {`evt.host = 'archrabbit'`, true}, + {`evt.nparams = 5`, true}, + {`evt.arg[file_path] = '\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll'`, true}, + {`evt.arg[type] = 'file'`, true}, + {`evt.arg[pid] = 3434`, true}, + + {`evt.desc contains 'Creates or opens a new file'`, true}, + + {`evt.date.d = 3 AND evt.date.m = 5 AND evt.time.s = 5 AND evt.time.m = 4 and evt.time.h = 15`, true}, + {`evt.time = '15:04:05'`, true}, + {`concat(evt.name, evt.host, evt.nparams) = 'CreateFilearchrabbit5'`, true}, + {`ltrim(evt.host, 'arch') = 'rabbit'`, true}, + {`concat(ltrim(evt.name, 'Create'), evt.host) = 'Filearchrabbit'`, true}, + {`lower(rtrim(evt.name, 'File')) = 'create'`, true}, + {`upper(rtrim(evt.name, 'File')) = 'CREATE'`, true}, + {`replace(evt.host, 'rabbit', '_bunny') = 'arch_bunny'`, true}, + {`replace(evt.host, 'rabbit', '_bunny', '_bunny', 'bunny') = 'archbunny'`, true}, {`split(file.path, '\\') IN ('windows', 'system32')`, true}, {`length(file.path) = 51`, true}, {`indexof(file.path, '\\') = 0`, true}, {`indexof(file.path, '\\', 'last') = 40`, true}, {`indexof(file.path, 'h2', 'any') = 22`, true}, {`substr(file.path, indexof(file.path, '\\'), indexof(file.path, '\\Hard')) = '\\Device'`, true}, - {`substr(kevt.desc, indexof(kevt.desc, '\\'), indexof(kevt.desc, 'NOT')) = 'Creates or opens a new file, directory, I/O device, pipe, console'`, true}, + {`substr(evt.desc, indexof(evt.desc, '\\'), indexof(evt.desc, 'NOT')) = 'Creates or opens a new file, directory, I/O device, pipe, console'`, true}, {`entropy(file.path) > 120`, true}, {`regex(file.path, '\\\\Device\\\\HarddiskVolume[2-9]+\\\\.*')`, true}, } @@ -759,27 +758,27 @@ func TestKeventFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { - t.Errorf("%d. %q kevt filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) + t.Errorf("%d. %q evt filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } } } func TestNetFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, PS: &pstypes.PS{ Name: "cmd.exe", }, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Category: event.Net, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } @@ -802,8 +801,8 @@ func TestNetFilter(t *testing.T) { {`ps.name = 'cmd.exe' and not ((net.sip in (222.1.1.1)) or (net.sip in (12.3.4.5)))`, true}, {`cidr_contains(net.dip, '216.58.201.1/24') = true`, true}, {`cidr_contains(net.dip, '226.58.201.1/24') = false`, true}, - {`cidr_contains(net.dip, '216.58.201.1/24', '216.58.201.10/24') = true and kevt.pid = 859`, true}, - {`kevt.name not in ('CreateProcess', 'Connect') and cidr_contains(net.dip, '216.58.201.1/24') = true`, true}, + {`cidr_contains(net.dip, '216.58.201.1/24', '216.58.201.10/24') = true and evt.pid = 859`, true}, + {`evt.name not in ('CreateProcess', 'Connect') and cidr_contains(net.dip, '216.58.201.1/24') = true`, true}, } for i, tt := range tests { @@ -812,25 +811,25 @@ func TestNetFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q net filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } } - kevt1 := &kevent.Kevent{ - Type: ktypes.SendTCPv4, + evt1 := &event.Event{ + Type: event.SendTCPv4, Tid: 2484, PID: 859, PS: &pstypes.PS{ Name: "cmd.exe", }, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(53)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("8.8.8.8")}, + Category: event.Net, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(53)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("8.8.8.8")}, }, } @@ -849,7 +848,7 @@ func TestNetFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt1) + matches := f.Run(evt1) if matches != tt.matches { t.Errorf("%d. %q net filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -857,17 +856,17 @@ func TestNetFilter(t *testing.T) { } func TestRegistryFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.RegSetValue, + evt := &event.Event{ + Type: event.RegSetValue, Tid: 2484, PID: 859, - Category: ktypes.Registry, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, - kparams.RegValue: {Name: kparams.RegValue, Type: kparams.Uint32, Value: uint32(10234)}, - kparams.RegValueType: {Name: kparams.RegValueType, Type: kparams.AnsiString, Value: "DWORD"}, - kparams.NTStatus: {Name: kparams.NTStatus, Type: kparams.AnsiString, Value: "success"}, - kparams.RegKeyHandle: {Name: kparams.RegKeyHandle, Type: kparams.Address, Value: uint64(18446666033449935464)}, + Category: event.Registry, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `HKEY_LOCAL_MACHINE\SYSTEM\Setup\Pid`}, + params.RegValue: {Name: params.RegValue, Type: params.Uint32, Value: uint32(10234)}, + params.RegValueType: {Name: params.RegValueType, Type: params.AnsiString, Value: "DWORD"}, + params.NTStatus: {Name: params.NTStatus, Type: params.AnsiString, Value: "success"}, + params.RegKeyHandle: {Name: params.RegKeyHandle, Type: params.Address, Value: uint64(18446666033449935464)}, }, } @@ -890,7 +889,7 @@ func TestRegistryFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q registry filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -898,17 +897,17 @@ func TestRegistryFilter(t *testing.T) { } func TestImageFilter(t *testing.T) { - e1 := &kevent.Kevent{ - Type: ktypes.LoadImage, - Category: ktypes.Image, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, - kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ffb313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(1), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(4), Enum: signature.Levels}, - kparams.FileIsDotnet: {Name: kparams.FileIsDotnet, Type: kparams.Bool, Value: false}, + e1 := &event.Event{ + Type: event.LoadImage, + Category: event.Image, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, + params.ImageCheckSum: {Name: params.ImageCheckSum, Type: params.Uint32, Value: uint32(2323432)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x7ffb313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(1), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(4), Enum: signature.Levels}, + params.FileIsDotnet: {Name: params.FileIsDotnet, Type: params.Bool, Value: false}, }, } @@ -949,17 +948,17 @@ func TestImageFilter(t *testing.T) { assert.Equal(t, signature.AuthenticodeLevel, sig.Level) // now exercise unsigned/unchecked signature - e2 := &kevent.Kevent{ - Type: ktypes.LoadImage, - Category: ktypes.Image, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, - kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x7ccb313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(0), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(0), Enum: signature.Levels}, - kparams.FileIsDotnet: {Name: kparams.FileIsDotnet, Type: kparams.Bool, Value: false}, + e2 := &event.Event{ + Type: event.LoadImage, + Category: event.Image, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "kernel32.dll")}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, + params.ImageCheckSum: {Name: params.ImageCheckSum, Type: params.Uint32, Value: uint32(2323432)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x7ccb313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(0), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(0), Enum: signature.Levels}, + params.FileIsDotnet: {Name: params.FileIsDotnet, Type: params.Bool, Value: false}, }, } @@ -992,17 +991,17 @@ func TestImageFilter(t *testing.T) { assert.NotNil(t, signature.GetSignatures().GetSignature(0x7ccb313833a3)) - e3 := &kevent.Kevent{ - Type: ktypes.LoadImage, - Category: ktypes.Image, - Kparams: kevent.Kparams{ - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\mscorlib.dll"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1023)}, - kparams.ImageCheckSum: {Name: kparams.ImageCheckSum, Type: kparams.Uint32, Value: uint32(2323432)}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0xfff313833a3)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Enum, Value: uint32(0), Enum: signature.Types}, - kparams.ImageSignatureLevel: {Name: kparams.ImageSignatureLevel, Type: kparams.Enum, Value: uint32(0), Enum: signature.Levels}, - kparams.FileIsDotnet: {Name: kparams.FileIsDotnet, Type: kparams.Bool, Value: true}, + e3 := &event.Event{ + Type: event.LoadImage, + Category: event.Image, + Params: event.Params{ + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\mscorlib.dll"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1023)}, + params.ImageCheckSum: {Name: params.ImageCheckSum, Type: params.Uint32, Value: uint32(2323432)}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0xfff313833a3)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Enum, Value: uint32(0), Enum: signature.Types}, + params.ImageSignatureLevel: {Name: params.ImageSignatureLevel, Type: params.Enum, Value: uint32(0), Enum: signature.Levels}, + params.FileIsDotnet: {Name: params.FileIsDotnet, Type: params.Bool, Value: true}, }, } @@ -1030,7 +1029,7 @@ func TestImageFilter(t *testing.T) { } func TestPEFilter(t *testing.T) { - kevt := &kevent.Kevent{ + evt := &event.Event{ PS: &pstypes.PS{ PE: &pe.PE{ NumberOfSections: 2, @@ -1074,7 +1073,7 @@ func TestPEFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q pe filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -1082,15 +1081,15 @@ func TestPEFilter(t *testing.T) { } func TestLazyPEFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.LoadImage, + evt := &event.Event{ + Type: event.LoadImage, PS: &pstypes.PS{ PID: 2312, Exe: filepath.Join(os.Getenv("windir"), "notepad.exe"), }, - Kparams: kevent.Kparams{ - kparams.FileIsDLL: {Name: kparams.FileIsDLL, Type: kparams.Bool, Value: true}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, + Params: event.Params{ + params.FileIsDLL: {Name: params.FileIsDLL, Type: params.Bool, Value: true}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, }, } @@ -1121,32 +1120,32 @@ func TestLazyPEFilter(t *testing.T) { if err != nil { t.Fatal(err) } - require.Nil(t, kevt.PS.PE) - matches := f.Run(kevt) + require.Nil(t, evt.PS.PE) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q pe lazy filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } - require.NotNil(t, kevt.PS.PE) - kevt.PS.PE = nil + require.NotNil(t, evt.PS.PE) + evt.PS.PE = nil } } func TestMemFilter(t *testing.T) { - kpars := kevent.Kparams{ - kparams.MemRegionSize: {Name: kparams.MemRegionSize, Type: kparams.Uint64, Value: uint64(8192)}, - kparams.MemBaseAddress: {Name: kparams.MemBaseAddress, Type: kparams.Address, Value: uint64(1311246336000)}, - kparams.MemAllocType: {Name: kparams.MemAllocType, Type: kparams.Flags, Value: uint32(0x00001000 | 0x00002000), Flags: kevent.MemAllocationFlags}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(345)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(0x40), Flags: kevent.MemProtectionFlags}, - kparams.MemProtectMask: {Name: kparams.MemProtectMask, Type: kparams.AnsiString, Value: "RWX"}, - kparams.MemPageType: {Name: kparams.MemPageType, Type: kparams.Enum, Value: uint32(0x1000000), Enum: processors.MemPageTypes}, - } - - kevt := &kevent.Kevent{ - Type: ktypes.VirtualAlloc, - Kparams: kpars, + pars := event.Params{ + params.MemRegionSize: {Name: params.MemRegionSize, Type: params.Uint64, Value: uint64(8192)}, + params.MemBaseAddress: {Name: params.MemBaseAddress, Type: params.Address, Value: uint64(1311246336000)}, + params.MemAllocType: {Name: params.MemAllocType, Type: params.Flags, Value: uint32(0x00001000 | 0x00002000), Flags: event.MemAllocationFlags}, + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(345)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(0x40), Flags: event.MemProtectionFlags}, + params.MemProtectMask: {Name: params.MemProtectMask, Type: params.AnsiString, Value: "RWX"}, + params.MemPageType: {Name: params.MemPageType, Type: params.Enum, Value: uint32(0x1000000), Enum: processors.MemPageTypes}, + } + + evt := &event.Event{ + Type: event.VirtualAlloc, + Params: pars, Name: "VirtualAlloc", - Category: ktypes.Mem, + Category: event.Mem, PS: &pstypes.PS{ Name: "svchost.exe", Envs: map[string]string{"ALLUSERSPROFILE": "C:\\ProgramData", "OS": "Windows_NT", "ProgramFiles(x86)": "C:\\Program Files (x86)"}, @@ -1173,7 +1172,7 @@ func TestMemFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q mem filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -1181,20 +1180,20 @@ func TestMemFilter(t *testing.T) { } func TestDNSFilter(t *testing.T) { - kevt := &kevent.Kevent{ - Type: ktypes.ReplyDNS, + evt := &event.Event{ + Type: event.ReplyDNS, Tid: 2484, PID: 859, PS: &pstypes.PS{ Name: "cmd.exe", }, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.DNSName: {Name: kparams.DNSName, Type: kparams.UnicodeString, Value: "r3.o.lencr.org"}, - kparams.DNSRR: {Name: kparams.DNSRR, Type: kparams.Enum, Value: uint32(0x0001), Enum: kevent.DNSRecordTypes}, - kparams.DNSOpts: {Name: kparams.DNSOpts, Type: kparams.Flags64, Value: uint64(0x00006000), Flags: kevent.DNSOptsFlags}, - kparams.DNSRcode: {Name: kparams.DNSRcode, Type: kparams.Enum, Value: uint32(0), Enum: kevent.DNSResponseCodes}, - kparams.DNSAnswers: {Name: kparams.DNSAnswers, Type: kparams.Slice, Value: []string{"incoming.telemetry.mozilla.org", "a1887.dscq.akamai.net"}}, + Category: event.Net, + Params: event.Params{ + params.DNSName: {Name: params.DNSName, Type: params.UnicodeString, Value: "r3.o.lencr.org"}, + params.DNSRR: {Name: params.DNSRR, Type: params.Enum, Value: uint32(0x0001), Enum: event.DNSRecordTypes}, + params.DNSOpts: {Name: params.DNSOpts, Type: params.Flags64, Value: uint64(0x00006000), Flags: event.DNSOptsFlags}, + params.DNSRcode: {Name: params.DNSRcode, Type: params.Enum, Value: uint32(0), Enum: event.DNSResponseCodes}, + params.DNSAnswers: {Name: params.DNSAnswers, Type: params.Slice, Value: []string{"incoming.telemetry.mozilla.org", "a1887.dscq.akamai.net"}}, }, } @@ -1216,7 +1215,7 @@ func TestDNSFilter(t *testing.T) { if err != nil { t.Fatal(err) } - matches := f.Run(kevt) + matches := f.Run(evt) if matches != tt.matches { t.Errorf("%d. %q dns filter mismatch: exp=%t got=%t", i, tt.filter, tt.matches, matches) } @@ -1224,32 +1223,32 @@ func TestDNSFilter(t *testing.T) { } func TestThreadpoolFilter(t *testing.T) { - e := &kevent.Kevent{ - Type: ktypes.SubmitThreadpoolCallback, + e := &event.Event{ + Type: event.SubmitThreadpoolCallback, Tid: 2484, PID: 1023, CPU: 1, Seq: 2, Name: "SubmitThreadpoolCallback", Timestamp: time.Now(), - Category: ktypes.Threadpool, - Kparams: kevent.Kparams{ - kparams.ThreadpoolPoolID: {Name: kparams.ThreadpoolPoolID, Type: kparams.Address, Value: uint64(0x20f5fc02440)}, - kparams.ThreadpoolTaskID: {Name: kparams.ThreadpoolTaskID, Type: kparams.Address, Value: uint64(0x20f7ecd21f8)}, - kparams.ThreadpoolCallback: {Name: kparams.ThreadpoolCallback, Type: kparams.Address, Value: uint64(0x7ffb3138592e)}, - kparams.ThreadpoolContext: {Name: kparams.ThreadpoolContext, Type: kparams.Address, Value: uint64(0x14d0d16fed8)}, - kparams.ThreadpoolContextRip: {Name: kparams.ThreadpoolContextRip, Type: kparams.Address, Value: uint64(0x143c9b07bd0)}, - kparams.ThreadpoolSubprocessTag: {Name: kparams.ThreadpoolSubprocessTag, Type: kparams.Address, Value: uint64(0x10d)}, - kparams.ThreadpoolContextRipSymbol: {Name: kparams.ThreadpoolContextRipSymbol, Type: kparams.UnicodeString, Value: "VirtualProtect"}, - kparams.ThreadpoolContextRipModule: {Name: kparams.ThreadpoolContextRipModule, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\kernelbase.dll"}, - kparams.ThreadpoolCallbackSymbol: {Name: kparams.ThreadpoolCallbackSymbol, Type: kparams.UnicodeString, Value: "RtlDestroyQueryDebugBuffer"}, - kparams.ThreadpoolCallbackModule: {Name: kparams.ThreadpoolCallbackModule, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\ntdll.dll"}, - kparams.ThreadpoolTimerSubqueue: {Name: kparams.ThreadpoolTimerSubqueue, Type: kparams.Address, Value: uint64(0x1db401703e8)}, - kparams.ThreadpoolTimerDuetime: {Name: kparams.ThreadpoolTimerDuetime, Type: kparams.Uint64, Value: uint64(18446744073699551616)}, - kparams.ThreadpoolTimer: {Name: kparams.ThreadpoolTimer, Type: kparams.Address, Value: uint64(0x3e8)}, - kparams.ThreadpoolTimerPeriod: {Name: kparams.ThreadpoolTimerPeriod, Type: kparams.Uint32, Value: uint32(100)}, - kparams.ThreadpoolTimerWindow: {Name: kparams.ThreadpoolTimerWindow, Type: kparams.Uint32, Value: uint32(50)}, - kparams.ThreadpoolTimerAbsolute: {Name: kparams.ThreadpoolTimerAbsolute, Type: kparams.Bool, Value: true}, + Category: event.Threadpool, + Params: event.Params{ + params.ThreadpoolPoolID: {Name: params.ThreadpoolPoolID, Type: params.Address, Value: uint64(0x20f5fc02440)}, + params.ThreadpoolTaskID: {Name: params.ThreadpoolTaskID, Type: params.Address, Value: uint64(0x20f7ecd21f8)}, + params.ThreadpoolCallback: {Name: params.ThreadpoolCallback, Type: params.Address, Value: uint64(0x7ffb3138592e)}, + params.ThreadpoolContext: {Name: params.ThreadpoolContext, Type: params.Address, Value: uint64(0x14d0d16fed8)}, + params.ThreadpoolContextRip: {Name: params.ThreadpoolContextRip, Type: params.Address, Value: uint64(0x143c9b07bd0)}, + params.ThreadpoolSubprocessTag: {Name: params.ThreadpoolSubprocessTag, Type: params.Address, Value: uint64(0x10d)}, + params.ThreadpoolContextRipSymbol: {Name: params.ThreadpoolContextRipSymbol, Type: params.UnicodeString, Value: "VirtualProtect"}, + params.ThreadpoolContextRipModule: {Name: params.ThreadpoolContextRipModule, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\kernelbase.dll"}, + params.ThreadpoolCallbackSymbol: {Name: params.ThreadpoolCallbackSymbol, Type: params.UnicodeString, Value: "RtlDestroyQueryDebugBuffer"}, + params.ThreadpoolCallbackModule: {Name: params.ThreadpoolCallbackModule, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\ntdll.dll"}, + params.ThreadpoolTimerSubqueue: {Name: params.ThreadpoolTimerSubqueue, Type: params.Address, Value: uint64(0x1db401703e8)}, + params.ThreadpoolTimerDuetime: {Name: params.ThreadpoolTimerDuetime, Type: params.Uint64, Value: uint64(18446744073699551616)}, + params.ThreadpoolTimer: {Name: params.ThreadpoolTimer, Type: params.Address, Value: uint64(0x3e8)}, + params.ThreadpoolTimerPeriod: {Name: params.ThreadpoolTimerPeriod, Type: params.Uint32, Value: uint32(100)}, + params.ThreadpoolTimerWindow: {Name: params.ThreadpoolTimerWindow, Type: params.Uint32, Value: uint32(50)}, + params.ThreadpoolTimerAbsolute: {Name: params.ThreadpoolTimerAbsolute, Type: params.Bool, Value: true}, }, } @@ -1292,15 +1291,15 @@ func TestInterpolateFields(t *testing.T) { var tests = []struct { original string interpolated string - evts []*kevent.Kevent + evts []*event.Event }{ { - original: "Credential discovery via %ps.name (%kevt.arg[cmdline]) and user %ps.sid", + original: "Credential discovery via %ps.name (%evt.arg[cmdline]) and user %ps.sid", interpolated: "Credential discovery via VaultCmd.exe (VaultCmd.exe /listcreds:Windows Credentials /all) and user LOCAL\\tor", - evts: []*kevent.Kevent{ + evts: []*event.Event{ { - Type: ktypes.CreateProcess, - Category: ktypes.Process, + Type: event.CreateProcess, + Category: event.Process, Name: "CreateProcess", PID: 1023, PS: &pstypes.PS{ @@ -1308,19 +1307,19 @@ func TestInterpolateFields(t *testing.T) { Ppid: 345, SID: "LOCAL\\tor", }, - Kparams: kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `VaultCmd.exe /listcreds:Windows Credentials /all`}, + Params: event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `VaultCmd.exe /listcreds:Windows Credentials /all`}, }, }, }, }, { - original: "Credential discovery via %ps.name and pid %kevt.pid", + original: "Credential discovery via %ps.name and pid %evt.pid", interpolated: "Credential discovery via N/A and pid 1023", - evts: []*kevent.Kevent{ + evts: []*event.Event{ { - Type: ktypes.CreateProcess, - Category: ktypes.Process, + Type: event.CreateProcess, + Category: event.Process, Name: "CreateProcess", PID: 1023, }, @@ -1329,14 +1328,14 @@ func TestInterpolateFields(t *testing.T) { { original: "Suspicious thread start module %thread.start_address.module", interpolated: "Suspicious thread start module C:\\Windows\\System32\\vault.dll", - evts: []*kevent.Kevent{ + evts: []*event.Event{ { - Type: ktypes.CreateThread, - Category: ktypes.Thread, + Type: event.CreateThread, + Category: event.Thread, Name: "CreateThread", PID: 1023, - Kparams: kevent.Kparams{ - kparams.StartAddressModule: {Name: kparams.StartAddressModule, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\vault.dll"}, + Params: event.Params{ + params.StartAddressModule: {Name: params.StartAddressModule, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\vault.dll"}, }, }, }, @@ -1349,10 +1348,10 @@ and subsequently write the %2.file.path dump file to the disk devic and read the memory of the Local Security And Authority Subsystem Service and subsequently write the C:\Users eo\Temp\lsass.dump dump file to the disk device`, - evts: []*kevent.Kevent{ + evts: []*event.Event{ { - Type: ktypes.OpenProcess, - Category: ktypes.Process, + Type: event.OpenProcess, + Category: event.Process, Name: "OpenProcess", PID: 1023, PS: &pstypes.PS{ @@ -1362,12 +1361,12 @@ eo\Temp\lsass.dump dump file to the disk device`, }, }, { - Type: ktypes.WriteFile, - Category: ktypes.File, + Type: event.WriteFile, + Category: event.File, Name: "WriteFile", PID: 1023, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, }, PS: &pstypes.PS{ Name: "taskmgr.exe", @@ -1385,10 +1384,10 @@ and subsequently write the %2.file.path dump file to the disk devic and read the memory of the Local Security And Authority Subsystem Service and subsequently write the C:\Users eo\Temp\lsass.dump dump file to the disk device`, - evts: []*kevent.Kevent{ + evts: []*event.Event{ { - Type: ktypes.OpenProcess, - Category: ktypes.Process, + Type: event.OpenProcess, + Category: event.Process, Name: "OpenProcess", PID: 1023, PS: &pstypes.PS{ @@ -1398,12 +1397,12 @@ eo\Temp\lsass.dump dump file to the disk device`, }, }, { - Type: ktypes.WriteFile, - Category: ktypes.File, + Type: event.WriteFile, + Category: event.File, Name: "WriteFile", PID: 1023, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Users\neo\\Temp\\lsass.dump"}, }, PS: &pstypes.PS{ Name: "taskmgr.exe", @@ -1428,21 +1427,21 @@ func BenchmarkFilterRun(b *testing.B) { f := New(`ps.name = 'mimikatz.exe' or ps.name contains 'svc'`, cfg) require.NoError(b, f.Compile()) - kpars := kevent.Kparams{ - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "svchost.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(1234)}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.Uint32, Value: uint32(345)}, + pars := event.Params{ + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost.exe -k RPCSS"}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "svchost.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(1234)}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.Uint32, Value: uint32(345)}, } - kevt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kpars, - Name: "CreateProcess", + evt := &event.Event{ + Type: event.CreateProcess, + Params: pars, + Name: "CreateProcess", } for i := 0; i < b.N; i++ { - f.Run(kevt) + f.Run(evt) } } diff --git a/pkg/filter/filter_windows.go b/pkg/filter/filter_windows.go index 12cc19b17..a38b8b06d 100644 --- a/pkg/filter/filter_windows.go +++ b/pkg/filter/filter_windows.go @@ -51,7 +51,7 @@ func New(expr string, config *config.Config, options ...Option) Filter { } accessors := []Accessor{ // general event parameters - newKevtAccessor(), + newEventAccessor(), // process state and parameters newPSAccessor(opts.psnap), // PE metadata diff --git a/pkg/filter/ql/error_test.go b/pkg/filter/ql/error_test.go index 288eee27b..ca131c384 100644 --- a/pkg/filter/ql/error_test.go +++ b/pkg/filter/ql/error_test.go @@ -25,7 +25,7 @@ import ( ) func TestParseError(t *testing.T) { - expr := `kevt.name in ('RegCreateKey', 'RegDeleteKey', 'RegSetValue', 'RegDeleteValue') + expr := `evt.name in ('RegCreateKey', 'RegDeleteKey', 'RegSetValue', 'RegDeleteValue') and registry.key.name icontains ( @@ -54,7 +54,7 @@ func TestParseError(t *testing.T) { ( 'user shell folders\\startup' )` - expected := `kevt.name in ('RegCreateKey', 'RegDeleteKey', 'RegSetValue', 'RegDeleteValue') + expected := `evt.name in ('RegCreateKey', 'RegDeleteKey', 'RegSetValue', 'RegDeleteValue') and registry.key.name icontains ( diff --git a/pkg/filter/ql/function.go b/pkg/filter/ql/function.go index 799aac899..e4c0c5982 100644 --- a/pkg/filter/ql/function.go +++ b/pkg/filter/ql/function.go @@ -308,7 +308,7 @@ func (f *Foreach) Desc() functions.FunctionDesc { "$mem": true, "$handle": true, "$dns": true, - "$kevt": true, + "$evt": true, } if reserved[v] { @@ -349,7 +349,7 @@ func (f *Foreach) Desc() functions.FunctionDesc { return fmt.Errorf("unused bound variable %s in predicate %q", v, e) } - var fieldRegexp = regexp.MustCompile(`(ps|pe|file|image|thread|registry|net|mem|handle|dns|kevt)\.[a-zA-Z0-9_.$]+`) + var fieldRegexp = regexp.MustCompile(`(ps|pe|file|image|thread|registry|net|mem|handle|dns|evt)\.[a-zA-Z0-9_.$]+`) matches = fieldRegexp.FindAllStringSubmatch(e, -1) if len(args) > 3 { diff --git a/pkg/filter/ql/literal.go b/pkg/filter/ql/literal.go index 29c263b62..78ebf75ed 100644 --- a/pkg/filter/ql/literal.go +++ b/pkg/filter/ql/literal.go @@ -19,9 +19,8 @@ package ql import ( + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/util/hashers" "golang.org/x/sys/windows" "net" @@ -282,12 +281,12 @@ type SequenceExpr struct { Alias string buckets map[uint32]bool - ktypes []ktypes.Ktype + types []event.Type } func (e *SequenceExpr) init() { e.buckets = make(map[uint32]bool) - e.ktypes = make([]ktypes.Ktype, 0) + e.types = make([]event.Type, 0) e.BoundFields = make([]*BoundFieldLiteral, 0) } @@ -342,8 +341,8 @@ func (e *SequenceExpr) walk() { if name == fields.KevtName || name == fields.KevtCategory { for _, v := range values { e.buckets[hashers.FnvUint32([]byte(v))] = true - if ktyp := ktypes.KeventNameToKtype(v); ktyp.Exists() { - e.ktypes = append(e.ktypes, ktyp) + if etype := event.NameToType(v); etype.Exists() { + e.types = append(e.types, etype) } } } @@ -354,8 +353,8 @@ func (e *SequenceExpr) walk() { // the event type filter fields defined in the expression. We permit the expression // to be evaluated when the incoming event type or category pertains to the one // defined in the field literal. -func (e *SequenceExpr) IsEvaluable(kevt *kevent.Kevent) bool { - return e.buckets[kevt.Type.Hash()] || e.buckets[kevt.Category.Hash()] +func (e *SequenceExpr) IsEvaluable(evt *event.Event) bool { + return e.buckets[evt.Type.Hash()] || e.buckets[evt.Category.Hash()] } // HasBoundFields determines if this sequence expression references any bound field. @@ -384,11 +383,11 @@ func (s *Sequence) init() { // is guaranteed guids := make(map[windows.GUID]bool) for _, expr := range s.Expressions { - for _, k := range expr.ktypes { - if k.CanArriveOutOfOrder() { + for _, etype := range expr.types { + if etype.CanArriveOutOfOrder() { s.IsUnordered = true } - guids[k.GUID()] = true + guids[etype.GUID()] = true } } diff --git a/pkg/filter/ql/parser_test.go b/pkg/filter/ql/parser_test.go index ddf6afcc0..30105584d 100644 --- a/pkg/filter/ql/parser_test.go +++ b/pkg/filter/ql/parser_test.go @@ -64,9 +64,9 @@ func TestParser(t *testing.T) { {expr: `ps.envs imatches 'C:\\Program Files'`}, {expr: `ps.pid[1] = 'svchost.exe'`, err: errors.New("ps.pid[1] = 'svchost.exe'\n╭──────^\n|\n|\n╰─────────────────── expected field without argument")}, {expr: `ps.envs[ProgramFiles = 'svchost.exe'`, err: errors.New("ps.envs[ProgramFiles = 'svchost.exe'\n╭───────────────────^\n|\n|\n╰─────────────────── expected ]")}, - {expr: `kevt.arg = 'svchost.exe'`, err: errors.New("kevt.arg = 'svchost.exe'\n╭───────^\n|\n|\n╰─────────────────── expected field argument")}, - {expr: `kevt.arg[name] = 'svchost.exe'`}, - {expr: `kevt.arg[Name$] = 'svchost.exe'`, err: errors.New("kevt.arg[Name$] = 'svchost.exe'\n╭────────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [a-z0-9_]+")}, + {expr: `evt.arg = 'svchost.exe'`, err: errors.New("evt.arg = 'svchost.exe'\n╭───────^\n|\n|\n╰─────────────────── expected field argument")}, + {expr: `evt.arg[name] = 'svchost.exe'`}, + {expr: `evt.arg[Name$] = 'svchost.exe'`, err: errors.New("evt.arg[Name$] = 'svchost.exe'\n╭────────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [a-z0-9_]+")}, {expr: `ps.ancestor[0] = 'svchost.exe'`}, {expr: `ps.ancestor[l0l] = 'svchost.exe'`, err: errors.New("ps.ancestor[l0l] = 'svchost.exe'\n╭───────────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [0-9]+")}, } @@ -145,43 +145,43 @@ func TestExpandMacros(t *testing.T) { err error }{ { - config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "kevt.name = 'CreateProcess'"}}), + config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "evt.name = 'CreateProcess'"}}), "spawn_process and ps.name in ('cmd.exe', 'powershell.exe')", - "kevt.name = CreateProcess AND ps.name IN (cmd.exe, powershell.exe)", + "evt.name = CreateProcess AND ps.name IN (cmd.exe, powershell.exe)", nil, }, { - config.FiltersWithMacros(map[string]*config.Macro{"span_process": {Expr: "kevt.name = 'CreateProcess'"}}), + config.FiltersWithMacros(map[string]*config.Macro{"span_process": {Expr: "evt.name = 'CreateProcess'"}}), "spawn_process and ps.name in ('cmd.exe', 'powershell.exe')", "", errors.New("expected field, string, number, bool, ip, function, pattern binding"), }, { - config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "kevt.name = 'CreateProcess'"}, "command_clients": {List: []string{"cmd.exe", "pwsh.exe"}}}), + config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "evt.name = 'CreateProcess'"}, "command_clients": {List: []string{"cmd.exe", "pwsh.exe"}}}), "spawn_process and ps.name in command_clients", - "kevt.name = CreateProcess AND ps.name IN (cmd.exe, pwsh.exe)", + "evt.name = CreateProcess AND ps.name IN (cmd.exe, pwsh.exe)", nil, }, { - config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "kevt.nnname = 'CreateProcess'"}, "command_clients": {List: []string{"cmd.exe", "pwsh.exe"}}}), + config.FiltersWithMacros(map[string]*config.Macro{"spawn_process": {Expr: "evt.nnname = 'CreateProcess'"}, "command_clients": {List: []string{"cmd.exe", "pwsh.exe"}}}), "spawn_process and ps.name in command_clients", "", errors.New("syntax error in \"spawn_process\" macro. expected field, string, number, bool, ip, function, pattern binding"), }, { config.FiltersWithMacros(map[string]*config.Macro{ - "rename": {Expr: "kevt.name = 'RenameFile'"}, - "remove": {Expr: "kevt.name = 'DeleteFile'"}, + "rename": {Expr: "evt.name = 'RenameFile'"}, + "remove": {Expr: "evt.name = 'DeleteFile'"}, "modify": {Expr: "rename or remove"}, "wcm_files": {List: []string{"?:\\Users\\*\\AppData\\*\\Microsoft\\Credentials\\*"}}}), "(modify) and file.name imatches wcm_files", - "(kevt.name = RenameFile OR kevt.name = DeleteFile) AND file.name IMATCHES (?:\\Users\\*\\AppData\\*\\Microsoft\\Credentials\\*)", + "(evt.name = RenameFile OR evt.name = DeleteFile) AND file.name IMATCHES (?:\\Users\\*\\AppData\\*\\Microsoft\\Credentials\\*)", nil, }, { config.FiltersWithMacros(map[string]*config.Macro{ - "rename": {Expr: "kevt.name = 'RenameFile'"}, - "remove": {Expr: "kevt.name = 'DeleteFile'"}, + "rename": {Expr: "evt.name = 'RenameFile'"}, + "remove": {Expr: "evt.name = 'DeleteFile'"}, "modify": {Expr: "rename or remove"}}), "entropy(file.name) > 0.22 and ren", "", @@ -189,22 +189,22 @@ func TestExpandMacros(t *testing.T) { }, { config.FiltersWithMacros(map[string]*config.Macro{ - "rename": {Expr: "kevt.name = 'RenameFile'"}, - "remove": {Expr: "kevt.name = 'DeleteFile'"}, + "rename": {Expr: "evt.name = 'RenameFile'"}, + "remove": {Expr: "evt.name = 'DeleteFile'"}, "modify": {Expr: "rename or remove"}}), "entropy(file.name) > 0.22 and rename", - "entropy(file.name) > 2.2e-01 AND kevt.name = RenameFile", + "entropy(file.name) > 2.2e-01 AND evt.name = RenameFile", nil, }, { config.FiltersWithMacros(map[string]*config.Macro{ - "rename": {Expr: "kevt.name = 'RenameFile'"}, - "remove": {Expr: "kevt.name = 'DeleteFile'"}, - "create": {Expr: "kevt.name = 'CreateFile' and file.operation = 'create'"}, + "rename": {Expr: "evt.name = 'RenameFile'"}, + "remove": {Expr: "evt.name = 'DeleteFile'"}, + "create": {Expr: "evt.name = 'CreateFile' and file.operation = 'create'"}, "modify": {Expr: "rename or remove"}, "change_fs": {Expr: "modify or (create)"}}), "change_fs", - "kevt.name = RenameFile OR kevt.name = DeleteFile OR (kevt.name = CreateFile AND file.operation = create)", + "evt.name = RenameFile OR evt.name = DeleteFile OR (evt.name = CreateFile AND file.operation = create)", nil, }, } @@ -231,40 +231,40 @@ func TestParseSequence(t *testing.T) { isConstrained bool }{ { - `kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile'| + `evt.name = 'CreateProcess'| + |evt.name = 'CreateFile'| `, errors.New("expected |"), time.Duration(0), false, }, { - `|kevt.name = 'CreateProcess' - kevt.name = 'CreateFile'| + `|evt.name = 'CreateProcess' + evt.name = 'CreateFile'| `, errors.New("expected operator, ')', ',', '|'"), time.Duration(0), false, }, { - `|kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile' + `|evt.name = 'CreateProcess'| + |evt.name = 'CreateFile' `, errors.New("expected |"), time.Duration(0), false, }, { - `|kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile'| + `|evt.name = 'CreateProcess'| + |evt.name = 'CreateFile'| `, nil, time.Duration(0), false, }, { - `|kevt.name = 'CreateProcess'| by ps.exe - |kevt.name = 'CreateFile'| by file.name + `|evt.name = 'CreateProcess'| by ps.exe + |evt.name = 'CreateFile'| by file.name `, nil, time.Duration(0), @@ -273,8 +273,8 @@ func TestParseSequence(t *testing.T) { { `by ps.pid - |kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile'| + |evt.name = 'CreateProcess'| + |evt.name = 'CreateFile'| `, nil, time.Duration(0), @@ -283,8 +283,8 @@ func TestParseSequence(t *testing.T) { { `by ps.pid - |kevt.name = 'CreateProcess'| by ps.pid - |kevt.name = 'CreateFile'| + |evt.name = 'CreateProcess'| by ps.pid + |evt.name = 'CreateFile'| `, errors.New("all expressions require the 'by' statement"), time.Duration(0), @@ -292,8 +292,8 @@ func TestParseSequence(t *testing.T) { }, { - `|kevt.name = 'CreateProcess'| by ps.pid - |kevt.name = 'CreateFile'| + `|evt.name = 'CreateProcess'| by ps.pid + |evt.name = 'CreateFile'| `, errors.New("all expressions require the 'by' statement"), time.Duration(0), @@ -302,8 +302,8 @@ func TestParseSequence(t *testing.T) { { `maxspan 20s - |kevt.name = 'CreateProcess'| by ps.pid - |kevt.name = 'CreateFile'| by ps.pid + |evt.name = 'CreateProcess'| by ps.pid + |evt.name = 'CreateFile'| by ps.pid `, nil, time.Second * 20, @@ -312,8 +312,8 @@ func TestParseSequence(t *testing.T) { { `maxspan 30s - |kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile'| + |evt.name = 'CreateProcess'| + |evt.name = 'CreateFile'| `, nil, time.Second * 30, @@ -322,8 +322,8 @@ func TestParseSequence(t *testing.T) { { `maxspan 30s - |kevt.name = 'CreateProcess'| as e1 - |kevt.name = 'CreateFile' and $e1.ps.name = file.name | + |evt.name = 'CreateProcess'| as e1 + |evt.name = 'CreateFile' and $e1.ps.name = file.name | `, nil, time.Second * 30, @@ -332,8 +332,8 @@ func TestParseSequence(t *testing.T) { { `maxspan 30s - |kevt.name = 'CreateProcess'| as e1 - |kevt.name = 'CreateFile' and $e1.ps.ame = file.name | + |evt.name = 'CreateProcess'| as e1 + |evt.name = 'CreateFile' and $e1.ps.ame = file.name | `, errors.New("expected field after bound ref"), time.Second * 30, @@ -342,8 +342,8 @@ func TestParseSequence(t *testing.T) { { `maxspan 40h - |kevt.name = 'CreateProcess'| as e1 - |kevt.name = 'CreateFile' and $e1.ps.ame = file.name | + |evt.name = 'CreateProcess'| as e1 + |evt.name = 'CreateFile' and $e1.ps.ame = file.name | `, errors.New("maximum span 40h0m0s cannot be greater than 4h"), time.Hour * 40, @@ -353,8 +353,8 @@ func TestParseSequence(t *testing.T) { `by ps.uuid maxspan 2m - |kevt.name = 'CreateProcess'| by ps.child.uuid - |kevt.name = 'CreateFile'| by ps.uuid + |evt.name = 'CreateProcess'| by ps.child.uuid + |evt.name = 'CreateFile'| by ps.uuid `, errors.New("sequence mixes global and per-expression 'by' statements"), time.Minute * 2, @@ -388,51 +388,51 @@ func TestIsSequenceUnordered(t *testing.T) { isUnordered bool }{ { - `|kevt.name = 'CreateProcess'| by ps.uuid - |kevt.name = 'OpenProcess'| by ps.uuid + `|evt.name = 'CreateProcess'| by ps.uuid + |evt.name = 'OpenProcess'| by ps.uuid `, true, }, { - `|kevt.name = 'CreateProcess'| - |kevt.name = 'CreateFile'| + `|evt.name = 'CreateProcess'| + |evt.name = 'CreateFile'| `, false, }, { - `|kevt.name = 'CreateProcess'| - |kevt.name = 'UnmapViewFile'| - |kevt.name = 'LoadImage'| + `|evt.name = 'CreateProcess'| + |evt.name = 'UnmapViewFile'| + |evt.name = 'LoadImage'| `, false, }, { - `|kevt.name = 'CreateProcess'| - |kevt.name = 'SetThreadContext'| + `|evt.name = 'CreateProcess'| + |evt.name = 'SetThreadContext'| `, true, }, { - `|kevt.name = 'OpenThread'| by ps.uuid - |kevt.name = 'OpenProcess'| by ps.uuid + `|evt.name = 'OpenThread'| by ps.uuid + |evt.name = 'OpenProcess'| by ps.uuid `, false, }, { - `|kevt.name = 'OpenThread' or kevt.name = 'OpenProcess'| by ps.uuid - |kevt.name = 'SetThreadContext'| by ps.uuid + `|evt.name = 'OpenThread' or evt.name = 'OpenProcess'| by ps.uuid + |evt.name = 'SetThreadContext'| by ps.uuid `, false, }, { - `|kevt.name = 'RegSetValue'| by ps.uuid - |kevt.name = 'SetThreadContext'| by ps.uuid + `|evt.name = 'RegSetValue'| by ps.uuid + |evt.name = 'SetThreadContext'| by ps.uuid `, true, }, { - `|kevt.name = 'RegSetValue'| by ps.uuid - |kevt.name = 'RegDeleteValue'| by ps.uuid + `|evt.name = 'RegSetValue'| by ps.uuid + |evt.name = 'RegDeleteValue'| by ps.uuid `, false, }, diff --git a/pkg/filter/util.go b/pkg/filter/util.go index 8c44fe02e..04dc37dd3 100644 --- a/pkg/filter/util.go +++ b/pkg/filter/util.go @@ -19,10 +19,9 @@ package filter import ( + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/util/loldrivers" "github.com/rabbitstack/fibratus/pkg/util/signature" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -31,16 +30,16 @@ import ( // isLOLDriver interacts with the loldrivers client to determine // whether the loaded/dropped driver is malicious or vulnerable. -func isLOLDriver(f fields.Field, e *kevent.Kevent) (kparams.Value, error) { +func isLOLDriver(f fields.Field, e *event.Event) (params.Value, error) { var filename string - if e.Category == ktypes.File { - filename = e.GetParamAsString(kparams.FilePath) + if e.Category == event.File { + filename = e.GetParamAsString(params.FilePath) } else { - filename = e.GetParamAsString(kparams.ImagePath) + filename = e.GetParamAsString(params.ImagePath) } - isDriver := filepath.Ext(filename) == ".sys" || e.Kparams.TryGetBool(kparams.FileIsDriver) + isDriver := filepath.Ext(filename) == ".sys" || e.Params.TryGetBool(params.FileIsDriver) if !isDriver { return nil, nil } diff --git a/pkg/handle/snapshotter.go b/pkg/handle/snapshotter.go index 047a17210..172905d3c 100644 --- a/pkg/handle/snapshotter.go +++ b/pkg/handle/snapshotter.go @@ -33,9 +33,9 @@ import ( "unsafe" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" log "github.com/sirupsen/logrus" ) @@ -69,10 +69,10 @@ type SnapshotBuildCompleted func(total uint64, named uint64) type Snapshotter interface { // Write updates the snapshotter state by storing a new entry for the inbound create handle event. It also notifies // the registered callback that a new handle has been created. - Write(kevt *kevent.Kevent) error + Write(evt *event.Event) error // Remove destroys the handle state for the specified handle object. The removal callback is triggered when an item // is deleted from the store. - Remove(kevt *kevent.Kevent) error + Remove(evt *event.Event) error // FindHandles returns a list of all known handles for the specified process identifier. FindHandles(pid uint32) ([]htypes.Handle, error) // FindByObject returns the handle for the given handle object reference. @@ -127,7 +127,7 @@ func NewSnapshotter(config *config.Config, fn SnapshotBuildCompleted) Snapshotte return s } -// NewFromKcap builds the handle snapshotter from kcap state. +// NewFromKcap builds the handle snapshotter from cap state. func NewFromKcap(handles []htypes.Handle) Snapshotter { s := &snapshotter{ handlesByObject: make(map[uint64]htypes.Handle), @@ -397,12 +397,12 @@ func (s *snapshotter) GetSnapshot() []htypes.Handle { return handles } -func (s *snapshotter) Write(e *kevent.Kevent) error { +func (s *snapshotter) Write(e *event.Event) error { if !e.IsCreateHandle() { return fmt.Errorf("expected CreateHandle event but got %s", e.Type) } h := unwrapHandle(e) - obj, err := e.Kparams.GetUint64(kparams.HandleObject) + obj, err := e.Params.GetUint64(params.HandleObject) if err != nil { return err } @@ -412,11 +412,11 @@ func (s *snapshotter) Write(e *kevent.Kevent) error { return nil } -func (s *snapshotter) Remove(e *kevent.Kevent) error { +func (s *snapshotter) Remove(e *event.Event) error { if !e.IsCloseHandle() { return fmt.Errorf("expected CloseHandle event but got %s", e.Type) } - obj, err := e.Kparams.GetUint64(kparams.HandleObject) + obj, err := e.Params.GetUint64(params.HandleObject) if err != nil { return err } @@ -433,10 +433,10 @@ func (s *snapshotter) Close() error { return nil } -func unwrapHandle(e *kevent.Kevent) htypes.Handle { +func unwrapHandle(e *event.Event) htypes.Handle { h := htypes.Handle{} - h.Type = e.GetParamAsString(kparams.HandleObjectTypeID) - h.Object, _ = e.Kparams.GetUint64(kparams.HandleObject) - h.Name, _ = e.Kparams.GetString(kparams.HandleObjectName) + h.Type = e.GetParamAsString(params.HandleObjectTypeID) + h.Object, _ = e.Params.GetUint64(params.HandleObject) + h.Name, _ = e.Params.GetString(params.HandleObjectName) return h } diff --git a/pkg/handle/snapshotter_mock.go b/pkg/handle/snapshotter_mock.go index 906712671..8b7241b01 100644 --- a/pkg/handle/snapshotter_mock.go +++ b/pkg/handle/snapshotter_mock.go @@ -22,8 +22,8 @@ package handle import ( + "github.com/rabbitstack/fibratus/pkg/event" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" "github.com/stretchr/testify/mock" ) @@ -33,14 +33,14 @@ type SnapshotterMock struct { } // Write method -func (s *SnapshotterMock) Write(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) Write(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } // Remove method -func (s *SnapshotterMock) Remove(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) Remove(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } diff --git a/pkg/handle/types/marshaller.go b/pkg/handle/types/marshaller.go index 3c84dbfc4..5e450b260 100644 --- a/pkg/handle/types/marshaller.go +++ b/pkg/handle/types/marshaller.go @@ -55,7 +55,7 @@ func (h Handle) Offset() uint16 { return offset } -// Marshal dumps the state of the handle to byte slice that is suitable for serializing to kcap file. +// Marshal dumps the state of the handle to byte slice that is suitable for serializing to cap file. func (h *Handle) Marshal() []byte { b := make([]byte, 0) diff --git a/pkg/handle/types/types.go b/pkg/handle/types/types.go index 3af407e4f..2d98349f2 100644 --- a/pkg/handle/types/types.go +++ b/pkg/handle/types/types.go @@ -87,7 +87,7 @@ func (h Handle) Len() int { return l } -// NewFromKcap restores handle state from the kcap buffer. +// NewFromKcap restores handle state from the cap buffer. func NewFromKcap(buf []byte) (Handle, error) { h := Handle{} err := h.Unmarshal(buf) diff --git a/pkg/kevent/README.md b/pkg/kevent/README.md deleted file mode 100644 index e053887dd..000000000 --- a/pkg/kevent/README.md +++ /dev/null @@ -1,27 +0,0 @@ -`Kevent` is the fundamental data structure for transporting kernel events. - -Each kernel event structure contains a series of canonical fields that describe the nature of the event such as its name, the process identifier that generated the event and such. The following is the list of all canonical fields. - -- **Sequence** is a monotonically increasing integer value that uniquely identifies an event. The sequence value is guaranteed to increment monotonically as long as the machine is not rebooted. After the restart, the sequence is restored to the zero value. -- **PID** represents the process identifier that triggered the kernel event. -- **TID** is the thread identifier connected to the kernel event. -- **CPU** designates the logical CPU core on which the event was originated. -- **Name** is the human-readable event name such as `CreateProcess` or `RegOpenKey`. -- **Timestamp** denotes the timestamp expressed in nanosecond precision as the instant the event occurred. -- **Category** designates the category to which the event pertains, e.g. `file` or `thread`. Each particular category is explained thoroughly in the next - sections. -- **Description** is a short explanation about the purpose of the event. For example, `CreateFile` kernel event creates or opens a file, directory, I/O device, pipe, console buffer or other block/pseudo device. -- **Host** represents the host name where the event was produced. - -### Parameters - -Also called as `kparams` in Fibratus parlance, contain each of the event's parameters. Internally, they are modeled as a collection of key/value pairs where the key is mapped to the structure consisting of parameter name, parameter type and the value. An example of the parameter tuple could be the `dip` parameter -that denotes a destination IP address with value `172.17.0.2` and therefore `IPv4` type. Additionally, parameter types can be scalar values, strings, slices, enumerations, and timestamps among others. - -### Process state - -Each event stores the process state that represents an extended information about the process including its allocated resources such as handles, dynamically-linked libraries, exported environment variables and other attributes. The process state internals are thoroughly explained in the [Process](/kevents/process) events section. - -### Metadata - -Metadata are an arbitrary sequence of tags in form of key/value pairs that you can squash into the event on behalf of [transformers](/transformers/introduction). A tag can be virtually any string data that you find meaningful to either identify the event or apply filtering/grouping once event is persisted in the data store. diff --git a/pkg/kevent/kparam_test.go b/pkg/kevent/kparam_test.go deleted file mode 100644 index b7b168f7b..000000000 --- a/pkg/kevent/kparam_test.go +++ /dev/null @@ -1,60 +0,0 @@ -/* - * Copyright 2019-2020 by Nedim Sabic Sabic - * https://www.fibratus.io - * All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kevent - -import ( - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" - "testing" -) - -func TestKparams(t *testing.T) { - kpars := Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(18446738026482168384)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.Uint32, Value: uint32(1484)}, - kparams.FileCreateOptions: {Name: kparams.FileCreateOptions, Type: kparams.Uint32, Value: uint32(1223456)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll"}, - kparams.FileShareMask: {Name: kparams.FileShareMask, Type: kparams.Uint32, Value: uint32(5)}, - } - - assert.True(t, kpars.Contains(kparams.FileObject)) - assert.False(t, kpars.Contains(kparams.FileOffset)) - - filename, err := kpars.GetString(kparams.FilePath) - require.NoError(t, err) - assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\kernel32.dll", filename) - - _, err = kpars.GetString(kparams.FileObject) - require.Error(t, err) - - assert.Equal(t, 5, kpars.Len()) - - kpars.Remove(kparams.ThreadID) - - assert.False(t, kpars.Contains(kparams.ThreadID)) - assert.Equal(t, 4, kpars.Len()) - - require.NoError(t, kpars.Set(kparams.FileShareMask, uint32(5), kparams.Enum)) - - require.NoError(t, kpars.SetValue(kparams.FilePath, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll")) - filename1, err := kpars.GetString(kparams.FilePath) - require.NoError(t, err) - assert.Equal(t, "\\Device\\HarddiskVolume2\\Windows\\system32\\KERNEL32.dll", filename1) -} diff --git a/pkg/kevent/stackwalk_test.go b/pkg/kevent/stackwalk_test.go deleted file mode 100644 index cdccf0dee..000000000 --- a/pkg/kevent/stackwalk_test.go +++ /dev/null @@ -1,130 +0,0 @@ -/* - * Copyright 2021-present by Nedim Sabic Sabic - * https://www.fibratus.io - * All Rights Reserved. - * - * Licensed under the Apache License, Version 2.0 (the "License"); - * you may not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, software - * distributed under the License is distributed on an "AS IS" BASIS, - * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - * See the License for the specific language governing permissions and - * limitations under the License. - */ - -package kevent - -import ( - "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" - "github.com/rabbitstack/fibratus/pkg/util/va" - "github.com/stretchr/testify/assert" - "testing" - "time" -) - -func TestStackwalkDecorator(t *testing.T) { - q := NewQueue(50, false, true) - cd := NewStackwalkDecorator(q) - - e := &Kevent{ - Type: ktypes.CreateFile, - Tid: 2484, - PID: 859, - CPU: 1, - Seq: 2, - Name: "CreateFile", - Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, - }, - } - - e1 := &Kevent{ - Type: ktypes.CreateFile, - Tid: 2484, - PID: 859, - CPU: 1, - Seq: 3, - Name: "CreateFile", - Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\kernel32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, - }, - } - - cd.Push(e) - cd.Push(e1) - - assert.Len(t, cd.buckets[e.StackID()], 2) - - sw := &Kevent{ - Type: ktypes.StackWalk, - Tid: 2484, - PID: 859, - CPU: 1, - Seq: 4, - Name: "StackWalk", - Timestamp: time.Now(), - Kparams: Kparams{ - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5eb70dc4, 0x7ffb5c191deb, 0x7ffb3138592e}}, - }, - } - - evt := cd.Pop(sw) - assert.Len(t, cd.buckets[e.StackID()], 1) - assert.Equal(t, ktypes.CreateFile, evt.Type) - assert.True(t, evt.Kparams.Contains(kparams.Callstack)) - assert.Equal(t, "C:\\Windows\\system32\\user32.dll", evt.GetParamAsString(kparams.FilePath)) -} - -func init() { - maxQueueTTLPeriod = time.Second * 2 - flusherInterval = time.Second -} - -func TestStackwalkDecoratorFlush(t *testing.T) { - q := NewQueue(50, false, true) - q.RegisterListener(&DummyListener{}) - cd := NewStackwalkDecorator(q) - defer cd.Stop() - - e := &Kevent{ - Type: ktypes.CreateFile, - Tid: 2484, - PID: 859, - CPU: 1, - Seq: 2, - Name: "CreateFile", - Timestamp: time.Now(), - Category: ktypes.File, - Kparams: Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(1), Enum: fs.FileCreateDispositions}, - }, - } - - cd.Push(e) - assert.Len(t, cd.buckets[e.StackID()], 1) - time.Sleep(time.Millisecond * 3100) - - evt := <-q.Events() - assert.Len(t, cd.buckets[e.StackID()], 0) - assert.Equal(t, ktypes.CreateFile, evt.Type) - assert.False(t, evt.Kparams.Contains(kparams.Callstack)) -} diff --git a/pkg/outputs/amqp/amqp.go b/pkg/outputs/amqp/amqp.go index df4056063..1a62f09d9 100644 --- a/pkg/outputs/amqp/amqp.go +++ b/pkg/outputs/amqp/amqp.go @@ -21,7 +21,7 @@ package amqp import ( "expvar" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" ) @@ -66,7 +66,7 @@ func (q *rabbitmq) Close() error { return q.client.close() } -func (q *rabbitmq) Publish(batch *kevent.Batch) error { +func (q *rabbitmq) Publish(batch *event.Batch) error { body := batch.MarshalJSON() err := q.client.publish(body) diff --git a/pkg/outputs/amqp/amqp_test.go b/pkg/outputs/amqp/amqp_test.go index db44d1ccc..6181b95ab 100644 --- a/pkg/outputs/amqp/amqp_test.go +++ b/pkg/outputs/amqp/amqp_test.go @@ -27,10 +27,9 @@ import ( "time" "github.com/phayes/freeport" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/outputs/amqp/_fixtures/garagemq/config" broker "github.com/rabbitstack/fibratus/pkg/outputs/amqp/_fixtures/garagemq/server" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" @@ -66,7 +65,7 @@ func TestPublishAmqpOutput(t *testing.T) { require.NoError(t, q.Connect()) defer q.Close() - err = consumeKevents(t, amqpURL(port), done) + err = consumeEvents(t, amqpURL(port), done) require.NoError(t, err) err = q.Publish(getBatch()) @@ -118,7 +117,7 @@ func TestHealthcheck(t *testing.T) { } //nolint:unused -func consumeKevents(t *testing.T, amqpURI string, done chan struct{}) error { +func consumeEvents(t *testing.T, amqpURI string, done chan struct{}) error { conn, err := amqp.Dial(amqpURI) if err != nil { return err @@ -166,7 +165,7 @@ func consumeKevents(t *testing.T, amqpURI string, done chan struct{}) error { done <- struct{}{} t.Error("got empty AMQP message") } - var kevents []*kevent.Kevent + var kevents []*event.Event err := json.Unmarshal(body, &kevents) if err != nil { done <- struct{}{} @@ -193,27 +192,27 @@ func amqpURL(port int) string { } //nolint:unused -func getBatch() *kevent.Batch { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, +func getBatch() *event.Batch { + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -262,26 +261,26 @@ func getBatch() *kevent.Batch { }, } - kevt1 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt1 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 459, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -330,26 +329,26 @@ func getBatch() *kevent.Batch { }, } - kevt2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt2 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 829, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 829, Ppid: 6304, @@ -398,5 +397,5 @@ func getBatch() *kevent.Batch { }, } - return kevent.NewBatch(kevt, kevt1, kevt2) + return event.NewBatch(evt, evt1, evt2) } diff --git a/pkg/outputs/client.go b/pkg/outputs/client.go index be98bdea8..7999056be 100644 --- a/pkg/outputs/client.go +++ b/pkg/outputs/client.go @@ -19,12 +19,12 @@ package outputs import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" ) // Client represents the minimal interface all output implementors have to satisfy. type Client interface { Close() error - Publish(*kevent.Batch) error + Publish(*event.Batch) error Connect() error } diff --git a/pkg/outputs/console/config.go b/pkg/outputs/console/config.go index 583b894bd..d39a577b9 100644 --- a/pkg/outputs/console/config.go +++ b/pkg/outputs/console/config.go @@ -38,7 +38,7 @@ type Config struct { // AddFlags registers persistent flags. func AddFlags(flags *pflag.FlagSet) { flags.String(frmt, string(pretty), "Specifies the output format. Choose between pretty|json") - flags.String(paramKVDelimiter, "", "The delimiter symbol for the kparams key/value pairs") + flags.String(paramKVDelimiter, "", "The delimiter symbol for the params key/value pairs") flags.String(tmpl, "", "Event formatting template") flags.Bool(enabled, true, "Indicates if the console output is enabled") } diff --git a/pkg/outputs/console/console.go b/pkg/outputs/console/console.go index 829cf4cc8..9eca570fb 100644 --- a/pkg/outputs/console/console.go +++ b/pkg/outputs/console/console.go @@ -21,7 +21,7 @@ package console import ( "bufio" "expvar" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" "os" ) @@ -36,12 +36,12 @@ const ( pretty format = "pretty" json format = "json" // template represents the default template used in pretty rendering mode - template = "{{ .Seq }} {{ .Timestamp }} - {{ .CPU }} {{ .Process }} ({{ .Pid }}) - {{ .Type }} ({{ .Kparams }})" + template = "{{ .Seq }} {{ .Timestamp }} - {{ .CPU }} {{ .Process }} ({{ .Pid }}) - {{ .Type }} ({{ .Params }})" ) type console struct { writer *bufio.Writer - formatter *kevent.Formatter + formatter *event.Formatter format format } @@ -59,12 +59,12 @@ func initConsole(config outputs.Config) (outputs.OutputGroup, error) { if tmpl == "" { tmpl = template } - formatter, err := kevent.NewFormatter(tmpl) + formatter, err := event.NewFormatter(tmpl) if err != nil { return outputs.Fail(err) } if cfg.ParamKVDelimiter != "" { - kevent.ParamKVDelimiter = cfg.ParamKVDelimiter + event.ParamKVDelimiter = cfg.ParamKVDelimiter } c := &console{ @@ -77,14 +77,14 @@ func initConsole(config outputs.Config) (outputs.OutputGroup, error) { func (c *console) Close() error { return c.writer.Flush() } func (c *console) Connect() error { return nil } -func (c *console) Publish(batch *kevent.Batch) error { - for _, kevt := range batch.Events { +func (c *console) Publish(batch *event.Batch) error { + for _, evt := range batch.Events { var buf []byte switch c.format { case json: - buf = kevt.MarshalJSON() + buf = evt.MarshalJSON() case pretty: - buf = c.formatter.Format(kevt) + buf = c.formatter.Format(evt) default: return nil } diff --git a/pkg/outputs/elasticsearch/elasticsearch.go b/pkg/outputs/elasticsearch/elasticsearch.go index bbca52bcd..230a3a8d4 100644 --- a/pkg/outputs/elasticsearch/elasticsearch.go +++ b/pkg/outputs/elasticsearch/elasticsearch.go @@ -25,7 +25,7 @@ import ( "fmt" "github.com/hashicorp/go-version" "github.com/olivere/elastic/v7" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" "github.com/rabbitstack/fibratus/pkg/util/tls" log "github.com/sirupsen/logrus" @@ -170,20 +170,20 @@ func (e *elasticsearch) Connect() error { return nil } -func (e *elasticsearch) Publish(batch *kevent.Batch) error { - for _, kevt := range batch.Events { - indexName := e.index.getName(kevt) +func (e *elasticsearch) Publish(batch *event.Batch) error { + for _, evt := range batch.Events { + indexName := e.index.getName(evt) // create the bulk index request for each event in the batch. // We already have a valid JSON body, so just pass the raw // JSON message as request document - e.bulkProcessor.Add(newBulkIndexRequest(indexName, kevt)) + e.bulkProcessor.Add(newBulkIndexRequest(indexName, evt)) totalBulkedDocs.Add(1) } return nil } -func newBulkIndexRequest(indexName string, kevt *kevent.Kevent) *elastic.BulkIndexRequest { - kjson := kevt.MarshalJSON() +func newBulkIndexRequest(indexName string, evt *event.Event) *elastic.BulkIndexRequest { + kjson := evt.MarshalJSON() return elastic.NewBulkIndexRequest().Index(indexName).Doc(json.RawMessage(kjson)) } diff --git a/pkg/outputs/elasticsearch/elasticsearch_test.go b/pkg/outputs/elasticsearch/elasticsearch_test.go index 635ad24e1..b956e8aba 100644 --- a/pkg/outputs/elasticsearch/elasticsearch_test.go +++ b/pkg/outputs/elasticsearch/elasticsearch_test.go @@ -31,10 +31,9 @@ import ( "time" "github.com/olivere/elastic/v7" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -97,7 +96,7 @@ func TestElasticsearchPublish(t *testing.T) { defer r.Body.Close() // check we have the correct index name assert.True(t, bytes.Contains(body, []byte("fibratus-2018-03"))) - // check kevent name is present + // check event name is present assert.True(t, bytes.Contains(body, []byte("CreateFile"))) // create the bulk response @@ -133,7 +132,7 @@ func TestElasticsearchPublish(t *testing.T) { })) defer srv.Close() - kevent.SerializeHandles = true + event.SerializeHandles = true cfg := Config{ Servers: []string{srv.URL}, @@ -158,29 +157,29 @@ func TestElasticsearchPublish(t *testing.T) { assert.Equal(t, int64(0), failedDocs.Value()) } -func getBatch() *kevent.Batch { +func getBatch() *event.Batch { ts, _ := time.Parse(time.RFC3339, "2018-05-03T15:04:05.323Z") - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: ts, - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -229,26 +228,26 @@ func getBatch() *kevent.Batch { }, } - kevt1 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt1 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 459, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: ts, - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -297,26 +296,26 @@ func getBatch() *kevent.Batch { }, } - kevt2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt2 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 829, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: ts, - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 829, Ppid: 6304, @@ -365,5 +364,5 @@ func getBatch() *kevent.Batch { }, } - return kevent.NewBatch(kevt, kevt1, kevt2) + return event.NewBatch(evt, evt1, evt2) } diff --git a/pkg/outputs/elasticsearch/index.go b/pkg/outputs/elasticsearch/index.go index 698032c52..8b5fb3522 100644 --- a/pkg/outputs/elasticsearch/index.go +++ b/pkg/outputs/elasticsearch/index.go @@ -23,7 +23,7 @@ import ( "context" "fmt" "github.com/olivere/elastic/v7" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "html/template" "strings" "time" @@ -77,12 +77,12 @@ func (i index) putTemplate() error { // getName creates an index name by replacing specifiers to create time frame indices. If no time specifiers are // used this method returns a fixed index name. -func (i index) getName(kevt *kevent.Kevent) string { +func (i index) getName(evt *event.Event) string { indexName := i.config.IndexName if !strings.Contains(indexName, "%") { return indexName } - return i.replace(kevt.Timestamp) + return i.replace(evt.Timestamp) } func (i index) replace(timestamp time.Time) string { diff --git a/pkg/outputs/elasticsearch/index_test.go b/pkg/outputs/elasticsearch/index_test.go index cb41f284b..ce1fa35c9 100644 --- a/pkg/outputs/elasticsearch/index_test.go +++ b/pkg/outputs/elasticsearch/index_test.go @@ -19,7 +19,7 @@ package elasticsearch import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/stretchr/testify/assert" "testing" "time" @@ -30,21 +30,21 @@ func TestProduceIndexName(t *testing.T) { ts, _ := time.Parse(time.RFC3339, "2011-05-03T15:04:05.323Z") - indexName := i.getName(&kevent.Kevent{Timestamp: ts}) + indexName := i.getName(&event.Event{Timestamp: ts}) assert.Equal(t, "fibratus-2011-05", indexName) i = index{config: Config{IndexName: "fibratus-%y-%d"}} - indexName = i.getName(&kevent.Kevent{Timestamp: ts}) + indexName = i.getName(&event.Event{Timestamp: ts}) assert.Equal(t, "fibratus-11-03", indexName) i = index{config: Config{IndexName: "fibratus-%d-%H"}} - indexName = i.getName(&kevent.Kevent{Timestamp: ts}) + indexName = i.getName(&event.Event{Timestamp: ts}) assert.Equal(t, "fibratus-03-15", indexName) i = index{config: Config{IndexName: "fibratus-events"}} - indexName = i.getName(&kevent.Kevent{Timestamp: ts}) + indexName = i.getName(&event.Event{Timestamp: ts}) assert.Equal(t, "fibratus-events", indexName) } diff --git a/pkg/outputs/elasticsearch/template.go b/pkg/outputs/elasticsearch/template.go index bb154f9ec..e6bf0244b 100644 --- a/pkg/outputs/elasticsearch/template.go +++ b/pkg/outputs/elasticsearch/template.go @@ -46,7 +46,7 @@ const indexTemplate = ` "timestamp": { "type": "date" }, - "kparams": { + "params": { "type": "nested", "properties": { "dip": { "type": "ip" }, diff --git a/pkg/outputs/eventlog/config.go b/pkg/outputs/eventlog/config.go index 045b6befe..d67576cfb 100644 --- a/pkg/outputs/eventlog/config.go +++ b/pkg/outputs/eventlog/config.go @@ -19,7 +19,7 @@ package eventlog import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "text/template" "github.com/spf13/pflag" @@ -47,7 +47,7 @@ type Config struct { func (c Config) parseTemplate() (*template.Template, error) { if c.Template == "" { // use built-in template - return template.New("evtlog").Parse(kevent.Template) + return template.New("evtlog").Parse(event.Template) } return template.New("evtlog").Parse(c.Template) } diff --git a/pkg/outputs/eventlog/eventlog.go b/pkg/outputs/eventlog/eventlog.go index 6912a1b6e..941ca7014 100644 --- a/pkg/outputs/eventlog/eventlog.go +++ b/pkg/outputs/eventlog/eventlog.go @@ -26,9 +26,7 @@ import ( "golang.org/x/sys/windows" "text/template" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" - - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" ) @@ -45,7 +43,7 @@ type evtlog struct { evtlog *Eventlog // eventlog writer config Config tmpl *template.Template - events []ktypes.KeventInfo + events []event.Info cats []string } @@ -67,8 +65,8 @@ func initEventlog(config outputs.Config) (outputs.OutputGroup, error) { } evtlog := &evtlog{ config: cfg, - events: ktypes.GetKtypesMetaIndexed(), - cats: ktypes.Categories(), + events: event.GetTypesMetaIndexed(), + cats: event.Categories(), } evtlog.tmpl, err = cfg.parseTemplate() if err != nil { @@ -101,22 +99,22 @@ func (e *evtlog) Close() error { return nil } -func (e *evtlog) Publish(batch *kevent.Batch) error { - for _, kevt := range batch.Events { - if err := e.publish(kevt); err != nil { +func (e *evtlog) Publish(batch *event.Batch) error { + for _, evt := range batch.Events { + if err := e.publish(evt); err != nil { return err } } return nil } -func (e *evtlog) publish(kevt *kevent.Kevent) error { - buf, err := kevt.RenderCustomTemplate(e.tmpl) +func (e *evtlog) publish(evt *event.Event) error { + buf, err := evt.RenderCustomTemplate(e.tmpl) if err != nil { return err } - categoryID := e.categoryID(kevt) - eventID := eventlog.EventID(windows.EVENTLOG_INFORMATION_TYPE, uint16(e.eventCode(kevt))) + categoryID := e.categoryID(evt) + eventID := eventlog.EventID(windows.EVENTLOG_INFORMATION_TYPE, uint16(e.eventCode(evt))) if eventID == 0 { return ErrUnknownEventID } @@ -128,9 +126,9 @@ func (e *evtlog) publish(kevt *kevent.Kevent) error { } // categoryID maps category name to eventlog identifier. -func (e *evtlog) categoryID(kevt *kevent.Kevent) uint16 { +func (e *evtlog) categoryID(evt *event.Event) uint16 { for i, cat := range e.cats { - if cat == string(kevt.Category) { + if cat == string(evt.Category) { return uint16(i + 1) } } @@ -138,9 +136,9 @@ func (e *evtlog) categoryID(kevt *kevent.Kevent) uint16 { } // eventCode returns the event ID from the event type. -func (e *evtlog) eventCode(kevt *kevent.Kevent) uint32 { - for i, evt := range e.events { - if evt.Name == kevt.Name { +func (e *evtlog) eventCode(evt *event.Event) uint32 { + for i, e := range e.events { + if evt.Name == e.Name { return uint32(i + categoryOffset) } } diff --git a/pkg/outputs/eventlog/eventlog_test.go b/pkg/outputs/eventlog/eventlog_test.go index c8a8ccbe0..2528d45e1 100644 --- a/pkg/outputs/eventlog/eventlog_test.go +++ b/pkg/outputs/eventlog/eventlog_test.go @@ -26,10 +26,9 @@ import ( "testing" "time" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/require" @@ -44,8 +43,8 @@ func TestEvtlogPublish(t *testing.T) { el := &evtlog{ config: c, tmpl: tmpl, - events: ktypes.GetKtypesMetaIndexed(), - cats: ktypes.Categories(), + events: event.GetTypesMetaIndexed(), + cats: event.Categories(), } err = eventlog.Install(eventlog.Levels) if err != nil && !errors.Is(err, eventlog.ErrKeyExists) { @@ -55,27 +54,27 @@ func TestEvtlogPublish(t *testing.T) { require.NoError(t, el.Publish(getBatch())) } -func getBatch() *kevent.Batch { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, +func getBatch() *event.Batch { + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -142,5 +141,5 @@ func getBatch() *kevent.Batch { }, } - return kevent.NewBatch(kevt) + return event.NewBatch(evt) } diff --git a/pkg/outputs/eventlog/mc/gen.go b/pkg/outputs/eventlog/mc/gen.go index 4c142a075..0663c9f5b 100644 --- a/pkg/outputs/eventlog/mc/gen.go +++ b/pkg/outputs/eventlog/mc/gen.go @@ -22,7 +22,7 @@ import ( "bytes" "fmt" "github.com/Masterminds/sprig/v3" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "io" "log" "math" @@ -33,13 +33,13 @@ import ( // Source contains the required data for producing the input for the message compiler. type Source struct { Categories []string - Events []ktypes.KeventInfo + Events []event.Info MaxEvents uint16 } func (s *Source) Generate(w io.Writer) error { funcmap := sprig.TxtFuncMap() - funcmap["length"] = func(evts []ktypes.KeventInfo) int { + funcmap["length"] = func(evts []event.Info) int { return len(evts) } funcmap["N"] = func(start, end int) (stream chan int) { @@ -64,8 +64,8 @@ func main() { var buf bytes.Buffer src := &Source{ - Categories: ktypes.Categories(), - Events: ktypes.GetKtypesMetaIndexed(), + Categories: event.Categories(), + Events: event.GetTypesMetaIndexed(), MaxEvents: math.MaxUint16, } diff --git a/pkg/outputs/http/http.go b/pkg/outputs/http/http.go index 726a1a788..3b8bab183 100644 --- a/pkg/outputs/http/http.go +++ b/pkg/outputs/http/http.go @@ -29,7 +29,7 @@ import ( "github.com/rabbitstack/fibratus/pkg/util/version" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" ) @@ -79,7 +79,7 @@ func initHTTP(config outputs.Config) (outputs.OutputGroup, error) { func (h *_http) Connect() error { return nil } func (h *_http) Close() error { return nil } -func (h *_http) Publish(batch *kevent.Batch) error { +func (h *_http) Publish(batch *event.Batch) error { var buf []byte switch h.config.Serializer { case outputs.JSON: diff --git a/pkg/outputs/http/http_test.go b/pkg/outputs/http/http_test.go index 875b904fd..82c113ef7 100644 --- a/pkg/outputs/http/http_test.go +++ b/pkg/outputs/http/http_test.go @@ -34,10 +34,9 @@ import ( "github.com/stretchr/testify/assert" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/stretchr/testify/require" ) @@ -55,7 +54,7 @@ func TestHttpPublish(t *testing.T) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - var kevents []*kevent.Kevent + var kevents []*event.Event if err := json.Unmarshal(body, &kevents); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -115,7 +114,7 @@ func TestHttpGzipPublish(t *testing.T) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - var kevents []*kevent.Kevent + var kevents []*event.Event if err := json.Unmarshal(body, &kevents); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return @@ -147,27 +146,27 @@ func TestHttpGzipPublish(t *testing.T) { require.NoError(t, err) } -func getBatch() *kevent.Batch { - kevt := &kevent.Kevent{ - Type: ktypes.CreateFile, +func getBatch() *event.Batch { + evt := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 859, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -216,26 +215,26 @@ func getBatch() *kevent.Batch { }, } - kevt1 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt1 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 459, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 2436, Ppid: 6304, @@ -284,26 +283,26 @@ func getBatch() *kevent.Batch { }, } - kevt2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + evt2 := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: 829, CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.AnsiString, Value: "open"}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Int8, Value: int8(2)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(2)}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "\\Device\\HarddiskVolume2\\Windows\\system32\\user32.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.AnsiString, Value: "open"}, + params.BasePrio: {Name: params.BasePrio, Type: params.Int8, Value: int8(2)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "baarz"}, PS: &pstypes.PS{ PID: 829, Ppid: 6304, @@ -352,5 +351,5 @@ func getBatch() *kevent.Batch { }, } - return kevent.NewBatch(kevt, kevt1, kevt2) + return event.NewBatch(evt, evt1, evt2) } diff --git a/pkg/outputs/null/null.go b/pkg/outputs/null/null.go index 16afcc7e9..8a0782656 100644 --- a/pkg/outputs/null/null.go +++ b/pkg/outputs/null/null.go @@ -20,7 +20,7 @@ package null import ( "expvar" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/outputs" ) @@ -39,7 +39,7 @@ func initNull(config outputs.Config) (outputs.OutputGroup, error) { func (null) Close() error { return nil } func (null) Connect() error { return nil } -func (null) Publish(batch *kevent.Batch) error { +func (null) Publish(batch *event.Batch) error { blackholeEventsCount.Add(batch.Len()) return nil } diff --git a/pkg/pe/marshaller.go b/pkg/pe/marshaller.go index 6e542d1c5..c4944afac 100644 --- a/pkg/pe/marshaller.go +++ b/pkg/pe/marshaller.go @@ -23,7 +23,7 @@ package pe import ( "fmt" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/rabbitstack/fibratus/pkg/util/bytes" "github.com/rabbitstack/fibratus/pkg/util/convert" @@ -124,7 +124,7 @@ func (pe *PE) Marshal() []byte { } // Unmarshal recovers the PE metadata from the byte stream. -func (pe *PE) Unmarshal(b []byte, ver kcapver.Version) error { +func (pe *PE) Unmarshal(b []byte, ver capver.Version) error { if len(b) < 6 { return fmt.Errorf("expected at least 6 bytes but got %d bytes", len(b)) } @@ -241,7 +241,7 @@ func (pe *PE) Unmarshal(b []byte, ver kcapver.Version) error { offset += roffset - if ver >= kcapver.PESecV2 { + if ver >= capver.PESecV2 { pe.IsSigned = convert.Itob(b[20+offset]) pe.IsTrusted = convert.Itob(b[21+offset]) @@ -283,7 +283,7 @@ func (pe *PE) Unmarshal(b []byte, ver kcapver.Version) error { } // NewFromKcap restores the PE metadata from the byte stream. -func NewFromKcap(b []byte, ver kcapver.Version) (*PE, error) { +func NewFromKcap(b []byte, ver capver.Version) (*PE, error) { pe := &PE{ Sections: make([]Sec, 0), Symbols: make([]string, 0), diff --git a/pkg/pe/marshaller_test.go b/pkg/pe/marshaller_test.go index 3943f533e..07ac3f8a0 100644 --- a/pkg/pe/marshaller_test.go +++ b/pkg/pe/marshaller_test.go @@ -22,7 +22,7 @@ package pe import ( - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" diff --git a/pkg/ps/snapshotter.go b/pkg/ps/snapshotter.go index 17a93279c..1eec7f18e 100644 --- a/pkg/ps/snapshotter.go +++ b/pkg/ps/snapshotter.go @@ -19,7 +19,7 @@ package ps import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" ) @@ -31,23 +31,23 @@ type Snapshotter interface { // Write appends a new process state to the snapshotter. It takes as an input the inbound event to fetch // the basic data, but also enriches the process' state with extra metadata such as process' env variables, PE // metadata for Windows binaries and so on. - Write(*kevent.Kevent) error + Write(*event.Event) error // AddThread builds thread state from the event representation. - AddThread(*kevent.Kevent) error + AddThread(*event.Event) error // AddModule builds module state from the event representation. - AddModule(*kevent.Kevent) error + AddModule(*event.Event) error // RemoveThread removes the thread from the given process. RemoveThread(pid uint32, tid uint32) error // RemoveModule removes the module the given process. RemoveModule(pid uint32, addr va.Address) error // AddMmap adds a new memory mapping (data memory-mapped file, image, or pagefile) to this process state. - AddMmap(*kevent.Kevent) error + AddMmap(*event.Event) error // RemoveMmap removes memory mapping at the given base address. RemoveMmap(pid uint32, addr va.Address) error - // WriteFromKcap appends a new process state to the snapshotter from the captured kernel event. - WriteFromKcap(kevt *kevent.Kevent) error + // WriteFromCapture appends a new process state to the snapshotter from the captured event. + WriteFromCapture(evt *event.Event) error // Remove deletes process's state from the snapshotter. - Remove(kevt *kevent.Kevent) error + Remove(evt *event.Event) error // Find attempts to retrieve process' state for the specified process identifier. Returns true // if the process was find in the state. Otherwise, returns false and constructs a fresh process // state by querying the OS via API functions. diff --git a/pkg/ps/snapshotter_mock.go b/pkg/ps/snapshotter_mock.go index ee4458efd..f0268da93 100644 --- a/pkg/ps/snapshotter_mock.go +++ b/pkg/ps/snapshotter_mock.go @@ -19,7 +19,7 @@ package ps import ( - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/util/va" "github.com/stretchr/testify/mock" @@ -31,14 +31,14 @@ type SnapshotterMock struct { } // Write method -func (s *SnapshotterMock) Write(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) Write(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } // Remove method -func (s *SnapshotterMock) Remove(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) Remove(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } @@ -79,14 +79,14 @@ func (s *SnapshotterMock) GetSnapshot() []*pstypes.PS { } // AddThread method -func (s *SnapshotterMock) AddThread(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) AddThread(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } // AddModule method -func (s *SnapshotterMock) AddModule(kevt *kevent.Kevent) error { - args := s.Called(kevt) +func (s *SnapshotterMock) AddModule(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } @@ -102,16 +102,16 @@ func (s *SnapshotterMock) RemoveModule(pid uint32, addr va.Address) error { return args.Error(0) } -// WriteFromKcap method -func (s *SnapshotterMock) WriteFromKcap(kevt *kevent.Kevent) error { return nil } +// WriteFromCapture method +func (s *SnapshotterMock) WriteFromCapture(evt *event.Event) error { return nil } -// AddFileMapping method -func (s *SnapshotterMock) AddMmap(kevt *kevent.Kevent) error { - args := s.Called(kevt) +// AddMmap method +func (s *SnapshotterMock) AddMmap(evt *event.Event) error { + args := s.Called(evt) return args.Error(0) } -// RemoveFileMapping method +// RemoveMmap method func (s *SnapshotterMock) RemoveMmap(pid uint32, address va.Address) error { args := s.Called(pid, address) return args.Error(0) diff --git a/pkg/ps/snapshotter_windows.go b/pkg/ps/snapshotter_windows.go index dc785375f..0080d8b17 100644 --- a/pkg/ps/snapshotter_windows.go +++ b/pkg/ps/snapshotter_windows.go @@ -30,11 +30,10 @@ import ( "time" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/pe" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" log "github.com/sirupsen/logrus" @@ -88,8 +87,8 @@ func NewSnapshotter(hsnap handle.Snapshotter, config *config.Config) Snapshotter return s } -// NewSnapshotterFromKcap restores the snapshotter state from the kcap file. -func NewSnapshotterFromKcap(hsnap handle.Snapshotter, config *config.Config) Snapshotter { +// NewSnapshotterFromCapture restores the snapshotter state from the cap file. +func NewSnapshotterFromCapture(hsnap handle.Snapshotter, config *config.Config) Snapshotter { s := &snapshotter{ procs: make(map[uint32]*pstypes.PS), dirty: make(map[uint32]*pstypes.PS), @@ -105,20 +104,20 @@ func NewSnapshotterFromKcap(hsnap handle.Snapshotter, config *config.Config) Sna return s } -func (s *snapshotter) WriteFromKcap(e *kevent.Kevent) error { +func (s *snapshotter) WriteFromCapture(e *event.Event) error { switch e.Type { - case ktypes.CreateProcess, ktypes.ProcessRundown: + case event.CreateProcess, event.ProcessRundown: s.mu.Lock() defer s.mu.Unlock() proc := e.PS if proc == nil { return nil } - pid, err := e.Kparams.GetPid() + pid, err := e.Params.GetPid() if err != nil { return err } - ppid, err := e.Kparams.GetPpid() + ppid, err := e.Params.GetPpid() if err != nil { return err } @@ -135,23 +134,23 @@ func (s *snapshotter) WriteFromKcap(e *kevent.Kevent) error { } } s.procs[pid] = proc - case ktypes.CreateThread, ktypes.ThreadRundown: + case event.CreateThread, event.ThreadRundown: return s.AddThread(e) - case ktypes.LoadImage, ktypes.ImageRundown: + case event.LoadImage, event.ImageRundown: return s.AddModule(e) } return nil } -func (s *snapshotter) Write(e *kevent.Kevent) error { +func (s *snapshotter) Write(e *event.Event) error { s.mu.Lock() defer s.mu.Unlock() processCount.Add(1) - pid, err := e.Kparams.GetPid() + pid, err := e.Params.GetPid() if err != nil { return err } - ppid, err := e.Kparams.GetPpid() + ppid, err := e.Params.GetPpid() if err != nil { return err } @@ -172,8 +171,8 @@ func (s *snapshotter) Write(e *kevent.Kevent) error { return err } -func (s *snapshotter) AddThread(e *kevent.Kevent) error { - pid, err := e.Kparams.GetPid() +func (s *snapshotter) AddThread(e *event.Event) error { + pid, err := e.Params.GetPid() if err != nil { return err } @@ -187,23 +186,23 @@ func (s *snapshotter) AddThread(e *kevent.Kevent) error { } thread := pstypes.Thread{} - thread.Tid, _ = e.Kparams.GetTid() - thread.UstackBase = e.Kparams.TryGetAddress(kparams.UstackBase) - thread.UstackLimit = e.Kparams.TryGetAddress(kparams.UstackLimit) - thread.KstackBase = e.Kparams.TryGetAddress(kparams.KstackBase) - thread.KstackLimit = e.Kparams.TryGetAddress(kparams.KstackLimit) - thread.IOPrio, _ = e.Kparams.GetUint8(kparams.IOPrio) - thread.BasePrio, _ = e.Kparams.GetUint8(kparams.BasePrio) - thread.PagePrio, _ = e.Kparams.GetUint8(kparams.PagePrio) - thread.StartAddress = e.Kparams.TryGetAddress(kparams.StartAddress) + thread.Tid, _ = e.Params.GetTid() + thread.UstackBase = e.Params.TryGetAddress(params.UstackBase) + thread.UstackLimit = e.Params.TryGetAddress(params.UstackLimit) + thread.KstackBase = e.Params.TryGetAddress(params.KstackBase) + thread.KstackLimit = e.Params.TryGetAddress(params.KstackLimit) + thread.IOPrio, _ = e.Params.GetUint8(params.IOPrio) + thread.BasePrio, _ = e.Params.GetUint8(params.BasePrio) + thread.PagePrio, _ = e.Params.GetUint8(params.PagePrio) + thread.StartAddress = e.Params.TryGetAddress(params.StartAddress) proc.AddThread(thread) return nil } -func (s *snapshotter) AddModule(e *kevent.Kevent) error { - pid, err := e.Kparams.GetPid() +func (s *snapshotter) AddModule(e *event.Event) error { + pid, err := e.Params.GetPid() if err != nil { return err } @@ -221,13 +220,13 @@ func (s *snapshotter) AddModule(e *kevent.Kevent) error { } module := pstypes.Module{} - module.Size, _ = e.Kparams.GetUint64(kparams.ImageSize) - module.Checksum, _ = e.Kparams.GetUint32(kparams.ImageCheckSum) - module.Name = e.GetParamAsString(kparams.ImagePath) - module.BaseAddress = e.Kparams.TryGetAddress(kparams.ImageBase) - module.DefaultBaseAddress = e.Kparams.TryGetAddress(kparams.ImageDefaultBase) - module.SignatureLevel, _ = e.Kparams.GetUint32(kparams.ImageSignatureLevel) - module.SignatureType, _ = e.Kparams.GetUint32(kparams.ImageSignatureType) + module.Size, _ = e.Params.GetUint64(params.ImageSize) + module.Checksum, _ = e.Params.GetUint32(params.ImageCheckSum) + module.Name = e.GetParamAsString(params.ImagePath) + module.BaseAddress = e.Params.TryGetAddress(params.ImageBase) + module.DefaultBaseAddress = e.Params.TryGetAddress(params.ImageDefaultBase) + module.SignatureLevel, _ = e.Params.GetUint32(params.ImageSignatureLevel) + module.SignatureType, _ = e.Params.GetUint32(params.ImageSignatureType) if strings.EqualFold(proc.Name, filepath.Base(module.Name)) && len(proc.Exe) < len(module.Name) { // if the module is loaded for the process executable, and @@ -278,7 +277,7 @@ func (s *snapshotter) FindModule(addr va.Address) (bool, *pstypes.Module) { return false, nil } -func (s *snapshotter) AddMmap(e *kevent.Kevent) error { +func (s *snapshotter) AddMmap(e *event.Event) error { s.mu.Lock() defer s.mu.Unlock() proc, ok := s.procs[e.PID] @@ -289,11 +288,11 @@ func (s *snapshotter) AddMmap(e *kevent.Kevent) error { mmapCount.Add(1) mmap := pstypes.Mmap{} - mmap.File = e.GetParamAsString(kparams.FilePath) - mmap.BaseAddress = e.Kparams.TryGetAddress(kparams.FileViewBase) - mmap.Size, _ = e.Kparams.GetUint64(kparams.FileViewSize) - mmap.Protection, _ = e.Kparams.GetUint32(kparams.MemProtect) - mmap.Type = e.GetParamAsString(kparams.FileViewSectionType) + mmap.File = e.GetParamAsString(params.FilePath) + mmap.BaseAddress = e.Params.TryGetAddress(params.FileViewBase) + mmap.Size, _ = e.Params.GetUint64(params.FileViewSize) + mmap.Protection, _ = e.Params.GetUint32(params.MemProtect) + mmap.Type = e.GetParamAsString(params.FileViewSectionType) proc.AddMmap(mmap) @@ -317,29 +316,29 @@ func (s *snapshotter) Close() error { return nil } -func (s *snapshotter) newProcState(pid, ppid uint32, e *kevent.Kevent) (*pstypes.PS, error) { +func (s *snapshotter) newProcState(pid, ppid uint32, e *event.Event) (*pstypes.PS, error) { proc := pstypes.New( pid, ppid, - e.GetParamAsString(kparams.ProcessName), - e.GetParamAsString(kparams.Cmdline), - e.GetParamAsString(kparams.Exe), - e.Kparams.MustGetSID(), - e.Kparams.MustGetUint32(kparams.SessionID), + e.GetParamAsString(params.ProcessName), + e.GetParamAsString(params.Cmdline), + e.GetParamAsString(params.Exe), + e.Params.MustGetSID(), + e.Params.MustGetUint32(params.SessionID), ) proc.Parent = s.procs[ppid] - proc.StartTime, _ = e.Kparams.GetTime(kparams.StartTime) - proc.IsWOW64 = (e.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsWOW64) != 0 - proc.IsPackaged = (e.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsPackaged) != 0 - proc.IsProtected = (e.Kparams.MustGetUint32(kparams.ProcessFlags) & kevent.PsProtected) != 0 + proc.StartTime, _ = e.Params.GetTime(params.StartTime) + proc.IsWOW64 = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsWOW64) != 0 + proc.IsPackaged = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsPackaged) != 0 + proc.IsProtected = (e.Params.MustGetUint32(params.ProcessFlags) & event.PsProtected) != 0 if !s.capture { if proc.Username != "" { - e.AppendParam(kparams.Username, kparams.UnicodeString, proc.Username) + e.AppendParam(params.Username, params.UnicodeString, proc.Username) } if proc.Domain != "" { - e.AppendParam(kparams.Domain, kparams.UnicodeString, proc.Domain) + e.AppendParam(params.Domain, params.UnicodeString, proc.Domain) } // retrieve process handles var err error @@ -352,8 +351,8 @@ func (s *snapshotter) newProcState(pid, ppid uint32, e *kevent.Kevent) (*pstypes // return early if we're reading from the capture file if s.capture { // reset username/domain from captured event parameters - proc.Domain = e.GetParamAsString(kparams.Domain) - proc.Username = e.GetParamAsString(kparams.Username) + proc.Domain = e.GetParamAsString(params.Domain) + proc.Username = e.GetParamAsString(params.Username) return proc, nil } @@ -387,10 +386,10 @@ func (s *snapshotter) newProcState(pid, ppid uint32, e *kevent.Kevent) (*pstypes return proc, nil } -func (s *snapshotter) Remove(e *kevent.Kevent) error { +func (s *snapshotter) Remove(e *event.Event) error { s.mu.Lock() defer s.mu.Unlock() - pid, err := e.Kparams.GetPid() + pid, err := e.Params.GetPid() if err != nil { return err } diff --git a/pkg/ps/snapshotter_windows_test.go b/pkg/ps/snapshotter_windows_test.go index 69f81740a..3ec17f499 100644 --- a/pkg/ps/snapshotter_windows_test.go +++ b/pkg/ps/snapshotter_windows_test.go @@ -20,11 +20,10 @@ package ps import ( "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/handle" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -47,22 +46,22 @@ func TestWrite(t *testing.T) { var tests = []struct { name string - evt *kevent.Kevent + evt *event.Event want *pstypes.PS }{ {"write state from spawned process", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, }, &pstypes.PS{ @@ -82,18 +81,18 @@ func TestWrite(t *testing.T) { }, }, {"write state from spawned process with parent", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, PID: uint32(os.Getpid()), }, @@ -117,18 +116,18 @@ func TestWrite(t *testing.T) { }, }, {"write state from rundown event", - &kevent.Kevent{ - Type: ktypes.ProcessRundown, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(8390)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + &event.Event{ + Type: event.ProcessRundown, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(8390)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, }, &pstypes.PS{ @@ -157,7 +156,7 @@ func TestWrite(t *testing.T) { require.NoError(t, psnap.Write(evt)) require.True(t, psnap.Size() > 0) - ok, proc := psnap.Find(evt.Kparams.MustGetPid()) + ok, proc := psnap.Find(evt.Params.MustGetPid()) require.True(t, ok) require.NotNil(t, proc) assert.Equal(t, ps.PID, proc.PID) @@ -194,22 +193,22 @@ func TestRemove(t *testing.T) { var tests = []struct { name string - evt *kevent.Kevent + evt *event.Event want bool }{ {"write and remove process state from snapshotter", - &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, }, false, @@ -226,7 +225,7 @@ func TestRemove(t *testing.T) { require.NoError(t, psnap.Remove(evt)) // process in dirty map, wait 6 seconds before lookup time.Sleep(time.Second * 6) - ok, _ := psnap.Find(evt.Kparams.MustGetPid()) + ok, _ := psnap.Find(evt.Params.MustGetPid()) assert.Equal(t, exists, ok) }) } @@ -238,59 +237,59 @@ func TestAddThread(t *testing.T) { psnap := NewSnapshotter(hsnap, &config.Config{}) defer psnap.Close() - evt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + evt := &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, } require.NoError(t, psnap.Write(evt)) var tests = []struct { name string - evt *kevent.Kevent + evt *event.Event want bool }{ {"add thread to existing process", - &kevent.Kevent{ - Type: ktypes.CreateThread, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(3453)}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Uint8, Value: uint8(13)}, - kparams.StartAddress: {Name: kparams.StartAddress, Type: kparams.Address, Value: uint64(140729524944768)}, - kparams.IOPrio: {Name: kparams.IOPrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackBase: {Name: kparams.KstackBase, Type: kparams.Address, Value: uint64(18446677035730165760)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(18446677035730137088)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(5)}, - kparams.UstackBase: {Name: kparams.UstackBase, Type: kparams.Address, Value: uint64(86376448)}, - kparams.UstackLimit: {Name: kparams.UstackLimit, Type: kparams.Address, Value: uint64(86372352)}, + &event.Event{ + Type: event.CreateThread, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(3453)}, + params.BasePrio: {Name: params.BasePrio, Type: params.Uint8, Value: uint8(13)}, + params.StartAddress: {Name: params.StartAddress, Type: params.Address, Value: uint64(140729524944768)}, + params.IOPrio: {Name: params.IOPrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackBase: {Name: params.KstackBase, Type: params.Address, Value: uint64(18446677035730165760)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(18446677035730137088)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(5)}, + params.UstackBase: {Name: params.UstackBase, Type: params.Address, Value: uint64(86376448)}, + params.UstackLimit: {Name: params.UstackLimit, Type: params.Address, Value: uint64(86372352)}, }, }, true, }, {"add thread to absent process", - &kevent.Kevent{ - Type: ktypes.CreateThread, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid() + 1)}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(3453)}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Uint8, Value: uint8(13)}, - kparams.StartAddress: {Name: kparams.StartAddress, Type: kparams.Address, Value: uint64(140729524944768)}, - kparams.IOPrio: {Name: kparams.IOPrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackBase: {Name: kparams.KstackBase, Type: kparams.Address, Value: uint64(18446677035730165760)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(18446677035730137088)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(5)}, - kparams.UstackBase: {Name: kparams.UstackBase, Type: kparams.Address, Value: uint64(86376448)}, - kparams.UstackLimit: {Name: kparams.UstackLimit, Type: kparams.Address, Value: uint64(86372352)}, + &event.Event{ + Type: event.CreateThread, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid() + 1)}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(3453)}, + params.BasePrio: {Name: params.BasePrio, Type: params.Uint8, Value: uint8(13)}, + params.StartAddress: {Name: params.StartAddress, Type: params.Address, Value: uint64(140729524944768)}, + params.IOPrio: {Name: params.IOPrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackBase: {Name: params.KstackBase, Type: params.Address, Value: uint64(18446677035730165760)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(18446677035730137088)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(5)}, + params.UstackBase: {Name: params.UstackBase, Type: params.Address, Value: uint64(86376448)}, + params.UstackLimit: {Name: params.UstackLimit, Type: params.Address, Value: uint64(86372352)}, }, }, false, @@ -303,11 +302,11 @@ func TestAddThread(t *testing.T) { exists := tt.want require.NoError(t, psnap.AddThread(evt)) - ok, proc := psnap.Find(evt.Kparams.MustGetPid()) + ok, proc := psnap.Find(evt.Params.MustGetPid()) require.Equal(t, exists, ok) if ok { - assert.Contains(t, proc.Threads, evt.Kparams.MustGetTid()) - assert.Equal(t, va.Address(140729524944768), proc.Threads[evt.Kparams.MustGetTid()].StartAddress) + assert.Contains(t, proc.Threads, evt.Params.MustGetTid()) + assert.Equal(t, va.Address(140729524944768), proc.Threads[evt.Params.MustGetTid()].StartAddress) } }) } @@ -319,35 +318,35 @@ func TestRemoveThread(t *testing.T) { hsnap.On("FindHandles", mock.Anything).Return([]htypes.Handle{}, nil) defer psnap.Close() - pevt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + pevt := &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, } require.NoError(t, psnap.Write(pevt)) - tevt := &kevent.Kevent{ - Type: ktypes.CreateThread, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ThreadID: {Name: kparams.ThreadID, Type: kparams.TID, Value: uint32(3453)}, - kparams.BasePrio: {Name: kparams.BasePrio, Type: kparams.Uint8, Value: uint8(13)}, - kparams.StartAddress: {Name: kparams.StartAddress, Type: kparams.Address, Value: uint64(140729524944768)}, - kparams.IOPrio: {Name: kparams.IOPrio, Type: kparams.Uint8, Value: uint8(2)}, - kparams.KstackBase: {Name: kparams.KstackBase, Type: kparams.Address, Value: uint64(18446677035730165760)}, - kparams.KstackLimit: {Name: kparams.KstackLimit, Type: kparams.Address, Value: uint64(18446677035730137088)}, - kparams.PagePrio: {Name: kparams.PagePrio, Type: kparams.Uint8, Value: uint8(5)}, - kparams.UstackBase: {Name: kparams.UstackBase, Type: kparams.Address, Value: uint64(86376448)}, - kparams.UstackLimit: {Name: kparams.UstackLimit, Type: kparams.Address, Value: uint64(86372352)}, + tevt := &event.Event{ + Type: event.CreateThread, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ThreadID: {Name: params.ThreadID, Type: params.TID, Value: uint32(3453)}, + params.BasePrio: {Name: params.BasePrio, Type: params.Uint8, Value: uint8(13)}, + params.StartAddress: {Name: params.StartAddress, Type: params.Address, Value: uint64(140729524944768)}, + params.IOPrio: {Name: params.IOPrio, Type: params.Uint8, Value: uint8(2)}, + params.KstackBase: {Name: params.KstackBase, Type: params.Address, Value: uint64(18446677035730165760)}, + params.KstackLimit: {Name: params.KstackLimit, Type: params.Address, Value: uint64(18446677035730137088)}, + params.PagePrio: {Name: params.PagePrio, Type: params.Uint8, Value: uint8(5)}, + params.UstackBase: {Name: params.UstackBase, Type: params.Address, Value: uint64(86376448)}, + params.UstackLimit: {Name: params.UstackLimit, Type: params.Address, Value: uint64(86372352)}, }, } @@ -367,43 +366,43 @@ func TestAddModule(t *testing.T) { psnap := NewSnapshotter(hsnap, &config.Config{}) defer psnap.Close() - evt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `Spotify.exe`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + evt := &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `Spotify.exe`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, } require.NoError(t, psnap.Write(evt)) var tests = []struct { name string - evt *kevent.Kevent + evt *event.Event want bool }{ {"add module to existing process", - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, }, }, true, }, {"add module to absent process", - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid() + 1)}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid() + 1)}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, }, }, false, @@ -416,10 +415,10 @@ func TestAddModule(t *testing.T) { exists := tt.want require.NoError(t, psnap.AddModule(evt)) - ok, proc := psnap.Find(evt.Kparams.MustGetPid()) + ok, proc := psnap.Find(evt.Params.MustGetPid()) require.Equal(t, exists, ok) if ok { - require.NotNil(t, proc.FindModule(evt.GetParamAsString(kparams.ImagePath))) + require.NotNil(t, proc.FindModule(evt.GetParamAsString(params.ImagePath))) assert.Equal(t, "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe", proc.Exe) } }) @@ -432,28 +431,28 @@ func TestRemoveModule(t *testing.T) { psnap := NewSnapshotter(hsnap, &config.Config{}) defer psnap.Close() - pevt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + pevt := &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --parent`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, } require.NoError(t, psnap.Write(pevt)) - mevt := &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0xffff7656)}, + mevt := &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0xffff7656)}, }, } @@ -473,50 +472,50 @@ func TestOverrideProcExecutable(t *testing.T) { psnap := NewSnapshotter(hsnap, &config.Config{}) defer psnap.Close() - evt := &kevent.Kevent{ - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(os.Getppid())}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `Spotify.exe`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + evt := &event.Event{ + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(os.Getppid())}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `Spotify.exe`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, } require.NoError(t, psnap.Write(evt)) var tests = []struct { expectedExe string - evt *kevent.Kevent + evt *event.Event }{ {`Spotify.exe`, - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\assembly\\NativeImages_v4.0.30319_32\\Microsoft.Dee252aac#\\707569faabe821b47fa4f59ecd9eb6ea\\Microsoft.Developer.IdentityService.ni.exe"}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\assembly\\NativeImages_v4.0.30319_32\\Microsoft.Dee252aac#\\707569faabe821b47fa4f59ecd9eb6ea\\Microsoft.Developer.IdentityService.ni.exe"}, }, }, }, {`Spotify.exe`, - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\notepad.exe"}, }, }, }, {`C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe`, - &kevent.Kevent{ - Type: ktypes.LoadImage, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ImagePath: {Name: kparams.ImagePath, Type: kparams.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, + &event.Event{ + Type: event.LoadImage, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ImagePath: {Name: params.ImagePath, Type: params.UnicodeString, Value: "C:\\Users\\admin\\AppData\\Roaming\\Spotify\\Spotify.exe"}, }, }, }, @@ -548,33 +547,33 @@ func TestReapDeadProcesses(t *testing.T) { t.Fatal("unable to spawn notepad process") } - evts := []*kevent.Kevent{ + evts := []*event.Event{ { - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: notepadPID}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(8390)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "notepad.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `c:\\windows\\system32\\notepad.exe`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `c:\\windows\\system32\\notepad.exe`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: notepadPID}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(8390)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "notepad.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `c:\\windows\\system32\\notepad.exe`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `c:\\windows\\system32\\notepad.exe`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, }, { - Type: ktypes.CreateProcess, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(8390)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, - kparams.StartTime: {Name: kparams.StartTime, Type: kparams.Time, Value: time.Now()}, - kparams.SessionID: {Name: kparams.SessionID, Type: kparams.Uint32, Value: uint32(1)}, - kparams.ProcessFlags: {Name: kparams.ProcessFlags, Type: kparams.Flags, Value: uint32(0x00000010)}, + Type: event.CreateProcess, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(8390)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe`}, + params.UserSID: {Name: params.UserSID, Type: params.WbemSID, Value: []byte{224, 8, 226, 31, 15, 167, 255, 255, 0, 0, 0, 0, 15, 167, 255, 255, 1, 1, 0, 0, 0, 0, 0, 5, 18, 0, 0, 0}}, + params.StartTime: {Name: params.StartTime, Type: params.Time, Value: time.Now()}, + params.SessionID: {Name: params.SessionID, Type: params.Uint32, Value: uint32(1)}, + params.ProcessFlags: {Name: params.ProcessFlags, Type: params.Flags, Value: uint32(0x00000010)}, }, }, } diff --git a/pkg/ps/types/marshaller_windows.go b/pkg/ps/types/marshaller_windows.go index 2b3d1f41e..613107525 100644 --- a/pkg/ps/types/marshaller_windows.go +++ b/pkg/ps/types/marshaller_windows.go @@ -20,9 +20,9 @@ package types import ( "fmt" + "github.com/rabbitstack/fibratus/pkg/cap/section" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kcap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/rabbitstack/fibratus/pkg/util/bytes" "github.com/rabbitstack/fibratus/pkg/util/convert" @@ -74,7 +74,7 @@ func (ps *PS) Marshal() []byte { } // write handles - sec := section.New(section.Handle, kcapver.HandleSecV1, uint32(len(ps.Handles)), 0) + sec := section.New(section.Handle, capver.HandleSecV1, uint32(len(ps.Handles)), 0) b = append(b, sec[:]...) for _, handle := range ps.Handles { buf := handle.Marshal() @@ -85,11 +85,11 @@ func (ps *PS) Marshal() []byte { // write the PE metadata if ps.PE != nil { buf := ps.PE.Marshal() - sec := section.New(section.PE, kcapver.PESecV2, 0, uint32(len(buf))) + sec := section.New(section.PE, capver.PESecV2, 0, uint32(len(buf))) b = append(b, sec[:]...) b = append(b, buf...) } else { - sec := section.New(section.PE, kcapver.PESecV2, 0, 0) + sec := section.New(section.PE, capver.PESecV2, 0, 0) b = append(b, sec[:]...) } @@ -174,7 +174,7 @@ func (ps *PS) Unmarshal(b []byte, psec section.Section) error { offset += uint32(aoffset) idx := uint32(20) // read session ID - if psec.Version() >= kcapver.ProcessSecV3 { + if psec.Version() >= capver.ProcessSecV3 { // session identifier was changed from uint8 to uint32 ps.SessionID = bytes.ReadUint32(b[idx+offset:]) idx += 4 @@ -226,7 +226,7 @@ readpe: sec = section.Read(b[idx+offset:]) idx += 10 if sec.Size() == 0 { - if psec.Version() >= kcapver.ProcessSecV2 { + if psec.Version() >= capver.ProcessSecV2 { // read start time l := uint32(bytes.ReadUint16(b[idx+offset:])) idx += 2 @@ -243,7 +243,7 @@ readpe: // read UUID ps.uuid = bytes.ReadUint64(b[idx+offset:]) } - if psec.Version() >= kcapver.ProcessSecV3 { + if psec.Version() >= capver.ProcessSecV3 { idx += 8 // read username l := bytes.ReadUint16(b[idx+offset:]) @@ -259,7 +259,7 @@ readpe: offset += uint32(l) ps.Domain = string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l]) } - if psec.Version() >= kcapver.ProcessSecV4 { + if psec.Version() >= capver.ProcessSecV4 { // process flags ps.IsWOW64 = convert.Itob(b[idx+offset]) idx++ @@ -278,7 +278,7 @@ readpe: } offset += sec.Size() - if psec.Version() >= kcapver.ProcessSecV2 { + if psec.Version() >= capver.ProcessSecV2 { // read start time l := uint32(bytes.ReadUint16(b[idx+offset:])) idx += 2 @@ -290,7 +290,7 @@ readpe: // read UUID ps.uuid = bytes.ReadUint64(b[idx+offset:]) } - if psec.Version() >= kcapver.ProcessSecV3 { + if psec.Version() >= capver.ProcessSecV3 { idx += 8 // read username l := bytes.ReadUint16(b[idx+offset:]) @@ -306,7 +306,7 @@ readpe: offset += uint32(l) ps.Domain = string((*[1<<30 - 1]byte)(unsafe.Pointer(&buf[0]))[:l:l]) } - if psec.Version() >= kcapver.ProcessSecV4 { + if psec.Version() >= capver.ProcessSecV4 { // process flags ps.IsWOW64 = convert.Itob(b[idx+offset]) idx++ diff --git a/pkg/ps/types/marshaller_windows_test.go b/pkg/ps/types/marshaller_windows_test.go index e039ae7ca..83f279ebd 100644 --- a/pkg/ps/types/marshaller_windows_test.go +++ b/pkg/ps/types/marshaller_windows_test.go @@ -22,8 +22,8 @@ import ( htypes "github.com/rabbitstack/fibratus/pkg/handle/types" "golang.org/x/sys/windows" - "github.com/rabbitstack/fibratus/pkg/kcap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/kcap/version" + "github.com/rabbitstack/fibratus/pkg/cap/section" + kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/stretchr/testify/assert" diff --git a/pkg/ps/types/types_windows.go b/pkg/ps/types/types_windows.go index 02a0ff29e..e837646fc 100644 --- a/pkg/ps/types/types_windows.go +++ b/pkg/ps/types/types_windows.go @@ -29,8 +29,8 @@ import ( "strings" "sync" + "github.com/rabbitstack/fibratus/pkg/cap/section" htypes "github.com/rabbitstack/fibratus/pkg/handle/types" - "github.com/rabbitstack/fibratus/pkg/kcap/section" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/rabbitstack/fibratus/pkg/util/bootid" diff --git a/pkg/rules/_fixtures/default/microsoft_edge.yml b/pkg/rules/_fixtures/default/microsoft_edge.yml index 796424149..d349eb7cf 100644 --- a/pkg/rules/_fixtures/default/microsoft_edge.yml +++ b/pkg/rules/_fixtures/default/microsoft_edge.yml @@ -1,5 +1,5 @@ name: Microsoft edge id: c3a50242-7161-43d5-a198-051021056195 version: 1.0.0 -condition: kevt.name = 'CreateProcess' and ps.comm startswith '\"C:\\Program Files (x86)\\Microsoft\\Edge Dev\\Application\\msedge.exe\" --type=' +condition: evt.name = 'CreateProcess' and ps.comm startswith '\"C:\\Program Files (x86)\\Microsoft\\Edge Dev\\Application\\msedge.exe\" --type=' min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/default/sequence_rule_simple.yml b/pkg/rules/_fixtures/default/sequence_rule_simple.yml index f3db5a11d..b157f594f 100644 --- a/pkg/rules/_fixtures/default/sequence_rule_simple.yml +++ b/pkg/rules/_fixtures/default/sequence_rule_simple.yml @@ -4,8 +4,8 @@ version: 1.0.0 condition: > sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe - |kevt.name = 'CreateFile' + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe + |evt.name = 'CreateFile' and file.path icontains 'temp' | by file.path diff --git a/pkg/rules/_fixtures/default/suspicious_domains.yml b/pkg/rules/_fixtures/default/suspicious_domains.yml index fbe32d9e5..31216a994 100644 --- a/pkg/rules/_fixtures/default/suspicious_domains.yml +++ b/pkg/rules/_fixtures/default/suspicious_domains.yml @@ -1,5 +1,5 @@ name: Suspicious domains id: c4cd547f-d64a-4452-abe8-846410617c06 version: 1.0.0 -condition: kevt.name = 'QueryDns' and dns.name = 'fishy.domain.dot' +condition: evt.name = 'QueryDns' and dns.name = 'fishy.domain.dot' min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/default/suspicious_module_loaded.yml b/pkg/rules/_fixtures/default/suspicious_module_loaded.yml index 483294c47..28889e204 100644 --- a/pkg/rules/_fixtures/default/suspicious_module_loaded.yml +++ b/pkg/rules/_fixtures/default/suspicious_module_loaded.yml @@ -1,5 +1,5 @@ name: Loaded suspicious module id: 1e4c3fbf-ed3a-4df4-9c54-8693d7397a75 version: 1.0.0 -condition: kevt.name = 'LoadImage' and image.name = 'svchost.dll' +condition: evt.name = 'LoadImage' and image.name = 'svchost.dll' min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/default/suspicious_network_connecting_binaries.yml b/pkg/rules/_fixtures/default/suspicious_network_connecting_binaries.yml index cddaf9d78..e209515a9 100644 --- a/pkg/rules/_fixtures/default/suspicious_network_connecting_binaries.yml +++ b/pkg/rules/_fixtures/default/suspicious_network_connecting_binaries.yml @@ -1,7 +1,7 @@ name: Suspicious sources for network-connecting binaries id: 0a8c6a06-eaf2-48c1-9b05-d0e706142311 version: 1.0.0 -condition: kevt.name = 'Connect' and ps.exe startswith +condition: evt.name = 'Connect' and ps.exe startswith ( 'C:\\Users', 'C:\\Recycle', diff --git a/pkg/rules/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml b/pkg/rules/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml index c6f5a1aca..f6455eb7f 100644 --- a/pkg/rules/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml +++ b/pkg/rules/_fixtures/default/windows_error_reporting_and_wmi_provider_host.yml @@ -1,7 +1,7 @@ name: Windows error reporting/telemetry, WMI provider host id: 0fe67e44-94e2-44cb-bc40-052bc2e0fdb2 version: 1.0.0 -condition: kevt.name = 'CreateProcess' and ps.comm startswith +condition: evt.name = 'CreateProcess' and ps.comm startswith ( ' \"C:\\Windows\\system32\\wermgr.exe\\" \"-queuereporting_svc\" ', 'C:\\Windows\\system32\\DllHost.exe /Processid', diff --git a/pkg/rules/_fixtures/kill_action.yml b/pkg/rules/_fixtures/kill_action.yml index 1c43a9f6c..a00879d0e 100644 --- a/pkg/rules/_fixtures/kill_action.yml +++ b/pkg/rules/_fixtures/kill_action.yml @@ -1,7 +1,7 @@ name: Kill calc.exe process id: 172902be-76e9-4ee7-a48a-6275fa571cf4 version: 1.0.0 -condition: kevt.name = 'CreateProcess' and ps.child.name = 'calc.exe' +condition: evt.name = 'CreateProcess' and ps.child.name = 'calc.exe' severity: critical action: - name: kill diff --git a/pkg/rules/_fixtures/merged_filters/filter1.yml b/pkg/rules/_fixtures/merged_filters/filter1.yml index 14aec5214..113d9daf0 100644 --- a/pkg/rules/_fixtures/merged_filters/filter1.yml +++ b/pkg/rules/_fixtures/merged_filters/filter1.yml @@ -1,6 +1,6 @@ name: match https connections id: 8f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/merged_filters/filter2.yml b/pkg/rules/_fixtures/merged_filters/filter2.yml index 0b3ebba28..3c404521d 100644 --- a/pkg/rules/_fixtures/merged_filters/filter2.yml +++ b/pkg/rules/_fixtures/merged_filters/filter2.yml @@ -1,5 +1,5 @@ name: match http connections id: 7f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 80 +condition: evt.name = 'Recv' and net.dport = 80 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/merged_filters/filter3.yml b/pkg/rules/_fixtures/merged_filters/filter3.yml index ed558f844..66ac3f5e1 100644 --- a/pkg/rules/_fixtures/merged_filters/filter3.yml +++ b/pkg/rules/_fixtures/merged_filters/filter3.yml @@ -1,5 +1,5 @@ name: match http connections id: 6f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.category = 'net' and net.dport = 80 +condition: evt.category = 'net' and net.dport = 80 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/merged_filters/filter4.yml b/pkg/rules/_fixtures/merged_filters/filter4.yml index 943275933..faf8f70e4 100644 --- a/pkg/rules/_fixtures/merged_filters/filter4.yml +++ b/pkg/rules/_fixtures/merged_filters/filter4.yml @@ -1,5 +1,5 @@ name: match ssh connections id: 5f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 22 +condition: evt.name = 'Recv' and net.dport = 22 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/min_engine_version/fail/filter1.yml b/pkg/rules/_fixtures/min_engine_version/fail/filter1.yml index d8b78abb8..28a3af442 100644 --- a/pkg/rules/_fixtures/min_engine_version/fail/filter1.yml +++ b/pkg/rules/_fixtures/min_engine_version/fail/filter1.yml @@ -1,5 +1,5 @@ name: match https connections id: 1f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 min-engine-version: 1.0.0 diff --git a/pkg/rules/_fixtures/min_engine_version/fail/filter2.yml b/pkg/rules/_fixtures/min_engine_version/fail/filter2.yml index 565424e0f..525469324 100644 --- a/pkg/rules/_fixtures/min_engine_version/fail/filter2.yml +++ b/pkg/rules/_fixtures/min_engine_version/fail/filter2.yml @@ -1,5 +1,5 @@ name: accept events where source port = 44123 id: 2f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sport = 44123 +condition: evt.name = 'Recv' and net.sport = 44123 min-engine-version: 2.2.0 diff --git a/pkg/rules/_fixtures/min_engine_version/fail/filter3.yml b/pkg/rules/_fixtures/min_engine_version/fail/filter3.yml index ace3c32f5..66f649fac 100644 --- a/pkg/rules/_fixtures/min_engine_version/fail/filter3.yml +++ b/pkg/rules/_fixtures/min_engine_version/fail/filter3.yml @@ -1,5 +1,5 @@ name: src ip address is not a loopback address id: 3f36f8e0-a5c2-498f-9563-eea306daa586 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sip != 127.0.0.1 +condition: evt.name = 'Recv' and net.sip != 127.0.0.1 min-engine-version: 1.5.0 diff --git a/pkg/rules/_fixtures/min_engine_version/ok/filter1.yml b/pkg/rules/_fixtures/min_engine_version/ok/filter1.yml index 88a006c7d..9797acb26 100644 --- a/pkg/rules/_fixtures/min_engine_version/ok/filter1.yml +++ b/pkg/rules/_fixtures/min_engine_version/ok/filter1.yml @@ -1,5 +1,5 @@ name: match https connections id: a155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/min_engine_version/ok/filter2.yml b/pkg/rules/_fixtures/min_engine_version/ok/filter2.yml index 2b6790f6e..3f8ca4f2e 100644 --- a/pkg/rules/_fixtures/min_engine_version/ok/filter2.yml +++ b/pkg/rules/_fixtures/min_engine_version/ok/filter2.yml @@ -1,5 +1,5 @@ name: accept events where source port = 44123 id: 1155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sport = 44123 +condition: evt.name = 'Recv' and net.sport = 44123 min-engine-version: 1.8.0 diff --git a/pkg/rules/_fixtures/min_engine_version/ok/filter3.yml b/pkg/rules/_fixtures/min_engine_version/ok/filter3.yml index 560c58902..377483de0 100644 --- a/pkg/rules/_fixtures/min_engine_version/ok/filter3.yml +++ b/pkg/rules/_fixtures/min_engine_version/ok/filter3.yml @@ -1,5 +1,5 @@ name: src ip address is not a loopback address id: 2155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sip != 127.0.0.1 +condition: evt.name = 'Recv' and net.sip != 127.0.0.1 min-engine-version: 1.5.0 diff --git a/pkg/rules/_fixtures/sequence_rule_complex.yml b/pkg/rules/_fixtures/sequence_rule_complex.yml index 0939e0d3e..1a3dad8c2 100644 --- a/pkg/rules/_fixtures/sequence_rule_complex.yml +++ b/pkg/rules/_fixtures/sequence_rule_complex.yml @@ -4,17 +4,17 @@ version: 1.0.0 condition: > sequence maxspan 1h - |kevt.name = 'CreateProcess' and ps.sibling.name + |evt.name = 'CreateProcess' and ps.sibling.name in ('firefox.exe', 'chrome.exe', 'edge.exe') | by ps.sibling.pid - |kevt.name = 'CreateFile' and file.operation = 'CREATE' + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.exe' | by ps.pid | - kevt.name in ('Send', 'Connect') + evt.name in ('Send', 'Connect') | by ps.pid output: "%2.ps.name process initiated outbound communication to %3.net.dip" min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/sequence_rule_ps_uuid.yml b/pkg/rules/_fixtures/sequence_rule_ps_uuid.yml index 6b5c8b823..f1fb655d0 100644 --- a/pkg/rules/_fixtures/sequence_rule_ps_uuid.yml +++ b/pkg/rules/_fixtures/sequence_rule_ps_uuid.yml @@ -5,11 +5,11 @@ condition: > sequence maxspan 1h by ps.uuid - |kevt.name = 'CreateProcess' and ps.child.name + |evt.name = 'CreateProcess' and ps.child.name in ('firefox.exe', 'chrome.exe', 'edge.exe') | - |kevt.name = 'CreateFile' and file.operation = 'CREATE' + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.exe' | diff --git a/pkg/rules/_fixtures/simple_and_sequence_rules/command_shell_spawned_chrome_browser.yml b/pkg/rules/_fixtures/simple_and_sequence_rules/command_shell_spawned_chrome_browser.yml index e32402167..45a501e88 100644 --- a/pkg/rules/_fixtures/simple_and_sequence_rules/command_shell_spawned_chrome_browser.yml +++ b/pkg/rules/_fixtures/simple_and_sequence_rules/command_shell_spawned_chrome_browser.yml @@ -3,6 +3,6 @@ id: 2155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 condition: > sequence maxspan 1s - |kevt.name = 'CreateProcess' and ps.name = 'powershell.exe'| by ps.pid - |kevt.name = 'CreateProcess' and ps.sibling.name = 'chrome.exe'| by ps.pid + |evt.name = 'CreateProcess' and ps.name = 'powershell.exe'| by ps.pid + |evt.name = 'CreateProcess' and ps.sibling.name = 'chrome.exe'| by ps.pid min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml b/pkg/rules/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml index 36a906513..375e8105b 100644 --- a/pkg/rules/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml +++ b/pkg/rules/_fixtures/simple_and_sequence_rules/powershell_created_temp_file.yml @@ -4,8 +4,8 @@ version: 1.0.0 condition: > sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'powershell.exe'| by ps.pid - |kevt.name = 'CreateFile' + |evt.name = 'CreateProcess' and ps.name = 'powershell.exe'| by ps.pid + |evt.name = 'CreateFile' and file.path icontains 'temp' | by ps.pid diff --git a/pkg/rules/_fixtures/simple_and_sequence_rules/process_spawned_by_powershell.yml b/pkg/rules/_fixtures/simple_and_sequence_rules/process_spawned_by_powershell.yml index e3f9a64da..2ded698bd 100644 --- a/pkg/rules/_fixtures/simple_and_sequence_rules/process_spawned_by_powershell.yml +++ b/pkg/rules/_fixtures/simple_and_sequence_rules/process_spawned_by_powershell.yml @@ -2,5 +2,5 @@ name: Process spawned by powershell id: 4155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 condition: > - kevt.name = 'CreateProcess' and ps.name = 'powershell.exe' + evt.name = 'CreateProcess' and ps.name = 'powershell.exe' min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_and_sequence_rules/spawn_chrome_browser.yml b/pkg/rules/_fixtures/simple_and_sequence_rules/spawn_chrome_browser.yml index fcf76d31d..02a91e9ee 100644 --- a/pkg/rules/_fixtures/simple_and_sequence_rules/spawn_chrome_browser.yml +++ b/pkg/rules/_fixtures/simple_and_sequence_rules/spawn_chrome_browser.yml @@ -2,5 +2,5 @@ name: Spawn Chrome browser id: 5155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 condition: > - kevt.name = 'CreateProcess' and ps.sibling.name = 'chrome.exe' + evt.name = 'CreateProcess' and ps.sibling.name = 'chrome.exe' min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_emit_alert.yml b/pkg/rules/_fixtures/simple_emit_alert.yml index 4adf619e2..d5c9703fe 100644 --- a/pkg/rules/_fixtures/simple_emit_alert.yml +++ b/pkg/rules/_fixtures/simple_emit_alert.yml @@ -1,7 +1,7 @@ name: match https connections id: 50ffc2a8-0bde-45c4-9e20-46158250fa91 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 output: "%ps.name process received data on port %net.dport" severity: critical min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_matches.yml b/pkg/rules/_fixtures/simple_matches.yml index 0e40c4985..6892acb3d 100644 --- a/pkg/rules/_fixtures/simple_matches.yml +++ b/pkg/rules/_fixtures/simple_matches.yml @@ -1,5 +1,5 @@ name: match https connections id: 60ffc2a8-0bde-45c4-9e20-46158250fa91 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_matches/filter1.yml b/pkg/rules/_fixtures/simple_matches/filter1.yml index 5d195efa9..a381967f3 100644 --- a/pkg/rules/_fixtures/simple_matches/filter1.yml +++ b/pkg/rules/_fixtures/simple_matches/filter1.yml @@ -1,5 +1,5 @@ name: match https connections id: 5155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.dport = 443 +condition: evt.name = 'Recv' and net.dport = 443 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_matches/filter2.yml b/pkg/rules/_fixtures/simple_matches/filter2.yml index 67e23d7ee..aff9bda65 100644 --- a/pkg/rules/_fixtures/simple_matches/filter2.yml +++ b/pkg/rules/_fixtures/simple_matches/filter2.yml @@ -1,5 +1,5 @@ name: accept events where source port = 44123 id: 6155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sport = 44123 +condition: evt.name = 'Recv' and net.sport = 44123 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_matches/filter3.yml b/pkg/rules/_fixtures/simple_matches/filter3.yml index 08602edef..b98789fd6 100644 --- a/pkg/rules/_fixtures/simple_matches/filter3.yml +++ b/pkg/rules/_fixtures/simple_matches/filter3.yml @@ -1,5 +1,5 @@ name: src ip address is not a loopback address id: 7155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sip != 127.0.0.1 +condition: evt.name = 'Recv' and net.sip != 127.0.0.1 min-engine-version: 2.0.0 diff --git a/pkg/rules/_fixtures/simple_matches/filter4.yml b/pkg/rules/_fixtures/simple_matches/filter4.yml index 18466d252..3db0742f2 100644 --- a/pkg/rules/_fixtures/simple_matches/filter4.yml +++ b/pkg/rules/_fixtures/simple_matches/filter4.yml @@ -1,5 +1,5 @@ name: src ip address is id: 8155539d-31bd-429e-81f9-c17ee1c01f93 version: 1.0.0 -condition: kevt.name = 'Recv' and net.sip = 172.0.0.1 +condition: evt.name = 'Recv' and net.sip = 172.0.0.1 min-engine-version: 2.0.0 diff --git a/pkg/rules/compiler.go b/pkg/rules/compiler.go index 35b8919f6..7016341e5 100644 --- a/pkg/rules/compiler.go +++ b/pkg/rules/compiler.go @@ -23,9 +23,9 @@ import ( "fmt" semver "github.com/hashicorp/go-version" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/version" log "github.com/sirupsen/logrus" @@ -114,44 +114,44 @@ func (c *compiler) compile() (map[*config.FilterConfig]filter.Filter, *config.Ru func (c *compiler) buildCompileResult(filters map[*config.FilterConfig]filter.Filter) *config.RulesCompileResult { rs := &config.RulesCompileResult{} - m := make(map[ktypes.Ktype]bool) - events := make([]ktypes.Ktype, 0) + m := make(map[event.Type]bool) + events := make([]event.Type, 0) for _, f := range filters { rs.NumberRules++ for name, values := range f.GetStringFields() { for _, v := range values { if name == fields.KevtName || name == fields.KevtCategory { - types := ktypes.KeventNameToKtypes(v) + types := event.NameToTypes(v) for _, typ := range types { switch typ.Category() { - case ktypes.Process: + case event.Process: rs.HasProcEvents = true - case ktypes.Thread: + case event.Thread: rs.HasThreadEvents = true - case ktypes.Image: + case event.Image: rs.HasImageEvents = true - case ktypes.File: + case event.File: rs.HasFileEvents = true - case ktypes.Net: + case event.Net: rs.HasNetworkEvents = true - case ktypes.Registry: + case event.Registry: rs.HasRegistryEvents = true - case ktypes.Mem: + case event.Mem: rs.HasMemEvents = true - case ktypes.Handle: + case event.Handle: rs.HasHandleEvents = true - case ktypes.Threadpool: + case event.Threadpool: rs.HasThreadpoolEvents = true } - if typ.Subcategory() == ktypes.DNS { + if typ.Subcategory() == event.DNS { rs.HasDNSEvents = true } - if typ == ktypes.MapViewFile || typ == ktypes.UnmapViewFile { + if typ == event.MapViewFile || typ == event.UnmapViewFile { rs.HasVAMapEvents = true } - if typ == ktypes.OpenProcess || typ == ktypes.OpenThread || typ == ktypes.SetThreadContext || - typ == ktypes.CreateSymbolicLinkObject { + if typ == event.OpenProcess || typ == event.OpenThread || typ == event.SetThreadContext || + typ == event.CreateSymbolicLinkObject { rs.HasAuditAPIEvents = true } diff --git a/pkg/rules/compiler_test.go b/pkg/rules/compiler_test.go index f093713fd..2bc6ac531 100644 --- a/pkg/rules/compiler_test.go +++ b/pkg/rules/compiler_test.go @@ -19,7 +19,7 @@ package rules import ( - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/version" "github.com/stretchr/testify/assert" @@ -39,11 +39,11 @@ func TestCompile(t *testing.T) { assert.False(t, rs.HasMemEvents) assert.False(t, rs.HasAuditAPIEvents) assert.True(t, rs.HasDNSEvents) - assert.Contains(t, rs.UsedEvents, ktypes.CreateProcess) - assert.Contains(t, rs.UsedEvents, ktypes.LoadImage) - assert.Contains(t, rs.UsedEvents, ktypes.QueryDNS) - assert.Contains(t, rs.UsedEvents, ktypes.ConnectTCPv4) - assert.Contains(t, rs.UsedEvents, ktypes.ConnectTCPv6) + assert.Contains(t, rs.UsedEvents, event.CreateProcess) + assert.Contains(t, rs.UsedEvents, event.LoadImage) + assert.Contains(t, rs.UsedEvents, event.QueryDNS) + assert.Contains(t, rs.UsedEvents, event.ConnectTCPv4) + assert.Contains(t, rs.UsedEvents, event.ConnectTCPv6) } func TestCompileMinEngineVersion(t *testing.T) { diff --git a/pkg/rules/engine.go b/pkg/rules/engine.go index b73fcff2a..2cd74569e 100644 --- a/pkg/rules/engine.go +++ b/pkg/rules/engine.go @@ -22,10 +22,9 @@ import ( "expvar" "fmt" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/filter/fields" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/rules/action" "github.com/rabbitstack/fibratus/pkg/util/hashers" @@ -37,7 +36,7 @@ import ( // RuleMatchFunc is rule match function definition. It accepts // the filter (rule) config and the group of events that fired // the rule -type RuleMatchFunc func(f *config.FilterConfig, evts ...*kevent.Kevent) +type RuleMatchFunc func(f *config.FilterConfig, evts ...*event.Event) var ( // sequenceGcInterval determines how often sequence GC kicks in @@ -78,28 +77,28 @@ type ruleMatch struct { // hashCache caches the event type/category FNV hashes type hashCache struct { mu sync.RWMutex - types map[ktypes.Ktype]uint32 - cats map[ktypes.Category]uint32 + types map[event.Type]uint32 + cats map[event.Category]uint32 lookupCategory bool } func newHashCache() *hashCache { - return &hashCache{types: make(map[ktypes.Ktype]uint32), cats: make(map[ktypes.Category]uint32)} + return &hashCache{types: make(map[event.Type]uint32), cats: make(map[event.Category]uint32)} } -func (c *hashCache) typeHash(e *kevent.Kevent) uint32 { +func (c *hashCache) typeHash(e *event.Event) uint32 { c.mu.RLock() defer c.mu.RUnlock() return c.types[e.Type] } -func (c *hashCache) categoryHash(e *kevent.Kevent) uint32 { +func (c *hashCache) categoryHash(e *event.Event) uint32 { c.mu.RLock() defer c.mu.RUnlock() return c.cats[e.Category] } -func (c *hashCache) addTypeHash(e *kevent.Kevent) uint32 { +func (c *hashCache) addTypeHash(e *event.Event) uint32 { c.mu.Lock() defer c.mu.Unlock() h := e.Type.Hash() @@ -107,7 +106,7 @@ func (c *hashCache) addTypeHash(e *kevent.Kevent) uint32 { return h } -func (c *hashCache) addCategoryHash(e *kevent.Kevent) uint32 { +func (c *hashCache) addCategoryHash(e *event.Event) uint32 { c.mu.Lock() defer c.mu.Unlock() h := e.Category.Hash() @@ -127,7 +126,7 @@ type compiledFilters map[uint32][]*compiledFilter // particular event type or category. If no filters // are found, the event is not asserted against the // ruleset. -func (filters compiledFilters) collect(hashCache *hashCache, e *kevent.Kevent) []*compiledFilter { +func (filters compiledFilters) collect(hashCache *hashCache, e *event.Event) []*compiledFilter { h := hashCache.typeHash(e) if h == 0 { h = hashCache.addTypeHash(e) @@ -163,7 +162,7 @@ func (f *compiledFilter) isSequence() bool { return f.ss != nil } -func (f *compiledFilter) run(e *kevent.Kevent) bool { +func (f *compiledFilter) run(e *event.Event) bool { if f.ss != nil { return f.ss.runSequence(e) } @@ -223,8 +222,8 @@ func (e *Engine) Compile() (*config.RulesCompileResult, error) { "event type or event category condition! "+ "This rule is being discarded by "+ "the engine. Please consider narrowing the "+ - "scope of the rule by including the `kevt.name` "+ - "or `kevt.category` condition", + "scope of the rule by including the `evt.name` "+ + "or `evt.category` condition", c.Name) continue } @@ -258,7 +257,7 @@ func (*Engine) CanEnqueue() bool { return true } // Filter is the internal lingo that designates a rule condition. // Filters can be simple direct-event matchers or sequence states that // track an ordered series of events over a short period of time. -func (e *Engine) ProcessEvent(evt *kevent.Kevent) (bool, error) { +func (e *Engine) ProcessEvent(evt *event.Event) (bool, error) { if len(e.filters) == 0 { return true, nil } @@ -342,11 +341,11 @@ func (e *Engine) processActions() error { return nil } -func (e *Engine) appendMatch(f *config.FilterConfig, evts ...*kevent.Kevent) { +func (e *Engine) appendMatch(f *config.FilterConfig, evts ...*event.Event) { for _, evt := range evts { - evt.AddMeta(kevent.RuleNameKey, f.Name) + evt.AddMeta(event.RuleNameKey, f.Name) for k, v := range f.Labels { - evt.AddMeta(kevent.MetadataKey(k), v) + evt.AddMeta(event.MetadataKey(k), v) } } ctx := &config.ActionContext{ diff --git a/pkg/rules/engine_test.go b/pkg/rules/engine_test.go index 37782053a..7c70f3a4e 100644 --- a/pkg/rules/engine_test.go +++ b/pkg/rules/engine_test.go @@ -21,10 +21,9 @@ package rules import ( "github.com/rabbitstack/fibratus/pkg/alertsender" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/sys" @@ -107,7 +106,7 @@ func compileRules(t *testing.T, e *Engine) { require.NotNil(t, rs) } -func wrapProcessEvent(e *kevent.Kevent, fn func(*kevent.Kevent) (bool, error)) bool { +func wrapProcessEvent(e *event.Event, fn func(*event.Event) (bool, error)) bool { match, err := fn(e) if err != nil { panic(err) @@ -117,19 +116,19 @@ func wrapProcessEvent(e *kevent.Kevent, fn func(*kevent.Kevent) (bool, error)) b func fireRules(t *testing.T, c *config.Config) bool { e := NewEngine(new(ps.SnapshotterMock), c) - evt := &kevent.Kevent{ - Type: ktypes.RecvTCPv4, + evt := &event.Event{ + Type: event.RecvTCPv4, Name: "Recv", Tid: 2484, PID: 859, - Category: ktypes.Net, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Category: event.Net, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), } compileRules(t, e) return wrapProcessEvent(evt, e.ProcessEvent) @@ -146,14 +145,14 @@ func TestCompileIndexableFilters(t *testing.T) { assert.Len(t, e.filters, 3) var tests = []struct { - evt *kevent.Kevent + evt *event.Event wants int }{ - {&kevent.Kevent{Type: ktypes.CreateProcess}, 2}, - {&kevent.Kevent{Type: ktypes.RecvUDPv6}, 3}, - {&kevent.Kevent{Type: ktypes.RecvTCPv4}, 3}, - {&kevent.Kevent{Type: ktypes.RecvTCPv4, Category: ktypes.Net}, 4}, - {&kevent.Kevent{Category: ktypes.Net}, 1}, + {&event.Event{Type: event.CreateProcess}, 2}, + {&event.Event{Type: event.RecvUDPv6}, 3}, + {&event.Event{Type: event.RecvTCPv4}, 3}, + {&event.Event{Type: event.RecvTCPv4, Category: event.Net}, 4}, + {&event.Event{Category: event.Net}, 1}, } for _, tt := range tests { @@ -164,7 +163,7 @@ func TestCompileIndexableFilters(t *testing.T) { assert.Len(t, e.hashCache.types, 4) - evt := &kevent.Kevent{Type: ktypes.RecvTCPv4} + evt := &event.Event{Type: event.RecvTCPv4} h1, h2 := e.hashCache.typeHash(evt), e.hashCache.categoryHash(evt) assert.Equal(t, uint32(0xfa4dab59), h1) @@ -194,11 +193,11 @@ func TestRunSequenceRule(t *testing.T) { e := NewEngine(new(ps.SnapshotterMock), newConfig("_fixtures/sequence_rule_complex.yml")) compileRules(t, e) - e1 := &kevent.Kevent{ + e1 := &event.Event{ Seq: 1, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 859, @@ -206,38 +205,38 @@ func TestRunSequenceRule(t *testing.T) { Name: "explorer.exe", Exe: "C:\\Windows\\system32\\explorer.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "firefox.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "firefox.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ + e2 := &event.Event{ Seq: 2, - Type: ktypes.CreateFile, + Type: event.CreateFile, Timestamp: time.Now().Add(time.Millisecond * 250), Name: "CreateFile", Tid: 2484, PID: 2243, - Category: ktypes.File, + Category: event.File, PS: &types.PS{ Name: "firefox.exe", Exe: "C:\\Program Files\\Mozilla Firefox\\firefox.exe", Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e3 := &kevent.Kevent{ + e3 := &event.Event{ Seq: 4, - Type: ktypes.ConnectTCPv4, + Type: event.ConnectTCPv4, Timestamp: time.Now().Add(time.Second), - Category: ktypes.Net, + Category: event.Net, Name: "Connect", Tid: 244, PID: 2243, @@ -246,10 +245,10 @@ func TestRunSequenceRule(t *testing.T) { Exe: "C:\\Program Files\\Mozilla Firefox\\firefox.exe", Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, - Kparams: kevent.Kparams{ - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("10.0.2.3")}, + Params: event.Params{ + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("10.0.2.3")}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } // register alert sender @@ -284,11 +283,11 @@ func TestRunSequenceRuleWithPsUUIDLink(t *testing.T) { e := NewEngine(new(ps.SnapshotterMock), newConfig("_fixtures/sequence_rule_ps_uuid.yml")) compileRules(t, e) - e1 := &kevent.Kevent{ + e1 := &event.Event{ Seq: 1, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: uint32(os.Getpid()), @@ -297,32 +296,32 @@ func TestRunSequenceRuleWithPsUUIDLink(t *testing.T) { Name: "explorer.exe", Exe: "C:\\Windows\\system32\\explorer.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "firefox.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "firefox.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ + e2 := &event.Event{ Seq: 2, - Type: ktypes.CreateFile, + Type: event.CreateFile, Timestamp: time.Now(), Name: "CreateFile", Tid: 2484, PID: uint32(os.Getpid()), - Category: ktypes.File, + Category: event.File, PS: &types.PS{ PID: uint32(os.Getpid()), Name: "firefox.exe", Exe: "C:\\Program Files\\Mozilla Firefox\\firefox.exe", Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, wrapProcessEvent(e1, e.ProcessEvent)) @@ -336,7 +335,7 @@ func TestRunSimpleAndSequenceRules(t *testing.T) { c := newConfig("_fixtures/simple_and_sequence_rules/*.yml") c.Filters.MatchAll = true e := NewEngine(new(ps.SnapshotterMock), c) - e.RegisterMatchFunc(func(f *config.FilterConfig, evts ...*kevent.Kevent) { + e.RegisterMatchFunc(func(f *config.FilterConfig, evts ...*event.Event) { ids := make([]uint64, 0) for _, evt := range evts { ids = append(ids, evt.Seq) @@ -346,12 +345,12 @@ func TestRunSimpleAndSequenceRules(t *testing.T) { compileRules(t, e) - evts := []*kevent.Kevent{ + evts := []*event.Event{ { Seq: 1, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 2243, @@ -359,35 +358,35 @@ func TestRunSimpleAndSequenceRules(t *testing.T) { Name: "powershell.exe", Exe: "C:\\Windows\\system32\\powershell.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "firefox.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "firefox.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { Seq: 2, - Type: ktypes.CreateFile, + Type: event.CreateFile, Timestamp: time.Now().Add(time.Millisecond * 544), Name: "CreateFile", Tid: 2484, PID: 2243, - Category: ktypes.File, + Category: event.File, PS: &types.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(2)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { Seq: 10, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now().Add(time.Second * 2), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 2243, @@ -395,11 +394,11 @@ func TestRunSimpleAndSequenceRules(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "chrome.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "chrome.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, } @@ -431,22 +430,22 @@ func TestAlertAction(t *testing.T) { e := NewEngine(new(ps.SnapshotterMock), newConfig("_fixtures/simple_emit_alert.yml")) compileRules(t, e) - evt := &kevent.Kevent{ - Type: ktypes.RecvTCPv4, + evt := &event.Event{ + Type: event.RecvTCPv4, Name: "Recv", Tid: 2484, PID: 859, - Category: ktypes.Net, + Category: event.Net, PS: &types.PS{ Name: "cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), } require.True(t, wrapProcessEvent(evt, e.ProcessEvent)) @@ -491,22 +490,22 @@ func TestKillAction(t *testing.T) { time.Sleep(time.Millisecond * 100 * time.Duration(i)) } - evt := &kevent.Kevent{ - Type: ktypes.CreateProcess, + evt := &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now(), Name: "CreateProcess", Tid: 2484, PID: 859, - Category: ktypes.Process, + Category: event.Process, PS: &types.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost-temp.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pi.ProcessId}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "calc.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pi.ProcessId}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "calc.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.True(t, sys.IsProcessRunning(pi.Process)) @@ -523,56 +522,56 @@ func BenchmarkRunRules(b *testing.B) { b.ResetTimer() - evts := []*kevent.Kevent{ + evts := []*event.Event{ { - Type: ktypes.ConnectTCPv4, + Type: event.ConnectTCPv4, Name: "Recv", Tid: 2484, PID: 859, - Category: ktypes.Net, + Category: event.Net, PS: &types.PS{ Name: "cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(443)}, - kparams.NetSport: {Name: kparams.NetSport, Type: kparams.Uint16, Value: uint16(43123)}, - kparams.NetSIP: {Name: kparams.NetSIP, Type: kparams.IPv4, Value: net.ParseIP("127.0.0.1")}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("216.58.201.174")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(443)}, + params.NetSport: {Name: params.NetSport, Type: params.Uint16, Value: uint16(43123)}, + params.NetSIP: {Name: params.NetSIP, Type: params.IPv4, Value: net.ParseIP("127.0.0.1")}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), }, { - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Name: "CreateProcess", - Category: ktypes.Process, + Category: event.Process, Tid: 2484, PID: 859, PS: &types.PS{ Name: "powershell.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: 2323}, - kparams.ProcessParentID: {Name: kparams.ProcessParentID, Type: kparams.PID, Value: uint32(8390)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "spotify.exe"}, - kparams.Cmdline: {Name: kparams.Cmdline, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe`}, - kparams.UserSID: {Name: kparams.UserSID, Type: kparams.UnicodeString, Value: `admin\SYSTEM`}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: 2323}, + params.ProcessParentID: {Name: params.ProcessParentID, Type: params.PID, Value: uint32(8390)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "spotify.exe"}, + params.Cmdline: {Name: params.Cmdline, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe --type=crashpad-handler /prefetch:7 --max-uploads=5 --max-db-size=20 --max-db-age=5 --monitor-self-annotation=ptype=crashpad-handler "--metrics-dir=C:\Users\admin\AppData\Local\Spotify\User Data" --url=https://crashdump.spotify.com:443/ --annotation=platform=win32 --annotation=product=spotify --annotation=version=1.1.4.197 --initial-client-data=0x5a4,0x5a0,0x5a8,0x59c,0x5ac,0x6edcbf60,0x6edcbf70,0x6edcbf7c`}, + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: `C:\Users\admin\AppData\Roaming\Spotify\Spotify.exe`}, + params.UserSID: {Name: params.UserSID, Type: params.UnicodeString, Value: `admin\SYSTEM`}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), }, { - Type: ktypes.CreateHandle, + Type: event.CreateHandle, Name: "CreateHandle", - Category: ktypes.Handle, + Category: event.Handle, Tid: 2484, PID: 859, PS: &types.PS{ Name: "powershell.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: 2323}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: 2323}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), }, } diff --git a/pkg/rules/sequence.go b/pkg/rules/sequence.go index c441122f6..e1031fbad 100644 --- a/pkg/rules/sequence.go +++ b/pkg/rules/sequence.go @@ -23,11 +23,10 @@ import ( "expvar" fsm "github.com/qmuntal/stateless" "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/filter/ql" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/atomic" log "github.com/sirupsen/logrus" @@ -86,14 +85,14 @@ type sequenceState struct { maxSpan time.Duration // partials keeps the state of all matched events per expression - partials map[int][]*kevent.Kevent + partials map[int][]*event.Event // mu guards the partials map mu sync.RWMutex // matches stores only the event that matched // the upstream partials. These events will // be propagated in the rule action context - matches map[int]*kevent.Kevent + matches map[int]*event.Event // mmu guards the matches map mmu sync.RWMutex @@ -125,9 +124,9 @@ func newSequenceState(f filter.Filter, c *config.FilterConfig, psnap ps.Snapshot seq: f.GetSequence(), name: c.Name, maxSpan: f.GetSequence().MaxSpan, - partials: make(map[int][]*kevent.Kevent), + partials: make(map[int][]*event.Event), states: make(map[fsm.State]bool), - matches: make(map[int]*kevent.Kevent), + matches: make(map[int]*event.Event), exprs: make(map[int]string), spanDeadlines: make(map[fsm.State]*time.Timer), initialState: sequenceInitialState, @@ -142,10 +141,10 @@ func newSequenceState(f filter.Filter, c *config.FilterConfig, psnap ps.Snapshot return ss } -func (s *sequenceState) events() []*kevent.Kevent { +func (s *sequenceState) events() []*event.Event { s.mmu.RLock() defer s.mmu.RUnlock() - events := make([]*kevent.Kevent, 0, len(s.matches)) + events := make([]*event.Event, 0, len(s.matches)) for _, e := range s.matches { events = append(events, e) } @@ -261,7 +260,7 @@ func (s *sequenceState) configureFSM() { Permit(resetTransition, sequenceInitialState) } -func (s *sequenceState) matchTransition(seqID int, e *kevent.Kevent) error { +func (s *sequenceState) matchTransition(seqID int, e *event.Event) error { s.smu.Lock() defer s.smu.Unlock() shouldFire := !s.states[seqID] @@ -309,7 +308,7 @@ func (s *sequenceState) expr(state fsm.State) string { // addPartial appends the event that matched the expression at the // sequence index. If the event arrived out of order, then the isOOO // parameter is equal to false. -func (s *sequenceState) addPartial(seqID int, e *kevent.Kevent, isOOO bool) { +func (s *sequenceState) addPartial(seqID int, e *event.Event, isOOO bool) { s.mu.Lock() defer s.mu.Unlock() if len(s.partials[seqID]) > maxOutstandingPartials { @@ -331,7 +330,7 @@ func (s *sequenceState) addPartial(seqID int, e *kevent.Kevent, isOOO bool) { } } if isOOO { - e.AddMeta(kevent.RuleSequenceOOOKey, true) + e.AddMeta(event.RuleSequenceOOOKey, true) } log.Debugf("adding partial to sequence [%s] slot [%d] for expression %q, ooo: %t: %s", s.name, seqID, s.expr(seqID), isOOO, e) partialsPerSequence.Add(s.name, 1) @@ -365,8 +364,8 @@ func (s *sequenceState) gc() { } func (s *sequenceState) clear() { - s.partials = make(map[int][]*kevent.Kevent) - s.matches = make(map[int]*kevent.Kevent) + s.partials = make(map[int][]*event.Event) + s.matches = make(map[int]*event.Event) s.states = make(map[fsm.State]bool) s.spanDeadlines = make(map[fsm.State]*time.Timer) s.isPartialsBreached.Store(false) @@ -430,7 +429,7 @@ func (s *sequenceState) scheduleMaxSpanDeadline(seqID fsm.State, maxSpan time.Du s.spanDeadlines[seqID] = t } -func (s *sequenceState) runSequence(e *kevent.Kevent) bool { +func (s *sequenceState) runSequence(e *event.Event) bool { for i, expr := range s.seq.Expressions { // only try to evaluate the expression // if upstream expressions have matched @@ -481,7 +480,7 @@ func (s *sequenceState) runSequence(e *kevent.Kevent) bool { s.mu.RLock() for seqID := range s.partials { for _, evt := range s.partials[seqID] { - if !evt.ContainsMeta(kevent.RuleSequenceOOOKey) { + if !evt.ContainsMeta(event.RuleSequenceOOOKey) { continue } // try to initialize process state before evaluating the event @@ -496,7 +495,7 @@ func (s *sequenceState) runSequence(e *kevent.Kevent) bool { matchTransitionErrors.Add(1) log.Warnf("out of order match transition failure: %v", err) } - evt.RemoveMeta(kevent.RuleSequenceOOOKey) + evt.RemoveMeta(event.RuleSequenceOOOKey) } } } @@ -510,7 +509,7 @@ func (s *sequenceState) runSequence(e *kevent.Kevent) bool { // collect all events involved in the rule match isTerminal := s.isTerminalState() if isTerminal { - setMatch := func(seqID int, e *kevent.Kevent) { + setMatch := func(seqID int, e *event.Event) { s.mmu.Lock() defer s.mmu.Unlock() if s.matches[seqID] == nil { @@ -537,26 +536,26 @@ func (s *sequenceState) runSequence(e *kevent.Kevent) bool { return false } -func (s *sequenceState) expire(e *kevent.Kevent) bool { +func (s *sequenceState) expire(e *event.Event) bool { if !e.IsTerminateProcess() { return false } - canExpire := func(lhs, rhs *kevent.Kevent, isFinalSlot bool) bool { + canExpire := func(lhs, rhs *event.Event, isFinalSlot bool) bool { // if the TerminateProcess event arrives for the // process spawned by CreateProcess, and it pertains // to the final sequence slot, it is safe to expire // the whole sequence - pid := rhs.Kparams.MustGetPid() - if lhs.Type == ktypes.CreateProcess && isFinalSlot { - return lhs.Kparams.MustGetPid() == pid + pid := rhs.Params.MustGetPid() + if lhs.Type == event.CreateProcess && isFinalSlot { + return lhs.Params.MustGetPid() == pid } - if lhs.Type == ktypes.CreateThread { + if lhs.Type == event.CreateThread { // if the pids differ, the thread // is created in a remote process. // Sequence can be expired only if // the remote process terminates - if lhs.PID != lhs.Kparams.MustGetPid() { - return lhs.Kparams.MustGetPid() == pid + if lhs.PID != lhs.Params.MustGetPid() { + return lhs.Params.MustGetPid() == pid } } return lhs.PID == pid @@ -573,8 +572,8 @@ func (s *sequenceState) expire(e *kevent.Kevent) bool { } log.Debugf("removing event originated from %s (%d) "+ "in partials pertaining to sequence [%s] and slot [%d]", - e.Kparams.MustGetString(kparams.ProcessName), - e.Kparams.MustGetPid(), + e.Params.MustGetString(params.ProcessName), + e.Params.MustGetPid(), s.name, idx) // remove partial event from the corresponding slot diff --git a/pkg/rules/sequence_test.go b/pkg/rules/sequence_test.go index 884d41ff4..7cbedc5ae 100644 --- a/pkg/rules/sequence_test.go +++ b/pkg/rules/sequence_test.go @@ -20,11 +20,10 @@ package rules import ( "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/filter" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" log "github.com/sirupsen/logrus" @@ -44,9 +43,9 @@ func TestSequenceState(t *testing.T) { f := filter.New(` sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe - |kevt.name = 'CreateFile' and file.path icontains 'temp'| by file.path - |kevt.name = 'CreateProcess'| by ps.child.exe`, + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe + |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path + |evt.name = 'CreateProcess'| by ps.child.exe`, &config.Config{Kstream: config.KstreamConfig{}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) @@ -55,10 +54,10 @@ func TestSequenceState(t *testing.T) { assert.Equal(t, 0, ss.currentState()) assert.True(t, ss.isInitialState()) - assert.Equal(t, "kevt.name = CreateProcess AND ps.name = cmd.exe", ss.expr(ss.initialState)) + assert.Equal(t, "evt.name = CreateProcess AND ps.name = cmd.exe", ss.expr(ss.initialState)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e1 := &event.Event{ + Type: event.CreateProcess, Name: "CreateProcess", Tid: 2484, PID: 859, @@ -66,9 +65,9 @@ func TestSequenceState(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(4143)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "powershell.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(4143)}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "powershell.exe"}, }, } require.True(t, ss.next(0)) @@ -80,10 +79,10 @@ func TestSequenceState(t *testing.T) { require.False(t, ss.next(2)) assert.False(t, ss.isInitialState()) - assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) + assert.Equal(t, "evt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) - e2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e2 := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", Tid: 2484, PID: 4143, @@ -91,8 +90,8 @@ func TestSequenceState(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper"}, }, } // can't go to the next transitions as the expr hasn't matched @@ -106,15 +105,15 @@ func TestSequenceState(t *testing.T) { assert.Len(t, ss.partials[1], 1) assert.Equal(t, 2, ss.currentState()) - assert.Equal(t, "kevt.name = CreateProcess", ss.expr(ss.currentState())) + assert.Equal(t, "evt.name = CreateProcess", ss.expr(ss.currentState())) - e3 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e3 := &event.Event{ + Type: event.CreateProcess, Name: "CreateProcess", Tid: 2484, PID: 4143, - Kparams: kevent.Kparams{ - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + Params: event.Params{ + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, }, } require.NoError(t, ss.matchTransition(2, e3)) @@ -130,10 +129,10 @@ func TestSequenceState(t *testing.T) { // reset transition leads back to initial state assert.Equal(t, 0, ss.currentState()) - assert.Equal(t, "kevt.name = CreateProcess AND ps.name = cmd.exe", ss.expr(ss.currentState())) + assert.Equal(t, "evt.name = CreateProcess AND ps.name = cmd.exe", ss.expr(ss.currentState())) // deadline exceeded require.NoError(t, ss.matchTransition(0, e1)) - assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) + assert.Equal(t, "evt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) time.Sleep(time.Millisecond * 120) // transition to initial state assert.True(t, ss.isInitialState()) @@ -156,8 +155,8 @@ func TestSequenceState(t *testing.T) { require.False(t, ss.inDeadline.Load()) // expire entire sequence - e4 := &kevent.Kevent{ - Type: ktypes.TerminateProcess, + e4 := &event.Event{ + Type: event.TerminateProcess, Name: "TerminateProcess", Tid: 2484, PID: 859, @@ -165,9 +164,9 @@ func TestSequenceState(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(4143)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "powershell.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(4143)}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "powershell.exe"}, }, } require.True(t, ss.expire(e4)) @@ -176,7 +175,7 @@ func TestSequenceState(t *testing.T) { require.NoError(t, ss.matchTransition(0, e1)) require.False(t, ss.inExpired.Load()) - assert.Equal(t, "kevt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) + assert.Equal(t, "evt.name = CreateFile AND file.path ICONTAINS temp", ss.expr(ss.currentState())) } func TestSimpleSequence(t *testing.T) { @@ -186,19 +185,19 @@ func TestSimpleSequence(t *testing.T) { f := filter.New(` sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe - |kevt.name = 'CreateFile' and file.path icontains 'temp'| by file.path + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe + |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) var tests = []struct { - evts []*kevent.Kevent + evts []*event.Event matches []bool }{ - {[]*kevent.Kevent{{ - Type: ktypes.CreateProcess, + {[]*event.Event{{ + Type: event.CreateProcess, Name: "CreateProcess", Timestamp: time.Now(), Tid: 2484, @@ -207,26 +206,26 @@ func TestSimpleSequence(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost-temp.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { - Type: ktypes.CreateFile, + Type: event.CreateFile, Name: "CreateFile", Timestamp: time.Now(), Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}}}, []bool{false, true}}, - {[]*kevent.Kevent{{ - Type: ktypes.CreateProcess, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}}}, []bool{false, true}}, + {[]*event.Event{{ + Type: event.CreateProcess, Name: "CreateProcess", Timestamp: time.Now(), Tid: 2484, @@ -235,24 +234,24 @@ func TestSimpleSequence(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { - Type: ktypes.CreateFile, + Type: event.CreateFile, Name: "CreateFile", Timestamp: time.Now(), Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}}}, []bool{false, false}}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}}}, []bool{false, false}}, } for i, tt := range tests { @@ -272,8 +271,8 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { sequence maxspan 200ms by ps.pid - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| - |kevt.name = 'CreateFile' and file.path icontains 'temp'| + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| + |evt.name = 'CreateFile' and file.path icontains 'temp'| `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) @@ -281,8 +280,8 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { // create random matches which don't satisfy the sequence link for i, pid := range []uint32{2343, 1024, 11122, 3450, 12319} { - e1 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e1 := &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now().Add(time.Duration(i) * time.Millisecond), Name: "CreateProcess", Tid: 2484, @@ -291,26 +290,26 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: pid % 2}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: pid % 2}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e2 := &event.Event{ + Type: event.CreateFile, Timestamp: time.Now().Add(time.Duration(i) * time.Millisecond * 2), Name: "CreateFile", Tid: 2484, PID: pid * 2, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) require.False(t, ss.runSequence(e2)) @@ -320,9 +319,9 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { assert.Len(t, ss.partials[0], 5) assert.Len(t, ss.partials[1], 0) - e1 := &kevent.Kevent{ + e1 := &event.Event{ Seq: 20, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now().Add(time.Second), Name: "CreateProcess", Tid: 2484, @@ -334,27 +333,27 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { Name: "WmiPrvSE.exe", }, }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e2 := &event.Event{ + Type: event.CreateFile, Seq: 22, Timestamp: time.Now().Add(time.Second * time.Duration(2)), Name: "CreateFile", Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\file.tmp"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\file.tmp"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) @@ -368,7 +367,7 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { assert.Equal(t, uint32(859), ss.matches[0].PID) assert.Equal(t, "WmiPrvSE.exe", ss.matches[0].PS.Parent.Name) assert.Equal(t, uint32(859), ss.matches[1].PID) - assert.Equal(t, "C:\\Temp\\file.tmp", ss.matches[1].GetParamAsString(kparams.FilePath)) + assert.Equal(t, "C:\\Temp\\file.tmp", ss.matches[1].GetParamAsString(params.FilePath)) } func TestSimpleSequenceDeadline(t *testing.T) { @@ -378,15 +377,15 @@ func TestSimpleSequenceDeadline(t *testing.T) { f := filter.New(` sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe - |kevt.name = 'CreateFile' and file.path icontains 'temp'| by file.path + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe + |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e1 := &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now(), Name: "CreateProcess", Tid: 2484, @@ -395,28 +394,28 @@ func TestSimpleSequenceDeadline(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost-temp.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) - e2 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e2 := &event.Event{ + Type: event.CreateFile, Timestamp: time.Now(), Name: "CreateFile", Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } time.Sleep(time.Millisecond * 110) require.False(t, ss.runSequence(e2)) @@ -448,19 +447,19 @@ func TestComplexSequence(t *testing.T) { f := filter.New(` sequence maxspan 1h - |kevt.name = 'CreateProcess' and ps.child.name in ('firefox.exe', 'chrome.exe', 'edge.exe')| by ps.child.pid - |kevt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.exe'| by ps.pid - |kevt.name in ('Send', 'Connect')| by ps.pid + |evt.name = 'CreateProcess' and ps.child.name in ('firefox.exe', 'chrome.exe', 'edge.exe')| by ps.child.pid + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.exe'| by ps.pid + |evt.name in ('Send', 'Connect')| by ps.pid `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ + e1 := &event.Event{ Seq: 1, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 859, @@ -468,43 +467,43 @@ func TestComplexSequence(t *testing.T) { Name: "explorer.exe", Exe: "C:\\Windows\\system32\\explorer.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "firefox.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "firefox.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) - e2 := &kevent.Kevent{ + e2 := &event.Event{ Seq: 2, - Type: ktypes.CreateFile, + Type: event.CreateFile, Timestamp: time.Now().Add(time.Millisecond * 250), Name: "CreateFile", Tid: 2484, PID: 2243, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "firefox.exe", Exe: "C:\\Program Files\\Mozilla Firefox\\firefox.exe", Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper.exe"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e2)) assert.Len(t, ss.partials[0], 1) assert.Len(t, ss.partials[1], 1) - e3 := &kevent.Kevent{ + e3 := &event.Event{ Seq: 4, - Type: ktypes.ConnectTCPv4, + Type: event.ConnectTCPv4, Timestamp: time.Now().Add(time.Second), - Category: ktypes.Net, + Category: event.Net, Name: "Connect", Tid: 244, PID: 2243, @@ -513,10 +512,10 @@ func TestComplexSequence(t *testing.T) { Exe: "C:\\Program Files\\Mozilla Firefox\\firefox.exe", Cmdline: "C:\\Program Files\\Mozilla Firefox\\firefox.exe\" -contentproc --channel=\"10464.7.539748228\\1366525930\" -childID 6 -isF", }, - Kparams: kevent.Kparams{ - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("10.0.2.3")}, + Params: event.Params{ + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("10.0.2.3")}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } time.Sleep(time.Millisecond * 30) @@ -542,36 +541,36 @@ func TestSequenceOOO(t *testing.T) { f := filter.New(` sequence maxspan 2m - |kevt.name = 'OpenProcess' and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| by ps.uuid - |kevt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| by ps.uuid + |evt.name = 'OpenProcess' and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| by ps.uuid + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| by ps.uuid `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e1 := &event.Event{ + Type: event.CreateFile, Timestamp: time.Now(), Name: "CreateFile", Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\rundll32.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\temp\\lsass.dmp"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.UnicodeString, Value: "CREATE"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\temp\\lsass.dmp"}, + params.FileOperation: {Name: params.FileOperation, Type: params.UnicodeString, Value: "CREATE"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) require.Len(t, ss.partials[1], 1) - assert.True(t, ss.partials[1][0].ContainsMeta(kevent.RuleSequenceOOOKey)) + assert.True(t, ss.partials[1][0].ContainsMeta(event.RuleSequenceOOOKey)) - e2 := &kevent.Kevent{ - Type: ktypes.OpenProcess, + e2 := &event.Event{ + Type: event.OpenProcess, Timestamp: time.Now(), Name: "OpenProcess", Tid: 2484, @@ -580,17 +579,17 @@ func TestSequenceOOO(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\rundll32.exe", }, - Kparams: kevent.Kparams{ - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Flags, Value: uint32(0x1400), Flags: kevent.PsAccessRightFlags}, + Params: event.Params{ + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Flags, Value: uint32(0x1400), Flags: event.PsAccessRightFlags}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.True(t, ss.runSequence(e2)) assert.Len(t, ss.partials[0], 1) - assert.False(t, ss.partials[1][0].ContainsMeta(kevent.RuleSequenceOOOKey)) + assert.False(t, ss.partials[1][0].ContainsMeta(event.RuleSequenceOOOKey)) } func TestSequenceGC(t *testing.T) { @@ -602,15 +601,15 @@ func TestSequenceGC(t *testing.T) { f := filter.New(` sequence by ps.uuid - |kevt.name = 'OpenProcess' and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| - |kevt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| + |evt.name = 'OpenProcess' and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e := &kevent.Kevent{ - Type: ktypes.OpenProcess, + e := &event.Event{ + Type: event.OpenProcess, Timestamp: time.Now(), Name: "OpenProcess", Tid: 2484, @@ -619,12 +618,12 @@ func TestSequenceGC(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\rundll32.exe", }, - Kparams: kevent.Kparams{ - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Flags, Value: uint32(0x1400), Flags: kevent.PsAccessRightFlags}, + Params: event.Params{ + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Flags, Value: uint32(0x1400), Flags: event.PsAccessRightFlags}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e)) @@ -643,19 +642,19 @@ func TestSequenceExpire(t *testing.T) { var tests = []struct { c *config.FilterConfig expr string - evts []*kevent.Kevent + evts []*event.Event wants bool }{ { &config.FilterConfig{Name: "LSASS memory dumping via legitimate or offensive tools"}, `sequence maxspan 2m - |kevt.name = 'OpenProcess' and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| by ps.uuid - |kevt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| by ps.uuid + |evt.name = 'OpenProcess' and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| by ps.uuid + |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| by ps.uuid `, - []*kevent.Kevent{ + []*event.Event{ { - Type: ktypes.OpenProcess, + Type: event.OpenProcess, Timestamp: time.Now(), Name: "OpenProcess", Tid: 2484, @@ -664,15 +663,15 @@ func TestSequenceExpire(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\rundll32.exe", }, - Kparams: kevent.Kparams{ - kparams.Exe: {Name: kparams.Exe, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.DesiredAccess: {Name: kparams.DesiredAccess, Type: kparams.Flags, Value: uint32(0x1400), Flags: kevent.PsAccessRightFlags}, + Params: event.Params{ + params.Exe: {Name: params.Exe, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\lsass.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.DesiredAccess: {Name: params.DesiredAccess, Type: params.Flags, Value: uint32(0x1400), Flags: event.PsAccessRightFlags}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { - Type: ktypes.TerminateProcess, + Type: event.TerminateProcess, Name: "TerminateProcess", Tid: 2484, PID: 859, @@ -680,9 +679,9 @@ func TestSequenceExpire(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(4143)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "powershell.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(4143)}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "powershell.exe"}, }, }, }, @@ -692,15 +691,15 @@ func TestSequenceExpire(t *testing.T) { &config.FilterConfig{Name: "System Binary Proxy Execution via Rundll32"}, `sequence maxspan 2m - |kevt.name = 'CreateProcess' and ps.child.name = 'rundll32.exe'| by ps.child.pid - |kevt.name = 'CreateProcess' and ps.child.name = 'connhost.exe'| by ps.pid + |evt.name = 'CreateProcess' and ps.child.name = 'rundll32.exe'| by ps.child.pid + |evt.name = 'CreateProcess' and ps.child.name = 'connhost.exe'| by ps.pid `, - []*kevent.Kevent{ + []*event.Event{ { Seq: 1, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 859, @@ -708,17 +707,17 @@ func TestSequenceExpire(t *testing.T) { Name: "explorer.exe", Exe: "C:\\Windows\\system32\\explorer.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(2243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "rundll32.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(2243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "rundll32.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { Seq: 2, - Type: ktypes.CreateProcess, + Type: event.CreateProcess, Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Name: "CreateProcess", Tid: 2484, PID: 2243, @@ -726,14 +725,14 @@ func TestSequenceExpire(t *testing.T) { Name: "explorer.exe", Exe: "C:\\Windows\\system32\\explorer.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(12243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "connhost.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(12243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "connhost.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, }, { - Type: ktypes.TerminateProcess, + Type: event.TerminateProcess, Name: "TerminateProcess", Tid: 2484, PID: 859, @@ -741,9 +740,9 @@ func TestSequenceExpire(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(12243)}, - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.AnsiString, Value: "powershell.exe"}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(12243)}, + params.ProcessName: {Name: params.ProcessName, Type: params.AnsiString, Value: "powershell.exe"}, }, }, }, @@ -782,16 +781,16 @@ func TestSequenceBoundFields(t *testing.T) { f := filter.New(` sequence maxspan 200ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| as e1 - |kevt.name = 'CreateFile' and file.path icontains 'temp' and $e1.ps.sid = ps.sid| as e2 - |kevt.name = 'Connect' and ps.sid != $e2.ps.sid and ps.sid = $e1.ps.sid| + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| as e1 + |evt.name = 'CreateFile' and file.path icontains 'temp' and $e1.ps.sid = ps.sid| as e2 + |evt.name = 'Connect' and ps.sid != $e2.ps.sid and ps.sid = $e1.ps.sid| `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e1 := &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now(), Name: "CreateProcess", Tid: 2484, @@ -801,14 +800,14 @@ func TestSequenceBoundFields(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost-temp.exe", SID: "zinet", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e2 := &event.Event{ + Type: event.CreateProcess, Timestamp: time.Now().Add(time.Millisecond * 20), Name: "CreateProcess", Tid: 2484, @@ -818,47 +817,47 @@ func TestSequenceBoundFields(t *testing.T) { Exe: "C:\\Windows\\system32\\svchost-temp.exe", SID: "nusret", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e3 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e3 := &event.Event{ + Type: event.CreateFile, Timestamp: time.Now().Add(time.Second), Name: "CreateFile", Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", SID: "nusret", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\svchost-temp.exe"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e4 := &kevent.Kevent{ - Type: ktypes.ConnectTCPv4, + e4 := &event.Event{ + Type: event.ConnectTCPv4, Timestamp: time.Now().Add(time.Second * 3), Name: "Connect", Tid: 2484, PID: 859, - Category: ktypes.File, + Category: event.File, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", SID: "zinet", }, - Kparams: kevent.Kparams{ - kparams.NetDport: {Name: kparams.NetDport, Type: kparams.Uint16, Value: uint16(80)}, - kparams.NetDIP: {Name: kparams.NetDIP, Type: kparams.IPv4, Value: net.ParseIP("172.1.2.3")}, + Params: event.Params{ + params.NetDport: {Name: params.NetDport, Type: params.Uint16, Value: uint16(80)}, + params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("172.1.2.3")}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } require.False(t, ss.runSequence(e1)) @@ -876,8 +875,8 @@ func TestSequenceBoundFieldsWithFunctions(t *testing.T) { f := filter.New(` sequence maxspan 5m - |kevt.name = 'CreateFile' and file.path imatches '?:\\Windows\\System32\\*.dll'| as e1 - |kevt.name = 'RegSetValue' and registry.path ~= 'HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages' + |evt.name = 'CreateFile' and file.path imatches '?:\\Windows\\System32\\*.dll'| as e1 + |evt.name = 'RegSetValue' and registry.path ~= 'HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages' and get_reg_value(registry.path) iin (base($e1.file.path, false))| `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true, EnableRegistryKevents: true}, Filters: &config.Filters{}}) @@ -885,36 +884,36 @@ func TestSequenceBoundFieldsWithFunctions(t *testing.T) { ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateFile, + e1 := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 859, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\passwdflt.dll"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\passwdflt.dll"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ - Type: ktypes.RegSetValue, + e2 := &event.Event{ + Type: event.RegSetValue, Name: "RegSetValue", - Category: ktypes.Registry, + Category: event.Registry, Tid: 2484, PID: 859, PS: &pstypes.PS{ Name: "cmd.exe", Exe: "C:\\Windows\\system32\\cmd.exe", }, - Kparams: kevent.Kparams{ - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: "HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages"}, + Params: event.Params{ + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: "HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } key, err := registry.OpenKey(registry.CURRENT_USER, "Volatile Environment", registry.SET_VALUE) @@ -938,15 +937,15 @@ func TestIsExpressionEvaluable(t *testing.T) { f := filter.New(` sequence maxspan 100ms - |kevt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe - |kevt.name = 'CreateFile' and file.path icontains 'temp'| by file.path + |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe + |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) - e1 := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e1 := &event.Event{ + Type: event.CreateProcess, Name: "CreateProcess", Tid: 2484, PID: 859, @@ -954,14 +953,14 @@ func TestIsExpressionEvaluable(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.Uint32, Value: uint32(4143)}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.Uint32, Value: uint32(4143)}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } - e2 := &kevent.Kevent{ - Type: ktypes.RenameFile, + e2 := &event.Event{ + Type: event.RenameFile, Name: "RenameFile", Tid: 2484, PID: 859, @@ -969,10 +968,10 @@ func TestIsExpressionEvaluable(t *testing.T) { Name: "cmd.exe", Exe: "C:\\Windows\\system32\\svchost.exe", }, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Temp\\dropper"}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Temp\\dropper"}, }, - Metadata: map[kevent.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, + Metadata: map[event.MetadataKey]any{"foo": "bar", "fooz": "barzz"}, } assert.False(t, ss.filter.GetSequence().Expressions[0].IsEvaluable(e2)) diff --git a/pkg/ksource/doc.go b/pkg/source/doc.go similarity index 87% rename from pkg/ksource/doc.go rename to pkg/source/doc.go index c120e0f2b..88b68c408 100644 --- a/pkg/ksource/doc.go +++ b/pkg/source/doc.go @@ -16,5 +16,5 @@ * limitations under the License. */ -// Package ksource defines the contract all event sources have to satisfy. -package ksource +// Package source defines the contract all event sources have to satisfy. +package source diff --git a/pkg/ksource/source.go b/pkg/source/source.go similarity index 91% rename from pkg/ksource/source.go rename to pkg/source/source.go index 7f9433ddc..4ce4f4a7d 100644 --- a/pkg/ksource/source.go +++ b/pkg/source/source.go @@ -16,12 +16,12 @@ * limitations under the License. */ -package ksource +package source import ( "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/filter" - "github.com/rabbitstack/fibratus/pkg/kevent" ) // EventSource defines the contract all event sources have to satisfy. @@ -47,12 +47,12 @@ type EventSource interface { // Events return the channel where event source pushes all captured events. // At this point, the event has the full state associated with it. For example, // the full process state or the event call stack. - Events() <-chan *kevent.Kevent + Events() <-chan *event.Event // SetFilter attaches the filter to the event source. Only events that match // the filter are forwarded to the event source output channel. SetFilter(f filter.Filter) // RegisterEventListener installs event listener. Event listener represents any - // component that satisfies the kevent.Listener interface. Event listener can + // component that satisfies the event.Listener interface. Event listener can // decide if the event is pushed to the output queue. - RegisterEventListener(lis kevent.Listener) + RegisterEventListener(lis event.Listener) } diff --git a/pkg/symbolize/symbolizer.go b/pkg/symbolize/symbolizer.go index bb13b3faa..a62132254 100644 --- a/pkg/symbolize/symbolizer.go +++ b/pkg/symbolize/symbolizer.go @@ -23,9 +23,8 @@ import ( "fmt" "github.com/rabbitstack/fibratus/pkg/callstack" "github.com/rabbitstack/fibratus/pkg/config" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" @@ -201,10 +200,10 @@ func (s *Symbolizer) Close() { } } -func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { +func (s *Symbolizer) ProcessEvent(e *event.Event) (bool, error) { if e.IsTerminateProcess() { // release symbol handler and process handle - pid := e.Kparams.MustGetPid() + pid := e.Params.MustGetPid() s.mu.Lock() defer s.mu.Unlock() if _, ok := s.symbols[pid]; !ok { @@ -223,12 +222,12 @@ func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { } if e.IsLoadImage() || e.IsUnloadImage() { - filename := e.GetParamAsString(kparams.ImagePath) - addr := e.Kparams.TryGetAddress(kparams.ImageBase) + filename := e.GetParamAsString(params.ImagePath) + addr := e.Params.TryGetAddress(params.ImageBase) // if the kernel driver is loaded or unloaded, // load/unload symbol handlers respectively if (strings.ToLower(filepath.Ext(filename)) == ".sys" || - e.Kparams.TryGetBool(kparams.FileIsDriver)) && s.config.SymbolizeKernelAddresses { + e.Params.TryGetBool(params.FileIsDriver)) && s.config.SymbolizeKernelAddresses { if e.IsLoadImage() { err := s.r.LoadModule(windows.CurrentProcess(), filename, addr) if err != nil { @@ -248,10 +247,10 @@ func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { } } - if !e.Kparams.Contains(kparams.Callstack) { + if !e.Params.Contains(params.Callstack) { return true, nil } - defer e.Kparams.Remove(kparams.Callstack) + defer e.Params.Remove(params.Callstack) err := s.processCallstack(e) if err != nil { @@ -267,9 +266,9 @@ func (s *Symbolizer) ProcessEvent(e *kevent.Kevent) (bool, error) { // the new module is loaded and not already present in // the map, we parse its export directory and insert // into the map. -func (s *Symbolizer) syncModules(e *kevent.Kevent) error { - filename := e.GetParamAsString(kparams.ImagePath) - addr := e.Kparams.TryGetAddress(kparams.ImageBase) +func (s *Symbolizer) syncModules(e *event.Event) error { + filename := e.GetParamAsString(params.ImagePath) + addr := e.Params.TryGetAddress(params.ImageBase) s.mu.Lock() defer s.mu.Unlock() @@ -308,8 +307,8 @@ func (s *Symbolizer) syncModules(e *kevent.Kevent) error { return nil } -func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { - addrs := e.Kparams.MustGetSliceAddrs(kparams.Callstack) +func (s *Symbolizer) processCallstack(e *event.Event) error { + addrs := e.Params.MustGetSliceAddrs(params.Callstack) e.Callstack.Init(len(addrs)) // skip stack enrichment for the events generated by the System process @@ -330,12 +329,12 @@ func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { // get the address that we want to symbolize switch e.Type { - case ktypes.CreateThread: - pid = e.Kparams.MustGetPid() - addr = e.Kparams.TryGetAddress(kparams.StartAddress) - case ktypes.SubmitThreadpoolWork, ktypes.SubmitThreadpoolCallback: + case event.CreateThread: + pid = e.Params.MustGetPid() + addr = e.Params.TryGetAddress(params.StartAddress) + case event.SubmitThreadpoolWork, event.SubmitThreadpoolCallback: pid = e.PID - addr = e.Kparams.TryGetAddress(kparams.ThreadpoolCallback) + addr = e.Params.TryGetAddress(params.ThreadpoolCallback) } // symbolize thread start or thread pool callback address @@ -350,12 +349,12 @@ func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { if symbol != "" && symbol != "?" { switch e.Type { - case ktypes.CreateThread: - e.Kparams.Append(kparams.StartAddressSymbol, kparams.UnicodeString, symbol) - case ktypes.SubmitThreadpoolWork, ktypes.SubmitThreadpoolCallback: - e.Kparams.Append(kparams.ThreadpoolCallbackSymbol, kparams.UnicodeString, symbol) + case event.CreateThread: + e.Params.Append(params.StartAddressSymbol, params.UnicodeString, symbol) + case event.SubmitThreadpoolWork, event.SubmitThreadpoolCallback: + e.Params.Append(params.ThreadpoolCallbackSymbol, params.UnicodeString, symbol) - ctx := e.Kparams.TryGetAddress(kparams.ThreadpoolContext) + ctx := e.Params.TryGetAddress(params.ThreadpoolContext) // if the callback resolves to one of the functions // that receive the CONTEXT structure as a parameter @@ -364,16 +363,16 @@ func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { if ctx != 0 && threadcontext.IsParamOfFunc(symbol) { rip := threadcontext.Rip(pid, ctx) if rip != 0 { - e.Kparams.Append(kparams.ThreadpoolContextRip, kparams.Address, rip.Uint64()) + e.Params.Append(params.ThreadpoolContextRip, params.Address, rip.Uint64()) m := e.PS.FindModuleByVa(rip) if m != nil { - e.Kparams.Append(kparams.ThreadpoolContextRipModule, kparams.UnicodeString, m.Name) + e.Params.Append(params.ThreadpoolContextRipModule, params.UnicodeString, m.Name) } sym := s.symbolizeAddress(pid, rip, m) if sym != "" && sym != "?" { - e.Kparams.Append(kparams.ThreadpoolContextRipSymbol, kparams.UnicodeString, sym) + e.Params.Append(params.ThreadpoolContextRipSymbol, params.UnicodeString, sym) } } } @@ -382,10 +381,10 @@ func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { if mod != nil { switch e.Type { - case ktypes.CreateThread: - e.Kparams.Append(kparams.StartAddressModule, kparams.UnicodeString, mod.Name) - case ktypes.SubmitThreadpoolWork, ktypes.SubmitThreadpoolCallback: - e.Kparams.Append(kparams.ThreadpoolCallbackModule, kparams.UnicodeString, mod.Name) + case event.CreateThread: + e.Params.Append(params.StartAddressModule, params.UnicodeString, mod.Name) + case event.SubmitThreadpoolWork, event.SubmitThreadpoolCallback: + e.Params.Append(params.ThreadpoolCallbackModule, params.UnicodeString, mod.Name) } } } @@ -427,7 +426,7 @@ func (s *Symbolizer) processCallstack(e *kevent.Kevent) error { // addresses where the first element is the // most recent kernel return address that is // pushed last into the event callstack. -func (s *Symbolizer) pushFrames(addrs []va.Address, e *kevent.Kevent) { +func (s *Symbolizer) pushFrames(addrs []va.Address, e *event.Event) { for i := len(addrs) - 1; i >= 0; i-- { e.Callstack.PushFrame(s.produceFrame(addrs[i], e)) } @@ -440,7 +439,7 @@ func (s *Symbolizer) pushFrames(addrs []va.Address, e *kevent.Kevent) { // PE export directory entries. If either the // symbol or module are not resolved, then we // fall back to Debug API. -func (s *Symbolizer) produceFrame(addr va.Address, e *kevent.Kevent) callstack.Frame { +func (s *Symbolizer) produceFrame(addr va.Address, e *event.Event) callstack.Frame { frame := callstack.Frame{PID: e.PID, Addr: addr} if addr.InSystemRange() { if s.config.SymbolizeKernelAddresses { diff --git a/pkg/symbolize/symbolizer_test.go b/pkg/symbolize/symbolizer_test.go index 5c670aac6..28fcfb8aa 100644 --- a/pkg/symbolize/symbolizer_test.go +++ b/pkg/symbolize/symbolizer_test.go @@ -20,10 +20,9 @@ package symbolize import ( "github.com/rabbitstack/fibratus/pkg/config" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/fs" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" @@ -142,23 +141,23 @@ func TestProcessCallstackPeExports(t *testing.T) { }, } - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Tid: 2484, PID: uint32(os.Getpid()), CPU: 1, Seq: 2, Name: "CreateFile", Timestamp: time.Now(), - Category: ktypes.File, + Category: event.File, Host: "archrabbit", Description: "Creates or opens a new file, directory, I/O device, pipe, console", - Kparams: kevent.Kparams{ - kparams.FileObject: {Name: kparams.FileObject, Type: kparams.Uint64, Value: uint64(12456738026482168384)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\system32\\mimi.dll"}, - kparams.FileType: {Name: kparams.FileType, Type: kparams.AnsiString, Value: "file"}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, + Params: event.Params{ + params.FileObject: {Name: params.FileObject, Type: params.Uint64, Value: uint64(12456738026482168384)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\system32\\mimi.dll"}, + params.FileType: {Name: params.FileType, Type: params.AnsiString, Value: "file"}, + params.FileOperation: {Name: params.FileOperation, Type: params.Enum, Value: uint32(2), Enum: fs.FileCreateDispositions}, + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, }, PS: proc, } @@ -202,18 +201,18 @@ func TestProcessCallstackPeExports(t *testing.T) { // and when the image is unloaded and there are // no processes with the image section mapped // inside their VAS, we can remove the module - e2 := &kevent.Kevent{ - Type: ktypes.LoadImage, + e2 := &event.Event{ + Type: event.LoadImage, Tid: 2484, PID: uint32(12328), CPU: 1, Seq: 2, Name: "LoadImage", Timestamp: time.Now(), - Category: ktypes.Image, - Kparams: kevent.Kparams{ - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x12345f)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\bcrypt32.dll"}, + Category: event.Image, + Params: event.Params{ + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x12345f)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\bcrypt32.dll"}, }, PS: proc, } @@ -221,18 +220,18 @@ func TestProcessCallstackPeExports(t *testing.T) { require.NoError(t, err) assert.Len(t, s.mods, 4) - e3 := &kevent.Kevent{ - Type: ktypes.UnloadImage, + e3 := &event.Event{ + Type: event.UnloadImage, Tid: 2484, PID: uint32(12328), CPU: 1, Seq: 2, Name: "UnloadImage", Timestamp: time.Now(), - Category: ktypes.Image, - Kparams: kevent.Kparams{ - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Address, Value: uint64(0x12345f)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("SystemRoot"), "System32", "bcrypt32.dll")}, + Category: event.Image, + Params: event.Params{ + params.ImageBase: {Name: params.ImageBase, Type: params.Address, Value: uint64(0x12345f)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("SystemRoot"), "System32", "bcrypt32.dll")}, }, PS: proc, } @@ -280,18 +279,18 @@ func TestProcessCallstack(t *testing.T) { }, Envs: map[string]string{"ProgramData": "C:\\ProgramData", "COMPUTRENAME": "archrabbit"}, } - e := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e := &event.Event{ + Type: event.CreateProcess, Tid: 2484, PID: uint32(os.Getpid()), CPU: 1, Seq: 2, Name: "CreatedProcess", Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Host: "archrabbit", - Kparams: kevent.Kparams{ - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, + Params: event.Params{ + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, }, PS: proc, } @@ -301,18 +300,18 @@ func TestProcessCallstack(t *testing.T) { assert.Equal(t, 1, s.procsSize()) assert.Equal(t, "0x7ffb5c1d0396 C:\\WINDOWS\\System32\\ntdll.dll!NtCreateProcessEx+0x3a2|0x7ffb5d8e61f4 C:\\WINDOWS\\System32\\ntdll.dll!NtCreateProcessEx+0x3a2|0x7ffb3138592e C:\\WINDOWS\\System32\\ntdll.dll!NtCreateProcess+0x3a2|0x7ffb313853b2 C:\\WINDOWS\\System32\\KERNELBASE.dll!CreateProcessW+0x66|0x2638e59e0a5 C:\\WINDOWS\\System32\\KERNEL32.DLL!CreateProcessW+0x54", e.Callstack.String()) - e1 := &kevent.Kevent{ - Type: ktypes.TerminateProcess, + e1 := &event.Event{ + Type: event.TerminateProcess, Tid: 2484, PID: 12345, CPU: 1, Seq: 3, Name: "TerminateProcess", Timestamp: time.Now(), - Category: ktypes.Process, + Category: event.Process, Host: "archrabbit", - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, }, PS: proc, } @@ -379,20 +378,20 @@ func TestSymbolizeEventParamAddress(t *testing.T) { {Name: "C:\\Windows\\System32\\user32.dll", Size: 212354, Checksum: 33123343, BaseAddress: va.Address(0x7ffb5d8e11c4), DefaultBaseAddress: va.Address(0x7ffb5d8e11c4)}, }, } - e := &kevent.Kevent{ - Type: ktypes.CreateThread, + e := &event.Event{ + Type: event.CreateThread, Tid: 2484, PID: uint32(os.Getpid()), CPU: 1, Seq: 2, Name: "CreateThread", Timestamp: time.Now(), - Category: ktypes.Thread, + Category: event.Thread, Host: "archrabbit", - Kparams: kevent.Kparams{ - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, - kparams.StartAddress: {Name: kparams.StartAddress, Type: kparams.Address, Value: uint64(0x7ffb3138592e)}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(os.Getpid())}, + Params: event.Params{ + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, + params.StartAddress: {Name: params.StartAddress, Type: params.Address, Value: uint64(0x7ffb3138592e)}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(os.Getpid())}, }, PS: proc, } @@ -400,23 +399,23 @@ func TestSymbolizeEventParamAddress(t *testing.T) { _, err := s.ProcessEvent(e) require.NoError(t, err) - assert.Equal(t, "CreateProcessW", e.GetParamAsString(kparams.StartAddressSymbol)) - assert.Equal(t, "C:\\Windows\\System32\\ntdll.dll", e.GetParamAsString(kparams.StartAddressModule)) + assert.Equal(t, "CreateProcessW", e.GetParamAsString(params.StartAddressSymbol)) + assert.Equal(t, "C:\\Windows\\System32\\ntdll.dll", e.GetParamAsString(params.StartAddressModule)) - e1 := &kevent.Kevent{ - Type: ktypes.SubmitThreadpoolCallback, + e1 := &event.Event{ + Type: event.SubmitThreadpoolCallback, Tid: 2484, PID: uint32(os.Getpid()), CPU: 1, Seq: 2, Name: "SubmitThreadpoolCallback", Timestamp: time.Now(), - Category: ktypes.Threadpool, + Category: event.Threadpool, Host: "archrabbit", - Kparams: kevent.Kparams{ - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396}}, - kparams.ThreadpoolCallback: {Name: kparams.ThreadpoolCallback, Type: kparams.Address, Value: uint64(0x7ffb3138592e)}, - kparams.ThreadpoolContext: {Name: kparams.ThreadpoolContext, Type: kparams.Address, Value: uint64(0)}, + Params: event.Params{ + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5c1d0396}}, + params.ThreadpoolCallback: {Name: params.ThreadpoolCallback, Type: params.Address, Value: uint64(0x7ffb3138592e)}, + params.ThreadpoolContext: {Name: params.ThreadpoolContext, Type: params.Address, Value: uint64(0)}, }, PS: proc, } @@ -424,8 +423,8 @@ func TestSymbolizeEventParamAddress(t *testing.T) { _, err = s.ProcessEvent(e1) require.NoError(t, err) - assert.Equal(t, "CreateProcessW", e1.GetParamAsString(kparams.ThreadpoolCallbackSymbol)) - assert.Equal(t, "C:\\Windows\\System32\\ntdll.dll", e1.GetParamAsString(kparams.ThreadpoolCallbackModule)) + assert.Equal(t, "CreateProcessW", e1.GetParamAsString(params.ThreadpoolCallbackSymbol)) + assert.Equal(t, "C:\\Windows\\System32\\ntdll.dll", e1.GetParamAsString(params.ThreadpoolCallbackModule)) } func init() { @@ -452,18 +451,18 @@ func TestProcessCallstackProcsTTL(t *testing.T) { n := 10 for n > 0 { - e := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e := &event.Event{ + Type: event.CreateProcess, Tid: 2484, PID: uint32(os.Getpid()), CPU: 1, Seq: 2, Name: "CreatedProcess", Timestamp: time.Now().Add(time.Millisecond * time.Duration(n)), - Category: ktypes.Process, + Category: event.Process, Host: "archrabbit", - Kparams: kevent.Kparams{ - kparams.Callstack: {Name: kparams.Callstack, Type: kparams.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, + Params: event.Params{ + params.Callstack: {Name: params.Callstack, Type: params.Slice, Value: []va.Address{0x7ffb5c1d0396, 0x7ffb5d8e61f4, 0x7ffb3138592e, 0x7ffb313853b2, 0x2638e59e0a5}}, }, } _, _ = s.ProcessEvent(e) diff --git a/pkg/sys/etw/etw.go b/pkg/sys/etw/etw.go index f90f24051..3874d7e94 100644 --- a/pkg/sys/etw/etw.go +++ b/pkg/sys/etw/etw.go @@ -22,7 +22,7 @@ package etw import ( - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + "github.com/rabbitstack/fibratus/pkg/errors" "golang.org/x/sys/windows" "os" "unsafe" @@ -96,17 +96,17 @@ func StartTrace(name string, props EventTraceProperties) (TraceHandle, error) { } switch err.(windows.Errno) { case windows.ERROR_ACCESS_DENIED: - return TraceHandle(0), kerrors.ErrTraceAccessDenied + return TraceHandle(0), errors.ErrTraceAccessDenied case windows.ERROR_DISK_FULL: - return TraceHandle(0), kerrors.ErrTraceDiskFull + return TraceHandle(0), errors.ErrTraceDiskFull case windows.ERROR_ALREADY_EXISTS: - return TraceHandle(0), kerrors.ErrTraceAlreadyRunning + return TraceHandle(0), errors.ErrTraceAlreadyRunning case windows.ERROR_INVALID_PARAMETER: - return TraceHandle(0), kerrors.ErrTraceInvalidParameter + return TraceHandle(0), errors.ErrTraceInvalidParameter case windows.ERROR_BAD_LENGTH: - return TraceHandle(0), kerrors.ErrTraceBadLength + return TraceHandle(0), errors.ErrTraceBadLength case windows.ERROR_NO_SYSTEM_RESOURCES: - return TraceHandle(0), kerrors.ErrTraceNoSysResources + return TraceHandle(0), errors.ErrTraceNoSysResources default: return TraceHandle(0), os.NewSyscallError("StartTrace", err) } @@ -168,11 +168,11 @@ func ProcessTrace(handle TraceHandle) error { } switch err.(windows.Errno) { case windows.ERROR_WMI_INSTANCE_NOT_FOUND: - return kerrors.ErrKsessionNotRunning + return errors.ErrSessionNotRunning case windows.ERROR_NOACCESS: - return kerrors.ErrEventCallbackException + return errors.ErrEventCallbackException case windows.ERROR_CANCELLED: - return kerrors.ErrTraceCancelled + return errors.ErrTraceCancelled default: return os.NewSyscallError("ProcessTrace", err) } diff --git a/pkg/util/eventlog/eventlog.go b/pkg/util/eventlog/eventlog.go index 21082a6ca..7ee583ddd 100644 --- a/pkg/util/eventlog/eventlog.go +++ b/pkg/util/eventlog/eventlog.go @@ -20,7 +20,7 @@ package eventlog import ( "fmt" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "golang.org/x/sys/windows/registry" ) @@ -39,7 +39,7 @@ const ( var ErrKeyExists = fmt.Errorf("%s\\%s already exists", keyName, Source) // categoryCount indicates the number of current event categories -var categoryCount = uint32(len(ktypes.Categories())) +var categoryCount = uint32(len(event.Categories())) // Level is the type definition for the eventlog log level type Level uint16 diff --git a/pkg/yara/config/config.go b/pkg/yara/config/config.go index 9d29ce4ae..084adfdc0 100644 --- a/pkg/yara/config/config.go +++ b/pkg/yara/config/config.go @@ -22,9 +22,8 @@ import ( "bytes" "fmt" "github.com/mitchellh/mapstructure" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" "github.com/rabbitstack/fibratus/pkg/util/wildcard" ytypes "github.com/rabbitstack/fibratus/pkg/yara/types" "github.com/spf13/pflag" @@ -164,8 +163,8 @@ func (c Config) ShouldSkipFile(file string) bool { // AlertTitle returns the brief alert title depending on // whether the process scan took place or a file/registry // key was scanned. -func (c Config) AlertTitle(e *kevent.Kevent) string { - if (e.Category == ktypes.File && e.GetParamAsString(kparams.FilePath) != "") || e.Category == ktypes.Registry { +func (c Config) AlertTitle(e *event.Event) string { + if (e.Category == event.File && e.GetParamAsString(params.FilePath) != "") || e.Category == event.Registry { return FileThreatAlertTitle } return MemoryThreatAlertTitle @@ -174,7 +173,7 @@ func (c Config) AlertTitle(e *kevent.Kevent) string { // AlertText returns the short alert text if the Go template is // not specified. On the contrary, the provided Go template is // parsed and executing yielding the alert text. -func (c Config) AlertText(e *kevent.Kevent, match ytypes.MatchRule) (string, error) { +func (c Config) AlertText(e *event.Event, match ytypes.MatchRule) (string, error) { if c.AlertTemplate == "" { threat := match.ThreatName() if threat == "" { @@ -186,7 +185,7 @@ func (c Config) AlertText(e *kevent.Kevent, match ytypes.MatchRule) (string, err var writer bytes.Buffer var data = struct { Match ytypes.MatchRule - Event *kevent.Kevent + Event *event.Event }{ match, e, diff --git a/pkg/yara/config/config_test.go b/pkg/yara/config/config_test.go index c5d55d70b..aee4a9c33 100644 --- a/pkg/yara/config/config_test.go +++ b/pkg/yara/config/config_test.go @@ -20,9 +20,8 @@ package config import ( "errors" - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" + "github.com/rabbitstack/fibratus/pkg/event/params" ytypes "github.com/rabbitstack/fibratus/pkg/yara/types" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -106,25 +105,25 @@ func TestShouldSkipFile(t *testing.T) { func TestAlertTitle(t *testing.T) { var tests = []struct { - e *kevent.Kevent + e *event.Event t string }{ { - &kevent.Kevent{Type: ktypes.MapViewFile, Category: ktypes.File}, + &event.Event{Type: event.MapViewFile, Category: event.File}, MemoryThreatAlertTitle, }, { - &kevent.Kevent{Type: ktypes.MapViewFile, Category: ktypes.File, - Kparams: kevent.Kparams{kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "C:\\Windows\\System32\\wusa.exe"}}, + &event.Event{Type: event.MapViewFile, Category: event.File, + Params: event.Params{params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "C:\\Windows\\System32\\wusa.exe"}}, }, FileThreatAlertTitle, }, { - &kevent.Kevent{Type: ktypes.RegSetValue, Category: ktypes.Registry}, + &event.Event{Type: event.RegSetValue, Category: event.Registry}, FileThreatAlertTitle, }, { - &kevent.Kevent{Type: ktypes.LoadImage, Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Category: event.Image}, MemoryThreatAlertTitle, }, } @@ -141,7 +140,7 @@ func TestAlertText(t *testing.T) { var tests = []struct { name string c Config - e *kevent.Kevent + e *event.Event m ytypes.MatchRule text string err error @@ -149,7 +148,7 @@ func TestAlertText(t *testing.T) { { "empty template and no threat_name meta", Config{}, - &kevent.Kevent{Type: ktypes.LoadImage, Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Category: event.Image}, ytypes.MatchRule{Rule: "Badlands Trojan"}, "Threat detected Badlands Trojan", nil, @@ -157,7 +156,7 @@ func TestAlertText(t *testing.T) { { "empty template and threat_name meta", Config{}, - &kevent.Kevent{Type: ktypes.LoadImage, Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Category: event.Image}, ytypes.MatchRule{Rule: "Badlands Trojan", Metas: []ytypes.Meta{{Identifier: "threat_name", Value: "Gravity Trojan"}}}, "Threat detected Gravity Trojan", nil, @@ -170,7 +169,7 @@ func TestAlertText(t *testing.T) { Event name: {{ .Event.Name -}} `, }, - &kevent.Kevent{Type: ktypes.LoadImage, Name: "LoadImage", Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Name: "LoadImage", Category: event.Image}, ytypes.MatchRule{Rule: "Badlands Trojan", Metas: []ytypes.Meta{{Identifier: "threat_name", Value: "Gravity Trojan"}}}, ` Rule name: Badlands Trojan @@ -185,7 +184,7 @@ func TestAlertText(t *testing.T) { Event name: {{ .Evet.Name -}} `, }, - &kevent.Kevent{Type: ktypes.LoadImage, Name: "LoadImage", Category: ktypes.Image}, + &event.Event{Type: event.LoadImage, Name: "LoadImage", Category: event.Image}, ytypes.MatchRule{Rule: "Badlands Trojan", Metas: []ytypes.Meta{{Identifier: "threat_name", Value: "Gravity Trojan"}}}, "", errors.New("yara alert template syntax error"), diff --git a/pkg/yara/scanner.go b/pkg/yara/scanner.go index 2d59437c3..fb3bf21bd 100644 --- a/pkg/yara/scanner.go +++ b/pkg/yara/scanner.go @@ -27,9 +27,8 @@ import ( "fmt" "github.com/google/uuid" "github.com/rabbitstack/fibratus/pkg/alertsender" + "github.com/rabbitstack/fibratus/pkg/event/params" libntfs "github.com/rabbitstack/fibratus/pkg/fs/ntfs" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/rabbitstack/fibratus/pkg/util/signature" "github.com/rabbitstack/fibratus/pkg/util/va" @@ -40,7 +39,7 @@ import ( "strings" "github.com/hillu/go-yara/v4" - "github.com/rabbitstack/fibratus/pkg/kevent" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/util/multierror" "github.com/rabbitstack/fibratus/pkg/yara/config" @@ -172,39 +171,39 @@ func parseCompilerErrors(errors []yara.CompilerMessage) error { func (s scanner) CanEnqueue() bool { return false } -func (s *scanner) ProcessEvent(evt *kevent.Kevent) (bool, error) { +func (s *scanner) ProcessEvent(evt *event.Event) (bool, error) { if evt.IsTerminateProcess() { // cleanup - pid := evt.Kparams.MustGetPid() + pid := evt.Params.MustGetPid() delete(s.rwxs, pid) delete(s.mmaps, pid) } return s.Scan(evt) } -func (s scanner) Scan(e *kevent.Kevent) (bool, error) { +func (s scanner) Scan(e *event.Event) (bool, error) { var matches yara.MatchRules var isScanned bool var err error switch e.Type { - case ktypes.CreateProcess: + case event.CreateProcess: // scan the created child process - pid := e.Kparams.MustGetPid() - log.Debugf("scanning child process. pid: %d, exe: %s", pid, e.GetParamAsString(kparams.Exe)) + pid := e.Params.MustGetPid() + log.Debugf("scanning child process. pid: %d, exe: %s", pid, e.GetParamAsString(params.Exe)) matches, err = s.scan(pid) procScans.Add(1) isScanned = true - case ktypes.LoadImage: + case event.LoadImage: // scan the process loading unsigned/untrusted module // or loading the module from unbacked memory region pid := e.PID - addr := e.Kparams.MustGetUint64(kparams.ImageBase) - typ := e.Kparams.MustGetUint32(kparams.ImageSignatureType) + addr := e.Params.MustGetUint64(params.ImageBase) + typ := e.Params.MustGetUint32(params.ImageSignatureType) if typ != signature.None { return false, nil } - filename := e.GetParamAsString(kparams.ImagePath) + filename := e.GetParamAsString(params.ImagePath) if s.config.ShouldSkipFile(filename) { return false, nil } @@ -225,7 +224,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { moduleScans.Add(1) isScanned = true } - case ktypes.CreateFile: + case event.CreateFile: if s.config.SkipFiles { return false, nil } @@ -233,15 +232,15 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { return false, nil } - filename := e.GetParamAsString(kparams.FilePath) + filename := e.GetParamAsString(params.FilePath) if s.config.ShouldSkipFile(filename) || (e.PS != nil && s.config.ShouldSkipProcess(e.PS.Exe)) { return false, nil } // scan dropped PE files - isDLL := strings.ToLower(filepath.Ext(filename)) == ".dll" || e.Kparams.TryGetBool(kparams.FileIsDLL) - isDriver := strings.ToLower(filepath.Ext(filename)) == ".sys" || e.Kparams.TryGetBool(kparams.FileIsDriver) - isExe := strings.ToLower(filepath.Ext(filename)) == ".exe" || e.Kparams.TryGetBool(kparams.FileIsExecutable) + isDLL := strings.ToLower(filepath.Ext(filename)) == ".dll" || e.Params.TryGetBool(params.FileIsDLL) + isDriver := strings.ToLower(filepath.Ext(filename)) == ".sys" || e.Params.TryGetBool(params.FileIsDriver) + isExe := strings.ToLower(filepath.Ext(filename)) == ".exe" || e.Params.TryGetBool(params.FileIsExecutable) if isExe || isDLL || isDriver { log.Debugf("scanning PE file %s. pid: %d", filename, e.PID) @@ -271,16 +270,16 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { streamScans.Add(1) isScanned = true } - case ktypes.VirtualAlloc: + case event.VirtualAlloc: if s.config.SkipAllocs { return false, nil } // scan process allocating RWX memory region - pid := e.Kparams.MustGetPid() - addr := e.Kparams.TryGetAddress(kparams.MemBaseAddress) - if e.PID != 4 && e.Kparams.TryGetUint32(kparams.MemProtect) == windows.PAGE_EXECUTE_READWRITE && !s.isRwxMatched(pid) { - log.Debugf("scanning RWX allocation. pid: %d, exe: %s, addr: %s", pid, e.GetParamAsString(kparams.Exe), - e.GetParamAsString(kparams.MemBaseAddress)) + pid := e.Params.MustGetPid() + addr := e.Params.TryGetAddress(params.MemBaseAddress) + if e.PID != 4 && e.Params.TryGetUint32(params.MemProtect) == windows.PAGE_EXECUTE_READWRITE && !s.isRwxMatched(pid) { + log.Debugf("scanning RWX allocation. pid: %d, exe: %s, addr: %s", pid, e.GetParamAsString(params.Exe), + e.GetParamAsString(params.MemBaseAddress)) matches, err = s.scan(pid) allocScans.Add(1) isScanned = true @@ -288,18 +287,18 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { s.rwxs[pid] = addr } } - case ktypes.MapViewFile: + case event.MapViewFile: if s.config.SkipMmaps { return false, nil } // scan process mapping a suspicious RX/RWX section view - pid := e.Kparams.MustGetPid() - prot := e.Kparams.MustGetUint32(kparams.MemProtect) - size := e.Kparams.MustGetUint64(kparams.FileViewSize) + pid := e.Params.MustGetPid() + prot := e.Params.MustGetUint32(params.MemProtect) + size := e.Params.MustGetUint64(params.FileViewSize) if e.PID != 4 && size >= 4096 && ((prot&sys.SectionRX) != 0 && (prot&sys.SectionRWX) != 0) && !s.isMmapMatched(pid) { - filename := e.GetParamAsString(kparams.FilePath) + filename := e.GetParamAsString(params.FilePath) // skip mappings of signed images - addr := e.Kparams.MustGetUint64(kparams.FileViewBase) + addr := e.Params.MustGetUint64(params.FileViewBase) sign := signature.GetSignatures().GetSignature(addr) if sign != nil && sign.IsSigned() && sign.IsTrusted() { return false, nil @@ -309,13 +308,13 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { if s.config.ShouldSkipFile(filename) { return false, nil } - log.Debugf("scanning %s section view mapping. filename: %s pid: %d, addr: %s", e.GetParamAsString(kparams.MemProtect), - filename, pid, e.GetParamAsString(kparams.FileViewBase)) + log.Debugf("scanning %s section view mapping. filename: %s pid: %d, addr: %s", e.GetParamAsString(params.MemProtect), + filename, pid, e.GetParamAsString(params.FileViewBase)) matches, err = s.scan(filename) } else { // otherwise, scan the process - log.Debugf("scanning %s section view mapping. pid: %d, addr: %s", e.GetParamAsString(kparams.MemProtect), pid, - e.GetParamAsString(kparams.FileViewBase)) + log.Debugf("scanning %s section view mapping. pid: %d, addr: %s", e.GetParamAsString(params.MemProtect), pid, + e.GetParamAsString(params.FileViewBase)) matches, err = s.scan(pid) } if len(matches) > 0 { @@ -324,7 +323,7 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { mmapScans.Add(1) isScanned = true } - case ktypes.RegSetValue: + case event.RegSetValue: if s.config.SkipRegistry { return false, nil } @@ -332,16 +331,16 @@ func (s scanner) Scan(e *kevent.Kevent) (bool, error) { return false, nil } // scan registry binary values - if typ := e.Kparams.TryGetUint32(kparams.RegValueType); typ != registry.BINARY { + if typ := e.Params.TryGetUint32(params.RegValueType); typ != registry.BINARY { return false, nil } - v, err := e.Kparams.Get(kparams.RegValue) + v, err := e.Params.Get(params.RegValue) if err != nil { // value not attached to the event return false, nil } if b, ok := v.Value.([]byte); ok && len(b) > 0 { - log.Debugf("scanning registry binary value %s. pid: %d", e.GetParamAsString(kparams.RegPath), e.PID) + log.Debugf("scanning registry binary value %s. pid: %d", e.GetParamAsString(params.RegPath), e.PID) matches, err = s.scan(b) registryScans.Add(1) isScanned = true @@ -389,7 +388,7 @@ func (s scanner) scan(target any) (yara.MatchRules, error) { return matches, nil } -func (s scanner) emit(matches yara.MatchRules, e *kevent.Kevent) error { +func (s scanner) emit(matches yara.MatchRules, e *event.Event) error { senders := alertsender.FindAll() if len(senders) == 0 { return fmt.Errorf("no alertsenders registered. Alert won't be sent") @@ -418,7 +417,7 @@ func (s scanner) emit(matches yara.MatchRules, e *kevent.Kevent) error { if err != nil { return err } - e.AddMeta(kevent.YaraMatchesKey, string(b)) + e.AddMeta(event.YaraMatchesKey, string(b)) // render alert title and text title := s.config.AlertTitle(e) @@ -444,7 +443,7 @@ func (s scanner) emit(matches yara.MatchRules, e *kevent.Kevent) error { id = uuid.New().String() } alert.ID = id - alert.Events = []*kevent.Kevent{e} + alert.Events = []*event.Event{e} alert.Labels = m.Labels() alert.Description = m.Description() diff --git a/pkg/yara/scanner_test.go b/pkg/yara/scanner_test.go index 86079cd8f..80f0d3a36 100644 --- a/pkg/yara/scanner_test.go +++ b/pkg/yara/scanner_test.go @@ -22,8 +22,7 @@ package yara import ( - "github.com/rabbitstack/fibratus/pkg/kevent" - "github.com/rabbitstack/fibratus/pkg/kevent/ktypes" + "github.com/rabbitstack/fibratus/pkg/event" "github.com/rabbitstack/fibratus/pkg/ps" pstypes "github.com/rabbitstack/fibratus/pkg/ps/types" "github.com/rabbitstack/fibratus/pkg/sys" @@ -39,7 +38,7 @@ import ( "time" "github.com/rabbitstack/fibratus/pkg/alertsender" - "github.com/rabbitstack/fibratus/pkg/kevent/kparams" + "github.com/rabbitstack/fibratus/pkg/event/params" "golang.org/x/sys/windows" ) @@ -74,14 +73,14 @@ func TestScan(t *testing.T) { var tests = []struct { name string - setup func() (*kevent.Kevent, error) + setup func() (*event.Event, error) newScanner func() (Scanner, error) expectedAlert alertsender.Alert matches bool }{ { "scan spawned process", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { var si windows.StartupInfo si.Flags = windows.STARTF_USESHOWWINDOW var pi windows.ProcessInformation @@ -123,16 +122,16 @@ func TestScan(t *testing.T) { } psnap.On("Find", pi.ProcessId).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e := &event.Event{ + Type: event.CreateProcess, Name: "CreateProcess", Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "notepad.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pi.ProcessId}, + Params: event.Params{ + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "notepad.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pi.ProcessId}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -161,7 +160,7 @@ func TestScan(t *testing.T) { }, { "scan spawned process excluded by config", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { var si windows.StartupInfo si.Flags = windows.STARTF_USESHOWWINDOW si.ShowWindow = windows.SW_HIDE @@ -204,16 +203,16 @@ func TestScan(t *testing.T) { } psnap.On("Find", pi.ProcessId).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateProcess, + e := &event.Event{ + Type: event.CreateProcess, Name: "CreateProcess", Tid: 2484, PID: 859, - Kparams: kevent.Kparams{ - kparams.ProcessName: {Name: kparams.ProcessName, Type: kparams.UnicodeString, Value: "notepad.exe"}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pi.ProcessId}, + Params: event.Params{ + params.ProcessName: {Name: params.ProcessName, Type: params.UnicodeString, Value: "notepad.exe"}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pi.ProcessId}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -238,7 +237,7 @@ func TestScan(t *testing.T) { }, { "scan unsigned module loading", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { var si windows.StartupInfo si.Flags = windows.STARTF_USESHOWWINDOW var pi windows.ProcessInformation @@ -281,18 +280,18 @@ func TestScan(t *testing.T) { } psnap.On("Find", pid).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.LoadImage, + e := &event.Event{ + Type: event.LoadImage, Name: "LoadImage", Tid: 2484, PID: pid, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: "tests.exe"}, - kparams.ImageBase: {Name: kparams.ImageBase, Type: kparams.Uint64, Value: uint64(0x74888fd99)}, - kparams.ImageSignatureType: {Name: kparams.ImageSignatureType, Type: kparams.Uint32, Value: signature.None}, - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pid}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: "tests.exe"}, + params.ImageBase: {Name: params.ImageBase, Type: params.Uint64, Value: uint64(0x74888fd99)}, + params.ImageSignatureType: {Name: params.ImageSignatureType, Type: params.Uint32, Value: signature.None}, + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pid}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -321,7 +320,7 @@ func TestScan(t *testing.T) { }, { "scan pe file created in the file system", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", @@ -335,17 +334,17 @@ func TestScan(t *testing.T) { } psnap.On("Find", 565).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "notepad.exe")}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "notepad.exe")}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint32, Value: uint32(windows.FILE_CREATE)}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -374,7 +373,7 @@ func TestScan(t *testing.T) { }, { "scan pe file excluded by config", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", @@ -388,17 +387,17 @@ func TestScan(t *testing.T) { } psnap.On("Find", 565).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint32, Value: uint32(windows.FILE_CREATE)}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -425,7 +424,7 @@ func TestScan(t *testing.T) { }, { "scan non-pe file created in the file system", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", @@ -439,17 +438,17 @@ func TestScan(t *testing.T) { } psnap.On("Find", 565).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "splwow64.xml")}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "splwow64.xml")}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint32, Value: uint32(windows.FILE_CREATE)}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -473,7 +472,7 @@ func TestScan(t *testing.T) { }, { "scan pe file excluded by generating process name", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", @@ -487,17 +486,17 @@ func TestScan(t *testing.T) { } psnap.On("Find", 565).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "System32", "cmd.exe")}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint32, Value: uint32(windows.FILE_CREATE)}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -524,7 +523,7 @@ func TestScan(t *testing.T) { }, { "scan ads created in the file system", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { ads := filepath.Join(os.TempDir(), "suspicious-ads.txt:mal") f, err := os.Create(ads) if err != nil { @@ -549,17 +548,17 @@ func TestScan(t *testing.T) { } psnap.On("Find", 565).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.CreateFile, + e := &event.Event{ + Type: event.CreateFile, Name: "CreateFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: ads}, - kparams.FileOperation: {Name: kparams.FileOperation, Type: kparams.Uint32, Value: uint32(windows.FILE_CREATE)}, + Params: event.Params{ + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: ads}, + params.FileOperation: {Name: params.FileOperation, Type: params.Uint32, Value: uint32(windows.FILE_CREATE)}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -588,7 +587,7 @@ func TestScan(t *testing.T) { }, { "scan rwx memory region allocation", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { var si windows.StartupInfo si.Flags = windows.STARTF_USESHOWWINDOW var pi windows.ProcessInformation @@ -632,18 +631,18 @@ func TestScan(t *testing.T) { } psnap.On("Find", pid).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.VirtualAlloc, + e := &event.Event{ + Type: event.VirtualAlloc, Name: "VirtualAlloc", - Category: ktypes.Mem, + Category: event.Mem, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pid}, - kparams.MemBaseAddress: {Name: kparams.MemBaseAddress, Type: kparams.Address, Value: uint64(0x7ffe0000)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(windows.PAGE_EXECUTE_READWRITE), Flags: kevent.MemProtectionFlags}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pid}, + params.MemBaseAddress: {Name: params.MemBaseAddress, Type: params.Address, Value: uint64(0x7ffe0000)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(windows.PAGE_EXECUTE_READWRITE), Flags: event.MemProtectionFlags}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -672,7 +671,7 @@ func TestScan(t *testing.T) { }, { "scan rx pagefile mmap", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { var si windows.StartupInfo si.Flags = windows.STARTF_USESHOWWINDOW var pi windows.ProcessInformation @@ -716,19 +715,19 @@ func TestScan(t *testing.T) { } psnap.On("Find", pid).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.MapViewFile, + e := &event.Event{ + Type: event.MapViewFile, Name: "MapViewFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: pid}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Address, Value: uint64(0x7ffe0000)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(12333)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(sys.SectionRX), Flags: kevent.ViewProtectionFlags}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: pid}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Address, Value: uint64(0x7ffe0000)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(12333)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(sys.SectionRX), Flags: event.ViewProtectionFlags}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -757,7 +756,7 @@ func TestScan(t *testing.T) { }, { "scan rx pagefile mmap address for signed module", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", PID: 1123, @@ -772,19 +771,19 @@ func TestScan(t *testing.T) { signature.GetSignatures().PutSignature(uint64(0x7f3e1000), &signature.Signature{Level: signature.AuthenticodeLevel, Type: signature.Catalog}) - e := &kevent.Kevent{ - Type: ktypes.MapViewFile, + e := &event.Event{ + Type: event.MapViewFile, Name: "MapViewFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1123)}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Address, Value: uint64(0x7f3e1000)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(12333)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(sys.SectionRX), Flags: kevent.ViewProtectionFlags}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1123)}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Address, Value: uint64(0x7f3e1000)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(12333)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(sys.SectionRX), Flags: event.ViewProtectionFlags}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -808,7 +807,7 @@ func TestScan(t *testing.T) { }, { "scan rx pagefile readonly mmap", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", PID: 321321, @@ -821,19 +820,19 @@ func TestScan(t *testing.T) { } psnap.On("Find", uint32(321321)).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.MapViewFile, + e := &event.Event{ + Type: event.MapViewFile, Name: "MapViewFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 321321, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(321321)}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Address, Value: uint64(0x7ffe0000)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(12333)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(0x10000), Flags: kevent.ViewProtectionFlags}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(321321)}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Address, Value: uint64(0x7ffe0000)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(12333)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(0x10000), Flags: event.ViewProtectionFlags}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -857,7 +856,7 @@ func TestScan(t *testing.T) { }, { "scan rwx image file mmap", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", PID: 1123, @@ -870,20 +869,20 @@ func TestScan(t *testing.T) { } psnap.On("Find", 1123).Return(true, proc) - e := &kevent.Kevent{ - Type: ktypes.MapViewFile, + e := &event.Event{ + Type: event.MapViewFile, Name: "MapViewFile", - Category: ktypes.File, + Category: event.File, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.ProcessID: {Name: kparams.ProcessID, Type: kparams.PID, Value: uint32(1123)}, - kparams.FilePath: {Name: kparams.FilePath, Type: kparams.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "regedit.exe")}, - kparams.FileViewBase: {Name: kparams.FileViewBase, Type: kparams.Address, Value: uint64(0x7ffe0000)}, - kparams.FileViewSize: {Name: kparams.FileViewSize, Type: kparams.Uint64, Value: uint64(12333)}, - kparams.MemProtect: {Name: kparams.MemProtect, Type: kparams.Flags, Value: uint32(sys.SectionRWX), Flags: kevent.ViewProtectionFlags}, + Params: event.Params{ + params.ProcessID: {Name: params.ProcessID, Type: params.PID, Value: uint32(1123)}, + params.FilePath: {Name: params.FilePath, Type: params.UnicodeString, Value: filepath.Join(os.Getenv("windir"), "regedit.exe")}, + params.FileViewBase: {Name: params.FileViewBase, Type: params.Address, Value: uint64(0x7ffe0000)}, + params.FileViewSize: {Name: params.FileViewSize, Type: params.Uint64, Value: uint64(12333)}, + params.MemProtect: {Name: params.MemProtect, Type: params.Flags, Value: uint32(sys.SectionRWX), Flags: event.ViewProtectionFlags}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -912,7 +911,7 @@ func TestScan(t *testing.T) { }, { "scan registry binary value", - func() (*kevent.Kevent, error) { + func() (*event.Event, error) { proc := &pstypes.PS{ Name: "tests.exe", PID: 1123, @@ -926,18 +925,18 @@ func TestScan(t *testing.T) { psnap.On("Find", 1123).Return(true, proc) data := []byte{0x6F, 0x66, 0x74, 0x2E, 0x4E, 0x6F, 0x74, 0x65, 0x70, 0x61, 0x64, 0x00, 0x13, 0x00, 0x01, 0x1A} - e := &kevent.Kevent{ - Type: ktypes.RegSetValue, + e := &event.Event{ + Type: event.RegSetValue, Name: "RegSetValue", - Category: ktypes.Registry, + Category: event.Registry, Tid: 2484, PID: 565, - Kparams: kevent.Kparams{ - kparams.RegValueType: {Name: kparams.RegValueType, Type: kparams.Uint32, Value: uint32(registry.BINARY)}, - kparams.RegValue: {Name: kparams.RegValue, Type: kparams.Binary, Value: data}, - kparams.RegPath: {Name: kparams.RegPath, Type: kparams.UnicodeString, Value: `HKEY_LOCAL_MACHINE\CurrentControlSet\Control\DeviceGuard\Mal`}, + Params: event.Params{ + params.RegValueType: {Name: params.RegValueType, Type: params.Uint32, Value: uint32(registry.BINARY)}, + params.RegValue: {Name: params.RegValue, Type: params.Binary, Value: data}, + params.RegPath: {Name: params.RegPath, Type: params.UnicodeString, Value: `HKEY_LOCAL_MACHINE\CurrentControlSet\Control\DeviceGuard\Mal`}, }, - Metadata: make(map[kevent.MetadataKey]any), + Metadata: make(map[event.MetadataKey]any), PS: proc, } return e, nil @@ -990,12 +989,12 @@ func TestScan(t *testing.T) { assert.True(t, len(yaraAlert.Labels) > 0) assert.Len(t, yaraAlert.Events, 1) assert.NotEmpty(t, e.Metadata) - assert.Contains(t, e.Metadata, kevent.YaraMatchesKey) + assert.Contains(t, e.Metadata, event.YaraMatchesKey) } if e.IsCreateProcess() || e.IsLoadImage() || e.IsVirtualAlloc() || e.IsMapViewFile() { // cleanup - proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, e.Kparams.MustGetPid()) + proc, err := windows.OpenProcess(windows.PROCESS_TERMINATE, false, e.Params.MustGetPid()) if err == nil { windows.TerminateProcess(proc, uint32(257)) windows.Close(proc) diff --git a/pkg/yara/types.go b/pkg/yara/types.go index 2710eb00e..c26d0e08f 100644 --- a/pkg/yara/types.go +++ b/pkg/yara/types.go @@ -18,17 +18,17 @@ package yara -import "github.com/rabbitstack/fibratus/pkg/kevent" +import "github.com/rabbitstack/fibratus/pkg/event" // Scanner watches for certain events such as process creation or image loading and // triggers the scanning either on the process memory or on-disk file. If matches occur, // an alert is emitted via registered alert senders. type Scanner interface { - kevent.Listener + event.Listener // Scan runs a scan when the specified signal is observed. The signal // can be the creation of a new process, image loading, writing the PE // file or ADS to the file system, or a suspicious memory allocation. - Scan(*kevent.Kevent) (bool, error) + Scan(*event.Event) (bool, error) // Close disposes any resources allocated by the scanner. Close() } From beaf3ca6de96fe1aab29a34da7805f5d80d5a163 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Mon, 26 May 2025 21:52:21 +0200 Subject: [PATCH 2/4] refactor: Trim the `k` prefix from config types Most notable change is the refactoring of KstreamConfig to EventSourceConfig type along with other changes that trim the `k` prefix from types, identifiers or methods. --- cmd/fibratus/app/config/config.go | 4 +- cmd/fibratus/app/stats/stats.go | 4 +- configs/fibratus.json | 6 +- configs/fibratus.yml | 64 +++---- filaments/teamviewer_remote_file_copy.py | 4 +- internal/bootstrap/bootstrap.go | 6 +- internal/etw/consumer.go | 6 +- internal/etw/processors/chain_windows.go | 12 +- internal/etw/processors/fs_windows.go | 4 +- internal/etw/source.go | 28 ++-- internal/etw/source_test.go | 156 +++++++++--------- internal/etw/stackext.go | 14 +- internal/etw/stackext_test.go | 16 +- internal/etw/trace.go | 30 ++-- internal/etw/trace_test.go | 12 +- pkg/aggregator/aggregator_test.go | 8 +- pkg/cap/reader.go | 4 +- pkg/cap/reader_windows.go | 8 +- pkg/cap/section/section_windows_test.go | 6 +- pkg/cap/writer.go | 2 +- pkg/cap/writer_unsupported.go | 4 +- pkg/cap/writer_windows.go | 10 +- pkg/cap/writer_windows_test.go | 18 +- pkg/config/_fixtures/fibratus.json | 6 +- pkg/config/_fixtures/fibratus.yml | 18 +- pkg/config/_fixtures/http-output.yml | 2 +- pkg/config/_fixtures/output.yml | 2 +- pkg/config/_fixtures/transformers.yml | 2 +- pkg/config/config_windows.go | 58 +++---- pkg/config/{kstream.go => eventsource.go} | 114 ++++++------- .../{kstream_test.go => eventsource_test.go} | 34 ++-- pkg/config/print_test.go | 2 +- pkg/config/schema_windows.go | 10 +- pkg/event/formatter.go | 12 +- pkg/event/formatter_windows.go | 4 +- pkg/event/marshaller_test.go | 8 +- pkg/event/marshaller_windows.go | 2 +- pkg/event/queue.go | 6 +- pkg/event/types_windows.go | 8 +- pkg/filament/_fixtures/test_filter.py | 8 +- ...n_next_kevent.py => test_on_next_event.py} | 12 +- pkg/filament/_fixtures/top_hives_io.py | 2 +- pkg/filament/_fixtures/top_keys_io_table.py | 2 +- .../cpython/_fixtures/top_hives_io.py | 4 +- pkg/filament/dict_test.go | 8 +- pkg/filament/filament.go | 78 ++++----- pkg/filament/filament_test.go | 10 +- pkg/filter/filter_test.go | 18 +- pkg/filter/filter_windows.go | 20 +-- pkg/filter/ql/functions/yara_unsupported.go | 4 +- pkg/handle/snapshotter.go | 4 +- pkg/handle/types/types.go | 4 +- pkg/outputs/amqp/amqp_test.go | 22 +-- pkg/outputs/http/http_test.go | 12 +- pkg/pe/marshaller.go | 4 +- pkg/pe/marshaller_test.go | 4 +- pkg/ps/types/marshaller_windows.go | 4 +- pkg/ps/types/marshaller_windows_test.go | 10 +- pkg/ps/types/types_windows.go | 4 +- pkg/rules/engine_test.go | 17 +- pkg/rules/sequence_test.go | 22 +-- pkg/yara/scanner_unsupported.go | 4 +- 62 files changed, 495 insertions(+), 496 deletions(-) rename pkg/config/{kstream.go => eventsource.go} (56%) rename pkg/config/{kstream_test.go => eventsource_test.go} (53%) rename pkg/filament/_fixtures/{test_on_next_kevent.py => test_on_next_event.py} (77%) diff --git a/cmd/fibratus/app/config/config.go b/cmd/fibratus/app/config/config.go index 6ef1feded..88810d92b 100644 --- a/cmd/fibratus/app/config/config.go +++ b/cmd/fibratus/app/config/config.go @@ -22,7 +22,7 @@ import ( "fmt" "github.com/rabbitstack/fibratus/internal/bootstrap" "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/util/rest" "github.com/spf13/cobra" "os" @@ -49,7 +49,7 @@ func printConfig(cmd *cobra.Command, args []string) error { } body, err := rest.Get(rest.WithTransport(cfg.API.Transport), rest.WithURI("config")) if err != nil { - return kerrors.ErrHTTPServerUnavailable(cfg.API.Transport, err) + return errs.ErrHTTPServerUnavailable(cfg.API.Transport, err) } _, err = fmt.Fprintln(os.Stdout, string(body)) if err != nil { diff --git a/cmd/fibratus/app/stats/stats.go b/cmd/fibratus/app/stats/stats.go index 1335217ed..929775409 100644 --- a/cmd/fibratus/app/stats/stats.go +++ b/cmd/fibratus/app/stats/stats.go @@ -26,7 +26,7 @@ import ( "github.com/jedib0t/go-pretty/v6/table" "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/util/rest" "github.com/spf13/cobra" ) @@ -123,7 +123,7 @@ func stats(cmd *cobra.Command, args []string) error { c := cfg.API body, err := rest.Get(rest.WithTransport(c.Transport), rest.WithURI("debug/vars")) if err != nil { - return kerrors.ErrHTTPServerUnavailable(c.Transport, err) + return errs.ErrHTTPServerUnavailable(c.Transport, err) } var stats Stats if err := json.Unmarshal(body, &stats); err != nil { diff --git a/configs/fibratus.json b/configs/fibratus.json index cac66b122..b41e7bdb3 100644 --- a/configs/fibratus.json +++ b/configs/fibratus.json @@ -30,15 +30,15 @@ "init-snapshot": true }, - "kevent": { + "event": { }, - "kcap": { + "cap": { }, - "kstream": {}, + "eventsource": {}, "logging": {}, "output": { diff --git a/configs/fibratus.yml b/configs/fibratus.yml index aca889811..28a2cb34e 100644 --- a/configs/fibratus.yml +++ b/configs/fibratus.yml @@ -2,10 +2,10 @@ # =============================== Aggregator ========================================== -# Aggregator is responsible for creating kernel event batches, applying transformers to each event +# Aggregator is responsible for creating event batches, applying transformers to each event # present in the batch, and forwarding those batches to the output sinks. aggregator: - # Determines the flush period that triggers the flushing of the kernel event batches to output sinks + # Determines the flush period that triggers the flushing of the event batches to output sinks flush-period: 500ms # Represents the max time to wait before announcing failed flushing of enqueued events when fibratus @@ -111,7 +111,7 @@ forward: false # =============================== Filament ============================================= -# Filaments are lightweight Python scriplets that are executed on top of the kernel event stream. You can easily +# Filaments are lightweight Python scriplets that are executed on top of the event stream. You can easily # extend Fibratus with custom features that is encapsulated in filaments. This section controls the behaviour of # the filament engine. filament: @@ -156,10 +156,10 @@ handle: # Indicates if process handles are collected during startup or when a new process is spawn. enumerate-handles: false -# =============================== Kevent =============================================== +# =============================== Event =============================================== -# The following settings control the state of the kernel event. -kevent: +# The following settings control the state of the event. +event: # Indicates if threads are serialized as part of the process state serialize-threads: false @@ -175,19 +175,19 @@ kevent: # Indicates if environment variables are serialized as part of the process state serialize-envs: false -# =============================== Kcap ================================================= +# =============================== Capture ================================================= -# Contains the settings that dictate the behaviour of the kernel event captures. +# Contains the settings that dictate the behaviour of the captures. -kcap: - # Specifies the name of the output kcap file. If not empty, capture files are always stored +cap: + # Specifies the name of the output cap file. If not empty, capture files are always stored # to this file by overwriting any existing capture file file: "" -# =============================== Kstream ============================================== +# =============================== Event source ============================================== -# Tweaks for controlling the behaviour of the kernel stream consumer. -kstream: +# Tweaks for controlling the behaviour of the event source. +eventsource: # Determines the maximum number of buffers allocated for the event tracing session's buffer pool #max-buffers: @@ -202,32 +202,32 @@ kstream: # less memory but it increases the rate at which buffers must be flushed) #buffer-size: - # Determines whether thread kernel events are collected by Kernel Logger provider + # Determines whether thread events are collected by Kernel Logger provider #enable-thread: true - # Determines whether registry kernel events are collected by Kernel Logger provider + # Determines whether registry events are collected by Kernel Logger provider #enable-registry: true - # Determines whether network kernel events are collected by Kernel Logger provider + # Determines whether network events are collected by Kernel Logger provider #enable-net: true - # Determines whether file kernel events are collected by Kernel Logger provider + # Determines whether file events are collected by Kernel Logger provider #enable-fileio: true # Determines whether VA map/unmap events are collected by Kernel Logger provider #enable-vamap: true - # Determines whether image kernel events are collected by Kernel Logger provider + # Determines whether image events are collected by Kernel Logger provider #enable-image: true - # Determines whether object manager kernel events (handle creation/destruction) are + # Determines whether object manager events (handle creation/destruction) are # collected by Kernel Logger provider #enable-handle: false - # Determines whether memory manager kernel events are collected by Kernel Logger provider + # Determines whether memory manager events are collected by Kernel Logger provider #enable-mem: true - # Determines whether kernel Audit API calls events are collected + # Determines whether Audit API calls events are collected #enable-audit-api: true # Determines whether DNS client events are collected @@ -282,7 +282,7 @@ logging: # =============================== Output ================================================ -# Outputs transport the event flowing through kernel event stream to its final destination. Only one output +# Outputs transport the event flowing through event stream to its final destination. Only one output # can be active at the time. The following section contains available outputs and their preferences. output: # Console output writes the event to standard output stream. @@ -296,7 +296,7 @@ output: # Template that's feed into event formatter. The default event formatter template is: # - # {{ .Seq }} {{ .Timestamp }} - {{ .CPU }} {{ .Process }} ({{ .Pid }}) - {{ .Type }} ({{ .Kparams }}) + # {{ .Seq }} {{ .Timestamp }} - {{ .CPU }} {{ .Process }} ({{ .Pid }}) - {{ .Type }} ({{ .Params }}) # #template: @@ -330,7 +330,7 @@ output: # Specifies the timeout for periodic health checks #healthcheck-timeout: 5s - # Identifies the user name for the basic HTTP authentication + # Identifies the username for the basic HTTP authentication #username: # Identifies the password for the basic HTTP authentication @@ -349,7 +349,7 @@ output: # Specifies the name of the index template #template-name: fibratus - # Represents the target index for kernel events. It allows time specifiers to create indices per time frame. + # Represents the target index for events. It allows time specifiers to create indices per time frame. # For example, fibratus-%Y-%m generates the index name with current year and month time specifiers #index-name: fibratus @@ -380,7 +380,7 @@ output: # Specifies the AMQP connection timeout #timeout: 5s - # Specifies target exchange name that receives inbound kernel events + # Specifies target exchange name that receives inbound events #exchange: fibratus # Represents the AMQP exchange type. Available exchange type include common types are "direct", "fanout", @@ -519,7 +519,7 @@ pe: # =============================== Transformers ========================================= -# Transformers are responsible for augmenting, parsing or enriching kernel events. +# Transformers are responsible for augmenting, parsing or enriching events. transformers: # Remove transformer deletes provided event parameters. remove: @@ -527,7 +527,7 @@ transformers: enabled: false # Represents the list of parameters that are removed from the event - #kparams: + #params: # - irp # Rename transformer renames parameter from old to new name. @@ -537,7 +537,7 @@ transformers: # Contains the list of old/new mappings. Old represents the original # parameter name, while new is the new parameter name - #kparams: + #params: # - old: # new: @@ -549,7 +549,7 @@ transformers: # Contains the list of parameter replacements. For each target event parameter, the old represent the substring # that gets replaced by the new string. #replacements: - # - kparam: + # - param: # old: # new: @@ -571,12 +571,12 @@ transformers: # Contains the list of parameters associated with the prefix that is trimmed from the parameter's value #prefixes: - # - kparam: + # - param: # trim: # Contains the list of parameters associated with the suffix that is trimmed from the parameter's value #suffixes: - # - kparam: + # - param: # trim: # =============================== YARA ================================================= diff --git a/filaments/teamviewer_remote_file_copy.py b/filaments/teamviewer_remote_file_copy.py index 5e8ae067b..1850e553d 100644 --- a/filaments/teamviewer_remote_file_copy.py +++ b/filaments/teamviewer_remote_file_copy.py @@ -52,13 +52,13 @@ def on_init(): - kfilter("evt.name = 'CreateFile' and ps.name = 'TeamViewer.exe' and file.operation = 'create' " + set_filter("evt.name = 'CreateFile' and ps.name = 'TeamViewer.exe' and file.operation = 'create' " "and file.extension in (%s)" % (', '.join([f'\'{ext}\'' for ext in extensions]))) @dotdictify -def on_next_kevent(event): +def on_next_event(event): emit_alert( f'Remote File Copy via TeamViewer', f'TeamViewer downloaded an executable or script file {event.params.file_name} via transfer session', diff --git a/internal/bootstrap/bootstrap.go b/internal/bootstrap/bootstrap.go index 395c8d4b5..7cd552db1 100644 --- a/internal/bootstrap/bootstrap.go +++ b/internal/bootstrap/bootstrap.go @@ -120,7 +120,7 @@ func NewApp(cfg *config.Config, options ...Option) (*App, error) { sigs = signals.Install() } if opts.isCaptureReplay { - reader, err := cap.NewReader(cfg.KcapFile, cfg) + reader, err := cap.NewReader(cfg.CapFile, cfg) if err != nil { return nil, err } @@ -230,7 +230,7 @@ func (f *App) Run(args []string) error { }() } else { // register stack symbolizer - if cfg.Kstream.StackEnrichment { + if cfg.EventSource.StackEnrichment { f.symbolizer = symbolize.NewSymbolizer(symbolize.NewDebugHelpResolver(cfg), f.psnap, cfg, false) f.evs.RegisterEventListener(f.symbolizer) } @@ -288,7 +288,7 @@ func (f *App) WriteCapture(args []string) error { if err != nil { return err } - f.writer, err = cap.NewWriter(f.config.KcapFile, f.psnap, f.hsnap) + f.writer, err = cap.NewWriter(f.config.CapFile, f.psnap, f.hsnap) if err != nil { return err } diff --git a/internal/etw/consumer.go b/internal/etw/consumer.go index f3d4cff65..78fed5590 100644 --- a/internal/etw/consumer.go +++ b/internal/etw/consumer.go @@ -53,7 +53,7 @@ func NewConsumer( evts chan *event.Event, ) *Consumer { return &Consumer{ - q: event.NewQueueWithChannel(evts, config.Kstream.StackEnrichment, config.ForwardMode || config.IsCaptureSet()), + q: event.NewQueueWithChannel(evts, config.EventSource.StackEnrichment, config.ForwardMode || config.IsCaptureSet()), sequencer: sequencer, processors: processors.NewChain(psnap, hsnap, config), psnap: psnap, @@ -77,7 +77,7 @@ func (c *Consumer) ProcessEvent(ev *etw.EventRecord) error { if event.IsCurrentProcDropped(ev.Header.ProcessID) { return nil } - if c.config.Kstream.ExcludeKevent(ev.Header.ProviderID, ev.HookID()) { + if c.config.EventSource.ExcludeEvent(ev.Header.ProviderID, ev.HookID()) { eventsExcluded.Add(1) return nil } @@ -129,7 +129,7 @@ func (c *Consumer) ProcessEvent(ev *etw.EventRecord) error { // the filter is evaluated on the event to // decide whether it should get dropped if (evt.IsDropped(c.config.IsCaptureSet()) || - c.config.Kstream.ExcludeImage(evt.PS)) && !evt.IsStackWalk() { + c.config.EventSource.ExcludeImage(evt.PS)) && !evt.IsStackWalk() { eventsExcluded.Add(1) return nil } diff --git a/internal/etw/processors/chain_windows.go b/internal/etw/processors/chain_windows.go index 0036a0d26..d3651b0e7 100644 --- a/internal/etw/processors/chain_windows.go +++ b/internal/etw/processors/chain_windows.go @@ -50,22 +50,22 @@ func NewChain( chain.addProcessor(newPsProcessor(psnap, vaRegionProber)) - if config.Kstream.EnableFileIOKevents { + if config.EventSource.EnableFileIOEvents { chain.addProcessor(newFsProcessor(hsnap, psnap, devMapper, devPathResolver, config)) } - if config.Kstream.EnableRegistryKevents { + if config.EventSource.EnableRegistryEvents { chain.addProcessor(newRegistryProcessor(hsnap)) } - if config.Kstream.EnableImageKevents { + if config.EventSource.EnableImageEvents { chain.addProcessor(newImageProcessor(psnap)) } - if config.Kstream.EnableNetKevents { + if config.EventSource.EnableNetEvents { chain.addProcessor(newNetProcessor()) } - if config.Kstream.EnableHandleKevents { + if config.EventSource.EnableHandleEvents { chain.addProcessor(newHandleProcessor(hsnap, psnap, devMapper, devPathResolver)) } - if config.Kstream.EnableMemKevents { + if config.EventSource.EnableMemEvents { chain.addProcessor(newMemProcessor(psnap, vaRegionProber)) } diff --git a/internal/etw/processors/fs_windows.go b/internal/etw/processors/fs_windows.go index b1090ee60..f8737868c 100644 --- a/internal/etw/processors/fs_windows.go +++ b/internal/etw/processors/fs_windows.go @@ -208,7 +208,7 @@ func (f *fsProcessor) processEvent(e *event.Event) (*event.Event, error) { f.files[fileObject] = fileinfo } - if f.config.Kstream.EnableHandleKevents { + if f.config.EventSource.EnableHandleEvents { f.devPathResolver.AddPath(ev.GetParamAsString(params.FilePath)) } @@ -228,7 +228,7 @@ func (f *fsProcessor) processEvent(e *event.Event) (*event.Event, error) { // the previous stack walk for CreateFile is popped from // the queue and the callstack parameter attached to the // event. - if f.config.Kstream.StackEnrichment { + if f.config.EventSource.StackEnrichment { f.mu.Lock() defer f.mu.Unlock() diff --git a/internal/etw/source.go b/internal/etw/source.go index 3404a337a..5bcc62456 100644 --- a/internal/etw/source.go +++ b/internal/etw/source.go @@ -125,16 +125,16 @@ func (e *EventSource) Open(config *config.Config) error { // disabled in the config, then thread events // are not captured if e.r != nil { - config.Kstream.EnableThreadKevents = config.Kstream.EnableThreadKevents && e.r.HasThreadEvents - config.Kstream.EnableImageKevents = config.Kstream.EnableImageKevents && e.r.HasImageEvents - config.Kstream.EnableNetKevents = config.Kstream.EnableNetKevents && e.r.HasNetworkEvents - config.Kstream.EnableRegistryKevents = config.Kstream.EnableRegistryKevents && (e.r.HasRegistryEvents || (config.Yara.Enabled && !config.Yara.SkipRegistry)) - config.Kstream.EnableFileIOKevents = config.Kstream.EnableFileIOKevents && (e.r.HasFileEvents || (config.Yara.Enabled && !config.Yara.SkipFiles)) - config.Kstream.EnableVAMapKevents = config.Kstream.EnableVAMapKevents && (e.r.HasVAMapEvents || (config.Yara.Enabled && !config.Yara.SkipMmaps)) - config.Kstream.EnableMemKevents = config.Kstream.EnableMemKevents && (e.r.HasMemEvents || (config.Yara.Enabled && !config.Yara.SkipAllocs)) - config.Kstream.EnableDNSEvents = config.Kstream.EnableDNSEvents && e.r.HasDNSEvents - config.Kstream.EnableAuditAPIEvents = config.Kstream.EnableAuditAPIEvents && e.r.HasAuditAPIEvents - config.Kstream.EnableThreadpoolEvents = config.Kstream.EnableThreadpoolEvents && e.r.HasThreadpoolEvents + config.EventSource.EnableThreadEvents = config.EventSource.EnableThreadEvents && e.r.HasThreadEvents + config.EventSource.EnableImageEvents = config.EventSource.EnableImageEvents && e.r.HasImageEvents + config.EventSource.EnableNetEvents = config.EventSource.EnableNetEvents && e.r.HasNetworkEvents + config.EventSource.EnableRegistryEvents = config.EventSource.EnableRegistryEvents && (e.r.HasRegistryEvents || (config.Yara.Enabled && !config.Yara.SkipRegistry)) + config.EventSource.EnableFileIOEvents = config.EventSource.EnableFileIOEvents && (e.r.HasFileEvents || (config.Yara.Enabled && !config.Yara.SkipFiles)) + config.EventSource.EnableVAMapEvents = config.EventSource.EnableVAMapEvents && (e.r.HasVAMapEvents || (config.Yara.Enabled && !config.Yara.SkipMmaps)) + config.EventSource.EnableMemEvents = config.EventSource.EnableMemEvents && (e.r.HasMemEvents || (config.Yara.Enabled && !config.Yara.SkipAllocs)) + config.EventSource.EnableDNSEvents = config.EventSource.EnableDNSEvents && e.r.HasDNSEvents + config.EventSource.EnableAuditAPIEvents = config.EventSource.EnableAuditAPIEvents && e.r.HasAuditAPIEvents + config.EventSource.EnableThreadpoolEvents = config.EventSource.EnableThreadpoolEvents && e.r.HasThreadpoolEvents for _, typ := range event.All() { if typ == event.CreateProcess || typ == event.TerminateProcess || typ == event.LoadImage || typ == event.UnloadImage { @@ -157,20 +157,20 @@ func (e *EventSource) Open(config *config.Config) error { } if !e.r.ContainsEvent(typ) { - config.Kstream.SetDropMask(typ) + config.EventSource.SetDropMask(typ) } } } e.addTrace(etw.KernelLoggerSession, etw.KernelTraceControlGUID) - if config.Kstream.EnableDNSEvents { + if config.EventSource.EnableDNSEvents { e.addTrace(etw.DNSClientSession, etw.DNSClientGUID) } - if config.Kstream.EnableAuditAPIEvents { + if config.EventSource.EnableAuditAPIEvents { e.addTrace(etw.KernelAuditAPICallsSession, etw.KernelAuditAPICallsGUID) } - if config.Kstream.EnableThreadpoolEvents { + if config.EventSource.EnableThreadpoolEvents { e.addTrace(etw.ThreadpoolSession, etw.ThreadpoolGUID) } diff --git a/internal/etw/source_test.go b/internal/etw/source_test.go index a3a73b9ea..ee4222e37 100644 --- a/internal/etw/source_test.go +++ b/internal/etw/source_test.go @@ -88,13 +88,13 @@ func TestEventSourceStartTraces(t *testing.T) { }{ {"start kernel logger session", &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableNetKevents: true, - EnableFileIOKevents: true, - EnableVAMapKevents: true, - BufferSize: 1024, - FlushTimer: time.Millisecond * 2300, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableNetEvents: true, + EnableFileIOEvents: true, + EnableVAMapEvents: true, + BufferSize: 1024, + FlushTimer: time.Millisecond * 2300, }, Filters: &config.Filters{}, }, @@ -103,16 +103,16 @@ func TestEventSourceStartTraces(t *testing.T) { }, {"start kernel logger and audit api sessions", &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableNetKevents: true, - EnableFileIOKevents: true, - EnableVAMapKevents: true, - EnableHandleKevents: true, - EnableRegistryKevents: true, - BufferSize: 1024, - FlushTimer: time.Millisecond * 2300, - EnableAuditAPIEvents: true, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableNetEvents: true, + EnableFileIOEvents: true, + EnableVAMapEvents: true, + EnableHandleEvents: true, + EnableRegistryEvents: true, + BufferSize: 1024, + FlushTimer: time.Millisecond * 2300, + EnableAuditAPIEvents: true, }, Filters: &config.Filters{}, }, @@ -183,12 +183,12 @@ func TestEventSourceEnableFlagsDynamically(t *testing.T) { }, } cfg := &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableRegistryKevents: true, - EnableImageKevents: true, - EnableFileIOKevents: true, - EnableAuditAPIEvents: true, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableRegistryEvents: true, + EnableImageEvents: true, + EnableFileIOEvents: true, + EnableAuditAPIEvents: true, }, Filters: &config.Filters{}, } @@ -197,7 +197,7 @@ func TestEventSourceEnableFlagsDynamically(t *testing.T) { require.NoError(t, evs.Open(cfg)) defer evs.Close() - flags := evs.(*EventSource).traces[0].enableFlagsDynamically(cfg.Kstream) + flags := evs.(*EventSource).traces[0].enableFlagsDynamically(cfg.EventSource) require.Len(t, evs.(*EventSource).traces, 2) @@ -216,10 +216,10 @@ func TestEventSourceEnableFlagsDynamically(t *testing.T) { // but VAMap is disabled in the config require.True(t, flags&etw.VaMap == 0) - require.False(t, cfg.Kstream.TestDropMask(event.UnloadImage)) - require.True(t, cfg.Kstream.TestDropMask(event.WriteFile)) - require.True(t, cfg.Kstream.TestDropMask(event.UnmapViewFile)) - require.False(t, cfg.Kstream.TestDropMask(event.OpenProcess)) + require.False(t, cfg.EventSource.TestDropMask(event.UnloadImage)) + require.True(t, cfg.EventSource.TestDropMask(event.WriteFile)) + require.True(t, cfg.EventSource.TestDropMask(event.UnmapViewFile)) + require.False(t, cfg.EventSource.TestDropMask(event.OpenProcess)) } func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { @@ -259,14 +259,14 @@ func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { }, } cfg := &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableRegistryKevents: true, - EnableImageKevents: true, - EnableFileIOKevents: true, - EnableAuditAPIEvents: true, - EnableVAMapKevents: false, - EnableMemKevents: true, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableRegistryEvents: true, + EnableImageEvents: true, + EnableFileIOEvents: true, + EnableAuditAPIEvents: true, + EnableVAMapEvents: false, + EnableMemEvents: true, }, Filters: &config.Filters{}, Yara: yara.Config{ @@ -281,7 +281,7 @@ func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { require.NoError(t, evs.Open(cfg)) defer evs.Close() - flags := evs.(*EventSource).traces[0].enableFlagsDynamically(cfg.Kstream) + flags := evs.(*EventSource).traces[0].enableFlagsDynamically(cfg.EventSource) // rules compile result doesn't have file events // but Yara file scanning is enabled @@ -292,9 +292,9 @@ func TestEventSourceEnableFlagsDynamicallyWithYaraEnabled(t *testing.T) { // alloc scanning is enabled require.True(t, flags&etw.VirtualAlloc != 0) - require.False(t, cfg.Kstream.TestDropMask(event.CreateFile)) - require.True(t, cfg.Kstream.TestDropMask(event.MapViewFile)) - require.False(t, cfg.Kstream.TestDropMask(event.VirtualAlloc)) + require.False(t, cfg.EventSource.TestDropMask(event.CreateFile)) + require.True(t, cfg.EventSource.TestDropMask(event.MapViewFile)) + require.False(t, cfg.EventSource.TestDropMask(event.VirtualAlloc)) } func TestEventSourceRundownEvents(t *testing.T) { @@ -315,17 +315,17 @@ func TestEventSourceRundownEvents(t *testing.T) { hsnap.On("FindByObject", mock.Anything).Return(htypes.Handle{}, false) hsnap.On("FindHandles", mock.Anything).Return([]htypes.Handle{}, nil) - kstreamConfig := config.KstreamConfig{ - EnableThreadKevents: true, - EnableImageKevents: true, - EnableFileIOKevents: true, - EnableNetKevents: true, - EnableRegistryKevents: true, + evsConfig := config.EventSourceConfig{ + EnableThreadEvents: true, + EnableImageEvents: true, + EnableFileIOEvents: true, + EnableNetEvents: true, + EnableRegistryEvents: true, } cfg := &config.Config{ - Kstream: kstreamConfig, - KcapFile: "fake.cap", // simulate capture to receive state/rundown events - Filters: &config.Filters{}, + EventSource: evsConfig, + CapFile: "fake.cap", // simulate capture to receive state/rundown events + Filters: &config.Filters{}, } evs := NewEventSource(psnap, hsnap, cfg, nil) @@ -727,21 +727,21 @@ func TestEventSourceAllEvents(t *testing.T) { hsnap.On("Write", mock.Anything).Return(nil) hsnap.On("Remove", mock.Anything).Return(nil) - kstreamConfig := config.KstreamConfig{ - EnableThreadKevents: true, - EnableImageKevents: true, - EnableFileIOKevents: true, - EnableVAMapKevents: true, - EnableNetKevents: true, - EnableRegistryKevents: true, - EnableMemKevents: true, - EnableHandleKevents: true, - EnableDNSEvents: true, - EnableAuditAPIEvents: true, - StackEnrichment: false, + evsConfig := config.EventSourceConfig{ + EnableThreadEvents: true, + EnableImageEvents: true, + EnableFileIOEvents: true, + EnableVAMapEvents: true, + EnableNetEvents: true, + EnableRegistryEvents: true, + EnableMemEvents: true, + EnableHandleEvents: true, + EnableDNSEvents: true, + EnableAuditAPIEvents: true, + StackEnrichment: false, } - cfg := &config.Config{Kstream: kstreamConfig, Filters: &config.Filters{}} + cfg := &config.Config{EventSource: evsConfig, Filters: &config.Filters{}} evs := NewEventSource(psnap, hsnap, cfg, nil) l := &MockListener{} @@ -818,7 +818,7 @@ func (s *NoopPsSnapshotter) AddModule(evt *event.Event) error func (s *NoopPsSnapshotter) FindModule(addr va.Address) (bool, *pstypes.Module) { return false, nil } func (s *NoopPsSnapshotter) RemoveThread(pid uint32, tid uint32) error { return nil } func (s *NoopPsSnapshotter) RemoveModule(pid uint32, addr va.Address) error { return nil } -func (s *NoopPsSnapshotter) WriteFromKcap(evt *event.Event) error { return nil } +func (s *NoopPsSnapshotter) WriteFromCapture(evt *event.Event) error { return nil } func (s *NoopPsSnapshotter) AddMmap(evt *event.Event) error { return nil } func (s *NoopPsSnapshotter) RemoveMmap(pid uint32, addr va.Address) error { return nil } @@ -1210,24 +1210,24 @@ func testCallstackEnrichment(t *testing.T, hsnap handle.Snapshotter, psnap ps.Sn }, } - kstreamConfig := config.KstreamConfig{ - EnableThreadKevents: true, - EnableImageKevents: true, - EnableFileIOKevents: true, - EnableRegistryKevents: true, - EnableMemKevents: true, - EnableAuditAPIEvents: true, - StackEnrichment: true, - BufferSize: 1024, - MinBuffers: uint32(runtime.NumCPU() * 2), - MaxBuffers: uint32((runtime.NumCPU() * 2) + 20), - ExcludedImages: []string{"System"}, - ExcludedKevents: []string{"WriteFile", "ReadFile", "RegOpenKey", "RegCloseKey", "CloseFile"}, - FlushTimer: 1, + evsConfig := config.EventSourceConfig{ + EnableThreadEvents: true, + EnableImageEvents: true, + EnableFileIOEvents: true, + EnableRegistryEvents: true, + EnableMemEvents: true, + EnableAuditAPIEvents: true, + StackEnrichment: true, + BufferSize: 1024, + MinBuffers: uint32(runtime.NumCPU() * 2), + MaxBuffers: uint32((runtime.NumCPU() * 2) + 20), + ExcludedImages: []string{"System"}, + ExcludedEvents: []string{"WriteFile", "ReadFile", "RegOpenKey", "RegCloseKey", "CloseFile"}, + FlushTimer: 1, } cfg := &config.Config{ - Kstream: kstreamConfig, + EventSource: evsConfig, Filters: &config.Filters{}, SymbolizeKernelAddresses: true, } diff --git a/internal/etw/stackext.go b/internal/etw/stackext.go index e87cc53e8..b2b2f9379 100644 --- a/internal/etw/stackext.go +++ b/internal/etw/stackext.go @@ -29,11 +29,11 @@ import ( // for particular event or event categories. type StackExtensions struct { ids []etw.ClassicEventID - config config.KstreamConfig + config config.EventSourceConfig } // NewStackExtensions creates an empty stack extensions. -func NewStackExtensions(config config.KstreamConfig) *StackExtensions { +func NewStackExtensions(config config.EventSourceConfig) *StackExtensions { return &StackExtensions{ids: make([]etw.ClassicEventID, 0), config: config} } @@ -61,11 +61,11 @@ func (s *StackExtensions) EventIds() []etw.ClassicEventID { return s.ids } // process address space. func (s *StackExtensions) EnableProcessCallstack() { s.AddStackTracing(event.CreateProcess) - if s.config.EnableThreadKevents { + if s.config.EnableThreadEvents { s.AddStackTracing(event.CreateThread) s.AddStackTracing(event.TerminateThread) } - if s.config.EnableImageKevents { + if s.config.EnableImageEvents { s.AddStackTracingWith(event.ProcessEventGUID, event.LoadImage.HookID()) } } @@ -74,7 +74,7 @@ func (s *StackExtensions) EnableProcessCallstack() { // with event types eligible for publishing call stack // return addresses for file system activity. func (s *StackExtensions) EnableFileCallstack() { - if s.config.EnableFileIOKevents { + if s.config.EnableFileIOEvents { s.AddStackTracing(event.CreateFile) s.AddStackTracing(event.DeleteFile) s.AddStackTracing(event.RenameFile) @@ -85,7 +85,7 @@ func (s *StackExtensions) EnableFileCallstack() { // with event types eligible for publishing call stack // return addresses for registry operations. func (s *StackExtensions) EnableRegistryCallstack() { - if s.config.EnableRegistryKevents { + if s.config.EnableRegistryEvents { s.AddStackTracing(event.RegCreateKey) s.AddStackTracing(event.RegDeleteKey) s.AddStackTracing(event.RegSetValue) @@ -96,7 +96,7 @@ func (s *StackExtensions) EnableRegistryCallstack() { // EnableMemoryCallstack enables stack tracing for the memory // events such as memory allocations. func (s *StackExtensions) EnableMemoryCallstack() { - if s.config.EnableMemKevents { + if s.config.EnableMemEvents { s.AddStackTracing(event.VirtualAlloc) } } diff --git a/internal/etw/stackext_test.go b/internal/etw/stackext_test.go index a2ea5470c..480761b73 100644 --- a/internal/etw/stackext_test.go +++ b/internal/etw/stackext_test.go @@ -29,16 +29,16 @@ import ( func TestStackExtensions(t *testing.T) { cfg := &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableNetKevents: true, - EnableFileIOKevents: true, - EnableMemKevents: true, - BufferSize: 1024, - FlushTimer: time.Millisecond * 2300, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableNetEvents: true, + EnableFileIOEvents: true, + EnableMemEvents: true, + BufferSize: 1024, + FlushTimer: time.Millisecond * 2300, }, } - exts := NewStackExtensions(cfg.Kstream) + exts := NewStackExtensions(cfg.EventSource) assert.Len(t, exts.EventIds(), 0) exts.EnableProcessCallstack() diff --git a/internal/etw/trace.go b/internal/etw/trace.go index 7a85963c4..6a1d78ac3 100644 --- a/internal/etw/trace.go +++ b/internal/etw/trace.go @@ -21,7 +21,7 @@ package etw import ( "fmt" "github.com/rabbitstack/fibratus/pkg/config" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/sys/etw" log "github.com/sirupsen/logrus" "golang.org/x/sys/windows" @@ -33,7 +33,7 @@ import ( // initEventTraceProps builds the trace properties descriptor which // influences the behaviour of event publishing to the trace session // buffers. -func initEventTraceProps(c config.KstreamConfig) etw.EventTraceProperties { +func initEventTraceProps(c config.EventSourceConfig) etw.EventTraceProperties { bufferSize := c.BufferSize if bufferSize > maxBufferSize { bufferSize = maxBufferSize @@ -122,7 +122,7 @@ type Trace struct { // NewTrace creates a new trace with specified name, provider GUID, and keywords. func NewTrace(name string, guid windows.GUID, keywords uint64, config *config.Config) *Trace { - t := &Trace{Name: name, GUID: guid, Keywords: keywords, stackExtensions: NewStackExtensions(config.Kstream), config: config} + t := &Trace{Name: name, GUID: guid, Keywords: keywords, stackExtensions: NewStackExtensions(config.EventSource), config: config} t.enableCallstacks() return t } @@ -151,7 +151,7 @@ func (t *Trace) Start() error { if len(t.Name) > maxLoggerNameSize { return fmt.Errorf("trace name [%s] is too long", t.Name) } - cfg := t.config.Kstream + cfg := t.config.EventSource props := initEventTraceProps(cfg) flags := t.enableFlagsDynamically(cfg) if t.IsKernelTrace() { @@ -171,7 +171,7 @@ func (t *Trace) Start() error { return err } if !t.startHandle.IsValid() { - return kerrors.ErrInvalidTrace + return errs.ErrInvalidTrace } if t.IsKernelTrace() { @@ -197,7 +197,7 @@ func (t *Trace) Start() error { sysTraceFlags[0] = flags // enable object manager tracking - if cfg.EnableHandleKevents { + if cfg.EnableHandleEvents { sysTraceFlags[4] = etw.Handle } // enable stack enrichment @@ -329,7 +329,7 @@ func (t *Trace) IsThreadpoolTrace() bool { return t.GUID == etw.ThreadpoolGUID } // machine. Note these flags are relevant to system logger traces // and initializing the EnableFlags field of the etw.EventTraceProperties // structure for non-system logger providers will result in an error. -func (t *Trace) enableFlagsDynamically(config config.KstreamConfig) etw.EventTraceFlags { +func (t *Trace) enableFlagsDynamically(config config.EventSourceConfig) etw.EventTraceFlags { var flags etw.EventTraceFlags if !t.IsKernelTrace() { @@ -338,28 +338,28 @@ func (t *Trace) enableFlagsDynamically(config config.KstreamConfig) etw.EventTra flags |= etw.Process - if config.EnableThreadKevents { + if config.EnableThreadEvents { flags |= etw.Thread } - if config.EnableImageKevents { + if config.EnableImageEvents { flags |= etw.ImageLoad } - if config.EnableNetKevents { + if config.EnableNetEvents { flags |= etw.NetTCPIP } - if config.EnableRegistryKevents { + if config.EnableRegistryEvents { flags |= etw.Registry } - if config.EnableFileIOKevents { + if config.EnableFileIOEvents { flags |= etw.DiskFileIO | etw.FileIO | etw.FileIOInit } - if config.EnableVAMapKevents { + if config.EnableVAMapEvents { flags |= etw.VaMap } - if config.EnableMemKevents { + if config.EnableMemEvents { flags |= etw.VirtualAlloc } - if config.EnableRegistryKevents { + if config.EnableRegistryEvents { flags |= etw.Registry } diff --git a/internal/etw/trace_test.go b/internal/etw/trace_test.go index 6e212212b..23075a2ad 100644 --- a/internal/etw/trace_test.go +++ b/internal/etw/trace_test.go @@ -28,12 +28,12 @@ import ( func TestStartTrace(t *testing.T) { cfg := &config.Config{ - Kstream: config.KstreamConfig{ - EnableThreadKevents: true, - EnableNetKevents: true, - EnableFileIOKevents: true, - BufferSize: 1024, - FlushTimer: time.Millisecond * 2300, + EventSource: config.EventSourceConfig{ + EnableThreadEvents: true, + EnableNetEvents: true, + EnableFileIOEvents: true, + BufferSize: 1024, + FlushTimer: time.Millisecond * 2300, }, } diff --git a/pkg/aggregator/aggregator_test.go b/pkg/aggregator/aggregator_test.go index 37ad1bbb6..b48b1a50b 100644 --- a/pkg/aggregator/aggregator_test.go +++ b/pkg/aggregator/aggregator_test.go @@ -31,10 +31,10 @@ import ( ) func TestNewBufferedAggregator(t *testing.T) { - keventsc := make(chan *event.Event, 20) + eventsc := make(chan *event.Event, 20) errsc := make(chan error, 1) agg, err := NewBuffered( - keventsc, + eventsc, errsc, Config{FlushPeriod: time.Millisecond * 200}, outputs.Config{Type: outputs.Console, Output: console.Config{Format: "pretty"}}, @@ -56,7 +56,7 @@ func TestNewBufferedAggregator(t *testing.T) { params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - keventsc <- evt + eventsc <- evt } <-time.After(time.Millisecond * 275) assert.Equal(t, int64(4), batchEvents.Value()) @@ -74,7 +74,7 @@ func TestNewBufferedAggregator(t *testing.T) { params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - keventsc <- evt + eventsc <- evt } <-time.After(time.Millisecond * 260) assert.Equal(t, int64(6), batchEvents.Value()) diff --git a/pkg/cap/reader.go b/pkg/cap/reader.go index 9f52ec153..80673207e 100644 --- a/pkg/cap/reader.go +++ b/pkg/cap/reader.go @@ -40,9 +40,9 @@ var ( // ErrReadSection is thrown when section read errors occur ErrReadSection = func(s section.Type, err error) error { return fmt.Errorf("couldn't read %s section: %v", s, err) } - capReadKevents = expvar.NewInt("cap.read.events") + capReadEvents = expvar.NewInt("cap.read.events") capReadBytes = expvar.NewInt("cap.read.bytes") - capKeventUnmarshalErrors = expvar.NewInt("cap.event.unmarshal.errors") + capEventUnmarshalErrors = expvar.NewInt("cap.event.unmarshal.errors") capHandleUnmarshalErrors = expvar.NewInt("cap.reader.handle.unmarshal.errors") capDroppedByFilter = expvar.NewInt("cap.reader.dropped.by.filter") ) diff --git a/pkg/cap/reader_windows.go b/pkg/cap/reader_windows.go index be00cb3f7..cee14ca9c 100644 --- a/pkg/cap/reader_windows.go +++ b/pkg/cap/reader_windows.go @@ -136,7 +136,7 @@ func (r *reader) Read(ctx context.Context) (chan *event.Event, chan error) { evt, err := event.NewFromCapture(buf, sec.Version()) if err != nil { errsc <- fmt.Errorf("fail to unmarshal event: %v", err) - capKeventUnmarshalErrors.Add(1) + capEventUnmarshalErrors.Add(1) continue } capReadBytes.Add(int64(len(buf))) @@ -173,7 +173,7 @@ func (r *reader) read(evt *event.Event, eventsc chan *event.Event) { return } eventsc <- evt - capReadKevents.Add(1) + capReadEvents.Add(1) } func (r *reader) updateSnapshotters(evt *event.Event) error { @@ -247,11 +247,11 @@ func (r *reader) recoverHandleSnapshotter() (handle.Snapshotter, error) { } var err error - handles[i], err = htypes.NewFromKcap(b) + handles[i], err = htypes.NewFromCapture(b) if err != nil { capHandleUnmarshalErrors.Add(1) } } - r.hsnapshotter = handle.NewFromKcap(handles) + r.hsnapshotter = handle.NewFromCapture(handles) return r.hsnapshotter, nil } diff --git a/pkg/cap/section/section_windows_test.go b/pkg/cap/section/section_windows_test.go index 41fa28def..cec994f67 100644 --- a/pkg/cap/section/section_windows_test.go +++ b/pkg/cap/section/section_windows_test.go @@ -19,15 +19,15 @@ package section import ( - kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/stretchr/testify/assert" "testing" ) func TestSection(t *testing.T) { - s := New(Process, kcapver.ProcessSecV1, uint32(2456), uint32(30000)) + s := New(Process, capver.ProcessSecV1, uint32(2456), uint32(30000)) assert.Equal(t, Process, s.Type()) - assert.Equal(t, kcapver.ProcessSecV1, s.Version()) + assert.Equal(t, capver.ProcessSecV1, s.Version()) assert.Equal(t, uint32(2456), s.Len()) assert.Equal(t, uint32(30000), s.Size()) } diff --git a/pkg/cap/writer.go b/pkg/cap/writer.go index 9d1ac0844..19fbc2600 100644 --- a/pkg/cap/writer.go +++ b/pkg/cap/writer.go @@ -39,7 +39,7 @@ var ( handleWriteErrors = expvar.NewInt("cap.handle.write.errors") evtWriteErrors = expvar.NewInt("cap.evt.write.errors") flusherErrors = expvar.NewMap("cap.flusher.errors") - overflowKevents = expvar.NewInt("cap.overflow.kevents") + overflowEvents = expvar.NewInt("cap.overflow.events") eventSourceErrors = expvar.NewInt("cap.eventsource.errors") ) diff --git a/pkg/cap/writer_unsupported.go b/pkg/cap/writer_unsupported.go index c6c85cfba..824092c9f 100644 --- a/pkg/cap/writer_unsupported.go +++ b/pkg/cap/writer_unsupported.go @@ -22,12 +22,12 @@ package cap import ( - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/handle" "github.com/rabbitstack/fibratus/pkg/ps" ) // NewWriter returns unsupported writer. func NewWriter(filename string, psnap ps.Snapshotter, hsnap handle.Snapshotter) (Writer, error) { - return nil, kerrors.ErrFeatureUnsupported("cap") + return nil, errs.ErrFeatureUnsupported("cap") } diff --git a/pkg/cap/writer_windows.go b/pkg/cap/writer_windows.go index 08845273c..bd381a263 100644 --- a/pkg/cap/writer_windows.go +++ b/pkg/cap/writer_windows.go @@ -41,7 +41,7 @@ import ( ) type stats struct { - kcapFile string + capFile string evtsWritten uint64 bytesWritten uint64 handlesWritten uint64 @@ -67,7 +67,7 @@ func (s *stats) printStats() { t.SetTitle("Capture Statistics") t.SetStyle(table.StyleLight) - t.AppendRow(table.Row{"File", filepath.Base(s.kcapFile)}) + t.AppendRow(table.Row{"File", filepath.Base(s.capFile)}) t.AppendSeparator() t.AppendRow(table.Row{"Events written", atomic.LoadUint64(&s.evtsWritten)}) @@ -75,7 +75,7 @@ func (s *stats) printStats() { t.AppendRow(table.Row{"Processes written", atomic.LoadUint64(&s.procsWritten)}) t.AppendRow(table.Row{"Handles written", atomic.LoadUint64(&s.handlesWritten)}) - f, err := os.Stat(s.kcapFile) + f, err := os.Stat(s.capFile) if err != nil { t.Render() return @@ -142,7 +142,7 @@ func NewWriter(filename string, psnap ps.Snapshotter, hsnap handle.Snapshotter) psnap: psnap, hsnap: hsnap, stop: make(chan struct{}), - stats: &stats{kcapFile: filename}, + stats: &stats{capFile: filename}, } if err := w.writeSnapshots(); err != nil { @@ -220,7 +220,7 @@ func (w *writer) write(b []byte) error { defer w.mu.Unlock() l := len(b) if l > maxKevtSize { - overflowKevents.Add(1) + overflowEvents.Add(1) return fmt.Errorf("event size overflow by %d bytes", l-maxKevtSize) } if err := w.ws(section.Event, capver.EvtSecV2, 0, uint32(l)); err != nil { diff --git a/pkg/cap/writer_windows_test.go b/pkg/cap/writer_windows_test.go index 6a8d16618..4f81d5671 100644 --- a/pkg/cap/writer_windows_test.go +++ b/pkg/cap/writer_windows_test.go @@ -165,15 +165,15 @@ func TestWrite(t *testing.T) { func TestLiveCapture(t *testing.T) { t.SkipNow() cfg := &config.Config{ - Kstream: config.KstreamConfig{ - EnableFileIOKevents: true, - EnableImageKevents: true, - EnableRegistryKevents: true, - EnableNetKevents: true, - EnableThreadKevents: true, - EnableHandleKevents: true, + EventSource: config.EventSourceConfig{ + EnableFileIOEvents: true, + EnableImageEvents: true, + EnableRegistryEvents: true, + EnableNetEvents: true, + EnableThreadEvents: true, + EnableHandleEvents: true, }, - KcapFile: "../../test.cap", + CapFile: "../../test.cap", Filters: &config.Filters{}, InitHandleSnapshot: true, } @@ -193,7 +193,7 @@ func TestLiveCapture(t *testing.T) { } // bootstrap cap writer with inbound event channel - writer, err := NewWriter(cfg.KcapFile, psnap, hsnap) + writer, err := NewWriter(cfg.CapFile, psnap, hsnap) if err != nil { t.Fatal(err) } diff --git a/pkg/config/_fixtures/fibratus.json b/pkg/config/_fixtures/fibratus.json index cba8b29de..d2824b566 100644 --- a/pkg/config/_fixtures/fibratus.json +++ b/pkg/config/_fixtures/fibratus.json @@ -30,15 +30,15 @@ "init-snapshot": true }, - "Event": { + "event": { }, - "kcap": { + "cap": { }, - "kstream": {}, + "eventsource": {}, "logging": {}, "output": { "console": { diff --git a/pkg/config/_fixtures/fibratus.yml b/pkg/config/_fixtures/fibratus.yml index 9c8c9b9ac..86460d2a1 100644 --- a/pkg/config/_fixtures/fibratus.yml +++ b/pkg/config/_fixtures/fibratus.yml @@ -2,10 +2,10 @@ # =============================== Aggregator ========================================== -# Aggregator is responsible for creating kernel event batches, applying transformers to each event +# Aggregator is responsible for creating event batches, applying transformers to each event # present in the batch, and forwarding those batches to the output sinks. aggregator: - # Determines the flush period that triggers the flushing of the kernel event batches to output sinks. + # Determines the flush period that triggers the flushing of the event batches to output sinks. flush-period: 230ms # Represents the max time to wait before announcing failed flushing of enqueued events when fibratus @@ -41,7 +41,7 @@ alertsenders: # Represents the port of the SMTP server. port: 587 - # Specifies the user name when authenticating to the SMTP server. + # Specifies the username when authenticating to the SMTP server. user: bunny # Specifies the password when authenticating to the SMTP server. @@ -116,12 +116,12 @@ handle: # =============================== Kcap ================================================= -kcap: +cap: file: "" # =============================== Event =============================================== -Event: +event: serialize-threads: false serialize-images: false serialize-handles: false @@ -129,7 +129,7 @@ Event: # =============================== Kstream ============================================== -kstream: +eventsource: max-buffers: 2 min-buffers: 1 flush-interval: 1s @@ -209,7 +209,7 @@ transformers: replace: enabled: false replacements: - - Param: key_name + - param: key_name old: HKEY_CURRENT_USER new: HCU tags: @@ -220,10 +220,10 @@ transformers: trim: enabled: false prefixes: - - Param: key_name + - param: key_name trim: CurrentControlSet suffixes: - - Param: file_name + - param: file_name trim: .exe # =============================== YARA ================================================= diff --git a/pkg/config/_fixtures/http-output.yml b/pkg/config/_fixtures/http-output.yml index 898e0db00..50bd3ca88 100644 --- a/pkg/config/_fixtures/http-output.yml +++ b/pkg/config/_fixtures/http-output.yml @@ -1,4 +1,4 @@ -kstream: +eventsource: max-buffers: 10 min-buffers: 8 flush-interval: 1s diff --git a/pkg/config/_fixtures/output.yml b/pkg/config/_fixtures/output.yml index d2db8139e..cf45b7bd9 100644 --- a/pkg/config/_fixtures/output.yml +++ b/pkg/config/_fixtures/output.yml @@ -1,4 +1,4 @@ -kstream: +eventsource: max-buffers: 10 min-buffers: 8 flush-interval: 1s diff --git a/pkg/config/_fixtures/transformers.yml b/pkg/config/_fixtures/transformers.yml index 37a39665b..556fbb53e 100644 --- a/pkg/config/_fixtures/transformers.yml +++ b/pkg/config/_fixtures/transformers.yml @@ -1,4 +1,4 @@ -kstream: +eventsource: max-buffers: 10 min-buffers: 8 flush-interval: 1s diff --git a/pkg/config/config_windows.go b/pkg/config/config_windows.go index 0921bdcc6..3d51cb0c0 100644 --- a/pkg/config/config_windows.go +++ b/pkg/config/config_windows.go @@ -62,7 +62,7 @@ import ( ) const ( - kcapFile = "cap.file" + capFile = "cap.file" configFile = "config-file" debugPrivilege = "debug-privilege" initHandleSnapshot = "handle.init-snapshot" @@ -80,8 +80,8 @@ const ( // Config stores configuration options for fine-tuning the behaviour of Fibratus. type Config struct { - // Kstream stores different configuration options for fine-tuning kstream consumer/controller settings. - Kstream KstreamConfig `json:"kstream" yaml:"kstream"` + // EventSource stores different configuration options for fine-tuning the event source. + EventSource EventSourceConfig `json:"eventsource" yaml:"eventsource"` // Filament contains filament settings Filament FilamentConfig `json:"filament" yaml:"filament"` // PE contains the settings that influences the behaviour of the PE (Portable Executable) reader. @@ -105,8 +105,8 @@ type Config struct { // ForwardMode designates if event forwarding mode is engaged ForwardMode bool `json:"forward" yaml:"forward"` - // KcapFile represents the name of the capture file. - KcapFile string + // CapFile represents the name of the capture file. + CapFile string // API stores global HTTP API preferences API APIConfig `json:"api" yaml:"api"` @@ -201,16 +201,16 @@ func NewWithOpts(options ...Option) *Config { flagSet := new(pflag.FlagSet) c := &Config{ - Kstream: KstreamConfig{}, - Filament: FilamentConfig{}, - API: APIConfig{}, - PE: pe.Config{}, - Log: log.Config{}, - Aggregator: aggregator.Config{}, - Filters: &Filters{}, - viper: v, - flags: flagSet, - opts: opts, + EventSource: EventSourceConfig{}, + Filament: FilamentConfig{}, + API: APIConfig{}, + PE: pe.Config{}, + Log: log.Config{}, + Aggregator: aggregator.Config{}, + Filters: &Filters{}, + viper: v, + flags: flagSet, + opts: opts, } if opts.run || opts.replay { @@ -261,7 +261,7 @@ func (c *Config) MustViperize(cmd *cobra.Command) { panic(err) } if c.opts.capture || c.opts.replay { - if err := cmd.MarkPersistentFlagRequired(kcapFile); err != nil { + if err := cmd.MarkPersistentFlagRequired(capFile); err != nil { panic(err) } } @@ -269,7 +269,7 @@ func (c *Config) MustViperize(cmd *cobra.Command) { // Init setups the configuration state from Viper. func (c *Config) Init() error { - c.Kstream.initFromViper(c.viper) + c.EventSource.initFromViper(c.viper) c.Filament.initFromViper(c.viper) c.API.initFromViper(c.viper) c.PE.InitFromViper(c.viper) @@ -284,7 +284,7 @@ func (c *Config) Init() error { c.SymbolizeKernelAddresses = c.viper.GetBool(symbolizeKernelAddresses) c.DebugPrivilege = c.viper.GetBool(debugPrivilege) c.ForwardMode = c.viper.GetBool(forwardMode) - c.KcapFile = c.viper.GetString(kcapFile) + c.CapFile = c.viper.GetString(capFile) event.SerializeThreads = c.viper.GetBool(serializeThreads) event.SerializeImages = c.viper.GetBool(serializeImages) @@ -308,7 +308,7 @@ func (c *Config) Init() error { // IsCaptureSet determines if the events are stored // in the capture file. -func (c *Config) IsCaptureSet() bool { return c.KcapFile != "" } +func (c *Config) IsCaptureSet() bool { return c.CapFile != "" } // TryLoadFile attempts to load the configuration file from specified path on the file system. func (c *Config) TryLoadFile(file string) error { @@ -383,10 +383,10 @@ func (c *Config) addFlags() { c.flags.Bool(matchAll, true, "Indicates if the match all strategy is enabled for the rule engine. If the match all strategy is enabled, a single event can trigger multiple rules") } if c.opts.capture { - c.flags.StringP(kcapFile, "o", "", "The path of the output cap file") + c.flags.StringP(capFile, "o", "", "The path of the output cap file") } if c.opts.replay { - c.flags.StringP(kcapFile, "k", "", "The path of the input cap file") + c.flags.StringP(capFile, "k", "", "The path of the input cap file") } if c.opts.run || c.opts.replay || c.opts.list || c.opts.validate { c.flags.String(filamentPath, filepath.Join(os.Getenv("PROGRAMFILES"), "fibratus", "filaments"), "Denotes the directory where filaments are located") @@ -402,14 +402,14 @@ func (c *Config) addFlags() { c.flags.String(symbolPaths, "srv*c:\\\\SymCache*https://msdl.microsoft.com/download/symbols", "Designates the path or a series of paths separated by a semicolon that is used to search for symbols files") c.flags.Bool(symbolizeKernelAddresses, false, "Determines if kernel stack addresses are symbolized") - c.flags.Bool(enableThreadKevents, true, "Determines whether thread kernel events are collected by Kernel Logger provider") - c.flags.Bool(enableRegistryKevents, true, "Determines whether registry kernel events are collected by Kernel Logger provider") - c.flags.Bool(enableNetKevents, true, "Determines whether network (TCP/UDP) kernel events are collected by Kernel Logger provider") - c.flags.Bool(enableFileIOKevents, true, "Determines whether disk I/O kernel events are collected by Kernel Logger provider") - c.flags.Bool(enableVAMapKevents, true, "Determines whether VA map/unmap events are collected by Kernel Logger provider") - c.flags.Bool(enableImageKevents, true, "Determines whether file I/O kernel events are collected by Kernel Logger provider") - c.flags.Bool(enableHandleKevents, false, "Determines whether object manager kernel events (handle creation/destruction) are collected by Kernel Logger provider") - c.flags.Bool(enableMemKevents, true, "Determines whether memory manager kernel events are collected by Kernel Logger provider") + c.flags.Bool(enableThreadEvents, true, "Determines whether thread events are collected by Kernel Logger provider") + c.flags.Bool(enableRegistryEvents, true, "Determines whether registry events are collected by Kernel Logger provider") + c.flags.Bool(enableNetEvents, true, "Determines whether network (TCP/UDP) events are collected by Kernel Logger provider") + c.flags.Bool(enableFileIOEvents, true, "Determines whether disk I/O events are collected by Kernel Logger provider") + c.flags.Bool(enableVAMapEvents, true, "Determines whether VA map/unmap events are collected by Kernel Logger provider") + c.flags.Bool(enableImageEvents, true, "Determines whether file I/O events are collected by Kernel Logger provider") + c.flags.Bool(enableHandleEvents, false, "Determines whether object manager events (handle creation/destruction) are collected by Kernel Logger provider") + c.flags.Bool(enableMemEvents, true, "Determines whether memory manager events are collected by Kernel Logger provider") c.flags.Bool(enableAuditAPIEvents, true, "Determines whether kernel audit API calls events are published") c.flags.Bool(enableDNSEvents, true, "Determines whether DNS client events are enabled") c.flags.Bool(enableThreadpoolEvents, true, "Determines whether thread pool events are published") diff --git a/pkg/config/kstream.go b/pkg/config/eventsource.go similarity index 56% rename from pkg/config/kstream.go rename to pkg/config/eventsource.go index e0b09a78f..20fddfde2 100644 --- a/pkg/config/kstream.go +++ b/pkg/config/eventsource.go @@ -32,25 +32,25 @@ import ( ) const ( - enableThreadKevents = "kstream.enable-thread" - enableRegistryKevents = "kstream.enable-registry" - enableNetKevents = "kstream.enable-net" - enableFileIOKevents = "kstream.enable-fileio" - enableVAMapKevents = "kstream.enable-vamap" - enableImageKevents = "kstream.enable-image" - enableHandleKevents = "kstream.enable-handle" - enableMemKevents = "kstream.enable-mem" - enableAuditAPIEvents = "kstream.enable-audit-api" - enableDNSEvents = "kstream.enable-dns" - enableThreadpoolEvents = "kstream.enable-threadpool" - stackEnrichment = "kstream.stack-enrichment" - bufferSize = "kstream.buffer-size" - minBuffers = "kstream.min-buffers" - maxBuffers = "kstream.max-buffers" - flushInterval = "kstream.flush-interval" - - excludedEvents = "kstream.blacklist.events" - excludedImages = "kstream.blacklist.images" + enableThreadEvents = "eventsource.enable-thread" + enableRegistryEvents = "eventsource.enable-registry" + enableNetEvents = "eventsource.enable-net" + enableFileIOEvents = "eventsource.enable-fileio" + enableVAMapEvents = "eventsource.enable-vamap" + enableImageEvents = "eventsource.enable-image" + enableHandleEvents = "eventsource.enable-handle" + enableMemEvents = "eventsource.enable-mem" + enableAuditAPIEvents = "eventsource.enable-audit-api" + enableDNSEvents = "eventsource.enable-dns" + enableThreadpoolEvents = "eventsource.enable-threadpool" + stackEnrichment = "eventsource.stack-enrichment" + bufferSize = "eventsource.buffer-size" + minBuffers = "eventsource.min-buffers" + maxBuffers = "eventsource.max-buffers" + flushInterval = "eventsource.flush-interval" + + excludedEvents = "eventsource.blacklist.events" + excludedImages = "eventsource.blacklist.images" maxBufferSize = uint32(512) ) @@ -61,24 +61,24 @@ var ( defaultFlushInterval = time.Second ) -// KstreamConfig stores different configuration options for fine-tuning kstream consumer/controller settings. -type KstreamConfig struct { - // EnableThreadKevents indicates if thread events are collected by the ETW provider. - EnableThreadKevents bool `json:"enable-thread" yaml:"enable-thread"` - // EnableRegistryKevents indicates if registry events are collected by the ETW provider. - EnableRegistryKevents bool `json:"enable-registry" yaml:"enable-registry"` - // EnableNetKevents determines whether network (TCP/UDP) events are collected by the ETW provider. - EnableNetKevents bool `json:"enable-net" yaml:"enable-net"` - // EnableFileIOKevents indicates if file I/O events are collected by the ETW provider. - EnableFileIOKevents bool `json:"enable-fileio" yaml:"enable-fileio"` - // EnableVAMapKevents indicates if VA map/unmap events are collected by the ETW provider. - EnableVAMapKevents bool `json:"enable-vamap" yaml:"enable-vamap"` - // EnableImageKevents indicates if image events are collected by the ETW provider. - EnableImageKevents bool `json:"enable-image" yaml:"enable-image"` - // EnableHandleKevents indicates whether handle creation/disposal events are enabled. - EnableHandleKevents bool `json:"enable-handle" yaml:"enable-handle"` - // EnableMemKevents indicates whether memory manager events are enabled. - EnableMemKevents bool `json:"enable-memory" yaml:"enable-memory"` +// EventSourceConfig stores different configuration options for fine-tuning the event source. +type EventSourceConfig struct { + // EnableThreadEvents indicates if thread events are collected by the ETW provider. + EnableThreadEvents bool `json:"enable-thread" yaml:"enable-thread"` + // EnableRegistryEvents indicates if registry events are collected by the ETW provider. + EnableRegistryEvents bool `json:"enable-registry" yaml:"enable-registry"` + // EnableNetEvents determines whether network (TCP/UDP) events are collected by the ETW provider. + EnableNetEvents bool `json:"enable-net" yaml:"enable-net"` + // EnableFileIOEvents indicates if file I/O events are collected by the ETW provider. + EnableFileIOEvents bool `json:"enable-fileio" yaml:"enable-fileio"` + // EnableVAMapEvents indicates if VA map/unmap events are collected by the ETW provider. + EnableVAMapEvents bool `json:"enable-vamap" yaml:"enable-vamap"` + // EnableImageEvents indicates if image events are collected by the ETW provider. + EnableImageEvents bool `json:"enable-image" yaml:"enable-image"` + // EnableHandleEvents indicates whether handle creation/disposal events are enabled. + EnableHandleEvents bool `json:"enable-handle" yaml:"enable-handle"` + // EnableMemEvents indicates whether memory manager events are enabled. + EnableMemEvents bool `json:"enable-memory" yaml:"enable-memory"` // EnableAuditAPIEvents indicates if kernel audit API calls events are enabled EnableAuditAPIEvents bool `json:"enable-audit-api" yaml:"enable-audit-api"` // EnableDNSEvents indicates if DNS client events are enabled @@ -97,8 +97,8 @@ type KstreamConfig struct { MaxBuffers uint32 `json:"max-buffers" yaml:"max-buffers"` // FlushTimer specifies how often the trace buffers are forcibly flushed. FlushTimer time.Duration `json:"flush-interval" yaml:"flush-interval"` - // ExcludedKevents are kernel event names that will be dropped from the kernel event stream. - ExcludedKevents []string `json:"blacklist.events" yaml:"blacklist.events"` + // ExcludedEvents are kernel event names that will be dropped from the kernel event stream. + ExcludedEvents []string `json:"blacklist.events" yaml:"blacklist.events"` // ExcludedImages are process image names that will be rejected if they generate a kernel event. ExcludedImages []string `json:"blacklist.images" yaml:"blacklist.images"` @@ -107,15 +107,15 @@ type KstreamConfig struct { excludedImages map[string]bool } -func (c *KstreamConfig) initFromViper(v *viper.Viper) { - c.EnableThreadKevents = v.GetBool(enableThreadKevents) - c.EnableRegistryKevents = v.GetBool(enableRegistryKevents) - c.EnableNetKevents = v.GetBool(enableNetKevents) - c.EnableFileIOKevents = v.GetBool(enableFileIOKevents) - c.EnableVAMapKevents = v.GetBool(enableVAMapKevents) - c.EnableImageKevents = v.GetBool(enableImageKevents) - c.EnableHandleKevents = v.GetBool(enableHandleKevents) - c.EnableMemKevents = v.GetBool(enableMemKevents) +func (c *EventSourceConfig) initFromViper(v *viper.Viper) { + c.EnableThreadEvents = v.GetBool(enableThreadEvents) + c.EnableRegistryEvents = v.GetBool(enableRegistryEvents) + c.EnableNetEvents = v.GetBool(enableNetEvents) + c.EnableFileIOEvents = v.GetBool(enableFileIOEvents) + c.EnableVAMapEvents = v.GetBool(enableVAMapEvents) + c.EnableImageEvents = v.GetBool(enableImageEvents) + c.EnableHandleEvents = v.GetBool(enableHandleEvents) + c.EnableMemEvents = v.GetBool(enableMemEvents) c.EnableAuditAPIEvents = v.GetBool(enableAuditAPIEvents) c.EnableDNSEvents = v.GetBool(enableDNSEvents) c.EnableThreadpoolEvents = v.GetBool(enableThreadpoolEvents) @@ -124,12 +124,12 @@ func (c *KstreamConfig) initFromViper(v *viper.Viper) { c.MinBuffers = uint32(v.GetInt(minBuffers)) c.MaxBuffers = uint32(v.GetInt(maxBuffers)) c.FlushTimer = v.GetDuration(flushInterval) - c.ExcludedKevents = v.GetStringSlice(excludedEvents) + c.ExcludedEvents = v.GetStringSlice(excludedEvents) c.ExcludedImages = v.GetStringSlice(excludedImages) c.excludedImages = make(map[string]bool) - for _, name := range c.ExcludedKevents { + for _, name := range c.ExcludedEvents { if typ := event.NameToType(name); typ != event.UnknownType { c.dropMasks.Set(typ) } @@ -140,9 +140,9 @@ func (c *KstreamConfig) initFromViper(v *viper.Viper) { } // Init is an exported method to allow initializing exclusion maps from external modules. -func (c *KstreamConfig) Init() { +func (c *EventSourceConfig) Init() { c.excludedImages = make(map[string]bool) - for _, name := range c.ExcludedKevents { + for _, name := range c.ExcludedEvents { for _, typ := range event.NameToTypes(name) { if typ != event.UnknownType { c.dropMasks.Set(typ) @@ -157,26 +157,26 @@ func (c *KstreamConfig) Init() { // SetDropMask inserts the event mask in the bitset to // instruct the given event type should be dropped from // the event stream. -func (c *KstreamConfig) SetDropMask(Type event.Type) { +func (c *EventSourceConfig) SetDropMask(Type event.Type) { c.dropMasks.Set(Type) } // TestDropMask checks if the specified event type has // the drop mask in the bitset. -func (c *KstreamConfig) TestDropMask(Type event.Type) bool { +func (c *EventSourceConfig) TestDropMask(Type event.Type) bool { return c.dropMasks.Test(Type.GUID(), Type.HookID()) } -// ExcludeKevent determines whether the supplied provider GUID +// ExcludeEvent determines whether the supplied provider GUID // and the hook identifier are in the bitset of excluded events. -func (c *KstreamConfig) ExcludeKevent(guid windows.GUID, hookID uint16) bool { +func (c *EventSourceConfig) ExcludeEvent(guid windows.GUID, hookID uint16) bool { return c.dropMasks.Test(guid, hookID) } // ExcludeImage determines whether the process generating event is present in the // list of excluded images. If the hit occurs, the event associated with the process // is dropped. -func (c *KstreamConfig) ExcludeImage(ps *pstypes.PS) bool { +func (c *EventSourceConfig) ExcludeImage(ps *pstypes.PS) bool { if len(c.excludedImages) == 0 { return false } diff --git a/pkg/config/kstream_test.go b/pkg/config/eventsource_test.go similarity index 53% rename from pkg/config/kstream_test.go rename to pkg/config/eventsource_test.go index 7a3d6f258..cd43354fb 100644 --- a/pkg/config/kstream_test.go +++ b/pkg/config/eventsource_test.go @@ -31,17 +31,17 @@ import ( "github.com/stretchr/testify/require" ) -func TestKstreamConfig(t *testing.T) { +func TestEventSourceConfig(t *testing.T) { c := NewWithOpts(WithRun()) err := c.flags.Parse([]string{ - "--kstream.enable-thread=false", - "--kstream.enable-registry=false", - "--kstream.enable-fileio=false", - "--kstream.enable-net=false", - "--kstream.enable-image=false", - "--kstream.blacklist.events=CloseFile,CloseHandle", - "--kstream.blacklist.images=System,svchost.exe", + "--eventsource.enable-thread=false", + "--eventsource.enable-registry=false", + "--eventsource.enable-fileio=false", + "--eventsource.enable-net=false", + "--eventsource.enable-image=false", + "--eventsource.blacklist.events=CloseFile,CloseHandle", + "--eventsource.blacklist.images=System,svchost.exe", }) require.NoError(t, err) require.NoError(t, c.viper.BindPFlags(c.flags)) @@ -49,15 +49,15 @@ func TestKstreamConfig(t *testing.T) { require.NoError(t, c.Init()) - assert.False(t, c.Kstream.EnableThreadKevents) - assert.False(t, c.Kstream.EnableNetKevents) - assert.False(t, c.Kstream.EnableRegistryKevents) - assert.False(t, c.Kstream.EnableImageKevents) - assert.False(t, c.Kstream.EnableFileIOKevents) + assert.False(t, c.EventSource.EnableThreadEvents) + assert.False(t, c.EventSource.EnableNetEvents) + assert.False(t, c.EventSource.EnableRegistryEvents) + assert.False(t, c.EventSource.EnableImageEvents) + assert.False(t, c.EventSource.EnableFileIOEvents) - assert.True(t, c.Kstream.ExcludeKevent(event.CloseHandle.GUID(), event.CloseHandle.HookID())) - assert.False(t, c.Kstream.ExcludeKevent(event.CreateProcess.GUID(), event.CreateProcess.HookID())) + assert.True(t, c.EventSource.ExcludeEvent(event.CloseHandle.GUID(), event.CloseHandle.HookID())) + assert.False(t, c.EventSource.ExcludeEvent(event.CreateProcess.GUID(), event.CreateProcess.HookID())) - assert.True(t, c.Kstream.ExcludeImage(&pstypes.PS{Name: "svchost.exe"})) - assert.False(t, c.Kstream.ExcludeImage(&pstypes.PS{Name: "explorer.exe"})) + assert.True(t, c.EventSource.ExcludeImage(&pstypes.PS{Name: "svchost.exe"})) + assert.False(t, c.EventSource.ExcludeImage(&pstypes.PS{Name: "explorer.exe"})) } diff --git a/pkg/config/print_test.go b/pkg/config/print_test.go index 4e5f9b4ec..e5cf70478 100644 --- a/pkg/config/print_test.go +++ b/pkg/config/print_test.go @@ -25,7 +25,7 @@ import ( func TestConfigPrint(t *testing.T) { c := NewWithOpts(WithRun()) - err := c.flags.Parse([]string{"--kstream.enable-thread=false", "--config-file=_fixtures/fibratus.yml"}) + err := c.flags.Parse([]string{"--eventsource.enable-thread=false", "--config-file=_fixtures/fibratus.yml"}) require.NoError(t, c.viper.BindPFlags(c.flags)) require.NoError(t, err) require.NoError(t, c.TryLoadFile(c.GetConfigFile())) diff --git a/pkg/config/schema_windows.go b/pkg/config/schema_windows.go index 631e76665..69f0b2b0a 100644 --- a/pkg/config/schema_windows.go +++ b/pkg/config/schema_windows.go @@ -177,7 +177,7 @@ var schema = ` }, "additionalProperties": false }, - "kstream": { + "eventsource": { "type": "object", "properties": { "enable-thread": {"type": "boolean"}, @@ -195,7 +195,7 @@ var schema = ` "min-buffers": {"type": "integer", "minimum": 1, "maximum": {{ .MinBuffers }}}, "max-buffers": {"type": "integer", "minimum": 2, "maximum": {{ .MaxBuffers }}}, "buffer-size": {"type": "integer", "maximum": {{ .MaxBufferSize }}}, - "flush-interval": {"type": "string", "minLength": 2, "pattern": "[0-9]+s"}, + "flush-interval": {"type": "string", "minLength": 2, "pattern": "[0-9]+s"}, "blacklist": { "type": "object", "properties": { @@ -380,7 +380,7 @@ var schema = ` { "type": "object", "properties": { - "Param": {"type": "string", "minLength": 1}, + "param": {"type": "string", "minLength": 1}, "old": {"type": "string", "minLength": 1}, "new": {"type": "string"} }, @@ -427,7 +427,7 @@ var schema = ` { "type": "object", "properties": { - "Param": {"type": "string", "minLength": 1}, + "param": {"type": "string", "minLength": 1}, "trim": {"type": "string", "minLength": 1} }, "additionalProperties": false @@ -437,7 +437,7 @@ var schema = ` { "type": "object", "properties": { - "Param": {"type": "string", "minLength": 1}, + "param": {"type": "string", "minLength": 1}, "trim": {"type": "string", "minLength": 1} }, "additionalProperties": false diff --git a/pkg/event/formatter.go b/pkg/event/formatter.go index 3acd05e6e..620ec1f3f 100644 --- a/pkg/event/formatter.go +++ b/pkg/event/formatter.go @@ -64,8 +64,8 @@ var ( // tmplNormRegepx defines the regular expression for normalizing the template. This basically consists in removing // the brackets and trailing/leading spaces from the field name. tmplNormRegexp = regexp.MustCompile(`({{2}\s*([A-Za-z.]+)\s*}{2})`) - // tmplExpandKparamsRegexp determines whether Params. fields are expanded - tmplExpandKparamsRegexp = regexp.MustCompile(`{{\s*.Params.\S+}}`) + // tmplExpandParamsRegexp determines whether Params. fields are expanded + tmplExpandParamsRegexp = regexp.MustCompile(`{{\s*.Params.\S+}}`) ) var fields = map[string]bool{ @@ -104,8 +104,8 @@ func hintFields() string { // Formatter deals with producing event's output that is dictated by the template. type Formatter struct { - t *fasttemplate.Template - expandKparamsDot bool + t *fasttemplate.Template + expandParamsDot bool } // NewFormatter builds a new instance of event's formatter. @@ -142,8 +142,8 @@ func NewFormatter(template string) (*Formatter, error) { return nil, fmt.Errorf("invalid template format %q: %v", norm, err) } return &Formatter{ - t: t, - expandKparamsDot: tmplExpandKparamsRegexp.MatchString(norm), + t: t, + expandParamsDot: tmplExpandParamsRegexp.MatchString(norm), }, nil } diff --git a/pkg/event/formatter_windows.go b/pkg/event/formatter_windows.go index 7369c0f3e..c441ae650 100644 --- a/pkg/event/formatter_windows.go +++ b/pkg/event/formatter_windows.go @@ -22,7 +22,7 @@ import ( "strconv" ) -// Format applies the template on the provided kernel event. +// Format applies the template on the provided event. func (f *Formatter) Format(evt *Event) []byte { if evt == nil { return []byte{} @@ -65,7 +65,7 @@ func (f *Formatter) Format(evt *Event) []byte { values[cstack] = evt.Callstack.String() } - if f.expandKparamsDot { + if f.expandParamsDot { // expand all parameters into the map, so we can ask // for specific parameter names in the template for _, par := range evt.Params { diff --git a/pkg/event/marshaller_test.go b/pkg/event/marshaller_test.go index 3e4773906..13f4870e3 100644 --- a/pkg/event/marshaller_test.go +++ b/pkg/event/marshaller_test.go @@ -105,7 +105,7 @@ func TestMarshaller(t *testing.T) { assert.Equal(t, "barzz", clone.Metadata["fooz"]) } -func TestKeventMarshalJSON(t *testing.T) { +func TestEventMarshalJSON(t *testing.T) { evt := &Event{ Type: CreateFile, Tid: 2484, @@ -282,7 +282,7 @@ func TestUnmarshalHugeHandles(t *testing.T) { require.NotNil(t, clone) } -func TestKeventMarshalJSONMultiple(t *testing.T) { +func TestEventMarshalJSONMultiple(t *testing.T) { for i := 0; i < 10; i++ { seq := uint64(i + 1) evt := &Event{ @@ -364,7 +364,7 @@ func TestKeventMarshalJSONMultiple(t *testing.T) { } } -func BenchmarkKeventMarshalJSON(b *testing.B) { +func BenchmarkEventMarshalJSON(b *testing.B) { evt := &Event{ Type: CreateFile, Tid: 2484, @@ -448,7 +448,7 @@ func BenchmarkKeventMarshalJSON(b *testing.B) { } } -func BenchmarkKeventMarshalJSONStdlib(b *testing.B) { +func BenchmarkEventMarshalJSONStdlib(b *testing.B) { evt := &Event{ Type: CreateFile, Tid: 2484, diff --git a/pkg/event/marshaller_windows.go b/pkg/event/marshaller_windows.go index 5566f9329..80405ff8b 100644 --- a/pkg/event/marshaller_windows.go +++ b/pkg/event/marshaller_windows.go @@ -410,7 +410,7 @@ func (e *Event) UnmarshalRaw(b []byte, ver capver.Version) error { // read process state sec := section.Read(b[inc(idx, 14)+offset:]) if sec.Size() != 0 { - ps, err := ptypes.NewFromKcap(b[inc(idx, 24)+offset:], sec) + ps, err := ptypes.NewFromCapture(b[inc(idx, 24)+offset:], sec) if err != nil { return err } diff --git a/pkg/event/queue.go b/pkg/event/queue.go index cf185f4ee..31801ab5c 100644 --- a/pkg/event/queue.go +++ b/pkg/event/queue.go @@ -29,8 +29,8 @@ import ( // removed from the cache. const backlogCacheSize = 800 -// keventsEnqueued counts the number of events that are pushed to the queue -var keventsEnqueued = expvar.NewInt("kstream.kevents.enqueued") +// eventsEnqueued counts the number of events that are pushed to the queue +var eventsEnqueued = expvar.NewInt("eventsource.events.enqueued") // Listener is the minimal interface that all event listeners need to implement. type Listener interface { @@ -163,7 +163,7 @@ func (q *Queue) push(e *Event) error { } if enqueue || len(q.listeners) == 0 { q.q <- e - keventsEnqueued.Add(1) + eventsEnqueued.Add(1) } return nil } diff --git a/pkg/event/types_windows.go b/pkg/event/types_windows.go index db44c512e..8a2c67bf3 100644 --- a/pkg/event/types_windows.go +++ b/pkg/event/types_windows.go @@ -29,12 +29,12 @@ import ( // Remember to increment if a new event source is introduced. const ProvidersCount = 12 -// EventSource is the type that designates the provenance of the event -type EventSource uint8 +// Source is the type that designates the provenance of the event +type Source uint8 const ( // SystemLogger event is emitted by the system provider - SystemLogger EventSource = iota + SystemLogger Source = iota // AuditAPICallsLogger event is emitted by Audit API calls provider AuditAPICallsLogger // DNSLogger event is emitted by DNS provider @@ -576,7 +576,7 @@ func (t *Type) HookID() uint16 { } // Source designates the provenance of this event type. -func (t Type) Source() EventSource { +func (t Type) Source() Source { switch t { case OpenProcess, OpenThread, SetThreadContext, CreateSymbolicLinkObject: return AuditAPICallsLogger diff --git a/pkg/filament/_fixtures/test_filter.py b/pkg/filament/_fixtures/test_filter.py index 2211180a9..c6e346b83 100644 --- a/pkg/filament/_fixtures/test_filter.py +++ b/pkg/filament/_fixtures/test_filter.py @@ -18,10 +18,10 @@ Tests the filter expression. """ -kevents = [] +events = [] def on_init(): - kfilter('ps.name in (%s)' % ','.join(["'svchost.exe'", "'cmd.exe'", "'mimikatz.exe'"])) + set_filter('ps.name in (%s)' % ','.join(["'svchost.exe'", "'cmd.exe'", "'mimikatz.exe'"])) -def on_next_kevent(Event): - pass \ No newline at end of file +def on_next_event(event): + pass diff --git a/pkg/filament/_fixtures/test_on_next_kevent.py b/pkg/filament/_fixtures/test_on_next_event.py similarity index 77% rename from pkg/filament/_fixtures/test_on_next_kevent.py rename to pkg/filament/_fixtures/test_on_next_event.py index 080ae9132..3c326b070 100644 --- a/pkg/filament/_fixtures/test_on_next_kevent.py +++ b/pkg/filament/_fixtures/test_on_next_event.py @@ -15,20 +15,20 @@ # under the License. """ -Tests the on_next_kevent function. +Tests the on_next_event function. """ -kevents = [] +events = [] def on_init(): interval(1) columns(['Key', '#Seq']) sort_by('#Seq') -def on_next_kevent(Event): - kevents.append({'key_name': Event['params']['key_name'], 'seq': Event['seq'], 'dip': Event['params']['dip']}) +def on_next_event(event): + events.append({'key_name': event['params']['key_name'], 'seq': event['seq'], 'dip': event['params']['dip']}) def on_interval(): - for key in kevents: + for key in events: add_row([key['key_name'], key['seq']]) - render_table() \ No newline at end of file + render_table() diff --git a/pkg/filament/_fixtures/top_hives_io.py b/pkg/filament/_fixtures/top_hives_io.py index 7855e5922..7a12b4417 100644 --- a/pkg/filament/_fixtures/top_hives_io.py +++ b/pkg/filament/_fixtures/top_hives_io.py @@ -29,6 +29,6 @@ def on_init(): sort_by("1") -def on_next_kevent(Event): +def on_next_event(event): pass diff --git a/pkg/filament/_fixtures/top_keys_io_table.py b/pkg/filament/_fixtures/top_keys_io_table.py index ae039b73f..d32ba1f08 100644 --- a/pkg/filament/_fixtures/top_keys_io_table.py +++ b/pkg/filament/_fixtures/top_keys_io_table.py @@ -29,7 +29,7 @@ def on_init(): sort_by('#Ops') -def on_next_kevent(Event): +def on_next_event(event): pass diff --git a/pkg/filament/cpython/_fixtures/top_hives_io.py b/pkg/filament/cpython/_fixtures/top_hives_io.py index 5621a4cb1..2a133e542 100644 --- a/pkg/filament/cpython/_fixtures/top_hives_io.py +++ b/pkg/filament/cpython/_fixtures/top_hives_io.py @@ -32,8 +32,8 @@ def on_init(): #set_interval(1) -def on_next_kevent(Event): - print("Event\n", Event["params"]) +def on_next_event(event): + print("Event\n", event["params"]) #raise Exception('eggs', 'eggs') def on_interval(): diff --git a/pkg/filament/dict_test.go b/pkg/filament/dict_test.go index 069f72c26..7d714cf25 100644 --- a/pkg/filament/dict_test.go +++ b/pkg/filament/dict_test.go @@ -95,11 +95,11 @@ func TestProduceEventDictWithIPAddresses(t *testing.T) { require.NoError(t, err) require.NotNil(t, dict) - kpars := dict.Get(cpython.PyUnicodeFromString("params")) - kparamsDict := cpython.NewDictFromObject(kpars) + pars := dict.Get(cpython.PyUnicodeFromString("params")) + paramsDict := cpython.NewDictFromObject(pars) - assert.Equal(t, "216.58.201.174", kparamsDict.Get(cpython.PyUnicodeFromString("dip")).String()) - assert.Equal(t, "2001:db8:85a3::8a2e:370:7334", kparamsDict.Get(cpython.PyUnicodeFromString("sip")).String()) + assert.Equal(t, "216.58.201.174", paramsDict.Get(cpython.PyUnicodeFromString("dip")).String()) + assert.Equal(t, "2001:db8:85a3::8a2e:370:7334", paramsDict.Get(cpython.PyUnicodeFromString("sip")).String()) } func BenchmarkTestProduceEventDict(b *testing.B) { diff --git a/pkg/filament/filament.go b/pkg/filament/filament.go index 2a2c5f7a8..4490d8ad2 100644 --- a/pkg/filament/filament.go +++ b/pkg/filament/filament.go @@ -74,10 +74,10 @@ const ( ) var ( - keventErrors = expvar.NewMap("filament.event.errors") - keventProcessErrors = expvar.NewInt("filament.event.process.errors") - kdictErrors = expvar.NewInt("filament.kdict.errors") - batchFlushes = expvar.NewInt("filament.event.batch.flushes") + eventErrors = expvar.NewMap("filament.event.errors") + eventProcessErrors = expvar.NewInt("filament.event.process.errors") + dictErrors = expvar.NewInt("filament.dict.errors") + batchFlushes = expvar.NewInt("filament.event.batch.flushes") errFilamentsDir = func(path string) error { return fmt.Errorf("%s does not exist or is not a directory", path) } @@ -90,17 +90,17 @@ var ( tableOutput io.Writer ) -type kbatch []*event.Event +type batch []*event.Event -func (k *kbatch) append(evt *event.Event) { - if *k == nil { - *k = make([]*event.Event, 0) +func (b *batch) append(evt *event.Event) { + if *b == nil { + *b = make([]*event.Event, 0) } - *k = append(*k, evt) + *b = append(*b, evt) } -func (k *kbatch) reset() { *k = nil } -func (k kbatch) len() int { return len(k) } +func (b *batch) reset() { *b = nil } +func (b batch) len() int { return len(b) } type filament struct { name string @@ -123,8 +123,8 @@ type filament struct { initErrors []error - onNextKevent *cpython.PyObject - onStop *cpython.PyObject + onNextEvent *cpython.PyObject + onStop *cpython.PyObject table tab } @@ -228,19 +228,19 @@ func New( } f := &filament{ - name: name, - mod: mod, - config: config, - psnap: psnap, - hsnap: hsnap, - close: make(chan struct{}, 1), - fnerrs: make(chan error, 100), - gil: cpython.NewGIL(), - columns: make([]string, 0), - onNextKevent: onNextEvent, - interval: time.Second, - initErrors: make([]error, 0), - table: newTable(), + name: name, + mod: mod, + config: config, + psnap: psnap, + hsnap: hsnap, + close: make(chan struct{}, 1), + fnerrs: make(chan error, 100), + gil: cpython.NewGIL(), + columns: make([]string, 0), + onNextEvent: onNextEvent, + interval: time.Second, + initErrors: make([]error, 0), + table: newTable(), } if mod.HasAttr(onStopFn) { @@ -368,8 +368,8 @@ func New( return f, nil } -func (f *filament) Run(kevents <-chan *event.Event, errs <-chan error) error { - var batch kbatch +func (f *filament) Run(eventsc <-chan *event.Event, errs <-chan error) error { + var b batch var flusher = time.NewTicker(time.Second) for { select { @@ -380,19 +380,19 @@ func (f *filament) Run(kevents <-chan *event.Event, errs <-chan error) error { } select { - case evt := <-kevents: - batch.append(evt) + case evt := <-eventsc: + b.append(evt) case err := <-errs: - keventErrors.Add(err.Error(), 1) + eventErrors.Add(err.Error(), 1) case <-flusher.C: batchFlushes.Add(1) - if batch.len() > 0 { - err := f.pushEvents(batch) + if b.len() > 0 { + err := f.pushEvents(b) if err != nil { - log.Warnf("on_next_kevent failed: %v", err) - keventProcessErrors.Add(1) + log.Warnf("on_next_event failed: %v", err) + eventProcessErrors.Add(1) } - batch.reset() + b.reset() } case err := <-f.fnerrs: return err @@ -403,17 +403,17 @@ func (f *filament) Run(kevents <-chan *event.Event, errs <-chan error) error { } } -func (f *filament) pushEvents(b kbatch) error { +func (f *filament) pushEvents(b batch) error { f.gil.Lock() defer f.gil.Unlock() for _, evt := range b { dict, err := newEventDict(evt) if err != nil { dict.DecRef() - kdictErrors.Add(1) + dictErrors.Add(1) continue } - r := f.onNextKevent.Call(dict.Object()) + r := f.onNextEvent.Call(dict.Object()) if r != nil { r.DecRef() } diff --git a/pkg/filament/filament_test.go b/pkg/filament/filament_test.go index 862238fd6..0cb394fc8 100644 --- a/pkg/filament/filament_test.go +++ b/pkg/filament/filament_test.go @@ -53,18 +53,18 @@ func init() { tableOutput = &buf } -func TestOnNextKevent(t *testing.T) { +func TestOnNextEvent(t *testing.T) { // this test crashes in the CI. Reenable once // we investigate why this happens t.SkipNow() - filament, err := New("test_on_next_kevent", nil, nil, &config.Config{Filament: config.FilamentConfig{FlushPeriod: time.Millisecond * 250, Path: "_fixtures"}}) + filament, err := New("test_on_next_event", nil, nil, &config.Config{Filament: config.FilamentConfig{FlushPeriod: time.Millisecond * 250, Path: "_fixtures"}}) require.NoError(t, err) require.NotNil(t, filament) time.AfterFunc(time.Millisecond*1050, func() { filament.Close() }) - kevents := make(chan *event.Event, 100) + events := make(chan *event.Event, 100) errs := make(chan error, 10) for i := 1; i <= 100; i++ { evt := &event.Event{ @@ -83,9 +83,9 @@ func TestOnNextKevent(t *testing.T) { params.NetDIP: {Name: params.NetDIP, Type: params.IPv4, Value: net.ParseIP("216.58.201.174")}, }, } - kevents <- evt + events <- evt } - err = filament.Run(kevents, errs) + err = filament.Run(events, errs) require.Nil(t, err) sn := bufio.NewScanner(strings.NewReader(buf.String())) const headerOffset = 4 diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index aefce2002..956324da9 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -45,14 +45,14 @@ import ( ) var cfg = &config.Config{ - Kstream: config.KstreamConfig{ - EnableHandleKevents: true, - EnableNetKevents: true, - EnableRegistryKevents: true, - EnableFileIOKevents: true, - EnableImageKevents: true, - EnableThreadKevents: true, - EnableMemKevents: true, + EventSource: config.EventSourceConfig{ + EnableHandleEvents: true, + EnableNetEvents: true, + EnableRegistryEvents: true, + EnableFileIOEvents: true, + EnableImageEvents: true, + EnableThreadEvents: true, + EnableMemEvents: true, EnableDNSEvents: true, EnableThreadpoolEvents: true, }, @@ -690,7 +690,7 @@ func TestFileInfoFilter(t *testing.T) { } } -func TestKeventFilter(t *testing.T) { +func TestEventFilter(t *testing.T) { evt := &event.Event{ Type: event.CreateFile, Tid: 2484, diff --git a/pkg/filter/filter_windows.go b/pkg/filter/filter_windows.go index a38b8b06d..007d14b76 100644 --- a/pkg/filter/filter_windows.go +++ b/pkg/filter/filter_windows.go @@ -57,34 +57,34 @@ func New(expr string, config *config.Config, options ...Option) Filter { // PE metadata newPEAccessor(), } - kconfig := config.Kstream + fconfig := config.Filters - if kconfig.EnableThreadKevents { + if config.EventSource.EnableThreadEvents { accessors = append(accessors, newThreadAccessor()) } - if kconfig.EnableImageKevents { + if config.EventSource.EnableImageEvents { accessors = append(accessors, newImageAccessor()) } - if kconfig.EnableFileIOKevents { + if config.EventSource.EnableFileIOEvents { accessors = append(accessors, newFileAccessor()) } - if kconfig.EnableRegistryKevents { + if config.EventSource.EnableRegistryEvents { accessors = append(accessors, newRegistryAccessor()) } - if kconfig.EnableNetKevents { + if config.EventSource.EnableNetEvents { accessors = append(accessors, newNetworkAccessor()) } - if kconfig.EnableHandleKevents { + if config.EventSource.EnableHandleEvents { accessors = append(accessors, newHandleAccessor()) } - if kconfig.EnableMemKevents { + if config.EventSource.EnableMemEvents { accessors = append(accessors, newMemAccessor()) } - if kconfig.EnableDNSEvents { + if config.EventSource.EnableDNSEvents { accessors = append(accessors, newDNSAccessor()) } - if kconfig.EnableThreadpoolEvents { + if config.EventSource.EnableThreadpoolEvents { accessors = append(accessors, newThreadpoolAccessor()) } diff --git a/pkg/filter/ql/functions/yara_unsupported.go b/pkg/filter/ql/functions/yara_unsupported.go index 66f310e74..6f80b7f36 100644 --- a/pkg/filter/ql/functions/yara_unsupported.go +++ b/pkg/filter/ql/functions/yara_unsupported.go @@ -23,7 +23,7 @@ package functions import ( "fmt" - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" ) // Yara unsupported function @@ -40,7 +40,7 @@ func (f Yara) Desc() FunctionDesc { {Keyword: "vars", Types: []ArgType{Field, BoundField, Func, String}}, }, ArgsValidationFunc: func(args []string) error { - return fmt.Errorf("yara function is not supported. %w", kerrors.ErrFeatureUnsupported("yara")) + return fmt.Errorf("yara function is not supported. %w", errs.ErrFeatureUnsupported("yara")) }, } return desc diff --git a/pkg/handle/snapshotter.go b/pkg/handle/snapshotter.go index 172905d3c..dfcaebb2b 100644 --- a/pkg/handle/snapshotter.go +++ b/pkg/handle/snapshotter.go @@ -127,8 +127,8 @@ func NewSnapshotter(config *config.Config, fn SnapshotBuildCompleted) Snapshotte return s } -// NewFromKcap builds the handle snapshotter from cap state. -func NewFromKcap(handles []htypes.Handle) Snapshotter { +// NewFromCapture builds the handle snapshotter from the capture state. +func NewFromCapture(handles []htypes.Handle) Snapshotter { s := &snapshotter{ handlesByObject: make(map[uint64]htypes.Handle), capture: true, diff --git a/pkg/handle/types/types.go b/pkg/handle/types/types.go index 2d98349f2..e280f5a8c 100644 --- a/pkg/handle/types/types.go +++ b/pkg/handle/types/types.go @@ -87,8 +87,8 @@ func (h Handle) Len() int { return l } -// NewFromKcap restores handle state from the cap buffer. -func NewFromKcap(buf []byte) (Handle, error) { +// NewFromCapture restores handle state from the capture buffer. +func NewFromCapture(buf []byte) (Handle, error) { h := Handle{} err := h.Unmarshal(buf) if err != nil { diff --git a/pkg/outputs/amqp/amqp_test.go b/pkg/outputs/amqp/amqp_test.go index 6181b95ab..9a1539635 100644 --- a/pkg/outputs/amqp/amqp_test.go +++ b/pkg/outputs/amqp/amqp_test.go @@ -148,13 +148,13 @@ func consumeEvents(t *testing.T, amqpURI string, done chan struct{}) error { return err } deliveries, err := channel.Consume( - queue.Name, // name - "kevents-consumer", // consumerTag, - false, // noAck - false, // exclusive - false, // noLocal - false, // noWait - nil, // arguments + queue.Name, // name + "events-consumer", // consumerTag, + false, // noAck + false, // exclusive + false, // noLocal + false, // noWait + nil, // arguments ) require.NoError(t, err) @@ -165,15 +165,15 @@ func consumeEvents(t *testing.T, amqpURI string, done chan struct{}) error { done <- struct{}{} t.Error("got empty AMQP message") } - var kevents []*event.Event - err := json.Unmarshal(body, &kevents) + var events []*event.Event + err := json.Unmarshal(body, &events) if err != nil { done <- struct{}{} t.Error(err) } - if len(kevents) != 3 { + if len(events) != 3 { done <- struct{}{} - t.Errorf("expected 3 events in body but got %d", len(kevents)) + t.Errorf("expected 3 events in body but got %d", len(events)) } err = d.Ack(false) if err != nil { diff --git a/pkg/outputs/http/http_test.go b/pkg/outputs/http/http_test.go index 82c113ef7..c3995b560 100644 --- a/pkg/outputs/http/http_test.go +++ b/pkg/outputs/http/http_test.go @@ -54,12 +54,12 @@ func TestHttpPublish(t *testing.T) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - var kevents []*event.Event - if err := json.Unmarshal(body, &kevents); err != nil { + var events []*event.Event + if err := json.Unmarshal(body, &events); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - assert.Equal(t, 3, len(kevents)) + assert.Equal(t, 3, len(events)) assert.Equal(t, "aaabbbaaa", r.Header.Get("API-Key")) assert.Equal(t, "fibratus/", r.Header.Get("User-Agent")) assert.Equal(t, "1.1", r.Header.Get("Version")) @@ -114,12 +114,12 @@ func TestHttpGzipPublish(t *testing.T) { http.Error(w, err.Error(), http.StatusInternalServerError) return } - var kevents []*event.Event - if err := json.Unmarshal(body, &kevents); err != nil { + var events []*event.Event + if err := json.Unmarshal(body, &events); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } - assert.Equal(t, 3, len(kevents)) + assert.Equal(t, 3, len(events)) w.WriteHeader(http.StatusOK) }) diff --git a/pkg/pe/marshaller.go b/pkg/pe/marshaller.go index c4944afac..38ed57a06 100644 --- a/pkg/pe/marshaller.go +++ b/pkg/pe/marshaller.go @@ -282,8 +282,8 @@ func (pe *PE) Unmarshal(b []byte, ver capver.Version) error { return nil } -// NewFromKcap restores the PE metadata from the byte stream. -func NewFromKcap(b []byte, ver capver.Version) (*PE, error) { +// NewFromCapture restores the PE metadata from the byte stream. +func NewFromCapture(b []byte, ver capver.Version) (*PE, error) { pe := &PE{ Sections: make([]Sec, 0), Symbols: make([]string, 0), diff --git a/pkg/pe/marshaller_test.go b/pkg/pe/marshaller_test.go index 07ac3f8a0..ce4bf94a3 100644 --- a/pkg/pe/marshaller_test.go +++ b/pkg/pe/marshaller_test.go @@ -22,7 +22,7 @@ package pe import ( - kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/sys" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" @@ -64,7 +64,7 @@ func TestPEMarshal(t *testing.T) { b := pe.Marshal() newPE := &PE{VersionResources: make(map[string]string)} - err := newPE.Unmarshal(b, kcapver.PESecV2) + err := newPE.Unmarshal(b, capver.PESecV2) require.NoError(t, err) assert.Equal(t, uint16(7), newPE.NumberOfSections) diff --git a/pkg/ps/types/marshaller_windows.go b/pkg/ps/types/marshaller_windows.go index 613107525..97a1d22c9 100644 --- a/pkg/ps/types/marshaller_windows.go +++ b/pkg/ps/types/marshaller_windows.go @@ -212,7 +212,7 @@ func (ps *PS) Unmarshal(b []byte, psec section.Section) error { // read handle length l := uint32(bytes.ReadUint16(b[idx+offset+hoffset:])) off := idx + 2 + hoffset + offset - handle, err := htypes.NewFromKcap(b[off : off+l]) + handle, err := htypes.NewFromCapture(b[off : off+l]) if err != nil { return err } @@ -272,7 +272,7 @@ readpe: } var err error - ps.PE, err = pe.NewFromKcap(b[idx+offset:], sec.Version()) + ps.PE, err = pe.NewFromCapture(b[idx+offset:], sec.Version()) if err != nil { return err } diff --git a/pkg/ps/types/marshaller_windows_test.go b/pkg/ps/types/marshaller_windows_test.go index 83f279ebd..c4f26822d 100644 --- a/pkg/ps/types/marshaller_windows_test.go +++ b/pkg/ps/types/marshaller_windows_test.go @@ -23,7 +23,7 @@ import ( "golang.org/x/sys/windows" "github.com/rabbitstack/fibratus/pkg/cap/section" - kcapver "github.com/rabbitstack/fibratus/pkg/cap/version" + capver "github.com/rabbitstack/fibratus/pkg/cap/version" "github.com/rabbitstack/fibratus/pkg/pe" "github.com/stretchr/testify/assert" @@ -83,8 +83,8 @@ func TestPSMarshaler(t *testing.T) { } b := ps.Marshal() - sec := section.New(section.Process, kcapver.ProcessSecV4, 0, 0) - clone, err := NewFromKcap(b, sec) + sec := section.New(section.Process, capver.ProcessSecV4, 0, 0) + clone, err := NewFromCapture(b, sec) require.NoError(t, err) assert.Equal(t, uint32(2436), clone.PID) @@ -177,8 +177,8 @@ func TestPSMarshalerWithPE(t *testing.T) { } b := ps.Marshal() - sec := section.New(section.Process, kcapver.ProcessSecV3, 0, 0) - clone, err := NewFromKcap(b, sec) + sec := section.New(section.Process, capver.ProcessSecV3, 0, 0) + clone, err := NewFromCapture(b, sec) require.NoError(t, err) assert.Equal(t, uint32(2436), clone.PID) diff --git a/pkg/ps/types/types_windows.go b/pkg/ps/types/types_windows.go index e837646fc..bc372b312 100644 --- a/pkg/ps/types/types_windows.go +++ b/pkg/ps/types/types_windows.go @@ -401,8 +401,8 @@ func New(pid, ppid uint32, name, cmndline, exe string, sid *windows.SID, session return ps } -// NewFromKcap reconstructs the state of the process from the capture file. -func NewFromKcap(buf []byte, sec section.Section) (*PS, error) { +// NewFromCapture reconstructs the state of the process from the capture file. +func NewFromCapture(buf []byte, sec section.Section) (*PS, error) { ps := PS{ Args: make([]string, 0), Envs: make(map[string]string), diff --git a/pkg/rules/engine_test.go b/pkg/rules/engine_test.go index 7c70f3a4e..6484fb19a 100644 --- a/pkg/rules/engine_test.go +++ b/pkg/rules/engine_test.go @@ -81,16 +81,15 @@ func init() { } func newConfig(fromFiles ...string) *config.Config { - var kstreamConfig = config.KstreamConfig{ - EnableHandleKevents: true, - EnableNetKevents: true, - EnableRegistryKevents: true, - EnableFileIOKevents: true, - EnableImageKevents: true, - EnableThreadKevents: true, - } c := &config.Config{ - Kstream: kstreamConfig, + EventSource: config.EventSourceConfig{ + EnableHandleEvents: true, + EnableNetEvents: true, + EnableRegistryEvents: true, + EnableFileIOEvents: true, + EnableImageEvents: true, + EnableThreadEvents: true, + }, Filters: &config.Filters{ Rules: config.Rules{ FromPaths: fromFiles, diff --git a/pkg/rules/sequence_test.go b/pkg/rules/sequence_test.go index 7cbedc5ae..1f300ae0e 100644 --- a/pkg/rules/sequence_test.go +++ b/pkg/rules/sequence_test.go @@ -46,7 +46,7 @@ func TestSequenceState(t *testing.T) { |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path |evt.name = 'CreateProcess'| by ps.child.exe`, - &config.Config{Kstream: config.KstreamConfig{}, Filters: &config.Filters{}}) + &config.Config{EventSource: config.EventSourceConfig{}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) @@ -187,7 +187,7 @@ func TestSimpleSequence(t *testing.T) { maxspan 100ms |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -273,7 +273,7 @@ func TestSimpleSequenceMultiplePartials(t *testing.T) { by ps.pid |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| |evt.name = 'CreateFile' and file.path icontains 'temp'| - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -379,7 +379,7 @@ func TestSimpleSequenceDeadline(t *testing.T) { maxspan 100ms |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -450,7 +450,7 @@ func TestComplexSequence(t *testing.T) { |evt.name = 'CreateProcess' and ps.child.name in ('firefox.exe', 'chrome.exe', 'edge.exe')| by ps.child.pid |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.exe'| by ps.pid |evt.name in ('Send', 'Connect')| by ps.pid - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -543,7 +543,7 @@ func TestSequenceOOO(t *testing.T) { maxspan 2m |evt.name = 'OpenProcess' and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| by ps.uuid |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| by ps.uuid - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -603,7 +603,7 @@ func TestSequenceGC(t *testing.T) { by ps.uuid |evt.name = 'OpenProcess' and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| |evt.name = 'CreateFile' and file.operation = 'CREATE' and file.extension = '.dmp'| - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -752,7 +752,7 @@ func TestSequenceExpire(t *testing.T) { for _, tt := range tests { t.Run(tt.expr, func(t *testing.T) { - f := filter.New(tt.expr, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + f := filter.New(tt.expr, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, tt.c, new(ps.SnapshotterMock)) @@ -784,7 +784,7 @@ func TestSequenceBoundFields(t *testing.T) { |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| as e1 |evt.name = 'CreateFile' and file.path icontains 'temp' and $e1.ps.sid = ps.sid| as e2 |evt.name = 'Connect' and ps.sid != $e2.ps.sid and ps.sid = $e1.ps.sid| - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -879,7 +879,7 @@ func TestSequenceBoundFieldsWithFunctions(t *testing.T) { |evt.name = 'RegSetValue' and registry.path ~= 'HKEY_CURRENT_USER\\Volatile Environment\\Notification Packages' and get_reg_value(registry.path) iin (base($e1.file.path, false))| - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true, EnableRegistryKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true, EnableRegistryEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) @@ -939,7 +939,7 @@ func TestIsExpressionEvaluable(t *testing.T) { maxspan 100ms |evt.name = 'CreateProcess' and ps.name = 'cmd.exe'| by ps.exe |evt.name = 'CreateFile' and file.path icontains 'temp'| by file.path - `, &config.Config{Kstream: config.KstreamConfig{EnableFileIOKevents: true}, Filters: &config.Filters{}}) + `, &config.Config{EventSource: config.EventSourceConfig{EnableFileIOEvents: true}, Filters: &config.Filters{}}) require.NoError(t, f.Compile()) ss := newSequenceState(f, c, new(ps.SnapshotterMock)) diff --git a/pkg/yara/scanner_unsupported.go b/pkg/yara/scanner_unsupported.go index 63f28b77f..828b2a3c0 100644 --- a/pkg/yara/scanner_unsupported.go +++ b/pkg/yara/scanner_unsupported.go @@ -22,12 +22,12 @@ package yara import ( - kerrors "github.com/rabbitstack/fibratus/pkg/errors" + errs "github.com/rabbitstack/fibratus/pkg/errors" "github.com/rabbitstack/fibratus/pkg/ps" "github.com/rabbitstack/fibratus/pkg/yara/config" ) // NewScanner returns unsupported scanner error. func NewScanner(psnap ps.Snapshotter, config config.Config) (Scanner, error) { - return nil, kerrors.ErrFeatureUnsupported("yara") + return nil, errs.ErrFeatureUnsupported("yara") } From 2a0fdb70763db5f6c4196240b859656334597ab8 Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Wed, 28 May 2025 19:09:00 +0200 Subject: [PATCH 3/4] refactor: Deprecate kevt.* filter fields --- pkg/filter/accessor.go | 44 ++++---- pkg/filter/fields/fields_windows.go | 168 ++++++++++++++++++++-------- pkg/filter/filter_test.go | 2 +- pkg/filter/ql/error_test.go | 2 +- pkg/filter/ql/literal.go | 2 +- pkg/filter/ql/parser_test.go | 4 +- pkg/rules/compiler.go | 2 +- pkg/rules/engine.go | 6 +- 8 files changed, 153 insertions(+), 77 deletions(-) diff --git a/pkg/filter/accessor.go b/pkg/filter/accessor.go index 27124c495..21e05dc72 100644 --- a/pkg/filter/accessor.go +++ b/pkg/filter/accessor.go @@ -64,51 +64,51 @@ const dateFmt = "2006-01-02" func (k *evtAccessor) Get(f Field, evt *event.Event) (params.Value, error) { switch f.Name { - case fields.KevtSeq: + case fields.EvtSeq, fields.KevtSeq: return evt.Seq, nil - case fields.KevtPID: + case fields.EvtPID, fields.KevtPID: return evt.PID, nil - case fields.KevtTID: + case fields.EvtTID, fields.KevtTID: return evt.Tid, nil - case fields.KevtCPU: + case fields.EvtCPU, fields.KevtCPU: return evt.CPU, nil - case fields.KevtName: + case fields.EvtName, fields.KevtName: return evt.Name, nil - case fields.KevtCategory: + case fields.EvtCategory, fields.KevtCategory: return string(evt.Category), nil - case fields.KevtDesc: + case fields.EvtDesc, fields.KevtDesc: return evt.Description, nil - case fields.KevtHost: + case fields.EvtHost, fields.KevtHost: return evt.Host, nil - case fields.KevtTime: + case fields.EvtTime, fields.KevtTime: return evt.Timestamp.Format(timeFmt), nil - case fields.KevtTimeHour: + case fields.EvtTimeHour, fields.KevtTimeHour: return uint8(evt.Timestamp.Hour()), nil - case fields.KevtTimeMin: + case fields.EvtTimeMin, fields.KevtTimeMin: return uint8(evt.Timestamp.Minute()), nil - case fields.KevtTimeSec: + case fields.EvtTimeSec, fields.KevtTimeSec: return uint8(evt.Timestamp.Second()), nil - case fields.KevtTimeNs: + case fields.EvtTimeNs, fields.KevtTimeNs: return evt.Timestamp.UnixNano(), nil - case fields.KevtDate: + case fields.EvtDate, fields.KevtDate: return evt.Timestamp.Format(dateFmt), nil - case fields.KevtDateDay: + case fields.EvtDateDay, fields.KevtDateDay: return uint8(evt.Timestamp.Day()), nil - case fields.KevtDateMonth: + case fields.EvtDateMonth, fields.KevtDateMonth: return uint8(evt.Timestamp.Month()), nil - case fields.KevtDateTz: + case fields.EvtDateTz, fields.KevtDateTz: tz, _ := evt.Timestamp.Zone() return tz, nil - case fields.KevtDateYear: + case fields.EvtDateYear, fields.KevtDateYear: return uint32(evt.Timestamp.Year()), nil - case fields.KevtDateWeek: + case fields.EvtDateWeek, fields.KevtDateWeek: _, week := evt.Timestamp.ISOWeek() return uint8(week), nil - case fields.KevtDateWeekday: + case fields.EvtDateWeekday, fields.KevtDateWeekday: return evt.Timestamp.Weekday().String(), nil - case fields.KevtNparams: + case fields.EvtNparams, fields.KevtNparams: return uint64(evt.Params.Len()), nil - case fields.KevtArg: + case fields.EvtArg, fields.KevtArg: // lookup the parameter from the field argument // and depending on the parameter type, return // the respective value. The field format is diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index 4970397cb..4c50c826f 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -300,52 +300,95 @@ const ( // PePsChildFileName represents the original file name of the child process executable provided at compile-time PePsChildFileName Field = "pe.ps.child.file.name" + // EvtSeq is the event sequence number + EvtSeq Field = "evt.seq" + // EvtPID is the process identifier that generated the event + EvtPID Field = "evt.pid" + // EvtTID is the thread identifier that generated the event + EvtTID Field = "evt.tid" + // EvtCPU is the CPU core where the event was generated + EvtCPU Field = "evt.cpu" + // EvtDesc represents the event description + EvtDesc Field = "evt.desc" + // EvtHost represents the host where the event was produced + EvtHost Field = "evt.host" + // EvtTime is the event time + EvtTime Field = "evt.time" + // EvtTimeHour is the hour part of the event time + EvtTimeHour Field = "evt.time.h" + // EvtTimeMin is the minute part of the event time + EvtTimeMin Field = "evt.time.m" + // EvtTimeSec is the second part of the event time + EvtTimeSec Field = "evt.time.s" + // EvtTimeNs is the nanosecond part of the event time + EvtTimeNs Field = "evt.time.ns" + // EvtDate is the event date + EvtDate Field = "evt.date" + // EvtDateDay is the day of event date + EvtDateDay Field = "evt.date.d" + // EvtDateMonth is the month of event date + EvtDateMonth Field = "evt.date.m" + // EvtDateYear is the year of event date + EvtDateYear Field = "evt.date.y" + // EvtDateTz is the time zone of event timestamp + EvtDateTz Field = "evt.date.tz" + // EvtDateWeek is the event week number + EvtDateWeek Field = "evt.date.week" + // EvtDateWeekday is the event week day + EvtDateWeekday Field = "evt.date.weekday" + // EvtName is the event name + EvtName Field = "evt.name" + // EvtCategory is the event category + EvtCategory Field = "evt.category" + // EvtNparams is the number of event parameters + EvtNparams Field = "evt.nparams" + // EvtArg represents the field sequence for generic argument access + EvtArg Field = "evt.arg" + // KevtSeq is the event sequence number - KevtSeq Field = "evt.seq" + KevtSeq Field = "kevt.seq" // KevtPID is the process identifier that generated the event - KevtPID Field = "evt.pid" + KevtPID Field = "kevt.pid" // KevtTID is the thread identifier that generated the event - KevtTID Field = "evt.tid" + KevtTID Field = "kevt.tid" // KevtCPU is the CPU core where the event was generated - KevtCPU Field = "evt.cpu" + KevtCPU Field = "kevt.cpu" // KevtDesc represents the event description - KevtDesc Field = "evt.desc" + KevtDesc Field = "kevt.desc" // KevtHost represents the host where the event was produced - KevtHost Field = "evt.host" + KevtHost Field = "kevt.host" // KevtTime is the event time - KevtTime Field = "evt.time" + KevtTime Field = "kevt.time" // KevtTimeHour is the hour part of the event time - KevtTimeHour Field = "evt.time.h" + KevtTimeHour Field = "kevt.time.h" // KevtTimeMin is the minute part of the event time - KevtTimeMin Field = "evt.time.m" + KevtTimeMin Field = "kevt.time.m" // KevtTimeSec is the second part of the event time - KevtTimeSec Field = "evt.time.s" + KevtTimeSec Field = "kevt.time.s" // KevtTimeNs is the nanosecond part of the event time - KevtTimeNs Field = "evt.time.ns" + KevtTimeNs Field = "kevt.time.ns" // KevtDate is the event date - KevtDate Field = "evt.date" + KevtDate Field = "kevt.date" // KevtDateDay is the day of event date - KevtDateDay Field = "evt.date.d" + KevtDateDay Field = "kevt.date.d" // KevtDateMonth is the month of event date - KevtDateMonth Field = "evt.date.m" + KevtDateMonth Field = "kevt.date.m" // KevtDateYear is the year of event date - KevtDateYear Field = "evt.date.y" + KevtDateYear Field = "kevt.date.y" // KevtDateTz is the time zone of event timestamp - KevtDateTz Field = "evt.date.tz" + KevtDateTz Field = "kevt.date.tz" // KevtDateWeek is the event week number - KevtDateWeek Field = "evt.date.week" + KevtDateWeek Field = "kevt.date.week" // KevtDateWeekday is the event week day - KevtDateWeekday Field = "evt.date.weekday" + KevtDateWeekday Field = "kevt.date.weekday" // KevtName is the event name - KevtName Field = "evt.name" + KevtName Field = "kevt.name" // KevtCategory is the event category - KevtCategory Field = "evt.category" - // KevtMeta is the event metadata - KevtMeta Field = "evt.meta" + KevtCategory Field = "kevt.category" // KevtNparams is the number of event parameters - KevtNparams Field = "evt.nparams" + KevtNparams Field = "kevt.nparams" // KevtArg represents the field sequence for generic argument access - KevtArg Field = "evt.arg" + KevtArg Field = "kevt.arg" // HandleID represents the handle identifier within the process address space HandleID Field = "handle.id" @@ -734,28 +777,61 @@ func IsPseudoField(f Field) bool { func (f Field) IsPeSectionsPseudo() bool { return f == PeSections } var fields = map[Field]FieldInfo{ - KevtSeq: {KevtSeq, "event sequence number", params.Uint64, []string{"evt.seq > 666"}, nil, nil}, - KevtPID: {KevtPID, "process identifier generating the kernel event", params.Uint32, []string{"evt.pid = 6"}, nil, nil}, - KevtTID: {KevtTID, "thread identifier generating the kernel event", params.Uint32, []string{"evt.tid = 1024"}, nil, nil}, - KevtCPU: {KevtCPU, "logical processor core where the event was generated", params.Uint8, []string{"evt.cpu = 2"}, nil, nil}, - KevtName: {KevtName, "symbolical kernel event name", params.AnsiString, []string{"evt.name = 'CreateThread'"}, nil, nil}, - KevtCategory: {KevtCategory, "event category", params.AnsiString, []string{"evt.category = 'registry'"}, nil, nil}, - KevtDesc: {KevtDesc, "event description", params.AnsiString, []string{"evt.desc contains 'Creates a new process'"}, nil, nil}, - KevtHost: {KevtHost, "host name on which the event was produced", params.UnicodeString, []string{"evt.host contains 'kitty'"}, nil, nil}, - KevtTime: {KevtTime, "event timestamp as a time string", params.Time, []string{"evt.time = '17:05:32'"}, nil, nil}, - KevtTimeHour: {KevtTimeHour, "hour within the day on which the event occurred", params.Time, []string{"evt.time.h = 23"}, nil, nil}, - KevtTimeMin: {KevtTimeMin, "minute offset within the hour on which the event occurred", params.Time, []string{"evt.time.m = 54"}, nil, nil}, - KevtTimeSec: {KevtTimeSec, "second offset within the minute on which the event occurred", params.Time, []string{"evt.time.s = 0"}, nil, nil}, - KevtTimeNs: {KevtTimeNs, "nanoseconds specified by event timestamp", params.Int64, []string{"evt.time.ns > 1591191629102337000"}, nil, nil}, - KevtDate: {KevtDate, "event timestamp as a date string", params.Time, []string{"evt.date = '2018-03-03'"}, nil, nil}, - KevtDateDay: {KevtDateDay, "day of the month on which the event occurred", params.Time, []string{"evt.date.d = 12"}, nil, nil}, - KevtDateMonth: {KevtDateMonth, "month of the year on which the event occurred", params.Time, []string{"evt.date.m = 11"}, nil, nil}, - KevtDateYear: {KevtDateYear, "year on which the event occurred", params.Uint32, []string{"evt.date.y = 2020"}, nil, nil}, - KevtDateTz: {KevtDateTz, "time zone associated with the event timestamp", params.AnsiString, []string{"evt.date.tz = 'UTC'"}, nil, nil}, - KevtDateWeek: {KevtDateWeek, "week number within the year on which the event occurred", params.Uint8, []string{"evt.date.week = 2"}, nil, nil}, - KevtDateWeekday: {KevtDateWeekday, "week day on which the event occurred", params.AnsiString, []string{"evt.date.weekday = 'Monday'"}, nil, nil}, - KevtNparams: {KevtNparams, "number of parameters", params.Int8, []string{"evt.nparams > 2"}, nil, nil}, - KevtArg: {KevtArg, "event parameter", params.Object, []string{"evt.arg[cmdline] istartswith 'C:\\Windows'"}, nil, &Argument{Optional: false, Pattern: "[a-z0-9_]+", ValidationFunc: func(s string) bool { + EvtSeq: {EvtSeq, "event sequence number", params.Uint64, []string{"evt.seq > 666"}, nil, nil}, + EvtPID: {EvtPID, "process identifier generating the event", params.Uint32, []string{"evt.pid = 6"}, nil, nil}, + EvtTID: {EvtTID, "thread identifier generating the event", params.Uint32, []string{"evt.tid = 1024"}, nil, nil}, + EvtCPU: {EvtCPU, "logical processor core where the event was generated", params.Uint8, []string{"evt.cpu = 2"}, nil, nil}, + EvtName: {EvtName, "symbolical event name", params.AnsiString, []string{"evt.name = 'CreateThread'"}, nil, nil}, + EvtCategory: {EvtCategory, "event category", params.AnsiString, []string{"evt.category = 'registry'"}, nil, nil}, + EvtDesc: {EvtDesc, "event description", params.AnsiString, []string{"evt.desc contains 'Creates a new process'"}, nil, nil}, + EvtHost: {EvtHost, "host name on which the event was produced", params.UnicodeString, []string{"evt.host contains 'kitty'"}, nil, nil}, + EvtTime: {EvtTime, "event timestamp as a time string", params.Time, []string{"evt.time = '17:05:32'"}, nil, nil}, + EvtTimeHour: {EvtTimeHour, "hour within the day on which the event occurred", params.Time, []string{"evt.time.h = 23"}, nil, nil}, + EvtTimeMin: {EvtTimeMin, "minute offset within the hour on which the event occurred", params.Time, []string{"evt.time.m = 54"}, nil, nil}, + EvtTimeSec: {EvtTimeSec, "second offset within the minute on which the event occurred", params.Time, []string{"evt.time.s = 0"}, nil, nil}, + EvtTimeNs: {EvtTimeNs, "nanoseconds specified by event timestamp", params.Int64, []string{"evt.time.ns > 1591191629102337000"}, nil, nil}, + EvtDate: {EvtDate, "event timestamp as a date string", params.Time, []string{"evt.date = '2018-03-03'"}, nil, nil}, + EvtDateDay: {EvtDateDay, "day of the month on which the event occurred", params.Time, []string{"evt.date.d = 12"}, nil, nil}, + EvtDateMonth: {EvtDateMonth, "month of the year on which the event occurred", params.Time, []string{"evt.date.m = 11"}, nil, nil}, + EvtDateYear: {EvtDateYear, "year on which the event occurred", params.Uint32, []string{"evt.date.y = 2020"}, nil, nil}, + EvtDateTz: {EvtDateTz, "time zone associated with the event timestamp", params.AnsiString, []string{"evt.date.tz = 'UTC'"}, nil, nil}, + EvtDateWeek: {EvtDateWeek, "week number within the year on which the event occurred", params.Uint8, []string{"evt.date.week = 2"}, nil, nil}, + EvtDateWeekday: {EvtDateWeekday, "week day on which the event occurred", params.AnsiString, []string{"evt.date.weekday = 'Monday'"}, nil, nil}, + EvtNparams: {EvtNparams, "number of parameters", params.Int8, []string{"evt.nparams > 2"}, nil, nil}, + EvtArg: {EvtArg, "event parameter", params.Object, []string{"evt.arg[cmdline] istartswith 'C:\\Windows'"}, nil, &Argument{Optional: false, Pattern: "[a-z0-9_]+", ValidationFunc: func(s string) bool { + for _, c := range s { + switch { + case unicode.IsLower(c): + case unicode.IsNumber(c): + case c == '_': + default: + return false + } + } + return true + }}}, + KevtSeq: {KevtSeq, "event sequence number", params.Uint64, []string{"kevt.seq > 666"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtSeq}}, nil}, + KevtPID: {KevtPID, "process identifier generating the event", params.Uint32, []string{"kevt.pid = 6"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtPID}}, nil}, + KevtTID: {KevtTID, "thread identifier generating the event", params.Uint32, []string{"kevt.tid = 1024"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTID}}, nil}, + KevtCPU: {KevtCPU, "logical processor core where the event was generated", params.Uint8, []string{"kevt.cpu = 2"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtCPU}}, nil}, + KevtName: {KevtName, "symbolical event name", params.AnsiString, []string{"kevt.name = 'CreateThread'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtName}}, nil}, + KevtCategory: {KevtCategory, "event category", params.AnsiString, []string{"kevt.category = 'registry'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtCategory}}, nil}, + KevtDesc: {KevtDesc, "event description", params.AnsiString, []string{"kevt.desc contains 'Creates a new process'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDesc}}, nil}, + KevtHost: {KevtHost, "host name on which the event was produced", params.UnicodeString, []string{"kevt.host contains 'kitty'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtHost}}, nil}, + KevtTime: {KevtTime, "event timestamp as a time string", params.Time, []string{"kevt.time = '17:05:32'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTime}}, nil}, + KevtTimeHour: {KevtTimeHour, "hour within the day on which the event occurred", params.Time, []string{"kevt.time.h = 23"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTimeHour}}, nil}, + KevtTimeMin: {KevtTimeMin, "minute offset within the hour on which the event occurred", params.Time, []string{"kevt.time.m = 54"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTimeMin}}, nil}, + KevtTimeSec: {KevtTimeSec, "second offset within the minute on which the event occurred", params.Time, []string{"kevt.time.s = 0"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTimeSec}}, nil}, + KevtTimeNs: {KevtTimeNs, "nanoseconds specified by event timestamp", params.Int64, []string{"kevt.time.ns > 1591191629102337000"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtTimeNs}}, nil}, + KevtDate: {KevtDate, "event timestamp as a date string", params.Time, []string{"kevt.date = '2018-03-03'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDate}}, nil}, + KevtDateDay: {KevtDateDay, "day of the month on which the event occurred", params.Time, []string{"kevt.date.d = 12"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateDay}}, nil}, + KevtDateMonth: {KevtDateMonth, "month of the year on which the event occurred", params.Time, []string{"kevt.date.m = 11"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateMonth}}, nil}, + KevtDateYear: {KevtDateYear, "year on which the event occurred", params.Uint32, []string{"kevt.date.y = 2020"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateYear}}, nil}, + KevtDateTz: {KevtDateTz, "time zone associated with the event timestamp", params.AnsiString, []string{"kevt.date.tz = 'UTC'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateTz}}, nil}, + KevtDateWeek: {KevtDateWeek, "week number within the year on which the event occurred", params.Uint8, []string{"kevt.date.week = 2"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateWeek}}, nil}, + KevtDateWeekday: {KevtDateWeekday, "week day on which the event occurred", params.AnsiString, []string{"kevt.date.weekday = 'Monday'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtDateWeekday}}, nil}, + KevtNparams: {KevtNparams, "number of parameters", params.Int8, []string{"kevt.nparams > 2"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtNparams}}, nil}, + KevtArg: {KevtArg, "event parameter", params.Object, []string{"kevt.arg[cmdline] istartswith 'C:\\Windows'"}, &Deprecation{Since: "3.0.0", Fields: []Field{EvtArg}}, &Argument{Optional: false, Pattern: "[a-z0-9_]+", ValidationFunc: func(s string) bool { for _, c := range s { switch { case unicode.IsLower(c): diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index 956324da9..a105f25d7 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -104,7 +104,7 @@ func TestStringFields(t *testing.T) { f := New(`ps.name = 'cmd.exe' and evt.name = 'CreateProcess' or evt.name in ('TerminateProcess', 'CreateFile')`, cfg) require.NoError(t, f.Compile()) assert.Len(t, f.GetStringFields(), 2) - assert.Len(t, f.GetStringFields()[fields.KevtName], 3) + assert.Len(t, f.GetStringFields()[fields.EvtName], 3) assert.Len(t, f.GetStringFields()[fields.PsName], 1) } diff --git a/pkg/filter/ql/error_test.go b/pkg/filter/ql/error_test.go index ca131c384..fe27d25aa 100644 --- a/pkg/filter/ql/error_test.go +++ b/pkg/filter/ql/error_test.go @@ -59,7 +59,7 @@ func TestParseError(t *testing.T) { registry.key.name icontains ( CurrentVersion\\Run', -╭─────────────^ +╭──────────────^ | | 'Policies\\Explorer\\Run', | 'Group Policy\\Scripts', diff --git a/pkg/filter/ql/literal.go b/pkg/filter/ql/literal.go index 78ebf75ed..208d9268a 100644 --- a/pkg/filter/ql/literal.go +++ b/pkg/filter/ql/literal.go @@ -338,7 +338,7 @@ func (e *SequenceExpr) walk() { // initialize event type/category buckets for every such field for name, values := range stringFields { - if name == fields.KevtName || name == fields.KevtCategory { + if name == fields.EvtName || name == fields.EvtCategory { for _, v := range values { e.buckets[hashers.FnvUint32([]byte(v))] = true if etype := event.NameToType(v); etype.Exists() { diff --git a/pkg/filter/ql/parser_test.go b/pkg/filter/ql/parser_test.go index 30105584d..7199df993 100644 --- a/pkg/filter/ql/parser_test.go +++ b/pkg/filter/ql/parser_test.go @@ -64,9 +64,9 @@ func TestParser(t *testing.T) { {expr: `ps.envs imatches 'C:\\Program Files'`}, {expr: `ps.pid[1] = 'svchost.exe'`, err: errors.New("ps.pid[1] = 'svchost.exe'\n╭──────^\n|\n|\n╰─────────────────── expected field without argument")}, {expr: `ps.envs[ProgramFiles = 'svchost.exe'`, err: errors.New("ps.envs[ProgramFiles = 'svchost.exe'\n╭───────────────────^\n|\n|\n╰─────────────────── expected ]")}, - {expr: `evt.arg = 'svchost.exe'`, err: errors.New("evt.arg = 'svchost.exe'\n╭───────^\n|\n|\n╰─────────────────── expected field argument")}, + {expr: `evt.arg = 'svchost.exe'`, err: errors.New("evt.arg = 'svchost.exe'\n╭──────^\n|\n|\n╰─────────────────── expected field argument")}, {expr: `evt.arg[name] = 'svchost.exe'`}, - {expr: `evt.arg[Name$] = 'svchost.exe'`, err: errors.New("evt.arg[Name$] = 'svchost.exe'\n╭────────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [a-z0-9_]+")}, + {expr: `evt.arg[Name$] = 'svchost.exe'`, err: errors.New("evt.arg[Name$] = 'svchost.exe'\n╭───────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [a-z0-9_]+")}, {expr: `ps.ancestor[0] = 'svchost.exe'`}, {expr: `ps.ancestor[l0l] = 'svchost.exe'`, err: errors.New("ps.ancestor[l0l] = 'svchost.exe'\n╭───────────^\n|\n|\n╰─────────────────── expected a valid field argument matching the pattern [0-9]+")}, } diff --git a/pkg/rules/compiler.go b/pkg/rules/compiler.go index 7016341e5..7d964f3c2 100644 --- a/pkg/rules/compiler.go +++ b/pkg/rules/compiler.go @@ -121,7 +121,7 @@ func (c *compiler) buildCompileResult(filters map[*config.FilterConfig]filter.Fi rs.NumberRules++ for name, values := range f.GetStringFields() { for _, v := range values { - if name == fields.KevtName || name == fields.KevtCategory { + if name == fields.EvtName || name == fields.EvtCategory { types := event.NameToTypes(v) for _, typ := range types { switch typ.Category() { diff --git a/pkg/rules/engine.go b/pkg/rules/engine.go index 2cd74569e..e9b6cc294 100644 --- a/pkg/rules/engine.go +++ b/pkg/rules/engine.go @@ -151,7 +151,7 @@ func newCompiledFilter(f filter.Filter, c *config.FilterConfig, ss *sequenceStat // conditions. func (f *compiledFilter) isScoped() bool { for name := range f.filter.GetStringFields() { - if name == fields.KevtName || name == fields.KevtCategory { + if name == fields.EvtName || name == fields.EvtCategory { return true } } @@ -233,8 +233,8 @@ func (e *Engine) Compile() (*config.RulesCompileResult, error) { // or event category hash for name, values := range f.GetStringFields() { for _, v := range values { - if name == fields.KevtName || name == fields.KevtCategory { - if name == fields.KevtCategory { + if name == fields.EvtName || name == fields.EvtCategory { + if name == fields.EvtCategory { e.hashCache.lookupCategory = true } hash := hashers.FnvUint32([]byte(v)) From df7fc3635bcd3527b5d8faf3d65f800b55ba427b Mon Sep 17 00:00:00 2001 From: rabbitstack Date: Fri, 30 May 2025 18:56:54 +0200 Subject: [PATCH 4/4] refactor(rules): Adapt rules to use the `evt.` filter field --- rules/README.md | 2 +- ...ail_access_file_access_to_sam_database.yml | 4 +- ...ntial_access_from_backups_via_rundll32.yml | 4 +- ...cess_credential_discovery_via_vaultcmd.yml | 4 +- ..._lsass_access_from_unsigned_executable.yml | 6 +- ..._access_lsass_handle_leak_via_seclogon.yml | 6 +- ...mp_preparation_via_silent_process_exit.yml | 4 +- ...sass_memory_dump_via_minidumpwritedump.yml | 6 +- ...ntial_access_lsass_memory_dump_via_wer.yml | 4 +- ...credential_access_lsass_memory_dumping.yml | 6 +- ..._process_clone_creation_via_reflection.yml | 4 +- ...tial_access_potential_sam_hive_dumping.yml | 4 +- ...cess_remote_thread_creation_into_lsass.yml | 6 +- ...ss_to_active_directory_domain_database.yml | 4 +- ...ous_access_to_unattended_panther_files.yml | 4 +- ...us_access_to_windows_dpapi_master_keys.yml | 4 +- ...icious_access_to_windows_manager_files.yml | 4 +- ...spicious_access_to_windows_vault_files.yml | 4 +- ...cious_security_package_loaded_by_lsass.yml | 4 +- ...ccess_suspicious_vault_client_dll_load.yml | 4 +- ...tial_access_unusual_access_to_ssh_keys.yml | 4 +- ...ccess_to_web_browser_credential_stores.yml | 4 +- ...l_access_to_windows_credential_history.yml | 4 +- ...jection_via_clr_search_order_hijacking.yml | 4 +- rules/defense_evasion_clear_eventlog.yml | 6 +- ...fense_evasion_dll_loaded_via_apc_queue.yml | 4 +- ...asion_dll_loaded_via_callback_function.yml | 4 +- ..._dll_loaded_via_ldrpkernel32_overwrite.yml | 4 +- ...sion_dll_sideloading_via_copied_binary.yml | 4 +- ...ding_via_microsoft_office_dropped_file.yml | 4 +- ...t_assembly_loaded_by_unmanaged_process.yml | 4 +- ...e_evasion_hidden_registry_key_creation.yml | 6 +- ...vasion_image_load_via_ntfs_transaction.yml | 6 +- ...tential_injection_via_dotnet_debugging.yml | 4 +- ...tential_process_creation_via_shellcode.yml | 4 +- ...ential_process_doppelganging_injection.yml | 4 +- ..._potential_process_hollowing_injection.yml | 4 +- ...s_injection_via_tainted_memory_section.yml | 8 +-- ...llcode_execution_via_etw_logger_thread.yml | 6 +- ...n_potential_thread_execution_hijacking.yml | 4 +- ...ss_execution_from_self_deleting_binary.yml | 4 +- ...sion_process_spawned_via_remote_thread.yml | 4 +- ...e_evasion_regsvr32_scriptlet_execution.yml | 4 +- ...on_suspicious_access_to_the_hosts_file.yml | 4 +- ..._dll_loaded_via_memory_section_mapping.yml | 6 +- ...ious_html_application_script_execution.yml | 4 +- ...spicious_object_symbolic_link_creation.yml | 10 +-- ...ender_exclusions_registry_modification.yml | 4 +- ...vasion_suspicious_xsl_script_execution.yml | 4 +- ...em_binary_proxy_execution_via_rundll32.yml | 4 +- ...hread_context_set_from_unbacked_memory.yml | 4 +- ...signed_dll_injection_via_remote_thread.yml | 4 +- ...nder_protection_tampering_via_registry.yml | 4 +- ...acro_enabled_microsoft_office_document.yml | 4 +- ...execution_via_microsoft_office_process.yml | 4 +- ...macro_execution_via_script_interpreter.yml | 4 +- ..._file_execution_via_script_interpreter.yml | 4 +- ...icrosoft_office_file_execution_via_wmi.yml | 4 +- ...lickfix_infection_chain_via_run_window.yml | 4 +- ...acro_enabled_microsoft_office_document.yml | 4 +- ...dll_loaded_by_microsoft_office_process.yml | 4 +- ..._via_wmi_from_microsoft_office_process.yml | 4 +- ...cious_microsoft_office_embedded_object.yml | 4 +- rules/macros/macros.yml | 66 +++++++++---------- ...e_file_dropped_by_unsigned_service_dll.yml | 6 +- ...sistence_hidden_local_account_creation.yml | 4 +- ...ia_startup_folder_executable_or_script.yml | 4 +- ..._persistence_via_registry_modification.yml | 4 +- rules/persistence_rid_hijacking.yml | 4 +- ...reter_or_untrusted_process_persistence.yml | 6 +- ...spicious_microsoft_office_addin_loaded.yml | 4 +- ...e_suspicious_microsoft_office_template.yml | 4 +- ..._suspicious_netsh_helper_dll_execution.yml | 4 +- ..._persistence_via_registry_modification.yml | 4 +- ...istence_suspicious_port_monitor_loaded.yml | 4 +- ...ence_suspicious_print_processor_loaded.yml | 4 +- ...ious_startup_shell_folder_modification.yml | 4 +- ...unusual_file_written_in_startup_folder.yml | 4 +- ...sual_process_modified_registry_run_key.yml | 4 +- ...e_escalation_via_phantom_dll_hijacking.yml | 6 +- ...vulnerable_or_malicious_driver_dropped.yml | 4 +- ..._vulnerable_or_malicious_driver_loaded.yml | 4 +- 82 files changed, 212 insertions(+), 212 deletions(-) diff --git a/rules/README.md b/rules/README.md index a64c82605..f735475b4 100644 --- a/rules/README.md +++ b/rules/README.md @@ -51,7 +51,7 @@ As highlighted in the previous paragraph, all rules should have the event type c ### Prefer macros over raw conditions -Fibratus comes with a [macros](https://www.fibratus.io/#/filters/rules?id=macros) library to promote the reusability and modularization of rule conditions and lists. Before trying to spell out a raw rule condition, explore the library to check if there's already a macro you can pull into the rule. For example, detecting file accesses could be accomplished by declaring the `kevt.name = 'CreateFile' and file.operation = 'open'` expression. However, the macro library comes with the `open_file` macro that you can directly call in any rule. If you can't encounter a particular macro in the library, please consider creating it. Future detection engineers and rule writers could profit from those macros. +Fibratus comes with a [macros](https://www.fibratus.io/#/filters/rules?id=macros) library to promote the reusability and modularization of rule conditions and lists. Before trying to spell out a raw rule condition, explore the library to check if there's already a macro you can pull into the rule. For example, detecting file accesses could be accomplished by declaring the `evt.name = 'CreateFile' and file.operation = 'open'` expression. However, the macro library comes with the `open_file` macro that you can directly call in any rule. If you can't encounter a particular macro in the library, please consider creating it. Future detection engineers and rule writers could profit from those macros. ### Formatting styles diff --git a/rules/credentail_access_file_access_to_sam_database.yml b/rules/credentail_access_file_access_to_sam_database.yml index d9fd3de8a..af7d03164 100644 --- a/rules/credentail_access_file_access_to_sam_database.yml +++ b/rules/credentail_access_file_access_to_sam_database.yml @@ -1,6 +1,6 @@ name: File access to SAM database id: e3dace20-4962-4381-884e-40dcdde66626 -version: 1.0.3 +version: 1.0.4 description: | Identifies access to the Security Account Manager on-disk database. labels: @@ -32,4 +32,4 @@ condition: > '?:\\Windows\\System32\\srtasks.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_credential_access_from_backups_via_rundll32.yml b/rules/credential_access_credential_access_from_backups_via_rundll32.yml index d8a9301aa..5ed966629 100644 --- a/rules/credential_access_credential_access_from_backups_via_rundll32.yml +++ b/rules/credential_access_credential_access_from_backups_via_rundll32.yml @@ -1,6 +1,6 @@ name: Credentials access from backups via Rundll32 id: ff43852c-486c-4870-a318-ce976d2231a5 -version: 1.0.0 +version: 1.0.1 description: | Detects an attempt to obtain credentials from credential backups. labels: @@ -21,4 +21,4 @@ condition: > and (ps.child.args iin ('keymgr.dll') and ps.child.args iin ('KRShowKeyMgr')) -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_credential_discovery_via_vaultcmd.yml b/rules/credential_access_credential_discovery_via_vaultcmd.yml index ccae2d63c..bf9abb78a 100644 --- a/rules/credential_access_credential_discovery_via_vaultcmd.yml +++ b/rules/credential_access_credential_discovery_via_vaultcmd.yml @@ -1,6 +1,6 @@ name: Credential discovery via VaultCmd tool id: 2ce607d3-5a14-4628-be8a-22bcde97dab5 -version: 1.1.0 +version: 1.1.1 description: | Detects the usage of the VaultCmd tool to list Windows Credentials. VaultCmd creates, displays and deletes stored credentials. An adversary may abuse this to list or dump @@ -23,4 +23,4 @@ condition: > severity: medium -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_access_from_unsigned_executable.yml b/rules/credential_access_lsass_access_from_unsigned_executable.yml index 66329dfff..2de3fd1a3 100644 --- a/rules/credential_access_lsass_access_from_unsigned_executable.yml +++ b/rules/credential_access_lsass_access_from_unsigned_executable.yml @@ -1,6 +1,6 @@ name: LSASS access from unsigned executable id: 348bf896-2201-444f-b1c9-e957a1f063bf -version: 1.0.0 +version: 1.0.1 description: | Detects attempts by an unsigned process to access the Local Security Authority Subsystem Service (LSASS). Adversaries may try to dump credential information stored in the process memory of LSASS. @@ -21,7 +21,7 @@ condition: > maxspan 7m by ps.uuid |load_unsigned_executable| - |((open_process) or (open_thread)) and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| + |((open_process) or (open_thread)) and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe'| action: - name: kill @@ -29,4 +29,4 @@ output: > Unsigned executable %1.image.path attempted to access Local Security Authority Subsystem Service severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_handle_leak_via_seclogon.yml b/rules/credential_access_lsass_handle_leak_via_seclogon.yml index 920d2175a..f66b7aa9f 100644 --- a/rules/credential_access_lsass_handle_leak_via_seclogon.yml +++ b/rules/credential_access_lsass_handle_leak_via_seclogon.yml @@ -1,6 +1,6 @@ name: LSASS handle leak via Seclogon id: 5d55c938-875e-49e1-ae53-fa196d4445eb -version: 1.0.0 +version: 1.0.1 description: | Identifies suspicious access to LSASS process from a callstack pointing to seclogon.dll that may indicate an attempt to leak an LSASS handle via abusing the Secondary Logon service in @@ -19,10 +19,10 @@ references: - https://splintercod3.blogspot.com/p/the-hidden-side-of-seclogon-part-3.html condition: > - open_process and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' and ps.name ~= 'svchost.exe' + open_process and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' and ps.name ~= 'svchost.exe' and ps.access.mask.names in ('CREATE_PROCESS', 'DUP_HANDLE') and thread.callstack.modules imatches ('*seclogon.dll') severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml b/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml index dcf2248a0..36f66de07 100644 --- a/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml +++ b/rules/credential_access_lsass_memory_dump_preparation_via_silent_process_exit.yml @@ -1,6 +1,6 @@ name: LSASS memory dump preparation via SilentProcessExit id: d325e426-f89a-4f7c-b655-3874dad07986 -version: 1.0.2 +version: 1.0.3 description: | Adversaries may exploit the SilentProcessExit debugging technique to conduct LSASS memory dump via WerFault.exe (Windows Error Reporting) binary by creating @@ -27,4 +27,4 @@ references: condition: > modify_registry and registry.path imatches 'HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\SilentProcessExit\\lsass*' -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_memory_dump_via_minidumpwritedump.yml b/rules/credential_access_lsass_memory_dump_via_minidumpwritedump.yml index f17e0b35b..26f88a1f0 100644 --- a/rules/credential_access_lsass_memory_dump_via_minidumpwritedump.yml +++ b/rules/credential_access_lsass_memory_dump_via_minidumpwritedump.yml @@ -1,6 +1,6 @@ name: LSASS memory dump via MiniDumpWriteDump id: fd7ced77-4a95-4658-80f6-6b9d7b5e3777 -version: 1.0.0 +version: 1.0.1 description: | Identifies access to the Local Security Authority Subsystem Service (LSASS) process to dump the memory via MiniDumpWriteDump API. @@ -20,7 +20,7 @@ references: - https://www.ired.team/offensive-security/credential-access-and-credential-dumping/dumping-lsass-passwords-without-mimikatz-minidumpwritedump-av-signature-bypass condition: > - ((open_process) or (open_thread)) and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' + ((open_process) or (open_thread)) and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' and (thread.callstack.modules imatches ('*dbgcore.dll', '*comsvcs.dll') or thread.callstack.symbols imatches ('*MiniDumpWriteDump')) action: @@ -30,4 +30,4 @@ output: > LSASS memory dump attempt by process %ps.exe via MiniDumpWriteDump severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_memory_dump_via_wer.yml b/rules/credential_access_lsass_memory_dump_via_wer.yml index b8f8357d7..447b79aa0 100644 --- a/rules/credential_access_lsass_memory_dump_via_wer.yml +++ b/rules/credential_access_lsass_memory_dump_via_wer.yml @@ -1,6 +1,6 @@ name: LSASS memory dump via Windows Error Reporting id: 7b4a74e2-c7a7-4c1f-b2ce-0e0273c3add7 -version: 1.0.2 +version: 1.0.3 description: | Adversaries may abuse Windows Error Reporting service to dump LSASS memory. The ALPC protocol can send a message to report an exception on LSASS and @@ -24,4 +24,4 @@ condition: > |spawn_process and ps.child.name iin ('WerFault.exe', 'WerFaultSecure.exe')| by ps.child.uuid |create_file and file.path icontains 'lsass'| by ps.uuid -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_memory_dumping.yml b/rules/credential_access_lsass_memory_dumping.yml index abfbee094..eb724f20f 100644 --- a/rules/credential_access_lsass_memory_dumping.yml +++ b/rules/credential_access_lsass_memory_dumping.yml @@ -1,6 +1,6 @@ name: LSASS memory dumping via legitimate or offensive tools id: 335795af-246b-483e-8657-09a30c102e63 -version: 1.0.2 +version: 1.0.3 description: | Detects an attempt to dump the LSAAS memory to the disk by employing legitimate tools such as procdump, Task Manager, Process Explorer or built-in Windows tools @@ -25,7 +25,7 @@ condition: > by ps.uuid |open_process and ps.access.mask.names in ('ALL_ACCESS', 'CREATE_PROCESS', 'VM_READ', 'DUP_HANDLE') and - kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' + evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' and ps.exe not imatches ( @@ -41,4 +41,4 @@ output: > and subsequently write the `%2.file.path` dump file to the disk device severity: critical -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_lsass_process_clone_creation_via_reflection.yml b/rules/credential_access_lsass_process_clone_creation_via_reflection.yml index fe5933f78..452489e32 100644 --- a/rules/credential_access_lsass_process_clone_creation_via_reflection.yml +++ b/rules/credential_access_lsass_process_clone_creation_via_reflection.yml @@ -1,6 +1,6 @@ name: LSASS process clone creation via reflection id: cdf3810a-4832-446a-ac9d-d108cf2e313c -version: 1.0.0 +version: 1.0.1 description: | Identifies the creation of an LSASS clone process via RtlCreateProcessReflection API function. Adversaries can use this technique to dump credentials material from the LSASS fork and evade @@ -28,4 +28,4 @@ action: severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_potential_sam_hive_dumping.yml b/rules/credential_access_potential_sam_hive_dumping.yml index 48079940d..d1a8dc93c 100644 --- a/rules/credential_access_potential_sam_hive_dumping.yml +++ b/rules/credential_access_potential_sam_hive_dumping.yml @@ -1,6 +1,6 @@ name: Potential SAM hive dumping id: 2f326557-0291-4eb1-a87a-7a17b7d941cb -version: 1.0.4 +version: 1.0.5 description: Identifies access to the Security Account Manager registry hives. labels: @@ -70,4 +70,4 @@ condition: > ) | by ps.uuid -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_remote_thread_creation_into_lsass.yml b/rules/credential_access_remote_thread_creation_into_lsass.yml index bb974e07b..41e74f904 100644 --- a/rules/credential_access_remote_thread_creation_into_lsass.yml +++ b/rules/credential_access_remote_thread_creation_into_lsass.yml @@ -1,6 +1,6 @@ name: Remote thread creation into LSASS id: e3ce8d6f-c260-48d6-9398-3c1c71726297 -version: 1.0.1 +version: 1.0.2 description: | Identifies the creation of a remote thread in LSASS (Local Security And Authority Subsystem Service) by untrusted or suspicious processes. This may indicate attempts to execute code inside the LSASS process @@ -17,8 +17,8 @@ labels: subtechnique.ref: https://attack.mitre.org/techniques/T1003/001/ condition: > - create_remote_thread and kevt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' + create_remote_thread and evt.arg[exe] imatches '?:\\Windows\\System32\\lsass.exe' and (ps.name iin script_interpreters or ps.name ~= 'rundll32.exe' or pe.is_signed = false or pe.is_trusted = false) -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml b/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml index 86558a328..0503e0825 100644 --- a/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml +++ b/rules/credential_access_suspicious_access_to_active_directory_domain_database.yml @@ -1,6 +1,6 @@ name: Suspicious access to Active Directory domain database id: a30c100e-28d0-4aa0-b98d-0d38025c2c29 -version: 1.0.2 +version: 1.0.3 description: | Detects suspicious access to the Active Directory domain database. Adversaries may attempt to access or create a copy of the Active Directory @@ -31,4 +31,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MsMpEng.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_access_to_unattended_panther_files.yml b/rules/credential_access_suspicious_access_to_unattended_panther_files.yml index 9413441de..a9868f7f2 100644 --- a/rules/credential_access_suspicious_access_to_unattended_panther_files.yml +++ b/rules/credential_access_suspicious_access_to_unattended_panther_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Unattended Panther files id: d305fb15-6ad1-4d61-a84b-ada462f23a55 -version: 1.0.2 +version: 1.0.3 description: | Identifies suspicious to access to unattend.xml files where credentials are commonly stored within the Panther directory. Adversaries may search local @@ -34,4 +34,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MsMpEng.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml b/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml index 723d40107..67b60e95d 100644 --- a/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml +++ b/rules/credential_access_suspicious_access_to_windows_dpapi_master_keys.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows DPAPI Master Keys id: b1d5732a-5ad4-4cdd-8791-c22e34c591e5 -version: 1.0.2 +version: 1.0.3 description: | Detects suspicious processes accessing the Windows Data Protection API Master keys which is a sign of potential credential stealing. @@ -41,4 +41,4 @@ condition: > '?:\\Windows\\SysWOW64\\*' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_access_to_windows_manager_files.yml b/rules/credential_access_suspicious_access_to_windows_manager_files.yml index 0d917fb7d..62f9aa076 100644 --- a/rules/credential_access_suspicious_access_to_windows_manager_files.yml +++ b/rules/credential_access_suspicious_access_to_windows_manager_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows Credential Manager files id: 4ab688f7-94e2-481b-9c7f-c49f3a79a379 -version: 1.0.2 +version: 1.0.3 description: | Identifies suspicious processes trying to acquire credentials from the Windows Credential Manager. labels: @@ -30,4 +30,4 @@ condition: > '?:\\Windows\\System32\\lsass.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_access_to_windows_vault_files.yml b/rules/credential_access_suspicious_access_to_windows_vault_files.yml index 622b878ce..16ac6729f 100644 --- a/rules/credential_access_suspicious_access_to_windows_vault_files.yml +++ b/rules/credential_access_suspicious_access_to_windows_vault_files.yml @@ -1,6 +1,6 @@ name: Suspicious access to Windows Vault files id: 44400221-f98d-424a-9388-497c75b18924 -version: 1.0.2 +version: 1.0.3 description: | Identifies attempts from adversaries to acquire credentials from Vault files. labels: @@ -33,4 +33,4 @@ condition: > '?:\\Windows\\System32\\svchost.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_security_package_loaded_by_lsass.yml b/rules/credential_access_suspicious_security_package_loaded_by_lsass.yml index 1472acec9..0c6e93b36 100644 --- a/rules/credential_access_suspicious_security_package_loaded_by_lsass.yml +++ b/rules/credential_access_suspicious_security_package_loaded_by_lsass.yml @@ -1,6 +1,6 @@ name: Suspicious security package DLL loaded id: 2c74f176-9a95-4344-a1aa-15aa06e16919 -version: 1.1.1 +version: 1.1.2 description: | Attackers can abuse Windows Security Support Provider and Authentication Packages to dynamically inject a Security Package into the Local Security Authority Subsystem Service @@ -24,4 +24,4 @@ condition: > and (load_unsigned_or_untrusted_module) -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_suspicious_vault_client_dll_load.yml b/rules/credential_access_suspicious_vault_client_dll_load.yml index 7681838b0..344308055 100644 --- a/rules/credential_access_suspicious_vault_client_dll_load.yml +++ b/rules/credential_access_suspicious_vault_client_dll_load.yml @@ -1,6 +1,6 @@ name: Suspicious Vault client DLL load id: 64af2e2e-2309-4079-9c0f-985f1dd930f5 -version: 1.0.1 +version: 1.0.2 description: | Identifies loading of the Vault client DLL by an unusual process. Adversaries can abuse the functions provided by the Credential Vault Client Library to enumerate or harvest saved credentials. @@ -59,4 +59,4 @@ output: > Suspicious process %2.ps.exe loaded the Credential Vault Client DLL for potential credentials harvesting severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_unusual_access_to_ssh_keys.yml b/rules/credential_access_unusual_access_to_ssh_keys.yml index cf5159cd4..4dcdf89d1 100644 --- a/rules/credential_access_unusual_access_to_ssh_keys.yml +++ b/rules/credential_access_unusual_access_to_ssh_keys.yml @@ -1,6 +1,6 @@ name: Unusual access to SSH keys id: 90f5c1bd-abd6-4d1b-94e0-229f04473d60 -version: 1.0.3 +version: 1.0.4 description: | Identifies access by unusual process to saved SSH keys. labels: @@ -33,4 +33,4 @@ condition: > 'WinSCP.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml b/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml index 6eb093b0b..d9c4af1fb 100644 --- a/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml +++ b/rules/credential_access_unusual_access_to_web_browser_credential_stores.yml @@ -1,6 +1,6 @@ name: Unusual access to Web Browser Credential stores id: 9d889b2b-ca13-4a04-8919-ff1151f23a71 -version: 1.0.2 +version: 1.0.3 description: | Identifies access to Web Browser Credential stores by unusual processes. labels: @@ -29,4 +29,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\*\\MpCopyAccelerator.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/credential_access_unusual_access_to_windows_credential_history.yml b/rules/credential_access_unusual_access_to_windows_credential_history.yml index e21056612..aa4b3e6c7 100644 --- a/rules/credential_access_unusual_access_to_windows_credential_history.yml +++ b/rules/credential_access_unusual_access_to_windows_credential_history.yml @@ -1,6 +1,6 @@ name: Unusual access to Windows Credential history files id: 9d94062f-2cf3-407c-bd65-4072fe4b167f -version: 1.0.3 +version: 1.0.4 description: | Detects unusual accesses to the Windows Credential history file. The CREDHIST file contains all previous password-linked master key hashes used by @@ -28,4 +28,4 @@ condition: > '?:\\Windows\\ccmcache\\*.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml b/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml index 7effb3613..56372b30e 100644 --- a/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml +++ b/rules/defense_evasion_appdomain_manager_injection_via_clr_search_order_hijacking.yml @@ -1,6 +1,6 @@ name: AppDomain Manager injection via CLR search order hijacking id: 9319fafd-b7dc-4d85-b41a-54a8d4f1ab18 -version: 1.0.2 +version: 1.0.4 description: | Adversaries may execute their own malicious payloads by hijacking how the .NET AppDomainManager loads assemblies. The .NET framework uses the AppDomainManager class to create and manage one or more isolated runtime environments @@ -33,4 +33,4 @@ output: > Process %ps.exe loaded untrusted .NET assembly %image.path from suspicious location severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_clear_eventlog.yml b/rules/defense_evasion_clear_eventlog.yml index 7adfe1725..c3f999b1f 100644 --- a/rules/defense_evasion_clear_eventlog.yml +++ b/rules/defense_evasion_clear_eventlog.yml @@ -1,6 +1,6 @@ name: Clear Eventlog id: 692d3143-e1fb-4dab-8c9c-3109ff80ec85 -version: 1.0.2 +version: 1.0.3 description: | Identifies attempts to clear Windows event log stores. Adversaries attempt to evade detection or destroy forensic evidence on a system to cover their trails and slow down incident response. @@ -19,11 +19,11 @@ condition: > sequence maxspan 1m by file.object - |set_file_information and kevt.pid != 4 and file.info_class = 'EOF' and file.info.eof_size > 50000 and file.path imatches '?:\\Windows\\System32\\winevt\\Logs\\*.evtx'| + |set_file_information and evt.pid != 4 and file.info_class = 'EOF' and file.info.eof_size > 50000 and file.path imatches '?:\\Windows\\System32\\winevt\\Logs\\*.evtx'| |set_file_information and file.info_class = 'Allocation' and file.info.allocation_size > 50000| output: > Windows Eventlog store %1.file.path was cleared severity: medium -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_loaded_via_apc_queue.yml b/rules/defense_evasion_dll_loaded_via_apc_queue.yml index 80b0cfdf4..860890144 100644 --- a/rules/defense_evasion_dll_loaded_via_apc_queue.yml +++ b/rules/defense_evasion_dll_loaded_via_apc_queue.yml @@ -1,6 +1,6 @@ name: DLL loaded via APC queue id: e1ee3912-ad7c-4acb-80f4-84db87e54d5e -version: 1.0.1 +version: 1.0.2 description: | Identifies loading of a DLL with a callstack originating from the thread alertable state that led to the execution of an APC routine. This may be @@ -30,4 +30,4 @@ condition: > and thread.callstack.symbols imatches ('KernelBase.dll!Sleep*') -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_loaded_via_callback_function.yml b/rules/defense_evasion_dll_loaded_via_callback_function.yml index ff5aaf820..d9cbfedbb 100644 --- a/rules/defense_evasion_dll_loaded_via_callback_function.yml +++ b/rules/defense_evasion_dll_loaded_via_callback_function.yml @@ -1,6 +1,6 @@ name: DLL loaded via a callback function id: c7f46d0a-10b2-421a-b33c-f4df79599f2e -version: 1.0.1 +version: 1.0.2 description: | Identifies module proxying as a method to conceal suspicious callstacks. Adversaries use module proxying the hide the origin of the LoadLibrary call from the callstack by loading the library from the callback @@ -39,4 +39,4 @@ output: > %2.image.path loaded from callback function by process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml b/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml index 7eb785c08..3709248bb 100644 --- a/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml +++ b/rules/defense_evasion_dll_loaded_via_ldrpkernel32_overwrite.yml @@ -1,6 +1,6 @@ name: DLL loaded via LdrpKernel32 overwrite id: 56739eda-210f-4a30-a114-d55ca60976df -version: 1.0.1 +version: 1.0.2 description: | Detects attempts to bypass the standard NTDLL bootstrap process by loading a malicious DLL early through hijacking. The malicious DLL, containing attacker-controlled code, is loaded in place of the legitimate kernel32 DLL. @@ -36,4 +36,4 @@ output: > DLL %image.path loaded via LdrpKernel32 overwrite evasion by process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_sideloading_via_copied_binary.yml b/rules/defense_evasion_dll_sideloading_via_copied_binary.yml index 033a9a306..311b610dc 100644 --- a/rules/defense_evasion_dll_sideloading_via_copied_binary.yml +++ b/rules/defense_evasion_dll_sideloading_via_copied_binary.yml @@ -1,6 +1,6 @@ name: DLL Side-Loading via a copied binary id: 80798e2c-6c37-472b-936c-1d2d6b95ff3c -version: 1.0.2 +version: 1.0.3 description: | Identifies when a binary is copied to a directory and shortly followed by the loading of an unsigned DLL from the same directory. Adversaries may @@ -29,4 +29,4 @@ condition: > (image.signature.type = 'NONE' or image.signature.level = 'UNCHECKED' or image.signature.level = 'UNSIGNED') | by ps.exe -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml b/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml index 388357c60..a40bde259 100644 --- a/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml +++ b/rules/defense_evasion_dll_sideloading_via_microsoft_office_dropped_file.yml @@ -1,6 +1,6 @@ name: DLL Side-Loading via Microsoft Office dropped file id: d808175d-c4f8-459d-b17f-ca9a88890c04 -version: 1.0.0 +version: 1.0.1 description: | Identifies Microsoft Office process creating a DLL or other variant of an executable object which is later loaded by a trusted binary. Adversaries may exploit this behavior by delivering malicious @@ -36,4 +36,4 @@ output: > Suspicious DLL %1.file.path dropped by Microsoft Office process %1.ps.exe and subsequently loaded by process %2.ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml b/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml index 88f353d77..e6c31313d 100644 --- a/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml +++ b/rules/defense_evasion_dotnet_assembly_loaded_by_unmanaged_process.yml @@ -1,6 +1,6 @@ name: .NET assembly loaded by unmanaged process id: 34be8bd1-1143-4fa8-bed4-ae2566b1394a -version: 1.0.6 +version: 1.0.7 description: | Identifies the loading of the .NET assembly by an unmanaged process. Adversaries can load the CLR runtime inside unmanaged process and execute the assembly via the ICLRRuntimeHost::ExecuteInDefaultAppDomain method. @@ -41,4 +41,4 @@ output: > .NET assembly %image.path loaded by unmanaged process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_hidden_registry_key_creation.yml b/rules/defense_evasion_hidden_registry_key_creation.yml index ac2464ead..45abfebf5 100644 --- a/rules/defense_evasion_hidden_registry_key_creation.yml +++ b/rules/defense_evasion_hidden_registry_key_creation.yml @@ -1,6 +1,6 @@ name: Hidden registry key creation id: 65deda38-9b1d-42a0-9f40-a68903e81b49 -version: 1.1.4 +version: 1.1.5 description: | Identifies the creation of a hidden registry key. Adversaries can utilize the native NtSetValueKey API to create a hidden registry key and conceal payloads @@ -16,7 +16,7 @@ references: - https://github.com/outflanknl/SharpHide condition: > - set_value and kevt.pid != 4 and registry.path endswith '\\' + set_value and evt.pid != 4 and registry.path endswith '\\' and thread.callstack.symbols imatches ('ntdll.dll!NtSetValueKey', 'ntdll.dll!ZwSetValueKey') and @@ -43,4 +43,4 @@ output: > Hidden registry key %registry.path created by process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_image_load_via_ntfs_transaction.yml b/rules/defense_evasion_image_load_via_ntfs_transaction.yml index 3f115ff34..eaf988a13 100644 --- a/rules/defense_evasion_image_load_via_ntfs_transaction.yml +++ b/rules/defense_evasion_image_load_via_ntfs_transaction.yml @@ -1,6 +1,6 @@ name: Image load via NTFS transaction id: ce8de3d0-0768-41a7-bab9-4eca27ed1e3c -version: 1.0.0 +version: 1.0.1 description: | Identifies image loading of a file written to disk via NTFS transaction. Adversaries may exploit the transactional API to execute code in the address space of the running process without committing @@ -19,10 +19,10 @@ condition: > sequence maxspan 2m |create_file and thread.callstack.symbols imatches ('kernel32.dll!CreateFileTransacted*', 'ntdll.dll!RtlSetCurrentTransaction')| by file.name - |load_module and kevt.pid != 4| by image.name + |load_module and evt.pid != 4| by image.name output: > Image %2.image.name written via transactional NTFS and loaded afterward severity: high -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_injection_via_dotnet_debugging.yml b/rules/defense_evasion_potential_injection_via_dotnet_debugging.yml index 5a7c048d9..99c7a2494 100644 --- a/rules/defense_evasion_potential_injection_via_dotnet_debugging.yml +++ b/rules/defense_evasion_potential_injection_via_dotnet_debugging.yml @@ -1,6 +1,6 @@ name: Potential injection via .NET debugging id: 193ebf2f-e365-4f57-a639-275b7cdf0319 -version: 1.0.2 +version: 1.0.3 description: | Identifies creation of a process on behalf of the CLR debugging facility which may be indicative of code injection. The CLR interface utilizes the OpenVirtualProcess @@ -33,4 +33,4 @@ output: > Process %ps.exe attached the .NET debugger to process %ps.child.exe for potential code injection severity: high -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_process_creation_via_shellcode.yml b/rules/defense_evasion_potential_process_creation_via_shellcode.yml index f505dc4bf..fa091e184 100644 --- a/rules/defense_evasion_potential_process_creation_via_shellcode.yml +++ b/rules/defense_evasion_potential_process_creation_via_shellcode.yml @@ -1,6 +1,6 @@ name: Potential process creation via shellcode id: 7a918532-12d1-4aa2-8c46-8769c67cac07 -version: 1.0.0 +version: 1.0.1 description: | Identifies the creation of a process with stack frames originating from floating memory area while invoking commonly used Windows API functions like WinExec. This behavior is a typical indicator of @@ -24,4 +24,4 @@ output: > Process %ps.child.exe created via potential shellcode injection by process %ps.exe severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_process_doppelganging_injection.yml b/rules/defense_evasion_potential_process_doppelganging_injection.yml index cd7bb866e..aeff0f8f0 100644 --- a/rules/defense_evasion_potential_process_doppelganging_injection.yml +++ b/rules/defense_evasion_potential_process_doppelganging_injection.yml @@ -1,6 +1,6 @@ name: Potential Process Doppelganging id: eb34cf6e-ccc3-4bce-bbcf-013720640a28 -version: 1.0.0 +version: 1.0.1 description: | Adversaries may inject malicious code into process via process doppelganging in order to evade process-based defenses as well as possibly elevate privileges. @@ -56,4 +56,4 @@ condition: > action: - name: kill -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_process_hollowing_injection.yml b/rules/defense_evasion_potential_process_hollowing_injection.yml index fe31cfb28..744770a62 100644 --- a/rules/defense_evasion_potential_process_hollowing_injection.yml +++ b/rules/defense_evasion_potential_process_hollowing_injection.yml @@ -1,6 +1,6 @@ name: Potential Process Hollowing id: 2a3fbae8-5e8c-4b71-b9da-56c3958c0d53 -version: 1.1.4 +version: 1.1.5 description: | Adversaries may inject malicious code into suspended and hollowed processes in order to evade process-based defenses. Process hollowing is a method of executing arbitrary code @@ -41,4 +41,4 @@ condition: > action: - name: kill -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_process_injection_via_tainted_memory_section.yml b/rules/defense_evasion_potential_process_injection_via_tainted_memory_section.yml index b57d05593..5f2178685 100644 --- a/rules/defense_evasion_potential_process_injection_via_tainted_memory_section.yml +++ b/rules/defense_evasion_potential_process_injection_via_tainted_memory_section.yml @@ -1,6 +1,6 @@ name: Potential process injection via tainted memory section id: 8e4182f3-02e7-4e95-afc3-93d18c9a9c09 -version: 1.0.3 +version: 1.0.4 description: | Identifies potential process injection when the adversary creates and maps a memory section with RW protection rights followed by mapping of the same memory section in @@ -22,7 +22,7 @@ references: condition: > sequence maxspan 1m - |map_view_of_section and file.view.protection = 'READWRITE' and kevt.pid != 4 and file.view.size >= 4096 and ps.exe not imatches + |map_view_of_section and file.view.protection = 'READWRITE' and evt.pid != 4 and file.view.size >= 4096 and ps.exe not imatches ( '?:\\Program Files\\*.exe', '?:\\Program Files (x86)\\*.exe', @@ -37,7 +37,7 @@ condition: > '?:\\WINDOWS\\System32\\services.exe' ) | as e1 - |map_view_of_section and file.view.protection = 'READONLY|EXECUTE' and file.key = $e1.file.key and kevt.pid != $e1.kevt.pid and ps.exe not imatches + |map_view_of_section and file.view.protection = 'READONLY|EXECUTE' and file.key = $e1.file.key and evt.pid != $e1.evt.pid and ps.exe not imatches ( '?:\\Program Files\\Mozilla Firefox\\firefox.exe', '?:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe' @@ -46,4 +46,4 @@ condition: > action: - name: kill -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_shellcode_execution_via_etw_logger_thread.yml b/rules/defense_evasion_potential_shellcode_execution_via_etw_logger_thread.yml index e6c26de1f..78c9709ae 100644 --- a/rules/defense_evasion_potential_shellcode_execution_via_etw_logger_thread.yml +++ b/rules/defense_evasion_potential_shellcode_execution_via_etw_logger_thread.yml @@ -1,6 +1,6 @@ name: Potential shellcode execution via ETW logger thread id: 3e915273-5ea0-4576-afc9-b018e2d53545 -version: 1.0.0 +version: 1.0.1 description: | Adversaries may employ the undocumented EtwpCreateEtwThread function to execute shellcode within the local process address space. @@ -16,7 +16,7 @@ references: - https://github.com/Ne0nd0g/go-shellcode/tree/master?tab=readme-ov-file#EtwpCreateEtwThread condition: > - create_thread and kevt.pid != 4 and thread.callstack.symbols iin ('ntdll.dll!EtwpCreateEtwThread') + create_thread and evt.pid != 4 and thread.callstack.symbols iin ('ntdll.dll!EtwpCreateEtwThread') and not (ps.exe imatches @@ -32,4 +32,4 @@ output: > Potential shellcode execution via EtwpCreateEtwThread API initiated by process %ps.exe severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_potential_thread_execution_hijacking.yml b/rules/defense_evasion_potential_thread_execution_hijacking.yml index 29ebb0dd9..6017a00af 100644 --- a/rules/defense_evasion_potential_thread_execution_hijacking.yml +++ b/rules/defense_evasion_potential_thread_execution_hijacking.yml @@ -1,6 +1,6 @@ name: Potential thread execution hijacking id: 8b9f6d47-e9ba-4b3a-9da2-d7bf27e08ca9 -version: 1.0.1 +version: 1.0.2 description: | Adversaries may inject malicious code into hijacked processes in order to evade process-based defenses as well as possibly elevate privileges. Thread Execution Hijacking is a method of @@ -40,4 +40,4 @@ condition: > action: - name: kill -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_process_execution_from_self_deleting_binary.yml b/rules/defense_evasion_process_execution_from_self_deleting_binary.yml index da42abcd4..713a805fd 100644 --- a/rules/defense_evasion_process_execution_from_self_deleting_binary.yml +++ b/rules/defense_evasion_process_execution_from_self_deleting_binary.yml @@ -1,6 +1,6 @@ name: Process execution from a self-deleting binary id: 0f0da517-b22c-4d14-9adc-36baeb621cf7 -version: 1.0.4 +version: 1.0.3 description: | Identifies the execution of the process from a self-deleting binary. The attackers can abuse undocumented API functions to create a process from a file-backed section. The file @@ -43,4 +43,4 @@ output: > Process %2.image.path spawned from self-deleting binary severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_process_spawned_via_remote_thread.yml b/rules/defense_evasion_process_spawned_via_remote_thread.yml index 02c59878e..76fd1fcf3 100644 --- a/rules/defense_evasion_process_spawned_via_remote_thread.yml +++ b/rules/defense_evasion_process_spawned_via_remote_thread.yml @@ -1,6 +1,6 @@ name: Process spawned via remote thread id: 9a2c7b40-4e5f-4edf-b02e-79cd33c9a137 -version: 1.0.2 +version: 1.0.3 description: | Identifies the creation of a process with the parent call stack not revealing normal API functions for process creation. This may be a @@ -22,4 +22,4 @@ condition: > action: - name: kill -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_regsvr32_scriptlet_execution.yml b/rules/defense_evasion_regsvr32_scriptlet_execution.yml index 16942a489..35667033c 100644 --- a/rules/defense_evasion_regsvr32_scriptlet_execution.yml +++ b/rules/defense_evasion_regsvr32_scriptlet_execution.yml @@ -1,6 +1,6 @@ name: Regsvr32 scriptlet execution id: 128f5254-67c9-43ac-b901-18b3731b1d0b -version: 1.0.1 +version: 1.0.2 description: | Identifies the execution of a scriptlet file by regsvr32.exe process. regsvr32.exe allows attackers to run arbitrary scripts to proxy execution of malicious code. @@ -67,4 +67,4 @@ condition: > '?:\\Program Files (x86)\\*.exe' ) -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_access_to_the_hosts_file.yml b/rules/defense_evasion_suspicious_access_to_the_hosts_file.yml index 5d894c9e0..f53ad80fe 100644 --- a/rules/defense_evasion_suspicious_access_to_the_hosts_file.yml +++ b/rules/defense_evasion_suspicious_access_to_the_hosts_file.yml @@ -1,6 +1,6 @@ name: Suspicious access to the hosts file id: f7b2c9d3-99e7-41d5-bb4a-6ea1a5f7f9e2 -version: 1.0.2 +version: 1.0.3 description: > Identifies suspicious process accessing the Windows hosts file for potential tampering. Adversaries can hijack the hosts files to block traffic to download/update servers or redirect the @@ -36,4 +36,4 @@ output: > Suspicious process %1.ps.child.exe accessed the hosts file for potential tampering severity: medium -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_dll_loaded_via_memory_section_mapping.yml b/rules/defense_evasion_suspicious_dll_loaded_via_memory_section_mapping.yml index 5b463ff25..9a5257f91 100644 --- a/rules/defense_evasion_suspicious_dll_loaded_via_memory_section_mapping.yml +++ b/rules/defense_evasion_suspicious_dll_loaded_via_memory_section_mapping.yml @@ -1,6 +1,6 @@ name: Suspicious DLL loaded via memory section mapping id: b06653fb-227e-4e63-9a69-55a5a90c79e5 -version: 1.0.1 +version: 1.0.2 description: | Identifies the mapping of a memory section with RX protection followed by unsigned DLL loading. Adversaries may inject dynamic-link libraries (DLLs) into processes in order to evade process-based defenses @@ -21,7 +21,7 @@ condition: > sequence maxspan 2m by ps.uuid - |map_view_of_section and file.view.protection = 'READONLY|EXECUTE' and kevt.pid != 4 and file.view.size >= 4096 + |map_view_of_section and file.view.protection = 'READONLY|EXECUTE' and evt.pid != 4 and file.view.size >= 4096 and ps.exe not imatches ( @@ -32,4 +32,4 @@ condition: > action: - name: kill -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_html_application_script_execution.yml b/rules/defense_evasion_suspicious_html_application_script_execution.yml index 85b51de9b..81b947740 100644 --- a/rules/defense_evasion_suspicious_html_application_script_execution.yml +++ b/rules/defense_evasion_suspicious_html_application_script_execution.yml @@ -1,6 +1,6 @@ name: Suspicious HTML Application script execution id: 4ec64ac2-851d-41b4-b7d2-910c21de334d -version: 1.0.1 +version: 1.0.2 description: | Identifies the execution of scripts via Microsoft HTML Application Host interpreter. Adversaries can proxy the execution of arbitrary script code through a trusted, signed utility to evade defenses. @@ -60,4 +60,4 @@ output: > Suspicious HTML Application script execution by mshta process with command line arguments %ps.child.cmdline severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_object_symbolic_link_creation.yml b/rules/defense_evasion_suspicious_object_symbolic_link_creation.yml index 367b49b37..e762c4811 100644 --- a/rules/defense_evasion_suspicious_object_symbolic_link_creation.yml +++ b/rules/defense_evasion_suspicious_object_symbolic_link_creation.yml @@ -1,6 +1,6 @@ name: Suspicious object symbolic link creation id: f9306355-1f5f-4a06-9779-195aa681db80 -version: 1.0.2 +version: 1.0.3 description: | Identifies the creation of the object symbolic link inside the object manager namespace by untrusted or unusual processes. @@ -18,7 +18,7 @@ references: - https://www.elastic.co/kr/blog/detect-block-unknown-knowndlls-windows-acl-hardening-attacks-cache-poisoning-escalation condition: > - create_symbolic_link_object and kevt.pid != 4 + create_symbolic_link_object and evt.pid != 4 and (pe.is_signed = false or pe.is_trusted = false or ps.exe not imatches ( @@ -32,10 +32,10 @@ condition: > ) ) and - kevt.arg[target] not imatches '\\Sessions\\*\\AppContainerNamedObjects\\*' + evt.arg[target] not imatches '\\Sessions\\*\\AppContainerNamedObjects\\*' output: > - Suspicious object symbolic link %kevt.arg[target] created by process %ps.exe + Suspicious object symbolic link %evt.arg[target] created by process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_windows_defender_exclusions_registry_modification.yml b/rules/defense_evasion_suspicious_windows_defender_exclusions_registry_modification.yml index 4c85755bd..c6b58d47a 100644 --- a/rules/defense_evasion_suspicious_windows_defender_exclusions_registry_modification.yml +++ b/rules/defense_evasion_suspicious_windows_defender_exclusions_registry_modification.yml @@ -1,6 +1,6 @@ name: Suspicious Windows Defender exclusions registry modification id: 92fdbbea-e177-494e-8a6a-d8b055daf0e9 -version: 1.0.0 +version: 1.0.1 description: | Identifies the modification of the Windows Defender process, path, or IP address registry key exclusions by suspicious processes. Adversaries may alter the Windows Defender exclusions to bypass defenses. @@ -45,4 +45,4 @@ output: > Windows Defender exclusion %registry.path added by suspicious process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_suspicious_xsl_script_execution.yml b/rules/defense_evasion_suspicious_xsl_script_execution.yml index 14e821d8e..fb9e9e170 100644 --- a/rules/defense_evasion_suspicious_xsl_script_execution.yml +++ b/rules/defense_evasion_suspicious_xsl_script_execution.yml @@ -1,6 +1,6 @@ name: Suspicious XSL script execution id: 65136b30-14ae-46dd-b8e5-9dfa99690d74 -version: 1.0.1 +version: 1.0.2 description: | Identifies a suspicious execution of XSL script via Windows Management Instrumentation command line tool or XSL transformation utility. Adversaries may bypass application control and obscure the execution of code by embedding @@ -45,4 +45,4 @@ output: > Suspicious XSL script executed by process %1.ps.child.name with command line arguments %1.ps.child.args severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_system_binary_proxy_execution_via_rundll32.yml b/rules/defense_evasion_system_binary_proxy_execution_via_rundll32.yml index 6e96ffd58..714357b33 100644 --- a/rules/defense_evasion_system_binary_proxy_execution_via_rundll32.yml +++ b/rules/defense_evasion_system_binary_proxy_execution_via_rundll32.yml @@ -1,6 +1,6 @@ name: System Binary Proxy Execution via Rundll32 id: 43d76718-cc46-485e-8f47-996eb7a9f83b -version: 1.0.1 +version: 1.0.2 description: | Detects the execution of rundll32.exe process with suspicious command line followed by the creation of a possibly malicious child process. @@ -63,4 +63,4 @@ condition: > action: - name: kill -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_thread_context_set_from_unbacked_memory.yml b/rules/defense_evasion_thread_context_set_from_unbacked_memory.yml index 35de509a8..f56f4ca00 100644 --- a/rules/defense_evasion_thread_context_set_from_unbacked_memory.yml +++ b/rules/defense_evasion_thread_context_set_from_unbacked_memory.yml @@ -1,6 +1,6 @@ name: Thread context set from unbacked memory id: f8219274-ee68-416b-8489-4d2e635c7844 -version: 1.0.3 +version: 1.0.4 description: | Identifies manipulation of the thread context from unbacked memory region. This may be indicative of process injection. @@ -23,4 +23,4 @@ condition: > '?:\\Windows\\System32\\taskhostw.exe' ) -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml b/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml index fd27e6af3..90be228aa 100644 --- a/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml +++ b/rules/defense_evasion_unsigned_dll_injection_via_remote_thread.yml @@ -1,6 +1,6 @@ name: Unsigned DLL injection via remote thread id: 21bdd944-3bda-464b-9a72-58fd37ba9163 -version: 1.1.2 +version: 1.1.3 description: | Identifies unsigned DLL injection via remote thread creation. Adversaries may inject dynamic-link libraries (DLLs) into processes in order to evade process-based defenses @@ -46,4 +46,4 @@ condition: > ps.exe not imatches '?:\\Program Files\\Common Files\\microsoft shared\\ClickToRun\\Updates\\*\\OfficeClickToRun.exe' | by ps.pid -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/defense_evasion_windows_defender_protection_tampering_via_registry.yml b/rules/defense_evasion_windows_defender_protection_tampering_via_registry.yml index 615dad6c4..e7df57e36 100644 --- a/rules/defense_evasion_windows_defender_protection_tampering_via_registry.yml +++ b/rules/defense_evasion_windows_defender_protection_tampering_via_registry.yml @@ -1,6 +1,6 @@ name: Windows Defender protection tampering via registry id: 47ad962b-be0f-44f8-9467-34109f41e5ff -version: 1.0.0 +version: 1.0.1 description: | Detects suspicious processes modifying Windows Defender configuration settings via registry to disable protection features. @@ -62,4 +62,4 @@ output: > Suspicious process %ps.exe tampered Windows Defender security settings in registry value %registry.path severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_executable_file_creation_from_macro_enabled_microsoft_office_document.yml b/rules/initial_access_executable_file_creation_from_macro_enabled_microsoft_office_document.yml index 939e2f389..7df2d39e9 100644 --- a/rules/initial_access_executable_file_creation_from_macro_enabled_microsoft_office_document.yml +++ b/rules/initial_access_executable_file_creation_from_macro_enabled_microsoft_office_document.yml @@ -1,6 +1,6 @@ name: Executable file creation from a macro-enabled Microsoft Office document id: fffcce75-2427-406e-9597-1f49b0c9ad5b -version: 1.0.1 +version: 1.0.2 description: | Identifies the Microsoft Office process writing an executable file type and the call stack reveals the file creation was originated from the Microsoft @@ -31,4 +31,4 @@ condition: > (file.is_exec or file.is_dll) ) -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_execution_via_microsoft_office_process.yml b/rules/initial_access_execution_via_microsoft_office_process.yml index d5b166c1d..e8c30ba99 100644 --- a/rules/initial_access_execution_via_microsoft_office_process.yml +++ b/rules/initial_access_execution_via_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Execution via Microsoft Office process id: a10ebe66-1b55-4005-a374-840f1e2933a3 -version: 1.0.1 +version: 1.0.2 description: Identifies the execution of the file dropped by Microsoft Office process. labels: @@ -20,4 +20,4 @@ condition: > |create_file and (file.extension iin executable_extensions or file.is_exec) and ps.name iin msoffice_binaries| by file.path |spawn_process and ps.name iin msoffice_binaries| by ps.child.exe -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_macro_execution_via_script_interpreter.yml b/rules/initial_access_macro_execution_via_script_interpreter.yml index c14a6f2e4..3bff927a8 100644 --- a/rules/initial_access_macro_execution_via_script_interpreter.yml +++ b/rules/initial_access_macro_execution_via_script_interpreter.yml @@ -1,6 +1,6 @@ name: Macro execution via script interpreter id: 845404de-df6f-472f-bd74-72148a7f5166 -version: 1.0.3 +version: 1.0.4 description: | Identifies the execution of the Windows scripting interpreter spawning a Microsoft Office process to execute suspicious Visual Basic macro. @@ -27,4 +27,4 @@ condition: > ) | by ps.uuid -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_microsoft_office_file_execution_via_script_interpreter.yml b/rules/initial_access_microsoft_office_file_execution_via_script_interpreter.yml index 9db167e2f..6b4edea27 100644 --- a/rules/initial_access_microsoft_office_file_execution_via_script_interpreter.yml +++ b/rules/initial_access_microsoft_office_file_execution_via_script_interpreter.yml @@ -1,6 +1,6 @@ name: Microsoft Office file execution via script interpreter id: bf3ea547-1470-4bcc-9945-3b495d962c2c -version: 1.0.0 +version: 1.0.1 description: | Identifies the execution via Windows script interpreter of the executable file written by the Microsoft Office process. @@ -32,4 +32,4 @@ output: > Microsoft Office process %1.ps.exe wrote the file %1.file.path and subsequently executed it via script interpreter %2.ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_microsoft_office_file_execution_via_wmi.yml b/rules/initial_access_microsoft_office_file_execution_via_wmi.yml index 10e36a4ce..35cb21c15 100644 --- a/rules/initial_access_microsoft_office_file_execution_via_wmi.yml +++ b/rules/initial_access_microsoft_office_file_execution_via_wmi.yml @@ -1,6 +1,6 @@ name: Microsoft Office file execution via WMI id: 50f6efa2-4d7b-4fb7-b1a9-65c3a24d9152 -version: 1.0.0 +version: 1.0.1 description: | Identifies the execution via Windows Management Instrumentation (WMI) of the binary file written by the Microsoft Office process. Attackers can exploit WMI to silently execute malicious code. @@ -29,4 +29,4 @@ output: > Microsoft Office process %1.ps.exe wrote the file %1.file.path and subsequently executed it via WMI severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_potential_clickfix_infection_chain_via_run_window.yml b/rules/initial_access_potential_clickfix_infection_chain_via_run_window.yml index f13bf04ec..65ef03f2d 100644 --- a/rules/initial_access_potential_clickfix_infection_chain_via_run_window.yml +++ b/rules/initial_access_potential_clickfix_infection_chain_via_run_window.yml @@ -1,6 +1,6 @@ name: Potential ClickFix infection chain via Run window id: ffe1fc54-2893-4760-ab50-51a83bd71d13 -version: 1.0.1 +version: 1.0.2 description: | Identifies the execution of the process via the Run command dialog box followed by spawning of the potential infostealer process. @@ -46,4 +46,4 @@ output: > Potential infostealer process %2.ps.child.exe executed via the Run command window by %1.ps.child.cmdline severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_process_spawned_from_macro_enabled_microsoft_office_document.yml b/rules/initial_access_process_spawned_from_macro_enabled_microsoft_office_document.yml index 82fc9d9eb..1c3a4e573 100644 --- a/rules/initial_access_process_spawned_from_macro_enabled_microsoft_office_document.yml +++ b/rules/initial_access_process_spawned_from_macro_enabled_microsoft_office_document.yml @@ -1,6 +1,6 @@ name: Process spawned from macro-enabled Microsoft Office document id: 47521206-e19d-4608-9dbc-dc3a1df99db5 -version: 1.0.2 +version: 1.0.3 description: | Identifies the execution of the child process spawned by Microsoft Office parent process where the call stack contains the Visual Basic @@ -41,4 +41,4 @@ condition: > '?:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe' ) -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml b/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml index 1c58c599f..93324020f 100644 --- a/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml +++ b/rules/initial_access_suspicious_dll_loaded_by_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Suspicious DLL loaded by Microsoft Office process id: 5868518c-2a83-4b26-ad4b-f14f0b85e744 -version: 1.0.1 +version: 1.0.2 description: Identifies loading of recently dropped DLL by Microsoft Office process. labels: @@ -23,4 +23,4 @@ condition: > | by file.name |load_module and ps.name iin msoffice_binaries| by image.name -min-engine-version: 2.0.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml b/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml index 2fafa2365..ff97c4942 100644 --- a/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml +++ b/rules/initial_access_suspicious_execution_via_wmi_from_microsoft_office_process.yml @@ -1,6 +1,6 @@ name: Suspicious execution via WMI from a Microsoft Office process id: cc3f0bbe-ec53-40a7-9eed-f0a8a3f7d7fa -version: 1.0.0 +version: 1.0.1 description: | Identifies a suspicious process execution via Windows Management Instrumentation (WMI) originated from the Microsoft Office process loading an unusual WMI DLL. This technique @@ -91,4 +91,4 @@ output: > Suspicious process %2.ps.child.exe launched via WMI from Microsoft Office process %1.ps.cmdline severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/initial_access_suspicious_microsoft_office_embedded_object.yml b/rules/initial_access_suspicious_microsoft_office_embedded_object.yml index 724e262c4..2e4fc722e 100644 --- a/rules/initial_access_suspicious_microsoft_office_embedded_object.yml +++ b/rules/initial_access_suspicious_microsoft_office_embedded_object.yml @@ -1,6 +1,6 @@ name: Suspicious Microsoft Office embedded object id: 47368d49-1192-4059-9c55-6bbc4fd1a73a -version: 1.0.1 +version: 1.0.2 description: | Identifies Microsoft Office processes dropping a file with suspicious extension and with the call stack indicating operations to save or load @@ -27,4 +27,4 @@ condition: > (file.is_exec or file.is_dll) ) -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/macros/macros.yml b/rules/macros/macros.yml index 5bb9d4768..d0e70d2a4 100644 --- a/rules/macros/macros.yml +++ b/rules/macros/macros.yml @@ -1,89 +1,89 @@ - macro: spawn_process - expr: kevt.name = 'CreateProcess' + expr: evt.name = 'CreateProcess' - macro: create_thread - expr: kevt.name = 'CreateThread' + expr: evt.name = 'CreateThread' - macro: create_remote_thread - expr: create_thread and kevt.pid != 4 and kevt.pid != thread.pid + expr: create_thread and evt.pid != 4 and evt.pid != thread.pid - macro: open_process - expr: kevt.name = 'OpenProcess' and ps.access.status = 'Success' + expr: evt.name = 'OpenProcess' and ps.access.status = 'Success' - macro: open_thread - expr: kevt.name = 'OpenThread' and thread.access.status = 'Success' + expr: evt.name = 'OpenThread' and thread.access.status = 'Success' - macro: open_remote_thread - expr: open_thread and kevt.pid != 4 and kevt.pid != kevt.arg[pid] + expr: open_thread and evt.pid != 4 and evt.pid != evt.arg[pid] - macro: write_file - expr: kevt.name = 'WriteFile' + expr: evt.name = 'WriteFile' - macro: open_file - expr: kevt.name = 'CreateFile' and file.operation = 'OPEN' and file.status = 'Success' + expr: evt.name = 'CreateFile' and file.operation = 'OPEN' and file.status = 'Success' - macro: create_file - expr: kevt.name = 'CreateFile' and file.operation != 'OPEN' and file.status = 'Success' + expr: evt.name = 'CreateFile' and file.operation != 'OPEN' and file.status = 'Success' - macro: rename_file - expr: kevt.name = 'RenameFile' + expr: evt.name = 'RenameFile' - macro: read_file - expr: kevt.name = 'ReadFile' + expr: evt.name = 'ReadFile' - macro: delete_file - expr: kevt.name = 'DeleteFile' + expr: evt.name = 'DeleteFile' - macro: set_file_information - expr: kevt.name = 'SetFileInformation' + expr: evt.name = 'SetFileInformation' - macro: query_registry - expr: kevt.name in ('RegQueryKey', 'RegQueryValue') and registry.status = 'Success' + expr: evt.name in ('RegQueryKey', 'RegQueryValue') and registry.status = 'Success' - macro: open_registry - expr: kevt.name = 'RegOpenKey' and registry.status = 'Success' + expr: evt.name = 'RegOpenKey' and registry.status = 'Success' - macro: load_module - expr: kevt.name = 'LoadImage' + expr: evt.name = 'LoadImage' - macro: unload_module - expr: kevt.name = 'UnloadImage' + expr: evt.name = 'UnloadImage' - macro: set_value - expr: kevt.name = 'RegSetValue' and registry.status = 'Success' + expr: evt.name = 'RegSetValue' and registry.status = 'Success' - macro: create_key - expr: kevt.name = 'RegCreateKey' and registry.status = 'Success' + expr: evt.name = 'RegCreateKey' and registry.status = 'Success' - macro: modify_registry expr: ((set_value) or (create_key)) - macro: send_socket - expr: kevt.name = 'Send' + expr: evt.name = 'Send' - macro: recv_socket - expr: kevt.name = 'Recv' + expr: evt.name = 'Recv' - macro: connect_socket - expr: kevt.name = 'Connect' + expr: evt.name = 'Connect' - macro: accept_socket - expr: kevt.name = 'Accept' + expr: evt.name = 'Accept' - macro: set_thread_context - expr: kevt.name = 'SetThreadContext' and kevt.arg[status] = 'Success' + expr: evt.name = 'SetThreadContext' and evt.arg[status] = 'Success' - macro: virtual_alloc - expr: kevt.name = 'VirtualAlloc' + expr: evt.name = 'VirtualAlloc' - macro: virtual_free - expr: kevt.name = 'VirtualFree' + expr: evt.name = 'VirtualFree' - macro: map_view_file - expr: kevt.name = 'MapViewFile' + expr: evt.name = 'MapViewFile' - macro: unmap_view_file - expr: kevt.name = 'UnmapViewFile' + expr: evt.name = 'UnmapViewFile' - macro: map_view_of_section expr: map_view_file and file.view.type in ('IMAGE', 'IMAGE_NO_EXECUTE', 'PAGEFILE') @@ -92,19 +92,19 @@ expr: unmap_view_file and file.view.type in ('IMAGE', 'IMAGE_NO_EXECUTE') - macro: duplicate_handle - expr: kevt.name = 'DuplicateHandle' + expr: evt.name = 'DuplicateHandle' - macro: create_handle - expr: kevt.name = 'CreateHandle' + expr: evt.name = 'CreateHandle' - macro: query_dns - expr: kevt.name = 'QueryDns' + expr: evt.name = 'QueryDns' - macro: reply_dns - expr: kevt.name = 'ReplyDns' + expr: evt.name = 'ReplyDns' - macro: create_symbolic_link_object - expr: kevt.name = 'CreateSymbolicLinkObject' and kevt.arg[status] = 'Success' + expr: evt.name = 'CreateSymbolicLinkObject' and evt.arg[status] = 'Success' - macro: inbound_network expr: > diff --git a/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml b/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml index 14909f4fc..0334bbbea 100644 --- a/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml +++ b/rules/persistence_executable_file_dropped_by_unsigned_service_dll.yml @@ -1,6 +1,6 @@ name: Executable file dropped by an unsigned service DLL id: 3e29da58-0fc4-44c0-91c0-0dfc6af87e9d -version: 1.0.0 +version: 1.0.1 description: | Identifies the loading of an unsigned DLL by svchost process followed by creating an executable file. Adversaries may rely on Windows Services to repeatedly execute malicious @@ -23,7 +23,7 @@ condition: > sequence maxspan 3m |load_unsigned_dll and ps.exe imatches ('?:\\Windows\\System32\\svchost.exe', '?:\\Windows\\SysWOW64\\svchost.exe')| as e1 - |create_file and kevt.pid != 4 and ps.exe imatches ('?:\\Windows\\System32\\svchost.exe', '?:\\Windows\\SysWOW64\\svchost.exe') + |create_file and evt.pid != 4 and ps.exe imatches ('?:\\Windows\\System32\\svchost.exe', '?:\\Windows\\SysWOW64\\svchost.exe') and (file.extension iin ('.exe', '.dll', '.com', '.js', '.vbs', '.cmd', '.bat', '.vbe') or file.is_exec or file.is_dll or file.is_driver) and @@ -34,4 +34,4 @@ output: > Service %1.ps.cmdline loaded an unsigned DLL %1.image.path and subsequently dropped an executable file %2.file.path severity: high -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_hidden_local_account_creation.yml b/rules/persistence_hidden_local_account_creation.yml index 67bdd53d5..861ff93af 100644 --- a/rules/persistence_hidden_local_account_creation.yml +++ b/rules/persistence_hidden_local_account_creation.yml @@ -1,6 +1,6 @@ name: Hidden local account creation id: bfa83754-3730-4c46-a0fd-cc71365f64df -version: 1.0.1 +version: 1.0.2 description: | Identifies the creation of a hidden local account. Adversaries can create hidden accounts by appending the dollar sign to the account name. This technique renders the account name hidden @@ -25,4 +25,4 @@ condition: > severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml b/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml index e737ddcc1..742eaeb49 100644 --- a/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml +++ b/rules/persistence_network_connection_via_startup_folder_executable_or_script.yml @@ -1,6 +1,6 @@ name: Network connection via startup folder executable or script id: 09b7278d-42e3-4792-9f00-dee38baecfad -version: 1.0.2 +version: 1.0.3 description: | Identifies the execution of unsigned binary or script from the Startup folder followed by network inbound or outbound connection. @@ -26,4 +26,4 @@ condition: > | |((inbound_network) or (outbound_network)) and ps.cmdline imatches startup_locations| -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_potential_port_monitor_or_print_processor_persistence_via_registry_modification.yml b/rules/persistence_potential_port_monitor_or_print_processor_persistence_via_registry_modification.yml index 86b3aeab4..a038d86aa 100644 --- a/rules/persistence_potential_port_monitor_or_print_processor_persistence_via_registry_modification.yml +++ b/rules/persistence_potential_port_monitor_or_print_processor_persistence_via_registry_modification.yml @@ -1,6 +1,6 @@ name: Potential port monitor or print processor persistence via registry modification id: de04ae6b-8141-41af-9baa-15630b5954cc -version: 1.0.0 +version: 1.0.1 description: | Identifies port monitor or print process registry modifications that would allow adversaries to run malicious DLLs during system boot. @@ -30,4 +30,4 @@ output: > Port monitor or print processor DLL registered under registry key %registry.path by process %ps.exe severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_rid_hijacking.yml b/rules/persistence_rid_hijacking.yml index 61bc5883a..f92afbfd6 100644 --- a/rules/persistence_rid_hijacking.yml +++ b/rules/persistence_rid_hijacking.yml @@ -1,6 +1,6 @@ name: RID Hijacking id: 5c25666a-4a9f-4b7c-b02f-db0b5cdbde83 -version: 1.0.2 +version: 1.0.3 description: | RID (Relative ID part of security identifier) hijacking allows an attacker with SYSTEM level privileges to covertly replace the RID of a low privileged account effectively making @@ -23,4 +23,4 @@ condition: > and ps.exe not imatches '?:\\Windows\\System32\\lsass.exe' -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml b/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml index eab21d60b..116f84632 100644 --- a/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml +++ b/rules/persistence_script_interpreter_or_untrusted_process_persistence.yml @@ -1,6 +1,6 @@ name: Script interpreter host or untrusted process persistence id: cc41ee3a-6e44-4903-85a4-0147ec6a7eea -version: 1.1.0 +version: 1.1.1 description: | Identifies the script interpreter or untrusted process writing to commonly abused run keys or the Startup folder locations. @@ -16,7 +16,7 @@ labels: subtechnique.ref: https://attack.mitre.org/techniques/T1547/001/ condition: > - (((modify_registry) or (create_file)) and kevt.pid != 4) + (((modify_registry) or (create_file)) and evt.pid != 4) and (ps.name in script_interpreters or ps.parent.name in script_interpreters or pe.is_trusted = false) and @@ -46,4 +46,4 @@ condition: > action: - name: kill -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_microsoft_office_addin_loaded.yml b/rules/persistence_suspicious_microsoft_office_addin_loaded.yml index 43eaead94..a477e205a 100644 --- a/rules/persistence_suspicious_microsoft_office_addin_loaded.yml +++ b/rules/persistence_suspicious_microsoft_office_addin_loaded.yml @@ -1,6 +1,6 @@ name: Suspicious Microsoft Office add-in loaded id: fe4daff8-d8aa-48d3-bf09-a9d868375a3c -version: 1.0.0 +version: 1.0.1 description: | Identifies attempts to load unsigned executables from known Microsoft Office add-ins directories, which adversaries may exploit to maintain persistence. @@ -29,4 +29,4 @@ output: Microsoft Office process %ps.name loaded a suspicious add-in %image.path severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_microsoft_office_template.yml b/rules/persistence_suspicious_microsoft_office_template.yml index 4d5ab823b..d81f77fcb 100644 --- a/rules/persistence_suspicious_microsoft_office_template.yml +++ b/rules/persistence_suspicious_microsoft_office_template.yml @@ -1,6 +1,6 @@ name: Suspicious Microsoft Office template id: c4be3b30-9d23-4a33-b974-fb12e17487a2 -version: 1.0.2 +version: 1.0.3 description: | Detects when attackers drop macro-enabled files in specific folders to trigger their execution every time the victim user @@ -41,4 +41,4 @@ condition: > output: > Office template %file.path created by suspicious process %ps.exe -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_netsh_helper_dll_execution.yml b/rules/persistence_suspicious_netsh_helper_dll_execution.yml index c61f1b686..af960b681 100644 --- a/rules/persistence_suspicious_netsh_helper_dll_execution.yml +++ b/rules/persistence_suspicious_netsh_helper_dll_execution.yml @@ -1,6 +1,6 @@ name: Suspicious Netsh Helper DLL execution id: bd17781d-38ca-4b9a-a12a-f807a1eb45e0 -version: 1.0.0 +version: 1.0.1 description: | Identifies the execution of a suspicious Netsh Helper DLL. Adversaries may establish persistence by executing malicious content triggered by Netsh Helper DLLs. Netsh.exe is a command-line scripting @@ -32,4 +32,4 @@ output: > Suspicious Netsh Helper DLL %2.thread.start_address.module executed severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_persistence_via_registry_modification.yml b/rules/persistence_suspicious_persistence_via_registry_modification.yml index 8a2e3f692..4a15b2a3e 100644 --- a/rules/persistence_suspicious_persistence_via_registry_modification.yml +++ b/rules/persistence_suspicious_persistence_via_registry_modification.yml @@ -1,6 +1,6 @@ name: Suspicious persistence via registry modification id: 1f496a17-4f0c-491a-823b-7a70adb9919c -version: 1.0.2 +version: 1.0.3 description: | Adversaries may abuse the registry to achieve persistence by modifying the keys that are unlikely modified by legitimate @@ -29,4 +29,4 @@ condition: > and registry.path imatches registry_persistence_keys -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_port_monitor_loaded.yml b/rules/persistence_suspicious_port_monitor_loaded.yml index f0bb210f4..8e3b4cffc 100644 --- a/rules/persistence_suspicious_port_monitor_loaded.yml +++ b/rules/persistence_suspicious_port_monitor_loaded.yml @@ -1,6 +1,6 @@ name: Suspicious port monitor loaded id: d6ab6bfa-1a97-46cb-a69a-7a6c98a699f1 -version: 1.0.1 +version: 1.0.2 description: | Identifies the loading of an unsigned DLL by the print spool service. Adversaries may use port monitors to run an adversary supplied DLL during system boot for persistence or privilege escalation. @@ -22,4 +22,4 @@ condition: > and thread.callstack.symbols imatches ('localspl.dll!SplAddMonitor*', 'spoolsv.exe!PrvAddMonitor*') -min-engine-version: 2.2.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_print_processor_loaded.yml b/rules/persistence_suspicious_print_processor_loaded.yml index 7f67a9e21..643d8475c 100644 --- a/rules/persistence_suspicious_print_processor_loaded.yml +++ b/rules/persistence_suspicious_print_processor_loaded.yml @@ -1,6 +1,6 @@ name: Suspicious print processor loaded id: 3e0f5ef7-8a0a-4604-b2bf-d09606f45483 -version: 1.0.0 +version: 1.0.1 description: | Identifies when the print spooler service loads unsigned or untrusted DLL and the callstack pattern indicates the print processor is loaded. Adversaries may abuse print processors to run malicious DLLs @@ -29,4 +29,4 @@ output: > Print spooler service loaded suspicious print processor DLL %image.path severity: high -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_suspicious_startup_shell_folder_modification.yml b/rules/persistence_suspicious_startup_shell_folder_modification.yml index a864901df..92dfde71b 100644 --- a/rules/persistence_suspicious_startup_shell_folder_modification.yml +++ b/rules/persistence_suspicious_startup_shell_folder_modification.yml @@ -1,6 +1,6 @@ name: Suspicious Startup shell folder modification id: 7a4082f6-f7e3-49bd-9514-dbc8dd4e68ad -version: 1.0.2 +version: 1.0.3 description: | Detects when adversaries attempt to modify the default Startup folder path to to circumvent runtime rules that hunt for file @@ -26,4 +26,4 @@ condition: > registry.value imatches ('%ProgramData%\\Microsoft\\Windows\\Start Menu\\Programs\\Startup') ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_unusual_file_written_in_startup_folder.yml b/rules/persistence_unusual_file_written_in_startup_folder.yml index 228df0891..6faa930e8 100644 --- a/rules/persistence_unusual_file_written_in_startup_folder.yml +++ b/rules/persistence_unusual_file_written_in_startup_folder.yml @@ -1,6 +1,6 @@ name: Unusual file written in Startup folder id: c5ffe15c-d94f-416b-bec7-c47f89843267 -version: 1.0.2 +version: 1.0.3 description: | Identifies suspicious files written to the startup folder that would allow adversaries to maintain persistence on the endpoint. @@ -35,4 +35,4 @@ condition: > '?:\\ProgramData\\Microsoft\\Windows Defender\\Platform\\*.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/persistence_unusual_process_modified_registry_run_key.yml b/rules/persistence_unusual_process_modified_registry_run_key.yml index 5b99617d6..b7d4d54a2 100644 --- a/rules/persistence_unusual_process_modified_registry_run_key.yml +++ b/rules/persistence_unusual_process_modified_registry_run_key.yml @@ -1,6 +1,6 @@ name: Unusual process modified registry run key id: 921508a5-b627-4c02-a295-6c6863c0897b -version: 1.0.4 +version: 1.0.5 description: | Identifies an attempt by unusual Windows native processes to modify the run key and gain persistence on users logons or machine reboots. @@ -44,4 +44,4 @@ condition: > '?:\\Windows\\System32\\CompatTelRunner.exe' ) -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml b/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml index ca6f2add3..222d7e9f9 100644 --- a/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml +++ b/rules/privilege_escalation_potential_privilege_escalation_via_phantom_dll_hijacking.yml @@ -1,6 +1,6 @@ name: Potential privilege escalation via phantom DLL hijacking id: 5ccdb5c2-3a30-4e14-87d2-d7aeb4c45fad -version: 1.0.3 +version: 1.0.4 description: | Identifies the loading of the phantom DLL that was previously dropped to the System directory. Adversaries may exploit this flow to escalate @@ -27,7 +27,7 @@ references: condition: > sequence maxspan 10m - |create_file and kevt.pid != 4 and file.path imatches + |create_file and evt.pid != 4 and file.path imatches ( '?:\\Windows\\System32\\wow64log.dll', '?:\\Windows\\wbemcomn.dll', @@ -58,4 +58,4 @@ condition: > | by file.path |load_dll| by image.path -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml b/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml index c7198e1a4..e76c23c9e 100644 --- a/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml +++ b/rules/privilege_escalation_vulnerable_or_malicious_driver_dropped.yml @@ -1,6 +1,6 @@ name: Vulnerable or malicious driver dropped id: d4742163-cf68-4ebd-b9a2-3ad17bbf63d5 -version: 1.0.1 +version: 1.0.2 description: | Detects when adversaries drop a vulnerable/malicious driver onto a compromised system as a preparation for vulnerability @@ -23,4 +23,4 @@ condition: > output: > Vulnerable or malicious %file.path driver dropped -min-engine-version: 2.4.0 +min-engine-version: 3.0.0 diff --git a/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml b/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml index c5db94e30..e2e660f0b 100644 --- a/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml +++ b/rules/privilege_escalation_vulnerable_or_malicious_driver_loaded.yml @@ -1,6 +1,6 @@ name: Vulnerable or malicious driver loaded id: e8005f1d-b4ec-45ee-a3ea-4247eac123db -version: 1.0.1 +version: 1.0.2 description: | Detects when adversaries load a vulnerable/malicious driver into the compromised system to exploit the vulnerability and @@ -23,4 +23,4 @@ condition: > output: > Vulnerable or malicious %image.path driver loaded -min-engine-version: 2.4.0 +min-engine-version: 3.0.0