detect: integer keywords now accept bitmasks

Ticket: 6648

Like &0x40=0x40 to test for a specific bit set
pull/10277/head
Philippe Antoine 1 year ago committed by Victor Julien
parent 370ac05419
commit d05f3ac791

@ -38,6 +38,8 @@ pub enum DetectUintMode {
DetectUintModeRange,
DetectUintModeNe,
DetectUintModeNegRg,
DetectUintModeBitmask,
DetectUintModeNegBitmask,
}
#[derive(Debug)]
@ -173,6 +175,37 @@ pub fn detect_parse_uint_start_interval<T: DetectIntType>(
))
}
pub fn detect_parse_uint_bitmask<T: DetectIntType>(
i: &str,
) -> IResult<&str, DetectUintData<T>> {
let (i, _) = opt(is_a(" "))(i)?;
let (i, _) = tag("&")(i)?;
let (i, _) = opt(is_a(" "))(i)?;
let (i, arg1) = detect_parse_uint_value(i)?;
let (i, _) = opt(is_a(" "))(i)?;
let (i, neg) = opt(tag("!"))(i)?;
let (i, _) = tag("=")(i)?;
let (i, _) = opt(is_a(" "))(i)?;
let (i, arg2) = detect_parse_uint_value(i)?;
if arg2 & arg1 != arg2 {
// could never match
return Err(Err::Error(make_error(i, ErrorKind::Verify)));
}
let mode = if neg.is_none() {
DetectUintMode::DetectUintModeBitmask
} else {
DetectUintMode::DetectUintModeNegBitmask
};
Ok((
i,
DetectUintData {
arg1,
arg2,
mode,
},
))
}
fn detect_parse_uint_start_interval_inclusive<T: DetectIntType>(
i: &str,
) -> IResult<&str, DetectUintData<T>> {
@ -298,6 +331,16 @@ pub fn detect_match_uint<T: DetectIntType>(x: &DetectUintData<T>, val: T) -> boo
return true;
}
}
DetectUintMode::DetectUintModeBitmask => {
if val & x.arg1 == x.arg2 {
return true;
}
}
DetectUintMode::DetectUintModeNegBitmask => {
if val & x.arg1 != x.arg2 {
return true;
}
}
}
return false;
}
@ -305,6 +348,7 @@ pub fn detect_match_uint<T: DetectIntType>(x: &DetectUintData<T>, val: T) -> boo
pub fn detect_parse_uint_notending<T: DetectIntType>(i: &str) -> IResult<&str, DetectUintData<T>> {
let (i, _) = opt(is_a(" "))(i)?;
let (i, uint) = alt((
detect_parse_uint_bitmask,
detect_parse_uint_start_interval,
detect_parse_uint_start_equal,
detect_parse_uint_start_symbol,
@ -487,6 +531,24 @@ mod tests {
assert_eq!(ctx.mode, DetectUintMode::DetectUintModeGt);
}
#[test]
fn test_parse_uint_bitmask() {
let (_, val) = detect_parse_uint::<u64>("&0x40!=0").unwrap();
assert_eq!(val.arg1, 0x40);
assert_eq!(val.arg2, 0);
assert_eq!(val.mode, DetectUintMode::DetectUintModeNegBitmask);
assert!(!detect_match_uint(&val, 0xBF));
assert!(detect_match_uint(&val, 0x40));
let (_, val) = detect_parse_uint::<u64>("&0xc0=0x80").unwrap();
assert_eq!(val.arg1, 0xc0);
assert_eq!(val.arg2, 0x80);
assert_eq!(val.mode, DetectUintMode::DetectUintModeBitmask);
assert!(detect_match_uint(&val, 0x80));
assert!(!detect_match_uint(&val, 0x40));
assert!(!detect_match_uint(&val, 0xc0));
// could never match
assert!(detect_parse_uint::<u64>("&0xc0=12").is_err());
}
#[test]
fn test_parse_uint_hex() {
let (_, val) = detect_parse_uint::<u64>("0x100").unwrap();

Loading…
Cancel
Save