Skip to content

Commit

Permalink
device: Add open_service() and Service API
Browse files Browse the repository at this point in the history
Co-authored-by: Håvard Sørbø <[email protected]>
  • Loading branch information
oleavr and hsorbo committed May 29, 2024
1 parent a549a77 commit 55b38df
Show file tree
Hide file tree
Showing 9 changed files with 317 additions and 0 deletions.
8 changes: 8 additions & 0 deletions examples/open_service/dtx/deviceinfo.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import frida

Check failure on line 1 in examples/open_service/dtx/deviceinfo.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import pprint

device = frida.get_usb_device()

deviceinfo = device.open_service("dtx:com.apple.instruments.server.services.deviceinfo")
response = deviceinfo.request({"method": "runningProcesses"})
pprint.pp(response)
26 changes: 26 additions & 0 deletions examples/open_service/dtx/opengl.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import frida

Check failure on line 1 in examples/open_service/dtx/opengl.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import sys


def on_message(message):
print("on_message:", message)


device = frida.get_usb_device()

opengl = device.open_service("dtx:com.apple.instruments.server.services.graphics.opengl")
opengl.on("message", on_message)
opengl.request(
{
"method": "setSamplingRate:",
"args": [5.0],
}
)
opengl.request(
{
"method": "startSamplingAtTimeInterval:",
"args": [0.0],
}
)

sys.stdin.read()
35 changes: 35 additions & 0 deletions examples/open_service/dtx/processcontrol.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import frida

Check failure on line 1 in examples/open_service/dtx/processcontrol.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import sys


def on_close():
print("on_close")


def on_message(message):
print("on_message:", message)


device = frida.get_usb_device()

processcontrol = device.open_service("dtx:com.apple.instruments.server.services.processcontrol")
processcontrol.on("close", on_close)
processcontrol.on("message", on_message)
pid = processcontrol.request(
{
"method": "launchSuspendedProcessWithDevicePath:bundleIdentifier:environment:arguments:options:",
"args": [
"",
"no.oleavr.HelloIOS",
{},
[],
{
"StartSuspendedKey": False,
},
],
}
)
processcontrol.request({"method": "startObservingPid:", "args": [pid]})

print(f"App spawned, PID: {pid}. Kill it to see an example message being emitted.")
sys.stdin.read()
14 changes: 14 additions & 0 deletions examples/open_service/dtx/screenshot.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import frida

Check failure on line 1 in examples/open_service/dtx/screenshot.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import sys

if len(sys.argv) != 2:
print(f"Usage: {sys.argv[0]} outfile.png", file=sys.stderr)
sys.exit(1)
outfile = sys.argv[1]

device = frida.get_usb_device()

screenshot = device.open_service("dtx:com.apple.instruments.server.services.screenshot")
response = screenshot.request({"method": "takeScreenshot"})
with open(outfile, "wb") as f:
f.write(response)
30 changes: 30 additions & 0 deletions examples/open_service/dtx/sysmontap.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
import frida

Check failure on line 1 in examples/open_service/dtx/sysmontap.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import sys
import time


def on_message(message):
print("on_message:", message)


device = frida.get_usb_device()

sysmontap = device.open_service("dtx:com.apple.instruments.server.services.sysmontap")
sysmontap.on("message", on_message)
sysmontap.request(
{
"method": "setConfig:",
"args": [
{
"ur": 1000,
"cpuUsage": True,
"sampleInterval": 1000000000,
},
],
}
)
sysmontap.request({"method": "start"})
time.sleep(5)
sysmontap.request({"method": "stop"})

sys.stdin.read()
9 changes: 9 additions & 0 deletions examples/open_service/plist.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import frida

device = frida.get_usb_device()

diag = device.open_service("plist:com.apple.mobile.diagnostics_relay")
diag.request({"type": "query", "payload": {"Request": "RSDCheckin", "ProtocolVersion": "2", "Label": "Frida"}})
diag.request({"type": "read"})
diag.request({"type": "query", "payload": {"Request": "Sleep", "WaitForDisconnect": True}})
diag.request({"type": "query", "payload": {"Request": "Goodbye"}})
14 changes: 14 additions & 0 deletions examples/open_service/xpc.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
import frida

