diff --git a/pkg/filter/accessor_windows.go b/pkg/filter/accessor_windows.go index d37f0830f..74b47289c 100644 --- a/pkg/filter/accessor_windows.go +++ b/pkg/filter/accessor_windows.go @@ -596,6 +596,16 @@ func (t *threadAccessor) Get(f Field, kevt *kevent.Kevent) (kparams.Value, error return kevt.Callstack.ContainsUnbacked(), nil case fields.ThreadCallstack: return kevt.Callstack, nil + case fields.ThreadStartAddressSymbol: + if kevt.Type != ktypes.CreateThread { + return nil, nil + } + return kevt.GetParamAsString(kparams.StartAddressSymbol), nil + case fields.ThreadStartAddressModule: + if kevt.Type != ktypes.CreateThread { + return nil, nil + } + return kevt.GetParamAsString(kparams.StartAddressModule), nil } return nil, nil diff --git a/pkg/filter/fields/fields_windows.go b/pkg/filter/fields/fields_windows.go index e86f03332..4ca583bf6 100644 --- a/pkg/filter/fields/fields_windows.go +++ b/pkg/filter/fields/fields_windows.go @@ -212,6 +212,10 @@ const ( ThreadCallstackCallsiteTrailingAssembly Field = "thread.callstack.callsite_trailing_assembly" // ThreadCallstackIsUnbacked represents the field that indicates if there is an unbacked stack frame ThreadCallstackIsUnbacked Field = "thread.callstack.is_unbacked" + // ThreadStartAddressSymbol represents the symbol corresponding to the thread start address + ThreadStartAddressSymbol Field = "thread.start_address.symbol" + // ThreadStartAddressModule represents the module corresponding to the thread start address + ThreadStartAddressModule Field = "thread.start_address.module" // PeNumSections represents the number of sections PeNumSections Field = "pe.nsections" @@ -797,6 +801,8 @@ var fields = map[Field]FieldInfo{ 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}, + 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}, 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}, diff --git a/pkg/filter/filter_test.go b/pkg/filter/filter_test.go index 03490f908..ed4f7ee3b 100644 --- a/pkg/filter/filter_test.go +++ b/pkg/filter/filter_test.go @@ -327,17 +327,19 @@ 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.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, @@ -396,6 +398,8 @@ func TestThreadFilter(t *testing.T) { {`length(thread.callstack.callsite_leading_assembly) > 0`, true}, {`thread.callstack.callsite_trailing_assembly matches ('*mov r10, rcx|mov eax, 0x*|syscall*')`, true}, {`thread.callstack.is_unbacked`, true}, + {`thread.start_address.symbol = 'LoadImage'`, true}, + {`thread.start_address.module = 'C:\\Windows\\System32\\kernel32.dll'`, true}, {`foreach(thread._callstack, $frame, $frame.address = '2638e59e0a5' or $frame.address = '7ffb5c1d0396')`, true}, {`foreach(thread._callstack, $frame, $frame.address = 'fffff8072ebc1f6f' or $frame.address = 'fffff8072eb8961b')`, true},