mirror of
https://github.com/mandiant/capa.git
synced 2025-12-22 15:16:22 -08:00
features: support characteristic(os/*) features
This commit is contained in:
@@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
Reference in New Issue
Block a user