Skip to content

Commit

Permalink
features: extract import A/W variants and their base names
Browse files Browse the repository at this point in the history
closes #246
  • Loading branch information
williballenthin committed Aug 31, 2020
1 parent 5b349c1 commit 090ec46
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 10 deletions.
29 changes: 29 additions & 0 deletions capa/features/extractors/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
import sys
import builtins

from capa.features.file import Import
from capa.features.insn import API

MIN_STACKSTRING_LEN = 8
Expand Down Expand Up @@ -65,6 +66,34 @@ def generate_api_features(apiname, va):
yield API(impname[:-1]), va


def is_ordinal(symbol):
return symbol[0] == "#"


def generate_import_features(dll, symbol, va):
"""
for a given dll, symbol, and address, generate import features.
we over-generate features to make matching easier.
these include:
- kernel32.CreateFileA
- kernel32.CreateFile
- CreateFileA
- CreateFile
"""
# (kernel32.CreateFileA, 0x401000)
yield Import(dll + "." + symbol), va
# (CreateFileA, 0x401000)
if not is_ordinal(symbol):
yield Import(symbol), va

if is_aw_function(symbol):
# (kernel32.CreateFile, 0x401000)
yield Import(dll + "." + symbol[:-1]), va
# (CreateFile, 0x401000)
if not is_ordinal(symbol):
yield Import(symbol[:-1]), va


def all_zeros(bytez):
return all(b == 0 for b in builtins.bytes(bytez))

Expand Down
14 changes: 10 additions & 4 deletions capa/features/extractors/ida/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,16 @@ def extract_file_import_names():
"""
for (ea, info) in capa.features.extractors.ida.helpers.get_file_imports().items():
if info[1]:
yield Import("%s.%s" % (info[0], info[1])), ea
yield Import(info[1]), ea
if info[2]:
yield Import("%s.#%s" % (info[0], str(info[2]))), ea
dll = info[0]
symbol = info[1]
elif info[2]:
dll = info[0]
symbol = "#%d" % (info[2])
else:
continue

for feature, ea in capa.features.extractors.helpers.generate_import_features(dll, symbol, ea):
yield feature, ea


def extract_file_section_names():
Expand Down
11 changes: 5 additions & 6 deletions capa/features/extractors/viv/file.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,9 @@
import PE.carve as pe_carve # vivisect PE

import capa.features.extractors.strings
import capa.features.extractors.helpers
from capa.features import String, Characteristic
from capa.features.file import Export, Import, Section
from capa.features.file import Export, Section


def extract_file_embedded_pe(vw, file_path):
Expand Down Expand Up @@ -41,11 +42,9 @@ def extract_file_import_names(vw, file_path):
if is_viv_ord_impname(impname):
# replace ord prefix with #
impname = "#%s" % impname[len("ord") :]
tinfo = "%s.%s" % (modname, impname)
yield Import(tinfo), va
else:
yield Import(tinfo), va
yield Import(impname), va

for feature, va in capa.features.extractors.helpers.generate_import_features(modname, impname, va):
yield feature, va


def is_viv_ord_impname(impname):
Expand Down
2 changes: 2 additions & 0 deletions tests/fixtures.py
Original file line number Diff line number Diff line change
Expand Up @@ -283,6 +283,8 @@ def parametrize(params, values, **kwargs):
("mimikatz", "file", capa.features.file.Import("nope"), False),
("mimikatz", "file", capa.features.file.Import("advapi32.CryptAcquireContextW"), True),
("mimikatz", "file", capa.features.file.Import("advapi32.CryptAcquireContext"), True),
("mimikatz", "file", capa.features.file.Import("CryptAcquireContextW"), True),
("mimikatz", "file", capa.features.file.Import("CryptAcquireContext"), True),
# function/characteristic(loop)
("mimikatz", "function=0x401517", capa.features.Characteristic("loop"), True),
("mimikatz", "function=0x401000", capa.features.Characteristic("loop"), False),
Expand Down

0 comments on commit 090ec46

Please sign in to comment.