features: extract import A/W variants and their base names

closes #246
This commit is contained in:
William Ballenthin
2020-08-31 17:13:10 -06:00
parent 5b349c1df8
commit 090ec46ca4
4 changed files with 46 additions and 10 deletions

View File

@@ -9,6 +9,7 @@
import sys
import builtins
from capa.features.file import Import
from capa.features.insn import API
MIN_STACKSTRING_LEN = 8
@@ -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))

View File

@@ -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():

View File

@@ -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):
@@ -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):

View File

@@ -283,6 +283,8 @@ FEATURE_PRESENCE_TESTS = [
("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),