ducky.mm package

Module contents

class ducky.mm.AnonymousMemoryPage(controller, index)[source]

Bases: ducky.mm.MemoryPage

“Anonymous” memory page - this page is just a plain array of bytes, and is not backed by any storage. Its content lives only in the memory.

Page is created with all bytes set to zero.

clear()[source]
read_u16(offset)[source]
read_u32(offset)[source]
read_u8(offset)[source]
write_u16(offset, value)[source]
write_u32(offset, value)[source]
write_u8(offset, value)[source]
class ducky.mm.ExternalMemoryPage(controller, index, data, offset=0)[source]

Bases: ducky.mm.MemoryPage

Memory page backed by an external source. Source is an array of bytes, and can be provided by device driver, mmaped file, or by any other mean.

clear()[source]
get(offset)[source]

Get one byte from page. Override this method in case you need a different offset of requested byte.

Parameters:offset (int) – offset of the requested byte.
Return type:int
Returns:byte at position in page.
put(offset, b)[source]

Put one byte into page. Override this method in case you need a different offset of requested byte.

Parameters:
  • offset (int) – offset of modified byte.
  • b (int) – new value.
read_u16(offset)[source]
read_u32(offset)[source]
read_u8(offset)[source]
save_state(parent)[source]
write_u16(offset, value)[source]
write_u32(offset, value)[source]
write_u8(offset, value)[source]
class ducky.mm.MMOperationList[source]

Bases: enum.IntEnum

ALLOC = 3
FREE = 4
MMAP = 6
UNMMAP = 7
UNUSED = 5
_member_map_ = OrderedDict([('ALLOC', <MMOperationList.ALLOC: 3>), ('FREE', <MMOperationList.FREE: 4>), ('UNUSED', <MMOperationList.UNUSED: 5>), ('MMAP', <MMOperationList.MMAP: 6>), ('UNMMAP', <MMOperationList.UNMMAP: 7>)])
_member_names_ = ['ALLOC', 'FREE', 'UNUSED', 'MMAP', 'UNMMAP']
_member_type_

alias of int

_value2member_map_ = {3: <MMOperationList.ALLOC: 3>, 4: <MMOperationList.FREE: 4>, 5: <MMOperationList.UNUSED: 5>, 6: <MMOperationList.MMAP: 6>, 7: <MMOperationList.UNMMAP: 7>}
exception ducky.mm.MalformedBinaryError[source]

Bases: exceptions.Exception

class ducky.mm.MemoryController(machine, size=16777216)[source]

Bases: object

Memory controller handles all operations regarding main memory.

Parameters:
  • machine (ducky.machine.Machine) – virtual machine that owns this controller.
  • size (int) – size of memory, in bytes.
Raises:

ducky.errors.InvalidResourceError – when memory size is not multiple of ducky.mm.PAGE_SIZE.

_MemoryController__alloc_page(index)

Allocate new anonymous page for usage. The first available index is used.

Be aware that this method does NOT check if page is already allocated. If it is, it is just overwritten by new anonymous page.

Parameters:index (int) – index of requested page.
Returns:newly reserved page.
Return type:ducky.mm.AnonymousMemoryPage
_MemoryController__remove_page(pg)

Removes page object for a specific memory page.

Parameters:pg (ducky.mm.MemoryPage) – page to be removed
_MemoryController__set_page(pg)

Install page object for a specific memory page.

Parameters:pg (ducky.mm.MemoryPage) – page to be installed
Returns:installed page
Return type:ducky.mm.MemoryPage
alloc_page(base=None)[source]

Allocate new anonymous page for usage. The first available index is used.

Parameters:base (int) – if set, start searching pages from this address.
Returns:newly reserved page.
Return type:ducky.mm.AnonymousMemoryPage
Raises:ducky.errors.InvalidResourceError – when there is no available page.
alloc_pages(base=None, count=1)[source]

Allocate continuous sequence of anonymous pages.

Parameters:
  • base (u24) – if set, start searching pages from this address.
  • count (int) – number of requested pages.
Returns:

list of newly allocated pages.

Return type:

list of ducky.mm.AnonymousMemoryPage

Raises:

ducky.errors.InvalidResourceError – when there is no available sequence of pages.

alloc_specific_page(index)[source]

Allocate new anonymous page with specific index for usage.

Parameters:index (int) – allocate page with this particular index.
Returns:newly reserved page.
Return type:ducky.mm.AnonymousMemoryPage
Raises:ducky.errors.AccessViolationError – when page is already allocated.
boot()[source]

Prepare memory controller for immediate usage by other components.

free_page(page)[source]

Free memory page when it’s no longer needed.

Parameters:page (ducky.mm.MemoryPage) – page to be freed.
free_pages(page, count=1)[source]

Free a continuous sequence of pages when they are no longer needed.

Parameters:
get_page(index)[source]

Return memory page, specified by its index from the beginning of memory.