Check failure on line 1 in examples/open_service/xpc.py

View workflow job for this annotation

GitHub Actions / isort

Imports are incorrectly sorted and/or formatted.
import pprint

device = frida.get_usb_device()

appservice = device.open_service("xpc:com.apple.coredevice.appservice")
response = appservice.request(
{
"CoreDevice.featureIdentifier": "com.apple.coredevice.feature.listprocesses",
"CoreDevice.action": {},
"CoreDevice.input": {},
}
)
pprint.pp(response)
109 changes: 109 additions & 0 deletions frida/_frida/extension.c
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ typedef struct _PySpawn PySpawn;
typedef struct _PyChild PyChild;
typedef struct _PyCrash PyCrash;
typedef struct _PyBus PyBus;
typedef struct _PyService PyService;
typedef struct _PySession PySession;
typedef struct _PyScript PyScript;
typedef struct _PyRelay PyRelay;
Expand Down Expand Up @@ -256,6 +257,11 @@ struct _PyBus
PyGObject parent;
};

struct _PyService
{
PyGObject parent;
};

struct _PySession
{
PyGObject parent;
Expand Down Expand Up @@ -397,6 +403,7 @@ static FridaSessionOptions * PyDevice_parse_session_options (const gchar * realm
static PyObject * PyDevice_inject_library_file (PyDevice * self, PyObject * args);
static PyObject * PyDevice_inject_library_blob (PyDevice * self, PyObject * args);
static PyObject * PyDevice_open_channel (PyDevice * self, PyObject * args);
static PyObject * PyDevice_open_service (PyDevice * self, PyObject * args);
static PyObject * PyDevice_unpair (PyDevice * self);

static PyObject * PyApplication_new_take_handle (FridaApplication * handle);
Expand Down Expand Up @@ -434,6 +441,11 @@ static PyObject * PyBus_new_take_handle (FridaBus * handle);
static PyObject * PyBus_attach (PySession * self);
static PyObject * PyBus_post (PyScript * self, PyObject * args, PyObject * kw);

static PyObject * PyService_new_take_handle (FridaService * handle);
static PyObject * PyService_activate (PyService * self);
static PyObject * PyService_cancel (PyService * self);
static PyObject * PyService_request (PyService * self, PyObject * args);

static PyObject * PySession_new_take_handle (FridaSession * handle);
static int PySession_init (PySession * self, PyObject * args, PyObject * kw);
static void PySession_init_from_handle (PySession * self, FridaSession * handle);
Expand Down Expand Up @@ -574,6 +586,7 @@ static PyMethodDef PyDevice_methods[] =
{ "inject_library_file", (PyCFunction) PyDevice_inject_library_file, METH_VARARGS, "Inject a library file to a PID." },
{ "inject_library_blob", (PyCFunction) PyDevice_inject_library_blob, METH_VARARGS, "Inject a library blob to a PID." },
{ "open_channel", (PyCFunction) PyDevice_open_channel, METH_VARARGS, "Open a device-specific communication channel." },
{ "open_service", (PyCFunction) PyDevice_open_service, METH_VARARGS, "Open a device-specific service." },
{ "unpair", (PyCFunction) PyDevice_unpair, METH_NOARGS, "Unpair device." },
{ NULL }
};
Expand Down Expand Up @@ -641,6 +654,14 @@ static PyMethodDef PyBus_methods[] =
{ NULL }
};

static PyMethodDef PyService_methods[] =
{
{ "activate", (PyCFunction) PyService_activate, METH_NOARGS, "Activate the service." },
{ "cancel", (PyCFunction) PyService_cancel, METH_NOARGS, "Cancel the service." },
{ "request", (PyCFunction) PyService_request, METH_VARARGS, "Perform a request." },
{ NULL }
};

