fix: string extraction and rendering (#1083)

This commit is contained in:
Moritz
2022-07-05 21:17:24 +02:00
committed by GitHub
parent ec81768fb5
commit b4d2fecf4b
4 changed files with 24 additions and 14 deletions

View File

@@ -18,7 +18,7 @@ import capa.features.extractors.helpers
import capa.features.extractors.strings
import capa.features.extractors.ida.helpers
from capa.features.file import Export, Import, Section, FunctionName
from capa.features.common import FORMAT_PE, FORMAT_ELF, Format, Feature, Characteristic
from capa.features.common import FORMAT_PE, FORMAT_ELF, Format, String, Feature, Characteristic
from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress, AbsoluteVirtualAddress
@@ -136,7 +136,13 @@ def extract_file_strings() -> Iterator[Tuple[Feature, Address]]:
"""
for seg in capa.features.extractors.ida.helpers.get_segments():
seg_buff = capa.features.extractors.ida.helpers.get_segment_buffer(seg)
yield from capa.features.extractors.common.extract_file_strings(seg_buff)
# differing to common string extractor factor in segment offset here
for s in capa.features.extractors.strings.extract_ascii_strings(seg_buff):
yield String(s.s), FileOffsetAddress(seg.start_ea + s.offset)
for s in capa.features.extractors.strings.extract_unicode_strings(seg_buff):
yield String(s.s), FileOffsetAddress(seg.start_ea + s.offset)
def extract_file_function_names() -> Iterator[Tuple[Feature, Address]]:

View File

@@ -818,7 +818,7 @@ class CapaExplorerForm(idaapi.PluginForm):
try:
self.doc = capa.render.result_document.ResultDocument.from_capa(meta, self.ruleset_cache, capabilities)
except Exception as e:
logger.error("Failed to collect results (error: %s)", e)
logger.error("Failed to collect results (error: %s)", e, exc_info=True)
return False
try:
@@ -827,7 +827,7 @@ class CapaExplorerForm(idaapi.PluginForm):
"capa rules directory: %s (%d rules)" % (settings.user[CAPA_SETTINGS_RULE_PATH], len(self.rules_cache))
)
except Exception as e:
logger.error("Failed to render results (error: %s)", e)
logger.error("Failed to render results (error: %s)", e, exc_info=True)
return False
return True

View File

@@ -14,7 +14,7 @@ import idaapi
from PyQt5 import QtCore
import capa.ida.helpers
from capa.features.address import Address, AbsoluteVirtualAddress
from capa.features.address import Address, FileOffsetAddress, AbsoluteVirtualAddress
def info_to_name(display):
@@ -311,7 +311,7 @@ class CapaExplorerFeatureItem(CapaExplorerDataItem):
@param location: virtual address as seen by IDA
"""
if location:
assert isinstance(location, AbsoluteVirtualAddress)
assert isinstance(location, (AbsoluteVirtualAddress, FileOffsetAddress))
ea = int(location)
super(CapaExplorerFeatureItem, self).__init__(parent, [display, ea_to_hex(ea), details])
else:
@@ -349,7 +349,7 @@ class CapaExplorerByteViewItem(CapaExplorerFeatureItem):
@param display: text to display in UI
@param location: virtual address as seen by IDA
"""
assert isinstance(location, AbsoluteVirtualAddress)
assert isinstance(location, (AbsoluteVirtualAddress, FileOffsetAddress))
ea = int(location)
byte_snap = idaapi.get_bytes(ea, 32)
@@ -373,7 +373,7 @@ class CapaExplorerStringViewItem(CapaExplorerFeatureItem):
@param display: text to display in UI
@param location: virtual address as seen by IDA
"""
assert isinstance(location, AbsoluteVirtualAddress)
assert isinstance(location, (AbsoluteVirtualAddress, FileOffsetAddress))
ea = int(location)
super(CapaExplorerStringViewItem, self).__init__(parent, display, location=location, details=value)

View File

@@ -17,6 +17,7 @@ import capa.rules
import capa.ida.helpers
import capa.render.utils as rutils
import capa.features.common
import capa.features.freeze as frz
import capa.render.result_document as rd
import capa.features.freeze.features as frzf
from capa.ida.plugin.item import (
@@ -540,6 +541,7 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel):
"""process capa doc feature node
@param parent: parent node to which child is assigned
@param match: match information
@param feature: capa doc feature node
@param locations: locations identified for feature
@param doc: capa doc
@@ -577,6 +579,7 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel):
"""render capa feature read from doc
@param parent: parent node to which new child is assigned
@param match: match information
@param feature: feature read from doc
@param doc: capa feature doc
@param location: address of feature
@@ -600,13 +603,14 @@ class CapaExplorerDataModel(QtCore.QAbstractItemModel):
matched_rule_name = feature.match
return CapaExplorerRuleMatchItem(parent, display, source=doc.rules[matched_rule_name].source)
# wb: 614: substring feature?
elif isinstance(feature, (frzf.RegexFeature, frzf.SubstringFeature)):
for capture, locations in sorted(match.captures.items()):
if location in locations:
return CapaExplorerStringViewItem(
parent, display, location, '"' + capa.features.common.escape_string(capture) + '"'
)
for capture, addrs in sorted(match.captures.items()):
for addr in addrs:
assert isinstance(addr, frz.Address)
if location == addr.value:
return CapaExplorerStringViewItem(
parent, display, location, '"' + capa.features.common.escape_string(capture) + '"'
)
# programming error: the given location should always be found in the regex matches
raise ValueError("regex match at location not found")