Class: CFrida::DeviceManager

Inherits:
GObject
  • Object
show all
Defined in:
ext/c_frida/DeviceManager.c

Instance Method Summary collapse

Constructor Details

#initializeObject



240
241
242
243
244
245
246
247
248
# File 'ext/c_frida/DeviceManager.c', line 240

static VALUE DeviceManager_initialize(VALUE self)
{
    GET_GOBJECT_DATA();
    d->handle = frida_device_manager_new();
    if (!d->handle)
        return (raise_rerror("failed to retrieve a device manager.", NULL), Qnil);
    d->destroy = DeviceManager_destroy;
    return (self);
}

Instance Method Details

#add_remote_device(*args) ⇒ Object



175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
# File 'ext/c_frida/DeviceManager.c', line 175

static VALUE DeviceManager_add_remote_device(int argc, VALUE *argv, VALUE self)
{
    GET_GOBJECT_DATA();
    REQUIRE_GOBJECT_HANDLE();
    VALUE	address, kws;
    FridaRemoteDeviceOptions *options;
    FridaDevice *device;

    rb_scan_args(argc, argv, "1:", &address, &kws);
    if (!RB_TYPE_P(address, T_STRING))
        return (raise_argerror("address must be a string."), Qnil);
    if (NIL_P(kws)) kws = rb_hash_new();
    options = parse_add_rdevice_kws_to_options(kws);
    if (!options)
        return (Qnil);
    add_remote_device_proxy_args args = {
        .device_manager = d->handle,
        .options = options,
        .address = StringValueCStr(address)
    };
    CALL_GVL_FREE_WITH_RET(device, add_remote_device_sync, &args);
    g_object_unref(options);
    return (Device_from_FridaDevice(device));

gerror:
    g_object_unref(options);
    raise_rerror(NULL, _gerr);
    return (Qnil);
}

#closeObject



40
41
42
43
44
45
46
47
48
# File 'ext/c_frida/DeviceManager.c', line 40

static VALUE DeviceManager_close(VALUE self)
{
    GET_GOBJECT_DATA();
    REQUIRE_GOBJECT_HANDLE();
    CALL_GVL_FREE_WITH_RET(void *dummy, close_device_manager_err, d->handle);
    return (Qnil);

    GERROR_BLOCK
}

#enumerate_devicesObject



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'ext/c_frida/DeviceManager.c', line 63

static VALUE DeviceManager_enumerate_devices(VALUE self)
{
    GET_GOBJECT_DATA();
    REQUIRE_GOBJECT_HANDLE();
    FridaDeviceList * devices;
    int devices_count;
    VALUE Devices_arr;

    CALL_GVL_FREE_WITH_RET(devices, enumerate_devices_sync, d->handle);
    devices_count = frida_device_list_size(devices);
    Devices_arr = rb_ary_new_capa(devices_count);
    for (int i = 0; i < devices_count; i++)
        rb_ary_store(Devices_arr, i, Device_from_FridaDevice(frida_device_list_get(devices, i)));
    frida_unref(devices);
    return (Devices_arr);

    GERROR_BLOCK
}

#get_device_matchingObject



86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'ext/c_frida/DeviceManager.c', line 86

static VALUE DeviceManager_get_device_matching(VALUE self)
{
    GET_GOBJECT_DATA();
    REQUIRE_GOBJECT_HANDLE();
    VALUE block;
    VALUE devices, current_device, block_ret;
    int	devices_count;

    if (!rb_block_given_p()) {
        raise_argerror("a block argument is required");
        return (Qnil);
    }
    block = rb_block_proc();
    // NOTE: Ruby does not support (currently) setting up a non Ruby created thread to be able
    // to call its C APIs, frida_device_manager_get_device_sync() would call our filtering predicate from a frida thread
    // which is not created by Ruby, and GET_EC() call in the Ruby's C APIs would return NULL.
    // so the filtering is done in this thread that currently holds the GVL, mimicking frida_device_manager_get_device_sync().
    devices = rb_funcall(self, rb_intern("enumerate_devices"), 0, NULL);
    devices_count = RARRAY_LEN(devices);
    for (int i = 0; i < devices_count; i++) {
        current_device = rb_ary_entry(devices, i);
        block_ret = rb_funcall(block, rb_intern("call"), 1, current_device);
        if (block_ret == Qtrue) return (current_device);
    }
    return (Qnil);
}

#remove_remote_device(address) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
# File 'ext/c_frida/DeviceManager.c', line 217

static VALUE DeviceManager_remove_remote_device(VALUE self, VALUE address)
{
    GET_GOBJECT_DATA();
    REQUIRE_GOBJECT_HANDLE();

    if (!RB_TYPE_P(address, T_STRING)) {
        raise_argerror("address should be a string.");
        return (Qnil);
    }
    remove_remote_devices_proxy_args args = {
        .device_manager = d->handle,
        .address = StringValueCStr(address)
    };
    CALL_GVL_FREE_WITH_RET(void *dummy, remove_remote_device_sync, &args);
    return (Qnil);

    GERROR_BLOCK
}