features: support characteristic(os/*) features

This commit is contained in:
William Ballenthin
2021-08-11 08:40:40 -06:00
parent aefe97e09e
commit a1eca58d7a
3 changed files with 34 additions and 2 deletions

View File

@@ -27,6 +27,11 @@ ARCH_X32 = "x32"
ARCH_X64 = "x64" ARCH_X64 = "x64"
VALID_ARCH = (ARCH_X32, ARCH_X64) VALID_ARCH = (ARCH_X32, ARCH_X64)
OS_WINDOWS = "os/windows"
OS_LINUX = "os/linux"
OS_MACOS = "os/macos"
VALID_OS = (OS_WINDOWS, OS_LINUX, OS_MACOS)
def bytes_to_str(b: bytes) -> str: def bytes_to_str(b: bytes) -> str:
return str(codecs.encode(b, "hex").decode("utf-8")) return str(codecs.encode(b, "hex").decode("utf-8"))
@@ -131,6 +136,7 @@ class MatchedRule(Feature):
class Characteristic(Feature): class Characteristic(Feature):
def __init__(self, value: str, description=None): def __init__(self, value: str, description=None):
super(Characteristic, self).__init__(value, description=description) super(Characteristic, self).__init__(value, description=description)

View File

@@ -34,7 +34,7 @@ import capa.features.insn
import capa.features.common import capa.features.common
import capa.features.basicblock import capa.features.basicblock
from capa.engine import Statement, FeatureSet from capa.engine import Statement, FeatureSet
from capa.features.common import MAX_BYTES_FEATURE_SIZE, Feature from capa.features.common import OS_LINUX, OS_MACOS, OS_WINDOWS, MAX_BYTES_FEATURE_SIZE, Feature
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
@@ -78,6 +78,9 @@ SUPPORTED_FEATURES = {
capa.features.file.FunctionName, capa.features.file.FunctionName,
capa.features.common.Characteristic("embedded pe"), capa.features.common.Characteristic("embedded pe"),
capa.features.common.String, capa.features.common.String,
capa.features.common.Characteristic(OS_WINDOWS),
capa.features.common.Characteristic(OS_LINUX),
capa.features.common.Characteristic(OS_MACOS),
}, },
FUNCTION_SCOPE: { FUNCTION_SCOPE: {
# plus basic block scope features, see below # plus basic block scope features, see below
@@ -86,6 +89,9 @@ SUPPORTED_FEATURES = {
capa.features.common.Characteristic("calls to"), capa.features.common.Characteristic("calls to"),
capa.features.common.Characteristic("loop"), capa.features.common.Characteristic("loop"),
capa.features.common.Characteristic("recursive call"), capa.features.common.Characteristic("recursive call"),
capa.features.common.Characteristic(OS_WINDOWS),
capa.features.common.Characteristic(OS_LINUX),
capa.features.common.Characteristic(OS_MACOS),
}, },
BASIC_BLOCK_SCOPE: { BASIC_BLOCK_SCOPE: {
capa.features.common.MatchedRule, capa.features.common.MatchedRule,
@@ -103,6 +109,9 @@ SUPPORTED_FEATURES = {
capa.features.common.Characteristic("tight loop"), capa.features.common.Characteristic("tight loop"),
capa.features.common.Characteristic("stack string"), capa.features.common.Characteristic("stack string"),
capa.features.common.Characteristic("indirect call"), capa.features.common.Characteristic("indirect call"),
capa.features.common.Characteristic(OS_WINDOWS),
capa.features.common.Characteristic(OS_LINUX),
capa.features.common.Characteristic(OS_MACOS),
}, },
} }

View File

@@ -15,7 +15,7 @@ import capa.engine
import capa.features.common import capa.features.common
from capa.features.file import FunctionName from capa.features.file import FunctionName
from capa.features.insn import Number, Offset from capa.features.insn import Number, Offset
from capa.features.common import ARCH_X32, ARCH_X64, String from capa.features.common import ARCH_X32, ARCH_X64, OS_WINDOWS, String, Characteristic
def test_rule_ctor(): def test_rule_ctor():
@@ -944,3 +944,20 @@ def test_function_name_features():
assert (FunctionName("strcpy") in children) == True assert (FunctionName("strcpy") in children) == True
assert (FunctionName("strcmp", description="copy from here to there") in children) == True assert (FunctionName("strcmp", description="copy from here to there") in children) == True
assert (FunctionName("strdup", description="duplicate a string") in children) == True assert (FunctionName("strdup", description="duplicate a string") in children) == True
def test_os_features():
rule = textwrap.dedent(
"""
rule:
meta:
name: test rule
scope: file
features:
- and:
- characteristic: os/windows
"""
)
r = capa.rules.Rule.from_yaml(rule)
children = list(r.statement.get_children())
assert (Characteristic(OS_WINDOWS) in children) == True