Skip to content
Open
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Update asif.py
  • Loading branch information
Schamper committed Jun 19, 2026
commit 2b3faaed0a78ea6073baf0c440069901f6ef00e8
44 changes: 25 additions & 19 deletions dissect/hypervisor/disk/asif.py
Original file line number Diff line number Diff line change
Expand Up @@ -175,15 +175,19 @@ def entries(self) -> list[int]:
self.asif.fh.seek(self.offset + 8)
return c_asif.uint64[self.asif._num_tables](self.asif.fh)

def table(self, index: int) -> Table:
def table(self, index: int) -> Table | None:
"""Get a table from the directory.

Args:
index: Index of the table in the directory.
"""
if index >= self.asif._num_tables:
raise IndexError("Table index out of range")
return Table(self.asif, index, self.entries[index] * self.asif.chunk_size)

if (entry := self.entries[index]) == 0:
return None

return Table(self.asif, index, entry * self.asif.chunk_size)


class Table:
Expand Down Expand Up @@ -251,25 +255,27 @@ def __init__(self, asif: ASIF, reserved: bool = False):
def _read(self, offset: int, length: int) -> bytes:
result = []
while length:
table = self.directory.table(offset // self.asif._size_per_table)

# Calculate the relative chunk index within the table
relative_block_index = (offset // self.asif.block_size) - (table.virtual_offset // self.asif.block_size)
relative_chunk_index = relative_block_index // self.asif._blocks_per_chunk

# Calculate the chunk group
chunk_group = relative_chunk_index // self.asif._num_chunks_per_group
# Each chunk group has a bitmap entry, so we need to account for that in the entry index
entry_index = relative_chunk_index + chunk_group

chunk = table.entries[entry_index] & 0x7FFFFFFFFFFFFF

read_length = min(length, self.asif.chunk_size)
if chunk == 0:
if (table := self.directory.table(offset // self.asif._size_per_table)) is None:
read_length = min(length, self.asif._size_per_table)
result.append(b"\x00" * read_length)
else:
self.asif.fh.seek(chunk * self.asif.chunk_size)
result.append(self.asif.fh.read(read_length))
# Calculate the relative chunk index within the table
relative_block_index = (offset // self.asif.block_size) - (table.virtual_offset // self.asif.block_size)
relative_chunk_index = relative_block_index // self.asif._blocks_per_chunk

# Calculate the chunk group
chunk_group = relative_chunk_index // self.asif._num_chunks_per_group
# Each chunk group has a bitmap entry, so we need to account for that in the entry index
entry_index = relative_chunk_index + chunk_group

chunk = table.entries[entry_index] & 0x7FFFFFFFFFFFFF

read_length = min(length, self.asif.chunk_size)
if chunk == 0:
result.append(b"\x00" * read_length)
else:
self.asif.fh.seek(chunk * self.asif.chunk_size)
result.append(self.asif.fh.read(read_length))

offset += read_length
length -= read_length
Expand Down
Loading