libguestrace

libguestrace — a library which allows programs to monitor the system calls serviced by a kernel running as a Xen guest.

Functions

Types and Values

typedef gt_reg_name_t
typedef gt_addr_t
typedef gt_pid_t
typedef gt_tid_t
typedef gt_reg_t
  GtCallbackRegistry
enum GtOSType
  GtGuestState
  GtLoop

Includes

#include <libguestrace/gt.h>

Description

A program using libguestrace registers callbacks which the guestrace event loop invokes when a system call occurs in the monitored guest operating system. Libguestrace builds upon libvmi, and it makes libvmi's lower-level facilities available from within a callback through its gt_guest_get_vmi_instance() and gt_guest_get_vmi_event() routines.

Example 1. Program which uses libguestrace to print open()s and read()s which occur on a Linux guest (error handling and other details omitted)

1
2
3
4
5
6
GLoop *loop = gt_loop_new("xen-guest-name");

gt_loop_set_cb(loop, "sys_open", open_cb, sysret_cb, NULL);
gt_loop_set_cb(loop, "sys_read", read_cb, sysret_cb, NULL);

gt_loop_run(loop);

Example 2. A simple open_cb() routine which prints the system-call's parameters

1
2
3
4
5
6
7
8
9
void *open_cb(GtGuestState *state, gt_pid_t pid, gt_tid_t tid, void *user_data)
{
       gt_addr_t addr = gt_guest_get_register(state, RDI);
       char *path     = gt_guest_get_string(state, addr);
       int flags      = gt_guest_get_register(state, RSI);
       int mode       = gt_guest_get_register(state, RDX);
       printf("%u called open(\"%s\", %i, %d)\n", pid, path, flags, mode);
       return NULL;
}

Functions

GtSyscallFunc ()

void *
(*GtSyscallFunc) (GtGuestState *state,
                  gt_pid_t pid,
                  gt_tid_t tid,
                  void *user_data);

Specifies one of the two types of functions passed to gt_loop_set_cb(). The guestrace event loop invokes this callback each time a program running on the guest invokes the corresponding system call. Implementations can optionally return a pointer which the guestrace event loop will later pass to the corresponding GtSysretFunc after the system call returns.

Parameters

vmi

the libvmi instance which abstracts the guest.

 

event

the event which abstracts the system call which caused the guestrace event loop to invoke this function.

 

pid

the ID of the process running when the event occurred.

 

tid

the unique ID of the thread running within the current process.

 

user_data

optional data which might have been passed to the corresponding gt_loop_set_cb(); if set, the guestrace event loop will pass it here.

 

GtSysretFunc ()

void
(*GtSysretFunc) (GtGuestState *state,
                 gt_pid_t pid,
                 gt_tid_t tid,
                 void *user_data);

Specifies one of the two types of functions passed to gt_loop_set_cb(). The guestrace event loop invokes this callback each time a system call on the guest returns control to a program. It is the responsibility of each GtSysretFunc implementation to free user_data if the corresponding GtSyscallFunc returned a pointer to a dynamically-allocated object.

Parameters

vmi

the libvmi instance which abstracts the guest.

 

event

the event which abstracts the system return which caused the guestrace event loop to invoke this function.

 

pid

the ID of the process running when the event occurred.

 

tid

the unique ID of the thread running within the current process.

 

user_data

the return value from GtSyscallFunc which the guestrace event loop passes to GtSysretFunc.

 

gt_loop_new ()

GtLoop *
gt_loop_new (const char *guest_name);

Creates a new GtLoop structure.

Parameters

guest_name

the name of a running guest virtual machine.

 

Returns

a new GtLoop.


gt_loop_get_ostype ()

GtOSType
gt_loop_get_ostype (GtLoop *loop);

Parameters

loop

a GtLoop.

 

Returns

the OS type of GtLoop.


gt_loop_get_guest_name ()

const char *
gt_loop_get_guest_name (GtLoop *loop);

Parameters

loop

a GtLoop.

 

Returns

the name of the guest to which GtLoop has attached. The GtLoop maintains ownership of the string. Thus the caller must not free the returned string.


gt_loop_get_vmi_instance ()

vmi_instance_t
gt_loop_get_vmi_instance (GtLoop *loop);

Returns the vmi_instance_t associated with loop . Refer to the libvmi documentation for a description of vmi_instance_t.

Parameters

loop

a pointer to a GtLoop.

 

gt_loop_set_cb ()

