frida 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (55) hide show
  1. checksums.yaml +4 -4
  2. data/CODE_OF_CONDUCT.md +84 -0
  3. data/Gemfile +12 -0
  4. data/Gemfile.lock +25 -0
  5. data/LICENSE.txt +21 -0
  6. data/README.md +64 -0
  7. data/Rakefile +20 -0
  8. data/exe/frida +3 -0
  9. data/ext/c_frida/Application.c +79 -0
  10. data/ext/c_frida/Bus.c +91 -0
  11. data/ext/c_frida/Child.c +134 -0
  12. data/ext/c_frida/Compiler.c +208 -0
  13. data/ext/c_frida/Crash.c +92 -0
  14. data/ext/c_frida/Device.c +955 -0
  15. data/ext/c_frida/DeviceManager.c +260 -0
  16. data/ext/c_frida/EndpointParameters.c +189 -0
  17. data/ext/c_frida/FileMonitor.c +67 -0
  18. data/ext/c_frida/GObject.c +138 -0
  19. data/ext/c_frida/IOStream.c +228 -0
  20. data/ext/c_frida/PortalMembership.c +43 -0
  21. data/ext/c_frida/PortalService.c +413 -0
  22. data/ext/c_frida/Process.c +67 -0
  23. data/ext/c_frida/Relay.c +121 -0
  24. data/ext/c_frida/Script.c +221 -0
  25. data/ext/c_frida/Session.c +626 -0
  26. data/ext/c_frida/Spawn.c +53 -0
  27. data/ext/c_frida/c_frida.c +68 -0
  28. data/ext/c_frida/extconf.rb +26 -25
  29. data/ext/c_frida/gutils.c +498 -0
  30. data/ext/c_frida/gvl_bridge.c +131 -0
  31. data/ext/c_frida/inc/Application.h +9 -0
  32. data/ext/c_frida/inc/Bus.h +15 -0
  33. data/ext/c_frida/inc/Child.h +9 -0
  34. data/ext/c_frida/inc/Compiler.h +21 -0
  35. data/ext/c_frida/inc/Crash.h +9 -0
  36. data/ext/c_frida/inc/Device.h +71 -0
  37. data/ext/c_frida/inc/DeviceManager.h +20 -0
  38. data/ext/c_frida/inc/EndpointParameters.h +15 -0
  39. data/ext/c_frida/inc/FileMonitor.h +9 -0
  40. data/ext/c_frida/inc/GObject.h +10 -0
  41. data/ext/c_frida/inc/IOStream.h +29 -0
  42. data/ext/c_frida/inc/PortalMembership.h +9 -0
  43. data/ext/c_frida/inc/PortalService.h +47 -0
  44. data/ext/c_frida/inc/Process.h +9 -0
  45. data/ext/c_frida/inc/Relay.h +9 -0
  46. data/ext/c_frida/inc/Script.h +21 -0
  47. data/ext/c_frida/inc/Session.h +40 -0
  48. data/ext/c_frida/inc/Spawn.h +9 -0
  49. data/ext/c_frida/inc/c_frida.h +129 -0
  50. data/ext/c_frida/inc/gutils.h +21 -0
  51. data/ext/c_frida/inc/gvl_bridge.h +42 -0
  52. data/frida.gemspec +39 -0
  53. data/lib/frida/version.rb +5 -0
  54. data/lib/frida.rb +8 -0
  55. 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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cApplication;
7
+
8
+ void define_Application();
9
+ VALUE Application_from_FridaApplication(FridaApplication *handle);
@@ -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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cChild;
7
+
8
+ void define_Child();
9
+ VALUE Child_from_FridaChild(FridaChild *stream);
@@ -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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cCrash;
7
+
8
+ void define_Crash();
9
+ VALUE Crash_from_FridaCrash(FridaCrash *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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cFileMonitor;
7
+
8
+ void define_FileMonitor();
9
+ VALUE FileMonitor_from_FridaFileMonitor(FridaFileMonitor *handle);
@@ -0,0 +1,10 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cGObject;
7
+
8
+ void GObject_free(GObject_d *d);
9
+
10
+ void define_GObject();
@@ -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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cPortalMembership;
7
+
8
+ void define_PortalMembership();
9
+ VALUE PortalMembership_from_FridaPortalMembership(FridaPortalMembership *handle);
@@ -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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cProcess;
7
+
8
+ void define_Process();
9
+ VALUE Process_from_FridaProcess(FridaProcess *handle);
@@ -0,0 +1,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cRelay;
7
+
8
+ void define_Relay();
9
+ VALUE Relay_from_FridaRelay(FridaRelay *handle);
@@ -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,9 @@
1
+ #pragma once
2
+
3
+ #include "c_frida.h"
4
+
5
+ extern VALUE mCFrida;
6
+ extern VALUE cSpawn;
7
+
8
+ void define_Spawn();
9
+ VALUE Spawn_from_FridaSpawn(FridaSpawn *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);