complex_block.py
ofrak.core.complex_block
ComplexBlock (MemoryRegion)
dataclass
A collection of basic blocks and data words that represent a logical unit of code (usually a function).
Attributes:
Name | Type | Description |
---|---|---|
virtual_address |
int |
the lowest virtual address in the complex block |
size |
int |
the size of the complex block |
name |
str |
the complex block's name |
get_basic_blocks(self)
async
Get complex block's basic blocks.
Returns:
Type | Description |
---|---|
Iterable[ofrak.core.basic_block.BasicBlock] |
basic blocks |
Source code in ofrak/core/complex_block.py
async def get_basic_blocks(self) -> Iterable[BasicBlock]:
"""
Get complex block's basic blocks.
:return: basic blocks
"""
return await self.resource.get_descendants_as_view(
BasicBlock,
r_filter=ResourceFilter.with_tags(BasicBlock),
r_sort=ResourceSort(Addressable.VirtualAddress),
)
get_assembly(self)
async
Get the complex block's instructions as an assembly string.
Returns:
Type | Description |
---|---|
str |
the complex block's assembly |
Source code in ofrak/core/complex_block.py
async def get_assembly(self) -> str:
"""
Get the complex block's instructions as an assembly string.
:return: the complex block's assembly
"""
bbs = await self.get_basic_blocks()
bb_assemblies = [bb_r.get_assembly() for bb_r in bbs]
return "\n".join(await asyncio.gather(*bb_assemblies))
get_data_words(self)
async
Get the complex block's data words.
Returns:
Type | Description |
---|---|
Iterable[ofrak.core.data.DataWord] |
the data words in the complex block |
Source code in ofrak/core/complex_block.py
async def get_data_words(self) -> Iterable[DataWord]:
"""
Get the complex block's [data words][ofrak.core.data.DataWord].
:return: the data words in the complex block
"""
return await self.resource.get_descendants_as_view(
DataWord,
r_filter=ResourceFilter.with_tags(DataWord),
r_sort=ResourceSort(Addressable.VirtualAddress),
)
get_mode(self)
async
Get the complex block's mode.
Returns:
Type | Description |
---|---|
InstructionSetMode |
the mode of the complex block |
Exceptions:
Type | Description |
---|---|
ValueError |
if the basic blocks in the complex block have more than one mode |
Source code in ofrak/core/complex_block.py
async def get_mode(self) -> InstructionSetMode:
"""
Get the complex block's [mode][ofrak_type.architecture.InstructionSetMode].
:raises ValueError: if the basic blocks in the complex block have more than one mode
:return: the mode of the complex block
"""
await self.resource.unpack()
bb_modes = {bb.mode for bb in await self.get_basic_blocks()}
if len(bb_modes) == 1:
return bb_modes.pop()
elif len(bb_modes) > 1:
raise ValueError(
f"Multiple modes present in complex block! Not all basic blocks have "
f"the same mode; found modes {bb_modes}"
)
else:
raise ValueError("No basic blocks found in complex block! Perhaps it was not unpacked")
ComplexBlockAnalyzer (Analyzer, ABC)
Analyze a complex block and extract its virtual address, size, and name.
analyze(self, resource, config=None)
async
Analyze a complex block resource and extract its virtual address, size, and name.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
the complex block resource |
required |
config |
None |
Returns:
Type | Description |
---|---|
ComplexBlock |
the analyzed complex block |
Source code in ofrak/core/complex_block.py
@abstractmethod
async def analyze(self, resource: Resource, config=None) -> ComplexBlock:
"""
Analyze a complex block resource and extract its virtual address, size, and name.
:param resource: the complex block resource
:param config:
:return: the analyzed complex block
"""
raise NotImplementedError()
ComplexBlockDataReferenceAttributes (ResourceAttributes)
dataclass
ComplexBlockDataReferenceAttributes(referenced_data_vm_addresses: Tuple[int, ...])
ComplexBlockUnpacker (Unpacker, ABC)
Unpack a complex block into basic blocks and data words.
unpack(self, resource, config=None)
async
Unpack a complex block, identifying all of the basic blocks and data words which are a part of it.
The identified basic blocks and data words must be within the previously identified range of the complex block. If the analysis engine identifies basic blocks outside of this range, those are be ignored - i.e. not unpacked - and the rest of the basic blocks in the function are unpacked as usual.
Source code in ofrak/core/complex_block.py
@abstractmethod
async def unpack(self, resource: Resource, config=None):
"""
Unpack a complex block, identifying all of the basic blocks and data words which are a part
of it.
The identified basic blocks and data words must be within the previously identified range
of the complex block. If the analysis engine identifies basic blocks outside of this
range, those are be ignored - i.e. not unpacked - and the rest of the basic blocks in
the function are unpacked as usual.
"""
raise NotImplementedError()
DataRefsAnalyzer (Analyzer, ABC)
Analyze the references a complex block makes to data addresses.
analyze(self, resource, config=None)
async
Analyze the references a complex block resource makes to data addresses
Parameters:
Name | Type | Description | Default |
---|---|---|---|
resource |
Resource |
the complex block resource |
required |
config |
None |
Returns:
Type | Description |
---|---|
Tuple[ofrak.core.complex_block.ComplexBlockDataReferenceAttributes] |
The virtual addresses of all the data words referenced by the complex block. |
Source code in ofrak/core/complex_block.py
@abstractmethod
async def analyze(
self, resource: Resource, config=None
) -> Tuple[ComplexBlockDataReferenceAttributes]:
"""
Analyze the references a complex block resource makes to data addresses
:param resource: the complex block resource
:param config:
:return: The virtual addresses of all the data words referenced by the complex block.
"""
raise NotImplementedError()