XDK Device Module

enum class RipAction

Enum representing the possible actions for RIP control.

Values:

enumerator Jmp
enumerator Call
enumerator Ret
struct CallLog
#include <xdk_device.h>

Structure to hold information about a kernel function call log.

Public Members

std::string function_name

The name of the function that was called.

std::vector<uint64_t> arguments

A vector of arguments passed to the function.

uint64_t return_value

The return value of the function.

std::string call_stack

The call stack at the time of the function call.

class XdkDevice
#include <xdk_device.h>

Manages communication and data for the XDK device.

Class representing the interface to the xdk kernel module.

Public Functions

XdkDevice()

Constructor for the XdkDevice class.

Throws:

ExpKitError – if the xdk device cannot be opened.

xdk_error Call(enum xdk_cmd cmd, void *arg, xdk_error expected_error) const

Calls a xdk command and checks the error code.

Parameters:
  • cmd – The command to call.

  • arg – The argument to the command.

  • expected_error – The expected error code if the command is not successful.

Throws:

ExpKitError – if the command was not successful and did not return with expected_error.

void Call(enum xdk_cmd cmd, void *arg) const

Calls a xdk command expecting success.

Parameters:
  • cmd – The command to call.

  • arg – The argument to the command.

Throws:

ExpKitError – if the command was not successful.

uint64_t AllocBuffer(uint64_t size, bool gfp_account) const

Allocates a buffer in kernel space.

Parameters:
  • size – The size of the buffer to allocate.

  • gfp_account – Whether to account for GFP_KERNEL allocations.

Returns:

The kernel address of the allocated buffer.

uint64_t AllocBuffer(const std::vector<uint8_t> &data, bool gfp_account) const

Allocates a buffer in kernel space and copies data into it.

Parameters:
  • data – The data to copy into the buffer.

  • gfp_account – Whether to account for GFP_KERNEL allocations.

Returns:

The kernel address of the allocated buffer.

std::vector<uint8_t> Read(uint64_t ptr, uint64_t size) const

Reads data from kernel space.

Parameters:
  • ptr – The kernel address to read from.

  • size – The number of bytes to read.

void Write(uint64_t ptr, const std::vector<uint8_t> &data) const

Writes data to kernel space.

Parameters:
  • ptr – The kernel address to write to.

  • data – The data to write.

void Kfree(uint64_t ptr) const

Frees a kernel buffer.

Parameters:

ptr – The kernel address of the buffer to free.

void Printk(const char *msg) const

Prints a message to the kernel log.

Parameters:

msg – The message to print.

uint64_t KaslrLeak()

Gets the KASLR base address.

Returns:

The KASLR base address.

uint64_t WinTarget()

Gets the address of the win target function.

If the win target is called (e.g. via ROP chain), then it sets a win flag in the kernel which can be checked with the CheckWin() function.

Returns:

The address of the win target function.

std::optional<uint64_t> SymAddrOpt(const char *name)

Gets the address of a kernel symbol if it exists in kallsyms.

Parameters:

name – The name of the symbol.

Returns:

An optional containing the address of the symbol if found, otherwise an empty optional.

uint64_t SymAddr(const char *name)

Gets the address of a kernel symbol if it exists in kallsyms.

Parameters:

name – The name of the symbol.

Throws:

ExpKitError – if the symbol was not found in kallsyms.

Returns:

The address of the symbol.

void RipControl(const rip_control_args &args)

Controls the RIP and other registers in the kernel.

Parameters:

args – The arguments for controlling the RIP and registers.

void RipControl(RipAction action, const std::map<Register, uint64_t> &regs = {})

Controls the RIP and other registers in the kernel.

Parameters:
  • action – The action to perform (Jump, Call, or Return).

  • regs – A map of registers to set and their values.

void CallAddr(uint64_t addr, const std::map<Register, uint64_t> &regs = {})

Calls a kernel function at a specific address (with the “call” asm call).

Parameters:
  • addr – The address of the function to call.

  • regs – A map of registers to set before the call.

void JumpToAddr(uint64_t addr, const std::map<Register, uint64_t> &regs = {})

Jumps to a specific address in the kernel (with the “jmp” asm call).

Parameters:
  • addr – The address to jump to.

  • regs – A map of registers to set before the jump.

void SetRspAndRet(uint64_t new_rsp, const std::map<Register, uint64_t> &regs = {})

Sets the RSP and performs a return (“mov rsp, <new_rsp>; ret”).

Parameters:
  • new_rsp – The new value for the RSP.

  • regs – A map of registers to set before the return.

uint64_t GetRipControlRecoveryAddr()

Gets the recovery address for RIP control.

Returns:

The recovery address.

Kprobe *InstallKprobe(const char *function_name, uint8_t arg_count = 0, enum kprobe_log_mode log_mode = (kprobe_log_mode)(ENTRY_WITH_CALLSTACK | RETURN), const char *log_call_stack_filter = nullptr)

Installs a Kprobe in the kernel.

Parameters:
  • function_name – The name of the function to probe.

  • arg_count – The number of arguments to log (default is 0).

  • log_mode – The logging mode (default is ENTRY_WITH_CALLSTACK | RETURN).

  • log_call_stack_filter – An optional filter for the call stack (default is nullptr which means no call stack filtering, all calls are recorded).

Returns:

A pointer to the installed Kprobe object.

void RemoveKprobe(Kprobe *probe)

Removes an installed Kprobe.

Parameters:

probe – A pointer to the Kprobe object to remove.

void PrintAllCallLog(bool clear_log = false)

Prints the call logs for all installed Kprobes.

Parameters:

clear_log – Whether to clear the logs after printing (default is false).

void CheckWin()

Checks if the win target has been called.

void Close()

Closes the connection to the xdk device and removes all installed Kprobes.

Public Static Functions

static bool IsAvailable()

Checks if the xdk device is available.

Returns:

True if the device exists, false otherwise.

class Kprobe
#include <xdk_device.h>

Class representing a Kprobe in the kernel.

Public Functions

Kprobe(const char *function_name, uint8_t arg_count = 0, enum kprobe_log_mode log_mode = (kprobe_log_mode)(ENTRY_WITH_CALLSTACK | RETURN), const char *log_call_stack_filter = nullptr)

Constructor for the Kprobe class.

Parameters:
  • function_name – The name of the function to probe.

  • arg_count – The number of arguments to log (default is 0).

  • log_mode – The logging mode (default is ENTRY_WITH_CALLSTACK | RETURN).

  • log_call_stack_filter – An optional filter for the call stack (default is nullptr).

std::vector<CallLog> GetCallLogs(bool clear_log = false)

Retrieves the call logs for this Kprobe.

Parameters:

clear_log – Whether to clear the log after retrieving (default is false).

Returns:

A vector of CallLog structures.

void PrintCallLog(bool clear_log = false)

Prints the call logs for this Kprobe to the console.

Parameters:

clear_log – Whether to clear the log after printing (default is false).

~Kprobe()

Destructor for the Kprobe class.