static PyMethodDef PySession_methods[] =
{
{ "is_detached", (PyCFunction) PySession_is_detached, METH_NOARGS, "Query whether the session is detached." },
Expand Down Expand Up @@ -818,6 +839,11 @@ PYFRIDA_DEFINE_TYPE ("_frida.Bus", Bus, GObject, NULL, g_object_unref,
{ Py_tp_methods, PyBus_methods },
);

PYFRIDA_DEFINE_TYPE ("_frida.Service", Service, GObject, NULL, g_object_unref,
{ Py_tp_doc, "Frida Service" },
{ Py_tp_methods, PyService_methods },
);

PYFRIDA_DEFINE_TYPE ("_frida.Session", Session, GObject, PySession_init_from_handle, frida_unref,
{ Py_tp_doc, "Frida Session" },
{ Py_tp_init, PySession_init },
Expand Down Expand Up @@ -2966,6 +2992,25 @@ PyDevice_open_channel (PyDevice * self, PyObject * args)
return PyIOStream_new_take_handle (stream);
}

static PyObject *
PyDevice_open_service (PyDevice * self, PyObject * args)
{
const char * address;
GError * error = NULL;
FridaService * service;

if (!PyArg_ParseTuple (args, "s", &address))
return NULL;

Py_BEGIN_ALLOW_THREADS
service = frida_device_open_service_sync (PY_GOBJECT_HANDLE (self), address, g_cancellable_get_current (), &error);
Py_END_ALLOW_THREADS
if (error != NULL)
return PyFrida_raise (error);

return PyService_new_take_handle (service);
}

static PyObject *
PyDevice_unpair (PyDevice * self)
{
Expand Down Expand Up @@ -3465,6 +3510,69 @@ PyBus_post (PyScript * self, PyObject * args, PyObject * kw)
}


static PyObject *
PyService_new_take_handle (FridaService * handle)
{
return PyGObject_new_take_handle (handle, PYFRIDA_TYPE (Service));
}

static PyObject *
PyService_activate (PyService * self)
{
GError * error = NULL;

Py_BEGIN_ALLOW_THREADS
frida_service_activate_sync (PY_GOBJECT_HANDLE (self), g_cancellable_get_current (), &error);
Py_END_ALLOW_THREADS
if (error != NULL)
return PyFrida_raise (error);

Py_RETURN_NONE;
}

static PyObject *
PyService_cancel (PyService * self)
{
GError * error = NULL;

Py_BEGIN_ALLOW_THREADS
frida_service_cancel_sync (PY_GOBJECT_HANDLE (self), g_cancellable_get_current (), &error);
Py_END_ALLOW_THREADS
if (error != NULL)
return PyFrida_raise (error);

Py_RETURN_NONE;
}

static PyObject *
PyService_request (PyService * self, PyObject * args)
{
PyObject * result, * params;
GVariant * raw_params, * raw_result;
GError * error = NULL;

if (!PyArg_ParseTuple (args, "O", &params))
return NULL;

if (!PyGObject_unmarshal_variant (params, &raw_params))
return NULL;

Py_BEGIN_ALLOW_THREADS
raw_result = frida_service_request_sync (PY_GOBJECT_HANDLE (self), raw_params, g_cancellable_get_current (), &error);
Py_END_ALLOW_THREADS

g_variant_unref (raw_params);

if (error != NULL)
return PyFrida_raise (error);

result = PyGObject_marshal_variant (raw_result);
g_variant_unref (raw_result);

return result;
}


static PyObject *
PySession_new_take_handle (FridaSession * handle)
{
Expand Down Expand Up @@ -5334,6 +5442,7 @@ MOD_INIT (_frida)
PYFRIDA_REGISTER_TYPE (Child, FRIDA_TYPE_CHILD);
PYFRIDA_REGISTER_TYPE (Crash, FRIDA_TYPE_CRASH);
PYFRIDA_REGISTER_TYPE (Bus, FRIDA_TYPE_BUS);
PYFRIDA_REGISTER_TYPE (Service, FRIDA_TYPE_SERVICE);
PYFRIDA_REGISTER_TYPE (Session, FRIDA_TYPE_SESSION);
PYFRIDA_REGISTER_TYPE (Script, FRIDA_TYPE_SCRIPT);
PYFRIDA_REGISTER_TYPE (Relay, FRIDA_TYPE_RELAY);
Expand Down
Loading

0 comments on commit 55b38df

Please sign in to comment.