Skip to content

Commit

Permalink
feat: provide interface frida.Device
Browse files Browse the repository at this point in the history
  • Loading branch information
NSEcho authored Jan 25, 2024
2 parents ef5b483 + b923faf commit 6e73be3
Show file tree
Hide file tree
Showing 4 changed files with 71 additions and 40 deletions.
37 changes: 34 additions & 3 deletions frida/device.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,38 @@ import (
"unsafe"
)

// Device represents FridaDevice struct from frida-core
type DeviceInt interface {
ID() string
Name() string
DeviceIcon() any
Bus() *Bus
Manager() *DeviceManager
IsLost() bool
Params() (map[string]any, error)
FrontmostApplication(scope Scope) (*Application, error)
EnumerateApplications(identifier string, scope Scope) ([]*Application, error)
ProcessByPID(pid int, scope Scope) (*Process, error)
ProcessByName(name string, scope Scope) (*Process, error)
FindProcessByPID(pid int, scope Scope) (*Process, error)
FindProcessByName(name string, scope Scope) (*Process, error)
EnumerateProcesses(scope Scope) ([]*Process, error)
EnableSpawnGating() error
DisableSpawnGating() error
EnumeratePendingSpawn() ([]*Spawn, error)
EnumeratePendingChildren() ([]*Child, error)
Spawn(name string, opts *SpawnOptions) (int, error)
Input(pid int, data []byte) error
Resume(pid int) error
Kill(pid int) error
Attach(val any, opts *SessionOptions) (*Session, error)
InjectLibraryFile(target any, path, entrypoint, data string) (uint, error)
InjectLibraryBlob(target any, byteData []byte, entrypoint, data string) (uint, error)
OpenChannel(address string) (*IOStream, error)
Clean()
On(sigName string, fn any)
}

// Device represents Device struct from frida-core
type Device struct {
device *C.FridaDevice
}
Expand Down Expand Up @@ -62,10 +93,10 @@ func (d *Device) Bus() *Bus {
}

// Manager returns device manager for the device.
func (d *Device) Manager() DeviceManager {
func (d *Device) Manager() *DeviceManager {
if d.device != nil {
mgr := C.frida_device_get_manager(d.device)
return &deviceManager{mgr}
return &DeviceManager{mgr}
}
return nil
}
Expand Down
10 changes: 5 additions & 5 deletions frida/frida.go
Original file line number Diff line number Diff line change
Expand Up @@ -34,14 +34,14 @@ func Version() string {
return C.GoString(C.frida_version_string())
}

func getDeviceManager() DeviceManager {
func getDeviceManager() *DeviceManager {
v, ok := data.Load("mgr")
if !ok {
mgr := NewDeviceManager()
data.Store("mgr", mgr)
return mgr
}
return v.(DeviceManager)
return v.(*DeviceManager)
}

// LocalDevice is a wrapper around DeviceByType(DeviceTypeLocal).
Expand All @@ -51,7 +51,7 @@ func LocalDevice() *Device {
if !ok {
dev, _ := mgr.DeviceByType(DeviceTypeLocal)
data.Store("localDevice", dev)
return dev
return dev.(*Device)
}
return v.(*Device)
}
Expand All @@ -71,7 +71,7 @@ func USBDevice() *Device {
return nil
}
data.Store("usbDevice", dev)
return dev
return dev.(*Device)
}
return v.(*Device)
}
Expand All @@ -91,7 +91,7 @@ func DeviceByID(id string) (*Device, error) {
return nil, err
}
data.Store(id, dev)
return dev, nil
return v.(*Device), nil
}
return v.(*Device), nil
}
Expand Down
62 changes: 31 additions & 31 deletions frida/manager.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,39 @@ import "C"

import "unsafe"

