signatures: Add data_end_offset to signature_match() and custom events

This change tracks the current offset (number of bytes fed into matchers)
on the top-level RuleEndpointState such that we can compute the relative ending
for matched texts individually.

Additionally, it adds the data_end_offset as a new optional parameter to
signature_match().
This commit is contained in:
Arne Welzel 2024-10-28 18:59:58 +01:00
parent 5859e23198
commit 04872d4e78
19 changed files with 219 additions and 24 deletions

View file

@ -91,10 +91,6 @@ Val* RuleMatcher::BuildRuleStateValue(const Rule* rule, const RuleEndpointState*
val->Assign(1, state->GetAnalyzer()->ConnVal());
val->Assign(2, state->is_orig);
val->Assign(3, state->payload_size);
int rule_offset = state->matched_by_patterns.member_pos(const_cast<Rule*>(rule));
if ( rule_offset >= 0 )
val->Assign(4, state->match_offsets[rule_offset]);
return val;
}
@ -180,6 +176,7 @@ void RuleHdrTest::PrintDebug() const {
RuleEndpointState::RuleEndpointState(analyzer::Analyzer* arg_analyzer, bool arg_is_orig,
RuleEndpointState* arg_opposite, analyzer::pia::PIA* arg_PIA) {
payload_size = -1;
current_pos = 0;
analyzer = arg_analyzer;
is_orig = arg_is_orig;
@ -654,8 +651,7 @@ RuleMatcher::MIME_Matches* RuleMatcher::Match(RuleFileMagicState* state, const u
set<Rule*> rule_matches;
for ( AcceptingMatchSet::const_iterator it = accepted_matches.begin(); it != accepted_matches.end(); ++it ) {
AcceptIdx aidx = it->first;
MatchPos mpos = it->second;
auto [aidx, mpos] = *it;
Rule* r = Rule::rule_table[aidx - 1];
@ -805,12 +801,19 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, const
state->payload_size = 0;
}
if ( clear )
state->current_pos = 0;
size_t pre_match_pos = state->current_pos;
// Feed data into all relevant matchers.
for ( const auto& m : state->matchers ) {
if ( m->type == type && m->state->Match((const u_char*)data, data_len, bol, eol, clear) )
newmatch = true;
}
state->current_pos += data_len;
// If no new match found, we're already done.
if ( ! newmatch )
return;
@ -844,8 +847,7 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, const
// Check which of the matching rules really belong to any of our nodes.
for ( set<pair<Rule*, MatchPos>>::const_iterator it = rule_matches.begin(); it != rule_matches.end(); ++it ) {
Rule* r = it->first;
MatchPos match_end_offset = it->second;
auto [r, match_end_pos] = *it;
DBG_LOG(DBG_RULES, "Accepted rule: %s", r->id);
@ -867,7 +869,7 @@ void RuleMatcher::Match(RuleEndpointState* state, Rule::PatternType type, const
state->matched_by_patterns.push_back(r);
String* s = new String(data, data_len, false);
state->matched_text.push_back(s);
state->match_offsets.push_back(match_end_offset);
state->matched_text_end_of_match.push_back(match_end_pos - pre_match_pos);
}
DBG_LOG(DBG_RULES, "And has not already fired");