mirror of
https://github.com/frida/frida-python
synced 2026-06-08 14:16:17 +00:00
compiler: Add Compiler API
This commit is contained in:
+2
-9
@@ -27,9 +27,11 @@ from . import core
|
||||
|
||||
__version__ = _frida.__version__
|
||||
|
||||
get_device_manager = core.get_device_manager
|
||||
Relay = _frida.Relay
|
||||
PortalService = core.PortalService
|
||||
EndpointParameters = core.EndpointParameters
|
||||
Compiler = core.Compiler
|
||||
FileMonitor = _frida.FileMonitor
|
||||
Cancellable = core.Cancellable
|
||||
|
||||
@@ -104,12 +106,3 @@ def enumerate_devices(**kwargs):
|
||||
@core.cancellable
|
||||
def shutdown():
|
||||
get_device_manager()._impl.close()
|
||||
|
||||
|
||||
global _device_manager
|
||||
_device_manager = None
|
||||
def get_device_manager():
|
||||
global _device_manager
|
||||
if _device_manager is None:
|
||||
_device_manager = core.DeviceManager(_frida.DeviceManager())
|
||||
return _device_manager
|
||||
|
||||
@@ -12,9 +12,17 @@ import traceback
|
||||
import _frida
|
||||
|
||||
|
||||
_device_manager = None
|
||||
_Cancellable = _frida.Cancellable
|
||||
|
||||
|
||||
def get_device_manager():
|
||||
global _device_manager
|
||||
if _device_manager is None:
|
||||
_device_manager = DeviceManager(_frida.DeviceManager())
|
||||
return _device_manager
|
||||
|
||||
|
||||
def cancellable(f):
|
||||
@wraps(f)
|
||||
def wrapper(*args, **kwargs):
|
||||
@@ -591,6 +599,28 @@ class PortalService(object):
|
||||
traceback.print_exc()
|
||||
|
||||
|
||||
class Compiler(object):
|
||||
def __init__(self):
|
||||
self._impl = _frida.Compiler(get_device_manager()._impl)
|
||||
|
||||
def __repr__(self):
|
||||
return repr(self._impl)
|
||||
|
||||
@cancellable
|
||||
def build(self, *args, **kwargs):
|
||||
return self._impl.build(*args, **kwargs)
|
||||
|
||||
@cancellable
|
||||
def watch(self, *args, **kwargs):
|
||||
return self._impl.watch(*args, **kwargs)
|
||||
|
||||
def on(self, signal, callback):
|
||||
self._impl.on(signal, callback)
|
||||
|
||||
def off(self, signal, callback):
|
||||
self._impl.off(signal, callback)
|
||||
|
||||
|
||||
class IOStream(object):
|
||||
def __init__(self, impl):
|
||||
self._impl = impl
|
||||
|
||||
+190
@@ -129,6 +129,7 @@ typedef struct _PyRelay PyRelay;
|
||||
typedef struct _PyPortalMembership PyPortalMembership;
|
||||
typedef struct _PyPortalService PyPortalService;
|
||||
typedef struct _PyEndpointParameters PyEndpointParameters;
|
||||
typedef struct _PyCompiler PyCompiler;
|
||||
typedef struct _PyFileMonitor PyFileMonitor;
|
||||
typedef struct _PyIOStream PyIOStream;
|
||||
typedef struct _PyCancellable PyCancellable;
|
||||
@@ -271,6 +272,11 @@ struct _FridaPythonAuthenticationService
|
||||
GThreadPool * pool;
|
||||
};
|
||||
|
||||
struct _PyCompiler
|
||||
{
|
||||
PyGObject parent;
|
||||
};
|
||||
|
||||
struct _PyFileMonitor
|
||||
{
|
||||
PyGObject parent;
|
||||
@@ -316,6 +322,7 @@ static PyObject * PyGObject_marshal_enum (gint value, GType type);
|
||||
static gboolean PyGObject_unmarshal_enum (const gchar * str, GType type, gpointer value);
|
||||
static PyObject * PyGObject_marshal_bytes (GBytes * bytes);
|
||||
static PyObject * PyGObject_marshal_bytes_non_nullable (GBytes * bytes);
|
||||
static PyObject * PyGObject_marshal_variant (GVariant * variant);
|
||||
static gboolean PyGObject_unmarshal_variant (PyObject * value, GVariant ** variant);
|
||||
static PyObject * PyGObject_marshal_parameters_dict (GHashTable * dict);
|
||||
static PyObject * PyGObject_marshal_socket_address (GSocketAddress * address);
|
||||
@@ -453,6 +460,12 @@ static gchar * frida_python_authentication_service_authenticate_finish (FridaAut
|
||||
GError ** error);
|
||||
static void frida_python_authentication_service_do_authenticate (GTask * task, FridaPythonAuthenticationService * self);
|
||||
|
||||
static int PyCompiler_init (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static PyObject * PyCompiler_build (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static PyObject * PyCompiler_watch (PyCompiler * self, PyObject * args, PyObject * kw);
|
||||
static gboolean PyCompiler_set_options (FridaCompilerOptions * options, const gchar * project_root_value, const gchar * source_maps_value,
|
||||
const gchar * compression_value);
|
||||
|
||||
static int PyFileMonitor_init (PyFileMonitor * self, PyObject * args, PyObject * kw);
|
||||
static PyObject * PyFileMonitor_enable (PyFileMonitor * self);
|
||||
static PyObject * PyFileMonitor_disable (PyFileMonitor * self);
|
||||
@@ -658,6 +671,13 @@ static PyMemberDef PyPortalService_members[] =
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static PyMethodDef PyCompiler_methods[] =
|
||||
{
|
||||
{ "build", (PyCFunction) PyCompiler_build, METH_VARARGS | METH_KEYWORDS, "Build an agent." },
|
||||
{ "watch", (PyCFunction) PyCompiler_watch, METH_VARARGS | METH_KEYWORDS, "Continuously build an agent." },
|
||||
{ NULL }
|
||||
};
|
||||
|
||||
static PyMethodDef PyFileMonitor_methods[] =
|
||||
{
|
||||
{ "enable", (PyCFunction) PyFileMonitor_enable, METH_NOARGS, "Enable the file monitor." },
|
||||
@@ -1321,6 +1341,48 @@ static PyTypeObject PyEndpointParametersType =
|
||||
|
||||
PYFRIDA_DEFINE_TYPE (EndpointParameters, NULL, g_object_unref);
|
||||
|
||||
static PyTypeObject PyCompilerType =
|
||||
{
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
"_frida.Compiler", /* tp_name */
|
||||
sizeof (PyCompiler), /* tp_basicsize */
|
||||
0, /* tp_itemsize */
|
||||
NULL, /* tp_dealloc */
|
||||
PYFRIDA_NO_PRINT_FUNC_OR_VECTORCALL_OFFSET, /* tp_{print,vco} */
|
||||
NULL, /* tp_getattr */
|
||||
NULL, /* tp_setattr */
|
||||
NULL, /* tp_compare */
|
||||
NULL, /* tp_repr */
|
||||
NULL, /* tp_as_number */
|
||||
NULL, /* tp_as_sequence */
|
||||
NULL, /* tp_as_mapping */
|
||||
NULL, /* tp_hash */
|
||||
NULL, /* tp_call */
|
||||
NULL, /* tp_str */
|
||||
NULL, /* tp_getattro */
|
||||
NULL, /* tp_setattro */
|
||||
NULL, /* tp_as_buffer */
|
||||
Py_TPFLAGS_DEFAULT, /* tp_flags */
|
||||
"Frida File Monitor", /* tp_doc */
|
||||
NULL, /* tp_traverse */
|
||||
NULL, /* tp_clear */
|
||||
NULL, /* tp_richcompare */
|
||||
0, /* tp_weaklistoffset */
|
||||
NULL, /* tp_iter */
|
||||
NULL, /* tp_iternext */
|
||||
PyCompiler_methods, /* tp_methods */
|
||||
NULL, /* tp_members */
|
||||
NULL, /* tp_getset */
|
||||
&PyGObjectType, /* tp_base */
|
||||
NULL, /* tp_dict */
|
||||
NULL, /* tp_descr_get */
|
||||
NULL, /* tp_descr_set */
|
||||
0, /* tp_dictoffset */
|
||||
(initproc) PyCompiler_init, /* tp_init */
|
||||
};
|
||||
|
||||
PYFRIDA_DEFINE_TYPE (Compiler, NULL, frida_unref);
|
||||
|
||||
static PyTypeObject PyFileMonitorType =
|
||||
{
|
||||
PyVarObject_HEAD_INIT (NULL, 0)
|
||||
@@ -1833,6 +1895,9 @@ PyGObject_marshal_value (const GValue * value)
|
||||
case G_TYPE_STRING:
|
||||
return PyGObject_marshal_string (g_value_get_string (value));
|
||||
|
||||
case G_TYPE_VARIANT:
|
||||
return PyGObject_marshal_variant (g_value_get_variant (value));
|
||||
|
||||
default:
|
||||
if (G_TYPE_IS_ENUM (type))
|
||||
return PyGObject_marshal_enum (g_value_get_enum (value), type);
|
||||
@@ -4993,6 +5058,130 @@ frida_python_authentication_service_do_authenticate (GTask * task, FridaPythonAu
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
PyCompiler_init (PyCompiler * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
PyDeviceManager * manager;
|
||||
|
||||
if (PyGObjectType.tp_init ((PyObject *) self, args, kw) < 0)
|
||||
return -1;
|
||||
|
||||
if (!PyArg_ParseTuple (args, "O!", &PYFRIDA_TYPE (DeviceManager), &manager))
|
||||
return -1;
|
||||
|
||||
PyGObject_take_handle (&self->parent, frida_compiler_new (PY_GOBJECT_HANDLE (manager)), &PYFRIDA_TYPE_SPEC (Compiler));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCompiler_build (PyCompiler * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
PyObject * result;
|
||||
static char * keywords[] = { "entrypoint", "project_root", "source_maps", "compression", NULL };
|
||||
const char * entrypoint;
|
||||
const char * project_root = NULL;
|
||||
const char * source_maps = NULL;
|
||||
const char * compression = NULL;
|
||||
FridaBuildOptions * options;
|
||||
GError * error = NULL;
|
||||
gchar * bundle;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords (args, kw, "s|sss", keywords, &entrypoint, &project_root, &source_maps, &compression))
|
||||
return NULL;
|
||||
|
||||
options = frida_build_options_new ();
|
||||
if (!PyCompiler_set_options (FRIDA_COMPILER_OPTIONS (options), project_root, source_maps, compression))
|
||||
goto invalid_option_value;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
bundle = frida_compiler_build_sync (PY_GOBJECT_HANDLE (self), entrypoint, options, g_cancellable_get_current (), &error);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
g_object_unref (options);
|
||||
|
||||
if (error != NULL)
|
||||
return PyFrida_raise (error);
|
||||
|
||||
result = PyUnicode_FromUTF8String (bundle);
|
||||
g_free (bundle);
|
||||
|
||||
return result;
|
||||
|
||||
invalid_option_value:
|
||||
{
|
||||
g_object_unref (options);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
PyCompiler_watch (PyCompiler * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
static char * keywords[] = { "entrypoint", "project_root", "source_maps", "compression", NULL };
|
||||
const char * entrypoint;
|
||||
const char * project_root = NULL;
|
||||
const char * source_maps = NULL;
|
||||
const char * compression = NULL;
|
||||
FridaWatchOptions * options;
|
||||
GError * error = NULL;
|
||||
|
||||
if (!PyArg_ParseTupleAndKeywords (args, kw, "s|sss", keywords, &entrypoint, &project_root, &source_maps, &compression))
|
||||
return NULL;
|
||||
|
||||
options = frida_watch_options_new ();
|
||||
if (!PyCompiler_set_options (FRIDA_COMPILER_OPTIONS (options), project_root, source_maps, compression))
|
||||
goto invalid_option_value;
|
||||
|
||||
Py_BEGIN_ALLOW_THREADS
|
||||
frida_compiler_watch_sync (PY_GOBJECT_HANDLE (self), entrypoint, options, g_cancellable_get_current (), &error);
|
||||
Py_END_ALLOW_THREADS
|
||||
|
||||
g_object_unref (options);
|
||||
|
||||
if (error != NULL)
|
||||
return PyFrida_raise (error);
|
||||
|
||||
Py_RETURN_NONE;
|
||||
|
||||
invalid_option_value:
|
||||
{
|
||||
g_object_unref (options);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
PyCompiler_set_options (FridaCompilerOptions * options, const gchar * project_root_value, const gchar * source_maps_value,
|
||||
const gchar * compression_value)
|
||||
{
|
||||
if (project_root_value != NULL)
|
||||
frida_compiler_options_set_project_root (options, project_root_value);
|
||||
|
||||
if (source_maps_value != NULL)
|
||||
{
|
||||
FridaSourceMaps source_maps;
|
||||
|
||||
if (!PyGObject_unmarshal_enum (source_maps_value, FRIDA_TYPE_SOURCE_MAPS, &source_maps))
|
||||
return FALSE;
|
||||
|
||||
frida_compiler_options_set_source_maps (options, source_maps);
|
||||
}
|
||||
|
||||
if (compression_value != NULL)
|
||||
{
|
||||
FridaJsCompression compression;
|
||||
|
||||
if (!PyGObject_unmarshal_enum (compression_value, FRIDA_TYPE_JS_COMPRESSION, &compression))
|
||||
return FALSE;
|
||||
|
||||
frida_compiler_options_set_compression (options, compression);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
|
||||
static int
|
||||
PyFileMonitor_init (PyFileMonitor * self, PyObject * args, PyObject * kw)
|
||||
{
|
||||
@@ -5613,6 +5802,7 @@ MOD_INIT (_frida)
|
||||
PYFRIDA_REGISTER_TYPE (PortalMembership, FRIDA_TYPE_PORTAL_MEMBERSHIP);
|
||||
PYFRIDA_REGISTER_TYPE (PortalService, FRIDA_TYPE_PORTAL_SERVICE);
|
||||
PYFRIDA_REGISTER_TYPE (EndpointParameters, FRIDA_TYPE_ENDPOINT_PARAMETERS);
|
||||
PYFRIDA_REGISTER_TYPE (Compiler, FRIDA_TYPE_COMPILER);
|
||||
PYFRIDA_REGISTER_TYPE (FileMonitor, FRIDA_TYPE_FILE_MONITOR);
|
||||
PYFRIDA_REGISTER_TYPE (IOStream, G_TYPE_IO_STREAM);
|
||||
PYFRIDA_REGISTER_TYPE (Cancellable, G_TYPE_CANCELLABLE);
|
||||
|
||||
Reference in New Issue
Block a user