pyplugins.interventions.hyperfile module

HyperFile Plugin

This module implements the HyperFile plugin for the Penguin framework, enabling hypercall-based file operations between a guest and the host. It provides a model for virtual files that can be read, written, or controlled via ioctl/getattr operations from the guest OS. The plugin is designed to be flexible and extensible, allowing users to specify custom file behaviors via models.

Features

  • Handles hypercalls for file operations (read, write, ioctl, getattr)

  • Supports dynamic file models for custom device/file behaviors

  • Logs and tracks file operation results for analysis

  • Provides default behaviors for unhandled operations

Example Usage

from pyplugins.interventions.hyperfile import HyperFile

# Register the plugin with Penguin, specifying file models and log file
plugin = HyperFile()

File Model Example

files = {
    "/dev/zero": {
        fops.HYP_READ: HyperFile.read_zero,
        fops.HYP_WRITE: HyperFile.write_discard,
        "size": 0,
    }
}

Classes

  • HyperFile: Main plugin class implementing the hypercall interface.

Functions

  • hyper(name: str) -> int: Map operation name to hyperfile operation constant.

  • hyper2name(num: int) -> str: Map hyperfile operation constant to operation name.

class pyplugins.interventions.hyperfile.HyperFile[source]

Bases: Plugin

The HyperFile plugin implements a virtual file interface for the guest OS, allowing the guest to perform file operations via hypercalls.

Attributes - arch_bytes (int): Number of bytes per architecture word. - log_file (Optional[str]): Path to the log file for operation results. - files (Optional[Dict[str, Dict]]): File models for virtual devices. - logger (Any): Logger instance. - endian (str): Endianness format for struct packing. - s_word, u_word (str): Signed/unsigned word format for struct packing. - results (Dict): Stores results of file operations for logging. - default_model (Dict): Default model for unhandled file operations.

static getattr(device_name, model)[source]

Handle a getattr operation, returning the file size.

Parameters - device_name (str): Device name. - model (Dict[str, Any]): File model dictionary.

Returns - Tuple[int, int]: (Return value, file size)

Parameters:
  • device_name (str)

  • model (Dict[str, Any])

Return type:

Tuple[int, int]

handle_file_op(cpu)[source]

Handle a file operation hypercall (read, write, ioctl, getattr).

Parameters - cpu (Any): The CPU context from Panda.

Returns - None

Parameters:

cpu (Any)

Return type:

None

handle_get_hyperfile_paths(cpu)[source]

Handle the hypercall to get the paths of all hyperfiles.

Parameters - cpu (Any): The CPU context from Panda.

Returns - None

Parameters:

cpu (Any)

Return type:

None

handle_get_num_hyperfiles(cpu)[source]

Handle the hypercall to get the number of hyperfiles.

Parameters - cpu (Any): The CPU context from Panda.

Returns - None

Parameters:

cpu (Any)

Return type:

None

handle_result(device_name, event, retval, *data)[source]

Record the result of a file operation for logging and analysis.

Parameters - device_name (str): The name of the device/file. - event (str): The event type (“read”, “write”, “ioctl”, “getattr”). - retval (int): The return value of the operation. - *data (Any): Additional data relevant to the event.

Returns - None

Parameters:
  • device_name (str)

  • event (str)

  • retval (int)

  • data (Any)

Return type:

None

static ioctl(devname, cmd, arg)[source]

Handle an ioctl operation (default: always succeeds).

Parameters - devname (str): Device name. - cmd (int): IOCTL command. - arg (int): IOCTL argument.

Returns - int: Return value (0 for success).

Parameters:
  • devname (str)

  • cmd (int)

  • arg (int)

Return type:

int

static ioctl_unhandled(devname, cmd, arg)[source]

Handle an unhandled ioctl operation.

Parameters - devname (str): Device name. - cmd (int): IOCTL command. - arg (int): IOCTL argument.

Returns - int: Return value (-25 for ENOTTY).

Parameters:
  • devname (str)

  • cmd (int)

  • arg (int)

Return type:

int

static read_unhandled(filename, buffer, length, offset)[source]

Handle an unhandled read operation.

Parameters - filename (str): File name. - buffer (int): Guest buffer address. - length (int): Number of bytes to read. - offset (int): Offset into the file.

Returns - Tuple[bytes, int]: (Empty bytes, -22 for EINVAL)

Parameters:
  • filename (str)

  • buffer (int)

  • length (int)

  • offset (int)

Return type:

Tuple[bytes, int]

static read_zero(devname, buffer, length, offset)[source]

Return a buffer of zero bytes for read operations.

Parameters - devname (str): Device name. - buffer (int): Guest buffer address. - length (int): Number of bytes to read. - offset (int): Offset into the file.

Returns - Tuple[bytes, int]: (Data read, number of bytes read)

Parameters:
  • devname (str)

  • buffer (int)

  • length (int)

  • offset (int)

Return type:

Tuple[bytes, int]

uninit()[source]

Dump the results to the log file on plugin unload.

Returns - None

Return type:

None

static write_discard(devname, buffer, length, offset, contents)[source]

Discard written data and return the number of bytes written.

Parameters - devname (str): Device name. - buffer (int): Guest buffer address. - length (int): Number of bytes to write. - offset (int): Offset into the file. - contents (bytes): Data to write.

Returns - int: Number of bytes written.

Parameters:
  • devname (str)

  • buffer (int)

  • length (int)

  • offset (int)

  • contents (bytes)

Return type:

int

static write_unhandled(filename, buffer, length, offset, contents)[source]

Handle an unhandled write operation.

Parameters - filename (str): File name. - buffer (int): Guest buffer address. - length (int): Number of bytes to write. - offset (int): Offset into the file. - contents (bytes): Data to write.

Returns - int: Return value (-22 for EINVAL).

Parameters:
  • filename (str)

  • buffer (int)

  • length (int)

  • offset (int)

  • contents (bytes)

Return type:

int

pyplugins.interventions.hyperfile.hyper(name)[source]

Map a string operation name to its corresponding hyperfile operation constant.

Parameters - name (str): The operation name (“read”, “write”, “ioctl”, “getattr”).

Returns - int: The corresponding hyperfile operation constant.

Raises - ValueError: If the operation name is unknown.

Parameters:

name (str)

Return type:

int

pyplugins.interventions.hyperfile.hyper2name(num)[source]

Map a hyperfile operation constant to its string operation name.

Parameters - num (int): The hyperfile operation constant.

Returns - str: The operation name.

Raises - ValueError: If the operation constant is unknown.

Parameters:

num (int)

Return type:

str