Merge pull request #44 from fireeye/doclint/unsigned

Doclint/unsigned
This commit is contained in:
Willi Ballenthin
2020-06-30 15:19:45 -06:00
committed by GitHub
3 changed files with 22 additions and 4 deletions

View File

@@ -348,7 +348,8 @@ Examples:
number: 0x10 number: 0x10
number: 0x40 = PAGE_EXECUTE_READWRITE number: 0x40 = PAGE_EXECUTE_READWRITE
TODO: signed vs unsigned. Note that capa treats all numbers as unsigned values. A negative number is not a valid feature value.
To match a negative number you may specify its two's complement representation. For example, `0xFFFFFFF0` (`-2`) in a 32-bit file.
### string ### string
A string referenced by the logic of the program. A string referenced by the logic of the program.
@@ -402,6 +403,8 @@ Examples:
offset: 0xC offset: 0xC
offset: 0x14 offset: 0x14
Note that capa treats all offsets as unsigned values. A negative number is not a valid feature value.
### mnemonic ### mnemonic
An instruction mnemonic found in the given function. An instruction mnemonic found in the given function.

View File

@@ -20,6 +20,7 @@ import argparse
import capa.main import capa.main
import capa.engine import capa.engine
import capa.features import capa.features
import capa.features.insn
logger = logging.getLogger('capa.lint') logger = logging.getLogger('capa.lint')
@@ -215,6 +216,20 @@ class FeatureStringTooShort(Lint):
return False return False
class FeatureNegativeNumberOrOffset(Lint):
name = 'feature value is negative'
recommendation = 'capa treats all numbers as unsigned values; you may specify the number\'s two\'s complement ' \
'representation; will not match on "{:d}"'
def check_features(self, ctx, features):
for feature in features:
if isinstance(feature, (capa.features.insn.Number, capa.features.insn.Offset)):
if feature.value < 0:
self.recommendation = self.recommendation.format(feature.value)
return True
return False
def run_lints(lints, ctx, rule): def run_lints(lints, ctx, rule):
for lint in lints: for lint in lints:
if lint.check_rule(ctx, rule): if lint.check_rule(ctx, rule):
@@ -264,6 +279,7 @@ def lint_meta(ctx, rule):
FEATURE_LINTS = ( FEATURE_LINTS = (
FeatureStringTooShort(), FeatureStringTooShort(),
FeatureNegativeNumberOrOffset(),
) )

View File

@@ -250,7 +250,7 @@ def test_number_symbol():
features: features:
- and: - and:
- number: 1 - number: 1
- number: -1 - number: 0xFFFFFFFF
- number: 2 = symbol name - number: 2 = symbol name
- number: 3 = symbol name - number: 3 = symbol name
- number: 4 = symbol name = another name - number: 4 = symbol name = another name
@@ -260,7 +260,7 @@ def test_number_symbol():
r = capa.rules.Rule.from_yaml(rule) r = capa.rules.Rule.from_yaml(rule)
children = list(r.statement.get_children()) children = list(r.statement.get_children())
assert (Number(1) in children) == True assert (Number(1) in children) == True
assert (Number(-1) in children) == True assert (Number(0xFFFFFFFF) in children) == True
assert (Number(2, 'symbol name') in children) == True assert (Number(2, 'symbol name') in children) == True
assert (Number(3, 'symbol name') in children) == True assert (Number(3, 'symbol name') in children) == True
assert (Number(4, 'symbol name = another name') in children) == True assert (Number(4, 'symbol name = another name') in children) == True
@@ -323,7 +323,6 @@ def test_offset_symbol():
features: features:
- and: - and:
- offset: 1 - offset: 1
# what about negative offsets?
- offset: 2 = symbol name - offset: 2 = symbol name
- offset: 3 = symbol name - offset: 3 = symbol name
- offset: 4 = symbol name = another name - offset: 4 = symbol name = another name