*: rename OperandImmediate to OperandNumber

This commit is contained in:
Willi Ballenthin
2022-03-31 10:37:06 -06:00
parent 76831e9b9d
commit 9da4ff10da
5 changed files with 19 additions and 19 deletions

View File

@@ -5,7 +5,7 @@
### New Features
- add new scope "instruction" for matching mnemonics and operands #767 @williballenthin
- add new feature "operand[{0, 1, 2}].immediate" for matching instruction operand immediate values #767 @williballenthin
- add new feature "operand[{0, 1, 2}].number" for matching instruction operand immediate values #767 @williballenthin
- add new feature "operand[{0, 1, 2}].offset" for matching instruction operand offsets #767 @williballenthin
### Breaking Changes

View File

@@ -60,13 +60,13 @@ class _Operand(Feature):
return (self.__class__.__name__, [self.index, self.value])
class OperandImmediate(_Operand):
class OperandNumber(_Operand):
# cached names so we don't do extra string formatting every ctor
NAMES = ["operand[%d].immediate" % i for i in range(MAX_OPERAND_INDEX)]
NAMES = ["operand[%d].number" % i for i in range(MAX_OPERAND_INDEX)]
# operand[i].immediate: 0x12
# operand[i].number: 0x12
def __init__(self, index: int, value: int, description=None):
super(OperandImmediate, self).__init__(index, value, description=description)
super(OperandNumber, self).__init__(index, value, description=description)
self.name = self.NAMES[index]
def get_value_str(self) -> str:

View File

@@ -125,7 +125,7 @@ SUPPORTED_FEATURES: Dict[str, Set] = {
capa.features.common.Bytes,
capa.features.insn.Offset,
capa.features.insn.Mnemonic,
capa.features.insn.OperandImmediate,
capa.features.insn.OperandNumber,
capa.features.insn.OperandOffset,
capa.features.common.Characteristic("nzxor"),
capa.features.common.Characteristic("peb access"),
@@ -365,7 +365,7 @@ def parse_description(s: Union[str, int, bytes], value_type: str, description=No
or value_type.startswith(("number/", "offset/"))
or (
value_type.startswith("operand[")
and (value_type.endswith("].immediate") or value_type.endswith("].offset"))
and (value_type.endswith("].number") or value_type.endswith("].offset"))
)
):
try:
@@ -535,8 +535,8 @@ def build_statements(d, scope: str):
elif key == "string" and not isinstance(d[key], str):
raise InvalidRule("ambiguous string value %s, must be defined as explicit string" % d[key])
elif key.startswith("operand[") and key.endswith("].immediate"):
index = key[len("operand[") : -len("].immediate")]
elif key.startswith("operand[") and key.endswith("].number"):
index = key[len("operand[") : -len("].number")]
try:
index = int(index)
except ValueError:
@@ -544,7 +544,7 @@ def build_statements(d, scope: str):
value, description = parse_description(d[key], key, d.get("description"))
try:
feature = capa.features.insn.OperandImmediate(index, value, description=description)
feature = capa.features.insn.OperandNumber(index, value, description=description)
except ValueError as e:
raise InvalidRule(str(e))
ensure_feature_valid_for_scope(scope, feature)

View File

@@ -418,9 +418,9 @@ FEATURE_PRESENCE_TESTS = sorted(
("mimikatz", "function=0x40105D", capa.features.insn.Mnemonic("xor"), True),
("mimikatz", "function=0x40105D", capa.features.insn.Mnemonic("in"), False),
("mimikatz", "function=0x40105D", capa.features.insn.Mnemonic("out"), False),
# insn/operand.immediate
("mimikatz", "function=0x40105D,bb=0x401073", capa.features.insn.OperandImmediate(1, 0xFF), True),
("mimikatz", "function=0x40105D,bb=0x401073", capa.features.insn.OperandImmediate(0, 0xFF), False),
# insn/operand.number
("mimikatz", "function=0x40105D,bb=0x401073", capa.features.insn.OperandNumber(1, 0xFF), True),
("mimikatz", "function=0x40105D,bb=0x401073", capa.features.insn.OperandNumber(0, 0xFF), False),
# insn/operand.offset
("mimikatz", "function=0x40105D,bb=0x4010B0", capa.features.insn.OperandOffset(0, 4), True),
("mimikatz", "function=0x40105D,bb=0x4010B0", capa.features.insn.OperandOffset(1, 4), False),

View File

@@ -533,7 +533,7 @@ def test_match_not_not():
assert "test rule" in matches
def test_match_operand_immediate():
def test_match_operand_number():
rule = textwrap.dedent(
"""
rule:
@@ -541,22 +541,22 @@ def test_match_operand_immediate():
name: test rule
features:
- and:
- operand[0].immediate: 0x10
- operand[0].number: 0x10
"""
)
r = capa.rules.Rule.from_yaml(rule)
assert capa.features.insn.OperandImmediate(0, 0x10) in {capa.features.insn.OperandImmediate(0, 0x10)}
assert capa.features.insn.OperandNumber(0, 0x10) in {capa.features.insn.OperandNumber(0, 0x10)}
_, matches = match([r], {capa.features.insn.OperandImmediate(0, 0x10): {1, 2}}, 0x0)
_, matches = match([r], {capa.features.insn.OperandNumber(0, 0x10): {1, 2}}, 0x0)
assert "test rule" in matches
# mismatching index
_, matches = match([r], {capa.features.insn.OperandImmediate(1, 0x10): {1, 2}}, 0x0)
_, matches = match([r], {capa.features.insn.OperandNumber(1, 0x10): {1, 2}}, 0x0)
assert "test rule" not in matches
# mismatching value
_, matches = match([r], {capa.features.insn.OperandImmediate(0, 0x11): {1, 2}}, 0x0)
_, matches = match([r], {capa.features.insn.OperandNumber(0, 0x11): {1, 2}}, 0x0)
assert "test rule" not in matches