Parameters:index (int) – index of requested page.
Return type:ducky.mm.MemoryPage
Raises:ducky.errors.AccessViolationError – when requested page is not allocated.
get_pages(pages_start=0, pages_cnt=None, ignore_missing=False)[source]

Return list of memory pages.

Parameters:
  • pages_start (int) – index of the first page, 0 by default.
  • pages_cnt (int) – number of pages to get, number of all memory pages by default.
  • ignore_missing (bool) – if True, ignore missing pages, False by default.
Raises:

ducky.errors.AccessViolationError – when ignore_missing == False and there’s a missing page in requested range, this exception is rised.

Returns:

list of pages in area

Return type:

list of ducky.mm.MemoryPage

halt()[source]
load_state(state)[source]
pages_in_area(address=0, size=None, ignore_missing=False)[source]

Return list of memory pages.

Parameters:
  • address (u24) – beggining address of the area, by default 0.
  • size (u24) – size of the area, by default the whole memory size.
  • ignore_missing (bool) – if True, ignore missing pages, False by default.
Raises:

ducky.errors.AccessViolationError – when ignore_missing == False and there’s a missing page in requested range, this exception is rised.

Returns:

list of pages in area

Return type:

list of ducky.mm.MemoryPage

read_u16(addr)[source]
read_u32(addr)[source]
read_u8(addr)[source]
register_page(pg)[source]

Install page object for a specific memory page. This method is intended for external objects, e.g. device drivers to install their memory page objects to handle memory-mapped IO.

Parameters:pg (ducky.mm.MemoryPage) – page to be installed
Returns:installed page
Return type:ducky.mm.AnonymousMemoryPage
Raises:ducky.errors.AccessViolationError – when there is already allocated page
save_state(parent)[source]
unregister_page(pg)[source]

Remove page object for a specific memory page. This method is intende for external objects, e.g. device drivers to remove their memory page objects handling memory-mapped IO.

Parameters:pg (ducky.mm.MemoryPage) – page to be removed
Raises:ducky.errors.AccessViolationError – when there is no allocated page
write_u16(addr, value)[source]
write_u32(addr, value)[source]
write_u8(addr, value)[source]
class ducky.mm.MemoryPage(controller, index)[source]

Bases: object

Base class for all memory pages of any kinds.

Memory page has a set of boolean flags that determine access to and behavior of the page.

Flag Meaning Default
read page is readable by executed instructions False
write page is writable by executed instructions False
execute content of the page can be used as executable instructions False
dirty there have been write access to this page, its content has changed False
Parameters:
clear()[source]

Clear page.

This operation is implemented by child classes.

load_state(state)[source]

Restore page from a snapshot.

read_u16(offset)[source]

Read word.

This operation is implemented by child classes.

Parameters:offset (int) – offset of requested word.
Return type:int
read_u32(offset)[source]

Read longword.

This operation is implemented by child classes.

Parameters:offset (int) – offset of requested longword.
Return type:int
read_u8(offset)[source]

Read byte.

This operation is implemented by child classes.

Parameters:offset (int) – offset of requested byte.
Return type:int
save_state(parent)[source]

Create state of this page, and attach it to snapshot tree.

Parameters:parent (ducky.snapshot.SnapshotNode) – Parent snapshot node.
write_u16(offset, value)[source]

Write word.

This operation is implemented by child classes.

Parameters:
  • offset (int) – offset of requested word.
  • value (int) – value to write into memory.
write_u32(offset, value)[source]

Write longword.

This operation is implemented by child classes.

Parameters:
  • offset (int) – offset of requested longword.
  • value (int) – value to write into memory.
write_u8(offset, value)[source]

Write byte.

This operation is implemented by child classes.

Parameters:
  • offset (int) – offset of requested byte.
  • value (int) – value to write into memory.
class ducky.mm.MemoryPageState(*args, **kwargs)[source]

Bases: ducky.snapshot.SnapshotNode

class ducky.mm.MemoryRegion(mc, name, address, size, flags)[source]

Bases: ducky.interfaces.ISnapshotable, object

load_state(state)[source]
region_id = 0
save_state(parent)[source]
class ducky.mm.MemoryRegionState[source]

Bases: ducky.snapshot.SnapshotNode

class ducky.mm.MemoryState[source]

Bases: ducky.snapshot.SnapshotNode

get_page_states()[source]
ducky.mm.OFFSET_FMT(offset)[source]
ducky.mm.PAGE_SIZE = 256

Size of memory page, in bytes.

class ducky.mm.PageTableEntry[source]

Bases: ducky.util.Flags

DIRTY = 8
EXECUTE = 4
READ = 1
WRITE = 2
_flags = ['read', 'write', 'execute', 'dirty']
_labels = 'RWXD'
ducky.mm.SIZE_FMT(size)[source]
class ducky.mm.VirtualMemoryPage(controller, index)[source]

Bases: ducky.mm.MemoryPage

Memory page without any real storage backend.

save_state(parent)[source]
ducky.mm.addr_to_offset(addr)[source]
ducky.mm.addr_to_page(addr)[source]
ducky.mm.area_to_pages(addr, size)[source]