frida 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +12 -0
- data/Gemfile.lock +25 -0
- data/LICENSE.txt +21 -0
- data/README.md +64 -0
- data/Rakefile +20 -0
- data/exe/frida +3 -0
- data/ext/c_frida/Application.c +79 -0
- data/ext/c_frida/Bus.c +91 -0
- data/ext/c_frida/Child.c +134 -0
- data/ext/c_frida/Compiler.c +208 -0
- data/ext/c_frida/Crash.c +92 -0
- data/ext/c_frida/Device.c +955 -0
- data/ext/c_frida/DeviceManager.c +260 -0
- data/ext/c_frida/EndpointParameters.c +189 -0
- data/ext/c_frida/FileMonitor.c +67 -0
- data/ext/c_frida/GObject.c +138 -0
- data/ext/c_frida/IOStream.c +228 -0
- data/ext/c_frida/PortalMembership.c +43 -0
- data/ext/c_frida/PortalService.c +413 -0
- data/ext/c_frida/Process.c +67 -0
- data/ext/c_frida/Relay.c +121 -0
- data/ext/c_frida/Script.c +221 -0
- data/ext/c_frida/Session.c +626 -0
- data/ext/c_frida/Spawn.c +53 -0
- data/ext/c_frida/c_frida.c +68 -0
- data/ext/c_frida/extconf.rb +26 -25
- data/ext/c_frida/gutils.c +498 -0
- data/ext/c_frida/gvl_bridge.c +131 -0
- data/ext/c_frida/inc/Application.h +9 -0
- data/ext/c_frida/inc/Bus.h +15 -0
- data/ext/c_frida/inc/Child.h +9 -0
- data/ext/c_frida/inc/Compiler.h +21 -0
- data/ext/c_frida/inc/Crash.h +9 -0
- data/ext/c_frida/inc/Device.h +71 -0
- data/ext/c_frida/inc/DeviceManager.h +20 -0
- data/ext/c_frida/inc/EndpointParameters.h +15 -0
- data/ext/c_frida/inc/FileMonitor.h +9 -0
- data/ext/c_frida/inc/GObject.h +10 -0
- data/ext/c_frida/inc/IOStream.h +29 -0
- data/ext/c_frida/inc/PortalMembership.h +9 -0
- data/ext/c_frida/inc/PortalService.h +47 -0
- data/ext/c_frida/inc/Process.h +9 -0
- data/ext/c_frida/inc/Relay.h +9 -0
- data/ext/c_frida/inc/Script.h +21 -0
- data/ext/c_frida/inc/Session.h +40 -0
- data/ext/c_frida/inc/Spawn.h +9 -0
- data/ext/c_frida/inc/c_frida.h +129 -0
- data/ext/c_frida/inc/gutils.h +21 -0
- data/ext/c_frida/inc/gvl_bridge.h +42 -0
- data/frida.gemspec +39 -0
- data/lib/frida/version.rb +5 -0
- data/lib/frida.rb +8 -0
- metadata +55 -3
@@ -0,0 +1,131 @@
|
|
1
|
+
#include "gvl_bridge.h"
|
2
|
+
|
3
|
+
static int _gvl_bridge_pipe[2] = {-1, -1};
|
4
|
+
static int __gvl_bridge_pipe[2] = {-1, -1};
|
5
|
+
static bool main_thread_exited = false;
|
6
|
+
|
7
|
+
static void gvl_bridge_signal_exit(VALUE _)
|
8
|
+
{
|
9
|
+
main_thread_exited = true;
|
10
|
+
close(_gvl_bridge_pipe[0]);
|
11
|
+
close(_gvl_bridge_pipe[1]);
|
12
|
+
close(__gvl_bridge_pipe[0]);
|
13
|
+
close(__gvl_bridge_pipe[1]);
|
14
|
+
}
|
15
|
+
|
16
|
+
void gvl_bridge_forward_GC(GClosure *closure, GValue *_, guint n_param_values, GValue *param_values, gpointer __, gpointer ___)
|
17
|
+
{
|
18
|
+
void *dummy;
|
19
|
+
gvl_bridge_data *data = malloc(sizeof(gvl_bridge_data));
|
20
|
+
|
21
|
+
data->type = GCLOSURE;
|
22
|
+
data->GC.closure = closure;
|
23
|
+
data->GC.n_param_values = n_param_values;
|
24
|
+
data->GC.param_values = param_values;
|
25
|
+
write(_gvl_bridge_pipe[1], &data, sizeof(void *));
|
26
|
+
// hold until the callback is done, also prevents GC-ing param_values
|
27
|
+
read(__gvl_bridge_pipe[0], &dummy, sizeof(void *));
|
28
|
+
if (data->GC.param_values != param_values)
|
29
|
+
free(data->GC.param_values);
|
30
|
+
free(data);
|
31
|
+
}
|
32
|
+
|
33
|
+
static VALUE GC_rbcall(gclosure_callback *callback)
|
34
|
+
{
|
35
|
+
RBClosure *rc = TO_RBCLOSURE(callback->closure);
|
36
|
+
VALUE *args_array;
|
37
|
+
|
38
|
+
int arity = rc->is_lambda ? MIN(callback->n_param_values, rc->arity) : (callback->n_param_values - 1);
|
39
|
+
if (arity == -1) // splat operator
|
40
|
+
arity = callback->n_param_values;
|
41
|
+
if (callback->n_param_values == arity)
|
42
|
+
args_array = rbGObjectSignalClosure_marshal_params(callback->param_values, arity);
|
43
|
+
else
|
44
|
+
args_array = rbGObjectSignalClosure_marshal_params(callback->param_values + 1, arity); // +1 skip sender instance.
|
45
|
+
callback->param_values = (void *)args_array;
|
46
|
+
rb_funcallv((VALUE)callback->closure->data, rb_intern("call"), arity, args_array);
|
47
|
+
return (Qnil);
|
48
|
+
}
|
49
|
+
|
50
|
+
static void gvl_bridge_call_GC(gclosure_callback *data)
|
51
|
+
{
|
52
|
+
int state;
|
53
|
+
|
54
|
+
rb_protect((VALUE (*)(VALUE))GC_rbcall, (VALUE)data, &state);
|
55
|
+
if (state)
|
56
|
+
rb_set_errinfo(Qnil);
|
57
|
+
}
|
58
|
+
|
59
|
+
void gvl_bridge_forward_GT(GTask *task, FridaRBAuthenticationService *self)
|
60
|
+
{
|
61
|
+
gvl_bridge_data *data = malloc(sizeof(gvl_bridge_data));
|
62
|
+
|
63
|
+
data->type = GTASK;
|
64
|
+
data->GT.task = task;
|
65
|
+
data->GT.self = self;
|
66
|
+
write(_gvl_bridge_pipe[1], &data, sizeof(void *));
|
67
|
+
}
|
68
|
+
|
69
|
+
static VALUE GT_rbcall(gtask_callback *data)
|
70
|
+
{
|
71
|
+
gchar *token;
|
72
|
+
|
73
|
+
token = g_task_get_task_data(data->task);
|
74
|
+
return (rb_funcall((VALUE)data->self->callback, rb_intern("call"), 1, rb_str_new_cstr(token)));
|
75
|
+
}
|
76
|
+
|
77
|
+
static void gvl_bridge_call_GT(gtask_callback *data)
|
78
|
+
{
|
79
|
+
int state;
|
80
|
+
gchar *msg = NULL;
|
81
|
+
VALUE result;
|
82
|
+
|
83
|
+
result = rb_protect((VALUE (*)(VALUE))GT_rbcall, (VALUE)data, &state);
|
84
|
+
if (state) {
|
85
|
+
result = rb_funcall(rb_gv_get("$!"), rb_intern("message"), 0);
|
86
|
+
if (result != Qnil)
|
87
|
+
msg = g_strdup(StringValueCStr(result));
|
88
|
+
else
|
89
|
+
msg = g_strdup("Internal error");
|
90
|
+
rb_set_errinfo(Qnil);
|
91
|
+
g_task_return_new_error(data->task, FRIDA_ERROR, FRIDA_ERROR_INVALID_ARGUMENT, "%s", msg);
|
92
|
+
g_free(msg);
|
93
|
+
} else {
|
94
|
+
rbGObject_unmarshal_string(result, &msg);
|
95
|
+
g_task_return_pointer(data->task, msg, g_free);
|
96
|
+
}
|
97
|
+
g_object_unref(data->task);
|
98
|
+
}
|
99
|
+
|
100
|
+
static void gvl_bridge_main()
|
101
|
+
{
|
102
|
+
gvl_bridge_data *data;
|
103
|
+
|
104
|
+
g_assert(sizeof(void *) <= sizeof(VALUE));
|
105
|
+
while (1) {
|
106
|
+
read(_gvl_bridge_pipe[0], &data, sizeof(void *));
|
107
|
+
if (!data || main_thread_exited)
|
108
|
+
return;
|
109
|
+
if (data->type == GCLOSURE) {
|
110
|
+
rb_thread_call_with_gvl((void_fp)gvl_bridge_call_GC, &data->GC);
|
111
|
+
write(__gvl_bridge_pipe[1], &data, sizeof(void *));
|
112
|
+
} else if (data->type == GTASK) {
|
113
|
+
rb_thread_call_with_gvl((void_fp)gvl_bridge_call_GT, &data->GT);
|
114
|
+
free(data);
|
115
|
+
}
|
116
|
+
}
|
117
|
+
}
|
118
|
+
|
119
|
+
void gvl_bridge(void)
|
120
|
+
{
|
121
|
+
if (pipe(_gvl_bridge_pipe) < 0) {
|
122
|
+
raise_rerror("pipe() error @ gvl_bridge", NULL);
|
123
|
+
exit(EXIT_FAILURE);
|
124
|
+
}
|
125
|
+
if (pipe(__gvl_bridge_pipe) < 0) {
|
126
|
+
raise_rerror("pipe() error @ gvl_bridge", NULL);
|
127
|
+
exit(EXIT_FAILURE);
|
128
|
+
}
|
129
|
+
rb_set_end_proc(gvl_bridge_signal_exit, Qnil);
|
130
|
+
rb_thread_call_without_gvl((void_fp)gvl_bridge_main, NULL, RUBY_UBF_IO, NULL);
|
131
|
+
}
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cBus;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
FridaBus *handle;
|
10
|
+
char *message;
|
11
|
+
GBytes *data;
|
12
|
+
} bus_post_proxy_args;
|
13
|
+
|
14
|
+
void define_Bus();
|
15
|
+
VALUE Bus_from_FridaBus(FridaBus *fridabus);
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cCompiler;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
FridaCompiler *handle;
|
10
|
+
char *entrypoint;
|
11
|
+
FridaBuildOptions *options;
|
12
|
+
} build_sync_proxy_args;
|
13
|
+
|
14
|
+
typedef struct {
|
15
|
+
FridaCompiler *handle;
|
16
|
+
char *entrypoint;
|
17
|
+
FridaWatchOptions *options;
|
18
|
+
} watch_sync_proxy_args;
|
19
|
+
|
20
|
+
void define_Compiler();
|
21
|
+
VALUE Compiler_from_FridaCompiler(FridaCompiler *handle);
|
@@ -0,0 +1,71 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cDevice;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
FridaDevice *device_handle;
|
10
|
+
char *address;
|
11
|
+
} open_channel_proxy_args;
|
12
|
+
|
13
|
+
typedef struct {
|
14
|
+
FridaDevice *device_handle;
|
15
|
+
FridaFrontmostQueryOptions *options;
|
16
|
+
} get_frontmost_application_proxy_args;
|
17
|
+
|
18
|
+
typedef struct {
|
19
|
+
FridaDevice *device_handle;
|
20
|
+
FridaProcessQueryOptions *options;
|
21
|
+
} enumerate_processes_proxy_args;
|
22
|
+
|
23
|
+
typedef struct {
|
24
|
+
FridaDevice *device_handle;
|
25
|
+
FridaApplicationQueryOptions *options;
|
26
|
+
} enumerate_applications_proxy_args;
|
27
|
+
|
28
|
+
typedef struct {
|
29
|
+
FridaDevice *device_handle;
|
30
|
+
char *program;
|
31
|
+
FridaSpawnOptions *options;
|
32
|
+
} spawn_sync_proxy_args;
|
33
|
+
|
34
|
+
typedef struct {
|
35
|
+
FridaDevice *device_handle;
|
36
|
+
guint pid;
|
37
|
+
} resume_sync_proxy_args;
|
38
|
+
|
39
|
+
typedef resume_sync_proxy_args kill_sync_proxy_args;
|
40
|
+
|
41
|
+
typedef struct {
|
42
|
+
FridaDevice *device_handle;
|
43
|
+
guint pid;
|
44
|
+
GBytes *data;
|
45
|
+
} input_sync_proxy_args;
|
46
|
+
|
47
|
+
typedef struct {
|
48
|
+
FridaDevice *device_handle;
|
49
|
+
guint pid;
|
50
|
+
char *path;
|
51
|
+
char *entrypoint;
|
52
|
+
char *data;
|
53
|
+
} inject_library_file_sync_proxy_args;
|
54
|
+
|
55
|
+
typedef struct {
|
56
|
+
FridaDevice *device_handle;
|
57
|
+
guint pid;
|
58
|
+
GBytes *blob;
|
59
|
+
char *entrypoint;
|
60
|
+
char *data;
|
61
|
+
} inject_library_blob_sync_proxy_args;
|
62
|
+
|
63
|
+
typedef struct {
|
64
|
+
FridaDevice *device_handle;
|
65
|
+
guint pid;
|
66
|
+
FridaSessionOptions *options;
|
67
|
+
} attach_sync_proxy_args;
|
68
|
+
|
69
|
+
void define_Device();
|
70
|
+
VALUE Device_from_FridaDevice(FridaDevice *device);
|
71
|
+
int array_all_type(VALUE arr, VALUE rtype);
|
@@ -0,0 +1,20 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cDeviceManager;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
FridaDeviceManager *device_manager;
|
10
|
+
char *address;
|
11
|
+
FridaRemoteDeviceOptions *options;
|
12
|
+
} add_remote_device_proxy_args;
|
13
|
+
|
14
|
+
typedef struct {
|
15
|
+
FridaDeviceManager *device_manager;
|
16
|
+
char *address;
|
17
|
+
} remove_remote_devices_proxy_args;
|
18
|
+
|
19
|
+
void define_DeviceManager();
|
20
|
+
VALUE DeviceManager_from_FridaDeviceManager(FridaDeviceManager *handle);
|
@@ -0,0 +1,15 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cEndpointParameters;
|
7
|
+
|
8
|
+
struct _FridaRBAuthenticationService {
|
9
|
+
GObject parent;
|
10
|
+
VALUE callback;
|
11
|
+
GThreadPool *pool;
|
12
|
+
};
|
13
|
+
|
14
|
+
void define_EndpointParameters();
|
15
|
+
VALUE EndpointParameters_from_FridaEndpointParameters(FridaEndpointParameters *handle);
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cIOStream;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
GObject_d base;
|
10
|
+
GInputStream *input;
|
11
|
+
GOutputStream *output;
|
12
|
+
} IOStream_d;
|
13
|
+
|
14
|
+
typedef struct {
|
15
|
+
GOutputStream *output;
|
16
|
+
char *data;
|
17
|
+
gsize size;
|
18
|
+
} write_proxy_args;
|
19
|
+
|
20
|
+
typedef struct {
|
21
|
+
GInputStream *input;
|
22
|
+
char *buffer;
|
23
|
+
gsize count;
|
24
|
+
} read_proxy_args;
|
25
|
+
|
26
|
+
void IOStream_free(IOStream_d *d);
|
27
|
+
|
28
|
+
void define_IOStream();
|
29
|
+
VALUE IOStream_from_GIOStream(GIOStream *stream);
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
typedef struct {
|
6
|
+
FridaPortalService *handle;
|
7
|
+
guint connection_id;
|
8
|
+
} kick_proxy_args;
|
9
|
+
|
10
|
+
typedef struct {
|
11
|
+
FridaPortalService *handle;
|
12
|
+
guint connection_id;
|
13
|
+
char *message;
|
14
|
+
GBytes *data;
|
15
|
+
} _post_proxy_args;
|
16
|
+
|
17
|
+
typedef struct {
|
18
|
+
FridaPortalService *handle;
|
19
|
+
char *tag;
|
20
|
+
char *message;
|
21
|
+
GBytes *data;
|
22
|
+
} narrowcast_proxy_args;
|
23
|
+
|
24
|
+
typedef struct {
|
25
|
+
FridaPortalService *handle;
|
26
|
+
char *message;
|
27
|
+
GBytes *data;
|
28
|
+
} broadcast_proxy_args;
|
29
|
+
|
30
|
+
typedef struct {
|
31
|
+
FridaPortalService *handle;
|
32
|
+
guint connection_id;
|
33
|
+
gint *tags_count;
|
34
|
+
} enumerate_tags_proxy_args;
|
35
|
+
|
36
|
+
typedef struct {
|
37
|
+
FridaPortalService *handle;
|
38
|
+
guint connection_id;
|
39
|
+
char *tag;
|
40
|
+
} tag_proxy_args;
|
41
|
+
|
42
|
+
typedef tag_proxy_args untag_proxy_args;
|
43
|
+
|
44
|
+
extern VALUE mCFrida;
|
45
|
+
extern VALUE cPortalService;
|
46
|
+
|
47
|
+
void define_PortalService();
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cScript;
|
7
|
+
extern VALUE cGObject;
|
8
|
+
|
9
|
+
typedef struct {
|
10
|
+
FridaScript *handle;
|
11
|
+
uint port;
|
12
|
+
} enable_debugger_proxy_args;
|
13
|
+
|
14
|
+
typedef struct {
|
15
|
+
FridaScript *handle;
|
16
|
+
char * message;
|
17
|
+
GBytes * data;
|
18
|
+
} post_proxy_args;
|
19
|
+
|
20
|
+
void define_Script();
|
21
|
+
VALUE Script_from_FridaScript(FridaScript *handle);
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
extern VALUE mCFrida;
|
6
|
+
extern VALUE cSession;
|
7
|
+
|
8
|
+
typedef struct {
|
9
|
+
FridaSession *handle;
|
10
|
+
char *source;
|
11
|
+
FridaScriptOptions *options;
|
12
|
+
} create_script_sync_proxy_args;
|
13
|
+
|
14
|
+
typedef create_script_sync_proxy_args compile_script_sync_proxy_args;
|
15
|
+
|
16
|
+
typedef struct {
|
17
|
+
FridaSession *handle;
|
18
|
+
char *embed_script;
|
19
|
+
FridaSnapshotOptions *options;
|
20
|
+
} snapshot_script_sync_proxy_args;
|
21
|
+
|
22
|
+
typedef struct {
|
23
|
+
FridaSession *handle;
|
24
|
+
GBytes *bytes;
|
25
|
+
FridaScriptOptions *options;
|
26
|
+
} create_script_from_bytes_sync_proxy_args;
|
27
|
+
|
28
|
+
typedef struct {
|
29
|
+
FridaSession *handle;
|
30
|
+
FridaPeerOptions *options;
|
31
|
+
} setup_peer_connection_sync_proxy_args;
|
32
|
+
|
33
|
+
typedef struct {
|
34
|
+
FridaSession *handle;
|
35
|
+
char *address;
|
36
|
+
FridaPortalOptions *options;
|
37
|
+
} join_portal_sync_proxy_args;
|
38
|
+
|
39
|
+
void define_Session();
|
40
|
+
VALUE Session_from_FridaSession(FridaSession *stream);
|
@@ -0,0 +1,129 @@
|
|
1
|
+
#ifndef FRIDA_RUBY_H
|
2
|
+
#define FRIDA_RUBY_H 1
|
3
|
+
|
4
|
+
#include "ruby.h"
|
5
|
+
#include "ruby/thread.h"
|
6
|
+
#include "ruby/vm.h"
|
7
|
+
#include "frida-core.h"
|
8
|
+
|
9
|
+
typedef struct _GObject_d {
|
10
|
+
void *handle;
|
11
|
+
void (*destroy)(void *);
|
12
|
+
GSList *signal_closures;
|
13
|
+
} GObject_d;
|
14
|
+
|
15
|
+
#define FRIDA_TYPE_RB_AUTHENTICATION_SERVICE frida_rb_authentication_service_get_type()
|
16
|
+
G_DECLARE_FINAL_TYPE(FridaRBAuthenticationService, frida_rb_authentication_service, FRIDA, RB_AUTHENTICATION_SERVICE, GObject)
|
17
|
+
|
18
|
+
#include "gutils.h"
|
19
|
+
|
20
|
+
#include "GObject.h"
|
21
|
+
#include "DeviceManager.h"
|
22
|
+
#include "Device.h"
|
23
|
+
#include "Bus.h"
|
24
|
+
#include "IOStream.h"
|
25
|
+
#include "Application.h"
|
26
|
+
#include "Process.h"
|
27
|
+
#include "Spawn.h"
|
28
|
+
#include "Child.h"
|
29
|
+
#include "Session.h"
|
30
|
+
#include "Script.h"
|
31
|
+
#include "Relay.h"
|
32
|
+
#include "PortalMembership.h"
|
33
|
+
#include "Crash.h"
|
34
|
+
#include "FileMonitor.h"
|
35
|
+
#include "Compiler.h"
|
36
|
+
#include "EndpointParameters.h"
|
37
|
+
#include "PortalService.h"
|
38
|
+
|
39
|
+
#include "gvl_bridge.h"
|
40
|
+
|
41
|
+
extern const rb_data_type_t GObject_dt;
|
42
|
+
|
43
|
+
#define DEFINE_KLASS_DATA_TYPE(klass) \
|
44
|
+
const rb_data_type_t klass##_dt = { \
|
45
|
+
.wrap_struct_name = "Frida::" #klass "Data", \
|
46
|
+
.function = { \
|
47
|
+
.dcompact = NULL, \
|
48
|
+
.dmark = NULL, \
|
49
|
+
.dsize = NULL, \
|
50
|
+
.dfree = (void (*)(void*))klass##_free, \
|
51
|
+
}, \
|
52
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY \
|
53
|
+
};
|
54
|
+
|
55
|
+
#define DEFINE_GOBJECT_CHILD_KLASS_DATA_TYPE(klass) \
|
56
|
+
static const rb_data_type_t klass##_dt = { \
|
57
|
+
.wrap_struct_name = "Frida::" #klass "Data", \
|
58
|
+
.function = { \
|
59
|
+
.dcompact = NULL, \
|
60
|
+
.dmark = NULL, \
|
61
|
+
.dsize = NULL, \
|
62
|
+
.dfree = (void (*)(void*))klass##_free, \
|
63
|
+
}, \
|
64
|
+
.parent = &GObject_dt, \
|
65
|
+
.flags = RUBY_TYPED_FREE_IMMEDIATELY \
|
66
|
+
};
|
67
|
+
|
68
|
+
#define MAKE_DATA(k) \
|
69
|
+
k##_d *d; \
|
70
|
+
VALUE obj = TypedData_Make_Struct(klass, k##_d, &k##_dt, d);
|
71
|
+
|
72
|
+
#define MAKE_DATA_EX(k, var) \
|
73
|
+
k##_d *var; \
|
74
|
+
VALUE obj = TypedData_Make_Struct(klass, k##_d, &k##_dt, var);
|
75
|
+
|
76
|
+
#define GET_DATA(klass) \
|
77
|
+
klass##_d *d; \
|
78
|
+
TypedData_Get_Struct(self, klass##_d, &klass##_dt, d);
|
79
|
+
|
80
|
+
#define GET_DATA_EX(klass, self, var) \
|
81
|
+
klass##_d *var; \
|
82
|
+
TypedData_Get_Struct(self, klass##_d, &klass##_dt, var);
|
83
|
+
|
84
|
+
#define GET_GOBJECT_DATA() \
|
85
|
+
GET_DATA(GObject);
|
86
|
+
|
87
|
+
#define REQUIRE_GOBJECT_HANDLE() \
|
88
|
+
if (!d->handle) return (Qnil);
|
89
|
+
|
90
|
+
#define CALL_GVL_FREE(func, arg) \
|
91
|
+
rb_thread_call_without_gvl((void_fp)func##_gvl_free, arg, NULL, NULL);
|
92
|
+
|
93
|
+
typedef struct {
|
94
|
+
void *ret;
|
95
|
+
GError *gerr;
|
96
|
+
} gvl_free_proxy_result;
|
97
|
+
|
98
|
+
#define GVL_FREE_PROXY_FUNC(name, arg) \
|
99
|
+
static gvl_free_proxy_result *name##_gvl_free(arg)
|
100
|
+
|
101
|
+
#define GERROR_BLOCK \
|
102
|
+
gerror: \
|
103
|
+
raise_rerror(NULL, _gerr); \
|
104
|
+
return (Qnil);
|
105
|
+
|
106
|
+
#define UNREACHABLE_GERROR_BLOCK GERROR_BLOCK
|
107
|
+
|
108
|
+
#define RETURN_GVL_FREE_RESULT(_ret) \
|
109
|
+
gvl_free_proxy_result *result = malloc(sizeof(gvl_free_proxy_result)); \
|
110
|
+
result->ret = _ret; \
|
111
|
+
result->gerr = gerr; \
|
112
|
+
return (result);
|
113
|
+
|
114
|
+
#define CALL_GVL_FREE_WITH_RET(_ret, func, arg) \
|
115
|
+
gvl_free_proxy_result *result = (gvl_free_proxy_result *)rb_thread_call_without_gvl((void_fp)func##_gvl_free, arg, NULL, NULL); \
|
116
|
+
_ret = result->ret; \
|
117
|
+
GError *_gerr = result->gerr; \
|
118
|
+
free(result); \
|
119
|
+
if (_gerr) goto gerror;
|
120
|
+
|
121
|
+
#define TO_RBCLOSURE(c) ((RBClosure *)c)
|
122
|
+
|
123
|
+
typedef void *(*void_fp)(void *);
|
124
|
+
|
125
|
+
void Init_c_frida(void);
|
126
|
+
void raise_rerror(char *err, GError *gerr);
|
127
|
+
void raise_argerror(char *err);
|
128
|
+
|
129
|
+
#endif
|
@@ -0,0 +1,21 @@
|
|
1
|
+
#pragma once
|
2
|
+
|
3
|
+
#include "c_frida.h"
|
4
|
+
|
5
|
+
VALUE rbGObject_marshal_string(const gchar * str);
|
6
|
+
VALUE rbGObject_marshal_enum(gint value, GType type);
|
7
|
+
VALUE rbGObject_marshal_variant(GVariant * variant);
|
8
|
+
gboolean rbGObject_unmarshal_certificate(const gchar *str, GTlsCertificate **certificate);
|
9
|
+
gboolean rbGObject_unmarshal_enum(const gchar *str, GType type, gpointer value);
|
10
|
+
VALUE rbGObject_marshal_dict(GHashTable *dict);
|
11
|
+
VALUE rbApplication_marshal_parameters_dict(GHashTable * dict);
|
12
|
+
#define rbProcess_marshal_parameters_dict rbApplication_marshal_parameters_dict
|
13
|
+
gboolean rbGObject_unmarshal_strv(VALUE value, gchar ***strv, gint *length);
|
14
|
+
gboolean rbGObject_unmarshal_envp(VALUE hash, gchar ***envp, gint *length);
|
15
|
+
gboolean rbGObject_unmarshal_string(VALUE value, gchar **str);
|
16
|
+
gboolean rbGObject_unmarshal_variant(VALUE value, GVariant ** variant);
|
17
|
+
VALUE rbGObject_marshal_strv(gchar **strv, gint length);
|
18
|
+
VALUE rbGObject_marshal_envp(const gchar **envp, gint length);
|
19
|
+
VALUE rbGObject_marshal_value(const GValue *value);
|
20
|
+
VALUE *rbGObjectSignalClosure_marshal_params(const GValue *params, guint params_length);
|
21
|
+
VALUE rbGObject_marshal_bytes(GBytes * bytes);
|