gboolean
gt_loop_set_cb (GtLoop *loop,
                const char *kernel_func,
                GtSyscallFunc syscall_cb,
                GtSysretFunc sysret_cb,
                void *user_data);

Sets the callback functions associated with kernel_func . Each time the guest kernel calls kernel_func to process a system call, the loop will invoke syscall_cb . When kernel_func returns, the loop will invoke sysret_cb . The loop passes user_data to syscall_cb , and it passes the return value from syscall_cb to sysret_cb .

Parameters

loop

a GtLoop.

 

kernel_func

the name of a function in the traced kernel which implements a system call.

 

syscall_cb

a GtSyscallFunc which will handle the named system call.

 

sysret_cb

a GtSysretFunc which will handle returns from the named system call, or NULL if the system call never returns.

 

user_data

optional data which the guestrace event loop will pass to each call of syscall_cb

 

Returns

TRUE on success, FALSE on failure; an invalid kernel_func will cause the callback registration to fail.


gt_loop_set_cbs ()

int
gt_loop_set_cbs (GtLoop *loop,
                 const GtCallbackRegistry callbacks[]);

A convenience function which repeatedly invokes gt_loop_set_cb for each callback defined in syscalls . The syscalls array must be terminated with a GtCallbackRegistry with each field set to NULL.

Parameters

loop

a GtLoop.

 

syscalls

an array of GtCallbackRegistry values, where each contains a function name and corresponding GtSyscallFunc and GtSysretFunc.

 

Returns

an integer which represents the number of callbacks successfully set; an invalid function name in syscalls will cause the corresponding callback registration to fail.


gt_loop_get_syscall_count ()

unsigned long
gt_loop_get_syscall_count (GtLoop *loop);

Parameters

loop

a GtLoop.

 

Returns

the number of system calls observed since attaching to the guest.


gt_loop_add_watch ()

guint
gt_loop_add_watch (GIOChannel *channel,
                   GIOCondition condition,
                   GIOFunc func,
                   gpointer user_data);

Adds a GIOChannel to the loop. The loop will call func each time one of the conditions specified in condition exists on channel , and it will pass user_data to func . This is useful for adding keyboard and other handlers to the loop.

Parameters

channel

a GIOChannel.

 

condition

the condition to watch for.

 

func

the function to call when the condition is satisfied.

 

user_data

user data to pass to func .

 

Returns

the event source ID.


gt_guest_get_register ()

gt_reg_t
gt_guest_get_register (GtGuestState *state,
                       gt_reg_name_t name);

Returns the value of the named register from the guest state.

Parameters

state

a pointer to a GtGuestState.

 

name

name of register to get.

 

gt_guest_get_bytes ()

size_t
gt_guest_get_bytes (GtGuestState *state,
                    gt_addr_t vaddr,
                    gt_pid_t pid,
                    void *buf,
                    size_t count);

Copies a sequence of up to count bytes which starts at vaddr into the memory starting at buf . Returns the number of bytes copied.

Parameters

state

a pointer to a GtGuestState.

 

vaddr

a virtual address from the guest's address space.

 

pid

PID of the virtual address space (0 for kernel).

 

buf

the data read from memory.

 

count

the number of bytes to read.

 

gt_guest_get_string ()

char *
gt_guest_get_string (GtGuestState *state,
                     gt_addr_t vaddr,
                     gt_pid_t pid);

Returns the NULL-terminated string which starts at vaddr or NULL on error. The caller must free the returned string.

Parameters

state

a pointer to a GtGuestState.

 

vaddr

a virtual address from the guest's address space.

 

pid

PID of the virtual address space (0 for kernel).

 

gt_guest_get_argv ()

char **
gt_guest_get_argv (GtGuestState *state,
                   gt_addr_t vaddr,
                   gt_pid_t pid);

Returns the NULL-terminated argv-style array which starts at vaddr or NULL on error. Each item in the array is a string. The caller must free the array and each string in the array.

Parameters

state

a pointer to a GtGuestState.

 

vaddr

a virtual address from the guest's address space.

 

pid

PID of the virtual address space (0 for kernel).

 

gt_guest_get_uint32 ()

status_t
gt_guest_get_uint32 (GtGuestState *state,
                     gt_addr_t vaddr,
                     gt_pid_t pid,
                     uint32_t *value);

Copies the 32-bit value at vaddr in the address space of pid to the address value .

Returns VMI_SUCCESS or some error code.

Parameters

state

a pointer to a GtGuestState.

 

vaddr

a virtual address from the guest's address space.

 

pid

PID of the virtual address space (0 for kernel).

 

