memory_region.py
ofrak.core.memory_region
MemoryRegion (Addressable)
dataclass
Binary bytes that are addressable.
Attributes:
Name | Type | Description |
---|---|---|
virtual_address |
int |
the virtual address of the start of the memory region |
size |
int |
the size of the memory region |
end_vaddr(self)
Get the virtual address of the end of the memory region.
Returns:
Type | Description |
---|---|
int |
the virtual address directly after the memory region |
Source code in ofrak/core/memory_region.py
def end_vaddr(self) -> int:
"""
Get the virtual address of the end of the memory region.
:returns: the virtual address directly after the memory region
"""
return self.virtual_address + self.size
contains(self, vaddr)
Does the memory region contain the given virtual address?
Parameters:
Name | Type | Description | Default |
---|---|---|---|
vaddr |
int |
a virtual address |
required |
Returns:
Type | Description |
---|---|
bool |
True if the memory region contains the given virtual address |
Source code in ofrak/core/memory_region.py
def contains(self, vaddr: int) -> bool:
"""
Does the memory region contain the given virtual address?
:param vaddr: a virtual address
:return: True if the memory region contains the given virtual address
"""
return self.virtual_address <= vaddr < self.end_vaddr()
get_offset_in_self(self, vaddr)
Get the physical offset within the memory region that corresponds to the given virtual address.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
vaddr |
int |
a virtual address |
required |
Returns:
Type | Description |
---|---|
int |
an offset within the memory region |
Source code in ofrak/core/memory_region.py
def get_offset_in_self(self, vaddr: int) -> int:
"""
Get the physical offset within the memory region that corresponds to the given virtual
address.
:param vaddr: a virtual address
:return: an offset within the memory region
"""
if not self.contains(vaddr):
raise ValueError(
f"Memory region {hex(self.virtual_address)}-{hex(self.end_vaddr())} "
f"does not contain vaddr {hex(vaddr)}"
)
return vaddr - self.virtual_address
create_child_region(self, child_mr, additional_attributes=())
async
Create a child memory region that is mapped into this memory region.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
child_mr |
MemoryRegion |
the child memory region |
required |
additional_attributes |
Iterable[ofrak.model.resource_model.ResourceAttributes] |
additional attributes passed to the child memory region |
() |
Returns:
Type | Description |
---|---|
Resource |
the created child resource |
Exceptions:
Type | Description |
---|---|
ValueError |
if the child's end offset is larger than the memory region's size |
Source code in ofrak/core/memory_region.py
async def create_child_region(
self,
child_mr: "MemoryRegion",
additional_attributes: Iterable[ResourceAttributes] = (),
) -> Resource:
"""
Create a child memory region that is mapped into this memory region.
:param child_mr: the child memory region
:param additional_attributes: additional attributes passed to the child memory region
:raises ValueError: if the child's end offset is larger than the memory region's size
:return: the created child resource
"""
start_offset = self.get_offset_in_self(child_mr.virtual_address)
end_offset = start_offset + child_mr.size
if start_offset < 0:
raise ValueError(
f"New child has vaddr {hex(child_mr.virtual_address)} which is before"
f" the proposed parent's vaddr {hex(self.virtual_address)}"
)
if end_offset > self.size:
raise ValueError(
f"New child at {hex(child_mr.virtual_address)} is too large to fit in the proposed "
f"parent - end vaddr {hex(child_mr.end_vaddr())} goes past the parent's end vaddr "
f"{hex(self.end_vaddr())}."
)
return await self.resource.create_child_from_view(
child_mr,
data_range=Range(start_offset, end_offset),
additional_attributes=additional_attributes,
)
get_mem_region_with_vaddr_from_sorted(vaddr, sorted_regions)
staticmethod
Return the first memory region in the input iterable that contains vaddr.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
vaddr |
int |
Virtual address |
required |
sorted_regions |
Iterable[MemoryRegion] |
Sorted iterable of memory regions to check in order for vaddr |
required |
Returns:
Type | Description |
---|---|
The first memory region in the sorted iterable containing vaddr |
Exceptions:
Type | Description |
---|---|
NotFoundError |
If vaddr is not in any element of the iterable |
Source code in ofrak/core/memory_region.py
@staticmethod
def get_mem_region_with_vaddr_from_sorted(vaddr: int, sorted_regions: Iterable["MemoryRegion"]):
"""
Return the first [memory region][ofrak.core.memory_region.MemoryRegion] in the input
iterable that contains vaddr.
:param vaddr: Virtual address
:param sorted_regions: Sorted iterable of memory regions to check in order for vaddr
:raises NotFoundError: If vaddr is not in any element of the iterable
:return: The first memory region in the sorted iterable containing vaddr
"""
for mem_view in sorted_regions:
# the first region we find should be the largest
mem_region_vaddr_range = Range(
mem_view.virtual_address,
mem_view.virtual_address + mem_view.size,
)
if vaddr in mem_region_vaddr_range:
return mem_view
raise NotFoundError(f"Cannot find memory region matching {hex(vaddr)}")
__hash__(self)
special
Return the hash of the virtual address and size.
Warning
Two memory regions may have the same hash, even if they refer to different data! As long as the address and size are the same, two regions will have the same hash, since the resource is not part of the data that is hashed. Be careful about comparing memory regions that refer to different data!
Source code in ofrak/core/memory_region.py
def __hash__(self):
"""
Return the hash of the virtual address and size.
!!! warning
Two memory regions may have the same hash, even if they refer to different data! As
long as the address and size are the same, two regions will have the same hash,
since the resource is not part of the data that is hashed. Be careful about comparing
memory regions that refer to different data!
"""
return hash((self.virtual_address, self.size))