mirror of
https://github.com/mandiant/capa.git
synced 2025-12-12 15:49:46 -08:00
address: remove dynamic return address concept, as its unused today
This commit is contained in:
@@ -116,29 +116,6 @@ class DynamicCallAddress(Address):
|
||||
return (self.thread, self.id) < (other.thread, other.id)
|
||||
|
||||
|
||||
class DynamicReturnAddress(Address):
|
||||
"""an address from a dynamic analysis trace"""
|
||||
|
||||
def __init__(self, call: DynamicCallAddress, return_address: int):
|
||||
assert return_address >= 0
|
||||
self.call = call
|
||||
self.return_address = return_address
|
||||
|
||||
def __repr__(self):
|
||||
return f"{self.call}, dynamic-call(return-address: 0x{self.return_address:x})"
|
||||
|
||||
def __hash__(self):
|
||||
return hash((self.call, self.return_address))
|
||||
|
||||
def __eq__(self, other):
|
||||
assert isinstance(other, DynamicReturnAddress)
|
||||
return (self.call, self.return_address) == (other.call, other.return_address)
|
||||
|
||||
def __lt__(self, other):
|
||||
assert isinstance(other, DynamicReturnAddress)
|
||||
return (self.call, self.return_address) < (other.call, other.return_address)
|
||||
|
||||
|
||||
class RelativeVirtualAddress(int, Address):
|
||||
"""a memory address relative to a base address"""
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ import capa.features.extractors.cape.global_
|
||||
import capa.features.extractors.cape.process
|
||||
from capa.features.insn import API, Number
|
||||
from capa.features.common import String, Feature
|
||||
from capa.features.address import Address, DynamicReturnAddress
|
||||
from capa.features.address import Address
|
||||
from capa.features.extractors.base_extractor import CallHandle, ThreadHandle, ProcessHandle
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -44,14 +44,13 @@ def extract_call_features(
|
||||
calls: List[Dict[str, Any]] = process["calls"]
|
||||
call = calls[ch.address.id]
|
||||
assert call["thread_id"] == str(th.address.tid)
|
||||
caller = DynamicReturnAddress(call=ch.address, return_address=int(call["caller"], 16))
|
||||
# list similar to disassembly: arguments right-to-left, call
|
||||
for arg in call["arguments"][::-1]:
|
||||
try:
|
||||
yield Number(int(arg["value"], 16)), caller
|
||||
yield Number(int(arg["value"], 16)), ch.address
|
||||
except ValueError:
|
||||
yield String(arg["value"]), caller
|
||||
yield API(call["api"]), caller
|
||||
yield String(arg["value"]), ch.address
|
||||
yield API(call["api"]), ch.address
|
||||
|
||||
|
||||
def extract_features(
|
||||
|
||||
@@ -84,18 +84,6 @@ class Address(HashableModel):
|
||||
elif isinstance(a, capa.features.address.DynamicCallAddress):
|
||||
return cls(type=AddressType.CALL, value=(a.thread.process.ppid, a.thread.process.pid, a.thread.tid, a.id))
|
||||
|
||||
elif isinstance(a, capa.features.address.DynamicReturnAddress):
|
||||
return cls(
|
||||
type=AddressType.DYNAMIC,
|
||||
value=(
|
||||
a.call.thread.process.ppid,
|
||||
a.call.thread.process.pid,
|
||||
a.call.thread.tid,
|
||||
a.call.id,
|
||||
a.return_address,
|
||||
),
|
||||
)
|
||||
|
||||
elif a == capa.features.address.NO_ADDRESS or isinstance(a, capa.features.address._NoAddress):
|
||||
return cls(type=AddressType.NO_ADDRESS, value=None)
|
||||
|
||||
@@ -159,19 +147,6 @@ class Address(HashableModel):
|
||||
id=id_,
|
||||
)
|
||||
|
||||
elif self.type is AddressType.DYNAMIC:
|
||||
assert isinstance(self.value, tuple)
|
||||
ppid, pid, tid, id_, return_address = self.value
|
||||
return capa.features.address.DynamicReturnAddress(
|
||||
call=capa.features.address.DynamicCallAddress(
|
||||
thread=capa.features.address.ThreadAddress(
|
||||
process=capa.features.address.ProcessAddress(ppid=ppid, pid=pid), tid=tid
|
||||
),
|
||||
id=id_,
|
||||
),
|
||||
return_address=return_address,
|
||||
)
|
||||
|
||||
elif self.type is AddressType.NO_ADDRESS:
|
||||
return capa.features.address.NO_ADDRESS
|
||||
|
||||
@@ -233,8 +208,10 @@ class ThreadFeature(HashableModel):
|
||||
class CallFeature(HashableModel):
|
||||
"""
|
||||
args:
|
||||
call: the call id to which this feature belongs.
|
||||
address: the address at which this feature is found (it's dynamic return address).
|
||||
call: the address of the call to which this feature belongs.
|
||||
address: the address at which this feature is found.
|
||||
|
||||
call != address for consistency with Process and Thread.
|
||||
"""
|
||||
|
||||
call: Address
|
||||
@@ -279,8 +256,7 @@ class InstructionFeature(HashableModel):
|
||||
instruction: the address of the instruction to which this feature belongs.
|
||||
address: the address at which this feature is found.
|
||||
|
||||
instruction != address because, e.g., the feature may be found *within* the scope (basic block),
|
||||
versus right at its starting address.
|
||||
instruction != address because, for consistency with Function and BasicBlock.
|
||||
"""
|
||||
|
||||
instruction: Address
|
||||
|
||||
@@ -273,8 +273,8 @@ def print_dynamic_features(processes, extractor: DynamicFeatureExtractor):
|
||||
continue
|
||||
|
||||
if isinstance(feature, API):
|
||||
assert isinstance(addr, capa.features.address.DynamicReturnAddress)
|
||||
apis.append((addr.call.id, str(feature.value)))
|
||||
assert isinstance(addr, capa.features.address.DynamicCallAddress)
|
||||
apis.append((addr.id, str(feature.value)))
|
||||
|
||||
if isinstance(feature, (Number, String)):
|
||||
arguments.append(str(feature.value))
|
||||
|
||||
Reference in New Issue
Block a user