value

address of location to which function will write value.

 

gt_guest_get_vmi_instance ()

vmi_instance_t
gt_guest_get_vmi_instance (GtGuestState *state);

Returns the vmi_instance_t associated with state . Refer to the libvmi documentation for a description of vmi_instance_t.

Parameters

state

a pointer to a GtGuestState.

 

gt_guest_get_vmi_event ()

vmi_event_t *
gt_guest_get_vmi_event (GtGuestState *state);

Returns the vmi_event_t associated with state . Refer to the libvmi documentation for a description of vmi_event_t.

Parameters

state

a pointer to a GtGuestState.

 

gt_guest_get_process_name ()

char *
gt_guest_get_process_name (GtGuestState *state);

Returns the process name associated with state . The caller must free the returned string.

Parameters

state

a pointer to a GtGuestState.

 

gt_guest_get_parent_pid ()

gt_pid_t
gt_guest_get_parent_pid (GtGuestState *state,
                         gt_pid_t pid,
                         gboolean *is_userspace);

Returns the PID of the parent of the process associated with state .

Parameters

state

a pointer to a GtGuestState.

 

gt_guest_hijack_return ()

void
gt_guest_hijack_return (GtGuestState *state,
                        reg_t retval);

This function manipulates the guest to hijack the current system call such that the system call does not execute and instead immediately returns retval . This function can only be called from within a GtSyscallFunc.

Parameters

state

a GtGuestState.

 

errno

a gint.

 

retval

a gint.

 

gt_guest_drop_return_breakpoint ()

void
gt_guest_drop_return_breakpoint (GtGuestState *state);

Drop the return breakpoint associated with this system call. Applications should call this in special cases, such as with clone/CLONE_VM on Linux. This function can only be called from within a GtSyscallFunc.

Parameters

state

a GtGuestState.

 

gt_guest_clear_return_state ()

void
gt_guest_clear_return_state (GtGuestState *state);

Free this and any other states associated with the process. Applications should call this when they know the instrumented function will never return, such as with pspexitthread on Windows. This function can only be called from within a GtSyscallFunc.

Parameters

state

a GtGuestState.

 

gt_loop_run ()

void
gt_loop_run (GtLoop *loop);

Uses libvmi to complete the preparations necessary to trace a guest's system calls. Runs loop until gt_loop_quit() is called on loop .

Parameters

loop

a GtLoop.

 

gt_loop_quit ()

void
gt_loop_quit (GtLoop *loop);

Stops loop from running. Any calls to gt_loop_run() for the loop will return. This removes any modifications to the guest's memory and allows the guest to run without instrumentation.

Parameters

loop

a GtLoop.

 

gt_loop_free ()

void
gt_loop_free (GtLoop *loop);

Free loop and its associated memory. If the loop is currently running, then gt_loop_quit() must first terminate the loop and remove the guest instrumentation.

Parameters

loop

a GtLoop.

 

gt_loop_jmp_past_cb ()

void
gt_loop_jmp_past_cb (GtLoop *loop);

Skip over the syscall/sysret handler, usually to gracefully exit after receiving a fatal signal. A typical use is to call gt_loop_quit() and gt_loop_jmp_past_cb() from a program's SIGSEGV handler.

Parameters

loop

a pointer to a GtLoop.

 

Types and Values

gt_reg_name_t

typedef int gt_reg_name_t;

The gt_reg_name_t enum contains the valid names of the registers found on the guest.


gt_addr_t

typedef addr_t    gt_addr_t;

A guest virtual memory address.


gt_pid_t

typedef vmi_pid_t gt_pid_t;

The unique identifier for a guest process.


gt_tid_t

typedef addr_t    gt_tid_t;

The unique identifier for a guest thread. An identifier which serves to correlate between calls and returns at thread granularity.


gt_reg_t

typedef reg_t     gt_reg_t;

The value of some guest register.


GtCallbackRegistry

typedef struct {
} GtCallbackRegistry;

Full callback definition for use with gt_loop_set_cbs().

Members


enum GtOSType

Enum values which specify the operating system running on the guest.

Members

GT_OS_UNKNOWN

an unknown operating system.

 

GT_OS_WINDOWS

a Windows operating system.

 

GT_OS_LINUX

a Linux operating system.

 

GtGuestState

typedef struct {
} GtGuestState;

The GtGuestState struct is an opaque data type representing the state of the instrumented guest.


GtLoop

typedef struct {
} GtLoop;

The GtLoop struct is an opaque data type representing the main event loop of a guestrace application.