// DeviceManager is the device DeviceManager interface
type DeviceManager interface {
// DeviceManagerInt is the device DeviceManagerInt interface
type DeviceManagerInt interface {
Close() error
EnumerateDevices() ([]*Device, error)
LocalDevice() (*Device, error)
USBDevice() (*Device, error)
RemoteDevice() (*Device, error)
DeviceByID(id string) (*Device, error)
DeviceByType(devType DeviceType) (*Device, error)
FindDeviceByID(id string) (*Device, error)
FindDeviceByType(devType DeviceType) (*Device, error)
AddRemoteDevice(address string, remoteOpts *RemoteDeviceOptions) (*Device, error)
EnumerateDevices() ([]DeviceInt, error)
LocalDevice() (DeviceInt, error)
USBDevice() (DeviceInt, error)
RemoteDevice() (DeviceInt, error)
DeviceByID(id string) (DeviceInt, error)
DeviceByType(devType DeviceType) (DeviceInt, error)
FindDeviceByID(id string) (DeviceInt, error)
FindDeviceByType(devType DeviceType) (DeviceInt, error)
AddRemoteDevice(address string, remoteOpts *RemoteDeviceOptions) (DeviceInt, error)
RemoveRemoteDevice(address string) error
Clean()
On(sigName string, fn any)

getManager() *C.FridaDeviceManager
}

// deviceManager is the main structure which holds on devices available to Frida
// Single instance of the deviceManager is created when you call frida.Attach() or frida.LocalDevice().
type deviceManager struct {
// DeviceManager is the main structure which holds on devices available to Frida
// Single instance of the DeviceManager is created when you call frida.Attach() or frida.LocalDevice().
type DeviceManager struct {
manager *C.FridaDeviceManager
}

// NewDeviceManager returns new frida device manager.
func NewDeviceManager() DeviceManager {
func NewDeviceManager() *DeviceManager {
manager := C.frida_device_manager_new()
return &deviceManager{manager}
return &DeviceManager{manager}
}

// Close method will close current manager.
func (d *deviceManager) Close() error {
func (d *DeviceManager) Close() error {
var err *C.GError
C.frida_device_manager_close_sync(d.manager, nil, &err)
if err != nil {
Expand All @@ -47,15 +47,15 @@ func (d *deviceManager) Close() error {
}

// EnumerateDevices will return all connected devices.
func (d *deviceManager) EnumerateDevices() ([]*Device, error) {
func (d *DeviceManager) EnumerateDevices() ([]DeviceInt, error) {
var err *C.GError
deviceList := C.frida_device_manager_enumerate_devices_sync(d.manager, nil, &err)
if err != nil {
return nil, &FError{err}
}

numDevices := int(C.frida_device_list_size(deviceList))
devices := make([]*Device, numDevices)
devices := make([]DeviceInt, numDevices)

for i := 0; i < numDevices; i++ {
device := C.frida_device_list_get(deviceList, C.gint(i))
Expand All @@ -67,23 +67,23 @@ func (d *deviceManager) EnumerateDevices() ([]*Device, error) {
}

// LocalDevice returns the device with type DeviceTypeLocal.
func (d *deviceManager) LocalDevice() (*Device, error) {
func (d *DeviceManager) LocalDevice() (DeviceInt, error) {
return d.DeviceByType(DeviceTypeLocal)
}

// USBDevice returns the device with type DeviceTypeUsb.
func (d *deviceManager) USBDevice() (*Device, error) {
func (d *DeviceManager) USBDevice() (DeviceInt, error) {
return d.DeviceByType(DeviceTypeUsb)
}

// RemoteDevice returns the device with type DeviceTypeRemote.
func (d *deviceManager) RemoteDevice() (*Device, error) {
func (d *DeviceManager) RemoteDevice() (DeviceInt, error) {
return d.DeviceByType(DeviceTypeRemote)
}

// DeviceByID will return device with id passed or an error if it can't find any.
// Note: the caller must call EnumerateDevices() to get devices that are of type usb
func (d *deviceManager) DeviceByID(id string) (*Device, error) {
func (d *DeviceManager) DeviceByID(id string) (DeviceInt, error) {
idC := C.CString(id)
defer C.free(unsafe.Pointer(idC))

Expand All @@ -99,7 +99,7 @@ func (d *deviceManager) DeviceByID(id string) (*Device, error) {

// DeviceByType will return device or an error by device type specified.
// Note: the caller must call EnumerateDevices() to get devices that are of type usb
func (d *deviceManager) DeviceByType(devType DeviceType) (*Device, error) {
func (d *DeviceManager) DeviceByType(devType DeviceType) (DeviceInt, error) {
var err *C.GError
device := C.frida_device_manager_get_device_by_type_sync(d.manager,
C.FridaDeviceType(devType),
Expand All @@ -114,7 +114,7 @@ func (d *deviceManager) DeviceByType(devType DeviceType) (*Device, error) {

// FindDeviceByID will try to find the device by id specified
// Note: the caller must call EnumerateDevices() to get devices that are of type usb
func (d *deviceManager) FindDeviceByID(id string) (*Device, error) {
func (d *DeviceManager) FindDeviceByID(id string) (DeviceInt, error) {
devID := C.CString(id)
defer C.free(unsafe.Pointer(devID))

Expand All @@ -135,7 +135,7 @@ func (d *deviceManager) FindDeviceByID(id string) (*Device, error) {

// FindDeviceByType will try to find the device by device type specified
// Note: the caller must call EnumerateDevices() to get devices that are of type usb
func (d *deviceManager) FindDeviceByType(devType DeviceType) (*Device, error) {
func (d *DeviceManager) FindDeviceByType(devType DeviceType) (DeviceInt, error) {
timeout := C.gint(defaultDeviceTimeout)

var err *C.GError
Expand All @@ -152,7 +152,7 @@ func (d *deviceManager) FindDeviceByType(devType DeviceType) (*Device, error) {
}

// AddRemoteDevice add a remote device from the provided address with remoteOpts populated
func (d *deviceManager) AddRemoteDevice(address string, remoteOpts *RemoteDeviceOptions) (*Device, error) {
func (d *DeviceManager) AddRemoteDevice(address string, remoteOpts *RemoteDeviceOptions) (DeviceInt, error) {
addressC := C.CString(address)
defer C.free(unsafe.Pointer(addressC))

Expand All @@ -166,7 +166,7 @@ func (d *deviceManager) AddRemoteDevice(address string, remoteOpts *RemoteDevice
}

// RemoveRemoteDevice removes remote device available at address
func (d *deviceManager) RemoveRemoteDevice(address string) error {
func (d *DeviceManager) RemoveRemoteDevice(address string) error {
addressC := C.CString(address)
defer C.free(unsafe.Pointer(addressC))

Expand All @@ -182,7 +182,7 @@ func (d *deviceManager) RemoveRemoteDevice(address string) error {
}

// Clean will clean the resources held by the manager.
func (d *deviceManager) Clean() {
func (d *DeviceManager) Clean() {
clean(unsafe.Pointer(d.manager), unrefFrida)
}

Expand All @@ -193,10 +193,10 @@ func (d *deviceManager) Clean() {
// - "added" with callback as func(device *frida.Device) {}
// - "removed" with callback as func(device *frida.Device) {}
// - "changed" with callback as func() {}
func (d *deviceManager) On(sigName string, fn any) {
func (d *DeviceManager) On(sigName string, fn any) {
connectClosure(unsafe.Pointer(d.manager), sigName, fn)
}

func (d *deviceManager) getManager() *C.FridaDeviceManager {
func (d *DeviceManager) getManager() *C.FridaDeviceManager {
return d.manager
}
2 changes: 1 addition & 1 deletion frida/portal_service.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ func NewPortal(clusterParams, controlParams *EndpointParameters) *Portal {
}

// Device returns portal device.
func (p *Portal) Device() *Device {
func (p *Portal) Device() DeviceInt {
dev := C.frida_portal_service_get_device(p.portal)
return &Device{dev}
}
Expand Down

0 comments on commit 6e73be3

Please sign in to comment.