pyplugins.apis.kffi module

KFFI API Plugin

This module provides the KFFI (Kernel Foreign Function Interface) plugin for the Penguin framework. It enables calling kernel-space functions and interacting with kernel memory from user-space plugins. The KFFI plugin abstracts low-level kernel function invocation, argument marshalling, and result handling, allowing other plugins to perform advanced kernel introspection and manipulation.

Features

  • Call arbitrary kernel functions with specified arguments.

  • Read and write kernel memory.

  • Marshal arguments and results between user-space and kernel-space.

  • Supports type-safe function signatures and return values.

  • Compile and inject dynamic C-structs/typedefs on the fly using DWARFFI.

Example usage

from penguin import plugins

# Call a kernel function (e.g., do_sys_open) with arguments
result = yield from plugins.kffi.call_function("do_sys_open", "/etc/passwd", 0, 0)

# Read kernel memory at a specific address
data = yield from plugins.kffi.read_kernel_memory(0xffff888000000000, 64)

# Write to kernel memory
yield from plugins.kffi.write_kernel_memory(0xffff888000000000, b"")

# Load a custom struct layout into the emulator's architecture
plugins.kffi.cdef("struct my_payload { int a; char b[10]; };")
class pyplugins.apis.kffi.KFFI[source]

Bases: Plugin

KFFI Plugin

Provides methods for calling kernel functions and interacting with kernel memory.

Methods

  • call_function: Call a kernel function with arguments.

call(func, *args)[source]
Parameters:
  • func (int | str)

  • args (Any)

Return type:

Generator[Any, Any, Any]

call_kernel_function(func, *args)[source]

Call a kernel function dynamically with the given arguments.

This uses the FFI mechanism to directly call kernel functions. CAUTION: This is extremely powerful and can easily crash the kernel if used incorrectly. Only call functions that are safe to call from arbitrary contexts.

Args:

func (int or str): Function address or name. *args (Any): Arguments to pass to the function (max 8).

Returns:

Any: Return value from the kernel function, or None if call fails.

Note:

This leaks memory. We should have a better policy on that.

Parameters:
  • func (int | str)

  • args (Any)

Return type:

Generator[Any, Any, Any]

callback(func)[source]

Register a trampoline callback and return an integer guest virtual address.

Immediately generates the trampoline, sets up the interrupt handler, and returns an integer address.

Return type:

Generator[Any, Any, Any]

cdef(source)[source]

Compile C definitions on the fly and load them into DWARFFI. Automatically handles architecture-specific compiler flags, musl headers, and caches the ISF output to speed up subsequent runs.

Args:

source (str): The C code containing structs/enums/typedefs to compile.

Parameters:

source (str)

Return type:

None

deref(ptr)[source]

Dereference a pointer to a type.

Args:

ptr (Ptr): Pointer object.

Returns:

Any: Value pointed to, or None if pointer is null.

Parameters:

ptr (Ptr)

Return type:

Generator[Any, Any, Any]

from_buffer(type_, buf, instance_offset_in_buffer=0)[source]

Create an instance of a type from a buffer.

Args:

type_ (str): Name of the type. buf (bytes): Buffer containing the data. instance_offset_in_buffer (int): Offset in buffer (default: 0).

Returns:

Any: Instance of the type.

Parameters:
  • type_ (str)

  • buf (bytes)

  • instance_offset_in_buffer (int)

Return type:

Any

generate_trampoline()[source]

Request a trampoline from the kernel via portal.

Returns:

dict: Keys include tramp_id, tramp_addr, and status.

Return type:

Generator[Any, Any, Any]

get_callback_id(f)[source]

Get the trampoline ID for a registered callback function or trampoline address.

Args:

f (int | Any): Callback function or trampoline address.

Returns:

Optional[int]: Trampoline ID, or None if not found.

Parameters:

f (int | Any)

Return type:

int | None

get_enum_dict(enum_name)[source]

Get dictionary of enum constants.

Args:

enum_name (str): Name of the enum.

Returns:

Wrapper: Wrapper containing enum constants.

Parameters:

enum_name (str)

Return type:

Wrapper

get_field_casted(struct, field)[source]

Get a field from a struct, casted to its declared CFFI type.

Args:

struct (Any): Struct instance. field (str): Field name.

Returns:

Any: Field value, or None if error occurs.

Parameters:
  • struct (Any)

  • field (str)

Return type:

Any

get_function_address(function)[source]

Get the address of a kernel function.

Args:

function (str): Name of the function.

Returns:

Optional[int]: Address of the function, or None if not found.

Parameters:

function (str)

Return type:

int | None

get_struct_size(struct_name)[source]

Get the size of a struct.

Args:

struct_name (str): Name of the struct.

Returns:

Optional[int]: Size of the struct, or None if not found.

Parameters:

struct_name (str)

Return type:

int | None

kallsyms_lookup(symbol)[source]

Look up a kernel symbol address using the kallsyms_lookup portal operation (simplified).

Args:

symbol (str): Name of the symbol to look up.

Returns:

Any: Address of the symbol as int, or None if not found.

Parameters:

symbol (str)

Return type:

Generator[Any, Any, Any]

kfree(addr)[source]

Free memory in the kernel using kfree.

Args:

addr (int): Address of memory to free.

Returns:

None

Parameters:

addr (int)

Return type:

Generator[Any, Any, Any]

kmalloc(size)[source]

Allocate memory in the kernel using kmalloc.

Args:

size (int): Size of memory to allocate.

Returns:

Any: Address of allocated memory, or None if allocation fails.

Parameters:

size (int)

Return type:

Generator[Any, Any, Any]

new(type_, init=None)[source]

Create a new instance of a type.

Args:

type_ (str): Name of the type. init (Any): Initial value for the instance (optional).

Returns:

Any: Instance of the type, or None if type not found.

Parameters:
  • type_ (str)

  • init (Any | None)

Return type:

Any

read_type(addr, type_)[source]

Read a type from kernel memory.

Args:

addr (int): Address to read from. type_ (str): Name of the type.

Returns:

Any: Instance of the type, or None if read fails.

Parameters:
  • addr (int)

  • type_ (str)

Return type:

Generator[Any, Any, Any]

read_type_panda(cpu, addr, type_)[source]

Read a type from kernel memory using PANDA.

Args:

cpu (Any): CPU context. addr (int): Address to read from. type_ (str): Name of the type.

Returns:

Any: Instance of the type, or None if read fails.

Parameters:
  • cpu (Any)

  • addr (int)

  • type_ (str)

Return type:

Any

ref(thing)[source]

Gets the address of an ffi type’d object (usually a struct)

Args:

thing (Any): Object.

Returns:

int: The address, or None if no address attribute.

Parameters:

thing (Any)

Return type:

int | None

sizeof(struct_name)[source]

Alias for get_struct_size.

Args:

struct_name (str): Name of the struct.

Returns:

Optional[int]: Size of the struct, or None if not found.

Parameters:

struct_name (str)

Return type:

int | None