|
|
|
@ -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();
|
|
|
|
|