frooky 0.1.2__py3-none-any.whl → 0.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
frooky/_version.py CHANGED
@@ -28,7 +28,7 @@ version_tuple: VERSION_TUPLE
28
28
  commit_id: COMMIT_ID
29
29
  __commit_id__: COMMIT_ID
30
30
 
31
- __version__ = version = '0.1.2'
32
- __version_tuple__ = version_tuple = (0, 1, 2)
31
+ __version__ = version = '0.2.0'
32
+ __version_tuple__ = version_tuple = (0, 2, 0)
33
33
 
34
34
  __commit_id__ = commit_id = None
@@ -0,0 +1,207 @@
1
+ 📦
2
+ 58138 /build/index.frooky.js
3
+
4
+ var Z=null,J={exceptions:"propagate"};function V(){if(Z!==null)return Z;let e={},t=[{module:"libsystem_malloc.dylib",functions:{free:["void",["pointer"]]}},{module:"libobjc.A.dylib",functions:{objc_msgSend:function(n){this.objc_msgSend=n},objc_msgSend_stret:function(n){this.objc_msgSend_stret=n},objc_msgSend_fpret:function(n){this.objc_msgSend_fpret=n},objc_msgSendSuper:function(n){this.objc_msgSendSuper=n},objc_msgSendSuper_stret:function(n){this.objc_msgSendSuper_stret=n},objc_msgSendSuper_fpret:function(n){this.objc_msgSendSuper_fpret=n},objc_getClassList:["int",["pointer","int"]],objc_lookUpClass:["pointer",["pointer"]],objc_allocateClassPair:["pointer",["pointer","pointer","pointer"]],objc_disposeClassPair:["void",["pointer"]],objc_registerClassPair:["void",["pointer"]],class_isMetaClass:["bool",["pointer"]],class_getName:["pointer",["pointer"]],class_getImageName:["pointer",["pointer"]],class_copyProtocolList:["pointer",["pointer","pointer"]],class_copyMethodList:["pointer",["pointer","pointer"]],class_getClassMethod:["pointer",["pointer","pointer"]],class_getInstanceMethod:["pointer",["pointer","pointer"]],class_getSuperclass:["pointer",["pointer"]],class_addProtocol:["bool",["pointer","pointer"]],class_addMethod:["bool",["pointer","pointer","pointer","pointer"]],class_copyIvarList:["pointer",["pointer","pointer"]],objc_getProtocol:["pointer",["pointer"]],objc_copyProtocolList:["pointer",["pointer"]],objc_allocateProtocol:["pointer",["pointer"]],objc_registerProtocol:["void",["pointer"]],protocol_getName:["pointer",["pointer"]],protocol_copyMethodDescriptionList:["pointer",["pointer","bool","bool","pointer"]],protocol_copyPropertyList:["pointer",["pointer","pointer"]],protocol_copyProtocolList:["pointer",["pointer","pointer"]],protocol_addProtocol:["void",["pointer","pointer"]],protocol_addMethodDescription:["void",["pointer","pointer","pointer","bool","bool"]],ivar_getName:["pointer",["pointer"]],ivar_getTypeEncoding:["pointer",["pointer"]],ivar_getOffset:["pointer",["pointer"]],object_isClass:["bool",["pointer"]],object_getClass:["pointer",["pointer"]],object_getClassName:["pointer",["pointer"]],method_getName:["pointer",["pointer"]],method_getTypeEncoding:["pointer",["pointer"]],method_getImplementation:["pointer",["pointer"]],method_setImplementation:["pointer",["pointer","pointer"]],property_getName:["pointer",["pointer"]],property_copyAttributeList:["pointer",["pointer","pointer"]],sel_getName:["pointer",["pointer"]],sel_registerName:["pointer",["pointer"]],class_getInstanceSize:["pointer",["pointer"]]},optionals:{objc_msgSend_stret:"ABI",objc_msgSend_fpret:"ABI",objc_msgSendSuper_stret:"ABI",objc_msgSendSuper_fpret:"ABI",object_isClass:"iOS8"}},{module:"libdispatch.dylib",functions:{dispatch_async_f:["void",["pointer","pointer","pointer"]]},variables:{_dispatch_main_q:function(n){this._dispatch_main_q=n}}}],r=0;return t.forEach(function(n){let i=n.module==="libobjc.A.dylib",s=n.functions||{},a=n.variables||{},c=n.optionals||{};r+=Object.keys(s).length+Object.keys(a).length;let o=(Process.findModuleByName(n.module)?.enumerateExports()??[]).reduce(function(l,u){return l[u.name]=u,l},{});Object.keys(s).forEach(function(l){let u=o[l];if(u!==void 0&&u.type==="function"){let d=s[l];typeof d=="function"?(d.call(e,u.address),i&&d.call(e,u.address)):(e[l]=new NativeFunction(u.address,d[0],d[1],J),i&&(e[l]=e[l])),r--}else c[l]&&r--}),Object.keys(a).forEach(function(l){let u=o[l];u!==void 0&&u.type==="variable"&&(a[l].call(e,u.address),r--)})}),r===0&&(e.objc_msgSend_stret||(e.objc_msgSend_stret=e.objc_msgSend),e.objc_msgSend_fpret||(e.objc_msgSend_fpret=e.objc_msgSend),e.objc_msgSendSuper_stret||(e.objc_msgSendSuper_stret=e.objc_msgSendSuper),e.objc_msgSendSuper_fpret||(e.objc_msgSendSuper_fpret=e.objc_msgSendSuper),Z=e),Z}var ue=`#include <glib.h>
5
+ #include <ptrauth.h>
6
+
7
+ #define KERN_SUCCESS 0
8
+ #define MALLOC_PTR_IN_USE_RANGE_TYPE 1
9
+ #if defined (HAVE_I386) && GLIB_SIZEOF_VOID_P == 8
10
+ # define OBJC_ISA_MASK 0x7ffffffffff8ULL
11
+ #elif defined (HAVE_ARM64)
12
+ # define OBJC_ISA_MASK 0xffffffff8ULL
13
+ #endif
14
+
15
+ typedef struct _ChooseContext ChooseContext;
16
+
17
+ typedef struct _malloc_zone_t malloc_zone_t;
18
+ typedef struct _malloc_introspection_t malloc_introspection_t;
19
+ typedef struct _vm_range_t vm_range_t;
20
+
21
+ typedef gpointer Class;
22
+ typedef int kern_return_t;
23
+ typedef guint mach_port_t;
24
+ typedef mach_port_t task_t;
25
+ typedef guintptr vm_offset_t;
26
+ typedef guintptr vm_size_t;
27
+ typedef vm_offset_t vm_address_t;
28
+
29
+ struct _ChooseContext
30
+ {
31
+ GHashTable * classes;
32
+ GArray * matches;
33
+ };
34
+
35
+ struct _malloc_zone_t
36
+ {
37
+ void * reserved1;
38
+ void * reserved2;
39
+ size_t (* size) (struct _malloc_zone_t * zone, const void * ptr);
40
+ void * (* malloc) (struct _malloc_zone_t * zone, size_t size);
41
+ void * (* calloc) (struct _malloc_zone_t * zone, size_t num_items, size_t size);
42
+ void * (* valloc) (struct _malloc_zone_t * zone, size_t size);
43
+ void (* free) (struct _malloc_zone_t * zone, void * ptr);
44
+ void * (* realloc) (struct _malloc_zone_t * zone, void * ptr, size_t size);
45
+ void (* destroy) (struct _malloc_zone_t * zone);
46
+ const char * zone_name;
47
+
48
+ unsigned (* batch_malloc) (struct _malloc_zone_t * zone, size_t size, void ** results, unsigned num_requested);
49
+ void (* batch_free) (struct _malloc_zone_t * zone, void ** to_be_freed, unsigned num_to_be_freed);
50
+
51
+ malloc_introspection_t * introspect;
52
+ };
53
+
54
+ typedef kern_return_t (* memory_reader_t) (task_t remote_task, vm_address_t remote_address, vm_size_t size, void ** local_memory);
55
+ typedef void (* vm_range_recorder_t) (task_t task, void * user_data, unsigned type, vm_range_t * ranges, unsigned count);
56
+ typedef kern_return_t (* enumerator_func) (task_t task, void * user_data, unsigned type_mask, vm_address_t zone_address, memory_reader_t reader,
57
+ vm_range_recorder_t recorder);
58
+
59
+ struct _malloc_introspection_t
60
+ {
61
+ enumerator_func enumerator;
62
+ };
63
+
64
+ struct _vm_range_t
65
+ {
66
+ vm_address_t address;
67
+ vm_size_t size;
68
+ };
69
+
70
+ extern int objc_getClassList (Class * buffer, int buffer_count);
71
+ extern Class class_getSuperclass (Class cls);
72
+ extern size_t class_getInstanceSize (Class cls);
73
+ extern kern_return_t malloc_get_all_zones (task_t task, memory_reader_t reader, vm_address_t ** addresses, unsigned * count);
74
+
75
+ static void collect_subclasses (Class klass, GHashTable * result);
76
+ static void collect_matches_in_ranges (task_t task, void * user_data, unsigned type, vm_range_t * ranges, unsigned count);
77
+ static kern_return_t read_local_memory (task_t remote_task, vm_address_t remote_address, vm_size_t size, void ** local_memory);
78
+
79
+ extern mach_port_t selfTask;
80
+
81
+ gpointer *
82
+ choose (Class * klass,
83
+ gboolean consider_subclasses,
84
+ guint * count)
85
+ {
86
+ ChooseContext ctx;
87
+ GHashTable * classes;
88
+ vm_address_t * malloc_zone_addresses;
89
+ unsigned malloc_zone_count, i;
90
+
91
+ classes = g_hash_table_new_full (NULL, NULL, NULL, NULL);
92
+ ctx.classes = classes;
93
+ ctx.matches = g_array_new (FALSE, FALSE, sizeof (gpointer));
94
+ if (consider_subclasses)
95
+ collect_subclasses (klass, classes);
96
+ else
97
+ g_hash_table_insert (classes, klass, GSIZE_TO_POINTER (class_getInstanceSize (klass)));
98
+
99
+ malloc_zone_count = 0;
100
+ malloc_get_all_zones (selfTask, read_local_memory, &malloc_zone_addresses, &malloc_zone_count);
101
+
102
+ for (i = 0; i != malloc_zone_count; i++)
103
+ {
104
+ vm_address_t zone_address = malloc_zone_addresses[i];
105
+ malloc_zone_t * zone = (malloc_zone_t *) zone_address;
106
+ enumerator_func enumerator;
107
+
108
+ if (zone != NULL && zone->introspect != NULL &&
109
+ (enumerator = (ptrauth_strip (zone->introspect, ptrauth_key_asda))->enumerator) != NULL)
110
+ {
111
+ enumerator = ptrauth_sign_unauthenticated (
112
+ ptrauth_strip (enumerator, ptrauth_key_asia),
113
+ ptrauth_key_asia, 0);
114
+
115
+ enumerator (selfTask, &ctx, MALLOC_PTR_IN_USE_RANGE_TYPE, zone_address, read_local_memory,
116
+ collect_matches_in_ranges);
117
+ }
118
+ }
119
+
120
+ g_hash_table_unref (classes);
121
+
122
+ *count = ctx.matches->len;
123
+
124
+ return (gpointer *) g_array_free (ctx.matches, FALSE);
125
+ }
126
+
127
+ void
128
+ destroy (gpointer mem)
129
+ {
130
+ g_free (mem);
131
+ }
132
+
133
+ static void
134
+ collect_subclasses (Class klass,
135
+ GHashTable * result)
136
+ {
137
+ Class * classes;
138
+ int count, i;
139
+
140
+ count = objc_getClassList (NULL, 0);
141
+ classes = g_malloc (count * sizeof (gpointer));
142
+ count = objc_getClassList (classes, count);
143
+
144
+ for (i = 0; i != count; i++)
145
+ {
146
+ Class candidate = classes[i];
147
+ Class c;
148
+
149
+ c = candidate;
150
+ do
151
+ {
152
+ if (c == klass)
153
+ {
154
+ g_hash_table_insert (result, candidate, GSIZE_TO_POINTER (class_getInstanceSize (candidate)));
155
+ break;
156
+ }
157
+
158
+ c = class_getSuperclass (c);
159
+ }
160
+ while (c != NULL);
161
+ }
162
+
163
+ g_free (classes);
164
+ }
165
+
166
+ static void
167
+ collect_matches_in_ranges (task_t task,
168
+ void * user_data,
169
+ unsigned type,
170
+ vm_range_t * ranges,
171
+ unsigned count)
172
+ {
173
+ ChooseContext * ctx = user_data;
174
+ GHashTable * classes = ctx->classes;
175
+ unsigned i;
176
+
177
+ for (i = 0; i != count; i++)
178
+ {
179
+ const vm_range_t * range = &ranges[i];
180
+ gconstpointer candidate = GSIZE_TO_POINTER (range->address);
181
+ gconstpointer isa;
182
+ guint instance_size;
183
+
184
+ isa = *(gconstpointer *) candidate;
185
+ #ifdef OBJC_ISA_MASK
186
+ isa = GSIZE_TO_POINTER (GPOINTER_TO_SIZE (isa) & OBJC_ISA_MASK);
187
+ #endif
188
+
189
+ instance_size = GPOINTER_TO_UINT (g_hash_table_lookup (classes, isa));
190
+ if (instance_size != 0 && range->size >= instance_size)
191
+ {
192
+ g_array_append_val (ctx->matches, candidate);
193
+ }
194
+ }
195
+ }
196
+
197
+ static kern_return_t
198
+ read_local_memory (task_t remote_task,
199
+ vm_address_t remote_address,
200
+ vm_size_t size,
201
+ void ** local_memory)
202
+ {
203
+ *local_memory = (void *) remote_address;
204
+
205
+ return KERN_SUCCESS;
206
+ }
207
+ `,{pointerSize:de}=Process,ee=null;function oe(){return ee===null&&(ee=fe()),ee}function fe(){let{objc_getClassList:e,class_getSuperclass:t,class_getInstanceSize:r}=V(),n=Memory.alloc(4);n.writeU32(Module.getGlobalExportByName("mach_task_self_").readU32());let i=new CModule(ue,{objc_getClassList:e,class_getSuperclass:t,class_getInstanceSize:r,malloc_get_all_zones:Process.getModuleByName("/usr/lib/system/libsystem_malloc.dylib").getExportByName("malloc_get_all_zones"),selfTask:n}),s=new NativeFunction(i.choose,"pointer",["pointer","bool","pointer"]),a=new NativeFunction(i.destroy,"void",["pointer"]);return{handle:i,choose(c,o){let l=[],u=Memory.alloc(4),d=s(c,o?1:0,u);try{let y=u.readU32();for(let p=0;p!==y;p++)l.push(d.add(p*de).readPointer())}finally{a(d)}return l}}}function me(){let pointerSize=Process.pointerSize,api=null,apiError=null,realizedClasses=new Set,classRegistry=new ClassRegistry,protocolRegistry=new ProtocolRegistry,replacedMethods=new Map,scheduledWork=new Map,nextId=1,workCallback=null,NSAutoreleasePool=null,bindings=new Map,readObjectIsa=null,msgSendBySignatureId=new Map,msgSendSuperBySignatureId=new Map,cachedNSString=null,cachedNSStringCtor=null,cachedNSNumber=null,cachedNSNumberCtor=null,singularTypeById=null,modifiers=null;try{tryInitialize()}catch(e){}function tryInitialize(){if(api!==null)return!0;if(apiError!==null)throw apiError;try{api=V()}catch(e){throw apiError=e,e}return api!==null}function dispose(){for(let[e,t]of replacedMethods.entries()){let r=ptr(e),[n,i]=t;api.method_getImplementation(r).equals(i)&&api.method_setImplementation(r,n)}replacedMethods.clear()}Script.bindWeak(this,dispose),Object.defineProperty(this,"available",{enumerable:!0,get(){return tryInitialize()}}),Object.defineProperty(this,"api",{enumerable:!0,get(){return V()}}),Object.defineProperty(this,"classes",{enumerable:!0,value:classRegistry}),Object.defineProperty(this,"protocols",{enumerable:!0,value:protocolRegistry}),Object.defineProperty(this,"Object",{enumerable:!0,value:ObjCObject}),Object.defineProperty(this,"Protocol",{enumerable:!0,value:ObjCProtocol}),Object.defineProperty(this,"Block",{enumerable:!0,value:Block}),Object.defineProperty(this,"mainQueue",{enumerable:!0,get(){return api?._dispatch_main_q??null}}),Object.defineProperty(this,"registerProxy",{enumerable:!0,value:registerProxy}),Object.defineProperty(this,"registerClass",{enumerable:!0,value:registerClass}),Object.defineProperty(this,"registerProtocol",{enumerable:!0,value:registerProtocol}),Object.defineProperty(this,"bind",{enumerable:!0,value:bind}),Object.defineProperty(this,"unbind",{enumerable:!0,value:unbind}),Object.defineProperty(this,"getBoundData",{enumerable:!0,value:getBoundData}),Object.defineProperty(this,"enumerateLoadedClasses",{enumerable:!0,value:enumerateLoadedClasses}),Object.defineProperty(this,"enumerateLoadedClassesSync",{enumerable:!0,value:enumerateLoadedClassesSync}),Object.defineProperty(this,"choose",{enumerable:!0,value:choose}),Object.defineProperty(this,"chooseSync",{enumerable:!0,value(e){let t=[];return choose(e,{onMatch(r){t.push(r)},onComplete(){}}),t}}),this.schedule=function(e,t){let r=ptr(nextId++);scheduledWork.set(r.toString(),t),workCallback===null&&(workCallback=new NativeCallback(performScheduledWorkItem,"void",["pointer"])),Script.pin(),api.dispatch_async_f(e,r,workCallback)};function performScheduledWorkItem(e){let t=e.toString(),r=scheduledWork.get(t);scheduledWork.delete(t),NSAutoreleasePool===null&&(NSAutoreleasePool=classRegistry.NSAutoreleasePool);let n=NSAutoreleasePool.alloc().init(),i=null;try{r()}catch(s){i=s}n.release(),setImmediate(performScheduledWorkCleanup,i)}function performScheduledWorkCleanup(e){if(Script.unpin(),e!==null)throw e}this.implement=function(e,t){return new NativeCallback(t,e.returnType,e.argumentTypes)},this.selector=selector,this.selectorAsString=selectorAsString;function selector(e){return api.sel_registerName(Memory.allocUtf8String(e))}function selectorAsString(e){return api.sel_getName(e).readUtf8String()}let registryBuiltins=new Set(["prototype","constructor","hasOwnProperty","toJSON","toString","valueOf"]);function ClassRegistry(){let e={},t=0,r=new Proxy(this,{has(l,u){return n(u)},get(l,u,d){switch(u){case"prototype":return l.prototype;case"constructor":return l.constructor;case"hasOwnProperty":return n;case"toJSON":return a;case"toString":return c;case"valueOf":return o;default:let y=s(u);return y!==null?y:void 0}},set(l,u,d,y){return!1},ownKeys(l){if(api===null)return[];let u=api.objc_getClassList(NULL,0);if(u!==t){let d=Memory.alloc(u*pointerSize);u=api.objc_getClassList(d,u);for(let y=0;y!==u;y++){let p=d.add(y*pointerSize).readPointer(),_=api.class_getName(p).readUtf8String();e[_]=p}t=u}return Object.keys(e)},getOwnPropertyDescriptor(l,u){return{writable:!1,configurable:!0,enumerable:!0}}});function n(l){return registryBuiltins.has(l)?!0:s(l)!==null}function i(l){let u=s(l);if(u===null)throw new Error("Unable to find class '"+l+"'");return u}function s(l){let u=e[l];if(u===void 0){if(u=api.objc_lookUpClass(Memory.allocUtf8String(l)),u.isNull())return null;e[l]=u,t++}return new ObjCObject(u,void 0,!0)}function a(){return Object.keys(r).reduce(function(l,u){return l[u]=i(u).toJSON(),l},{})}function c(){return"ClassRegistry"}function o(){return"ClassRegistry"}return r}function ProtocolRegistry(){let e={},t=0,r=new Proxy(this,{has(o,l){return n(l)},get(o,l,u){switch(l){case"prototype":return o.prototype;case"constructor":return o.constructor;case"hasOwnProperty":return n;case"toJSON":return s;case"toString":return a;case"valueOf":return c;default:let d=i(l);return d!==null?d:void 0}},set(o,l,u,d){return!1},ownKeys(o){if(api===null)return[];let l=Memory.alloc(pointerSize),u=api.objc_copyProtocolList(l);try{let d=l.readUInt();if(d!==t){e={};for(let y=0;y!==d;y++){let p=u.add(y*pointerSize).readPointer(),_=api.protocol_getName(p).readUtf8String();e[_]=p}t=d}}finally{api.free(u)}return Object.keys(e)},getOwnPropertyDescriptor(o,l){return{writable:!1,configurable:!0,enumerable:!0}}});function n(o){return registryBuiltins.has(o)?!0:i(o)!==null}function i(o){let l=e[o];if(l===void 0){if(l=api.objc_getProtocol(Memory.allocUtf8String(o)),l.isNull())return null;e[o]=l,t++}return new ObjCProtocol(l)}function s(){return Object.keys(r).reduce(function(o,l){return o[l]={handle:e[l]},o},{})}function a(){return"ProtocolRegistry"}function c(){return"ProtocolRegistry"}return r}let objCObjectBuiltins=new Set(["prototype","constructor","handle","hasOwnProperty","toJSON","toString","valueOf","equals","$kind","$super","$superClass","$class","$className","$moduleName","$protocols","$methods","$ownMethods","$ivars"]);function ObjCObject(e,t,r,n){let i=null,s=null,a=null,c=null,o=null,l=null,u=null,d=null,y=null,p=null,_=null,h={},S=null,v=null,O=null;if(e=getHandle(e),r===void 0){let b=api.object_getClass(e),g=b.toString();realizedClasses.has(g)||(api.objc_lookUpClass(api.class_getName(b)),realizedClasses.add(g))}let w=new Proxy(this,{has(b,g){return j(g)},get(b,g,C){switch(g){case"handle":return e;case"prototype":return b.prototype;case"constructor":return b.constructor;case"hasOwnProperty":return j;case"toJSON":return le;case"toString":case"valueOf":let k=C.description;if(k!==void 0){let N=k.call(C);if(N!==null)return N.UTF8String.bind(N)}return function(){return C.$className};case"equals":return ce;case"$kind":return s===null&&(I()?s=api.class_isMetaClass(e)?"meta-class":"class":s="instance"),s;case"$super":if(a===null){let N=api.class_getSuperclass(A());if(N.isNull())a=[null];else{let z=Memory.alloc(2*pointerSize);z.writePointer(e),z.add(pointerSize).writePointer(N),a=[new ObjCObject(e,void 0,r,z)]}}return a[0];case"$superClass":if(c===null){let N=api.class_getSuperclass(A());N.isNull()?c=[null]:c=[new ObjCObject(N)]}return c[0];case"$class":return o===null&&(o=new ObjCObject(api.object_getClass(e),void 0,!0)),o;case"$className":return l===null&&(n?l=api.class_getName(n.add(pointerSize).readPointer()).readUtf8String():I()?l=api.class_getName(e).readUtf8String():l=api.object_getClassName(e).readUtf8String()),l;case"$moduleName":return u===null&&(u=api.class_getImageName(A()).readUtf8String()),u;case"$protocols":if(d===null){d={};let N=Memory.alloc(pointerSize),z=api.class_copyProtocolList(A(),N);if(!z.isNull())try{let D=N.readUInt();for(let P=0;P!==D;P++){let R=z.add(P*pointerSize).readPointer(),F=new ObjCProtocol(R);d[F.name]=F}}finally{api.free(z)}}return d;case"$methods":if(S===null){let N=n?n.add(pointerSize).readPointer():A(),z=api.object_getClass(N),D=new Set,P=z;do{for(let R of collectMethodNames(P,"+ "))D.add(R);P=api.class_getSuperclass(P)}while(!P.isNull());P=N;do{for(let R of collectMethodNames(P,"- "))D.add(R);P=api.class_getSuperclass(P)}while(!P.isNull());S=Array.from(D)}return S;case"$ownMethods":if(v===null){let N=n?n.add(pointerSize).readPointer():A(),z=api.object_getClass(N),D=collectMethodNames(z,"+ "),P=collectMethodNames(N,"- ");v=D.concat(P)}return v;case"$ivars":return O===null&&(I()?O={}:O=new ObjCIvars(w,A())),O;default:if(typeof g=="symbol")return b[g];if(t){let N=L(g);if(N===null||!N.implemented)return}let T=W(g);return T===null?void 0:T}},set(b,g,C,k){return!1},ownKeys(b){if(y===null)if(t){let g=[],C=E();Object.keys(C).forEach(function(k){k[0]!=="+"&&k[0]!=="-"&&C[k].implemented&&g.push(k)}),y=g}else{let g={},C={},k=api.object_getClass(e);do{let T=Memory.alloc(pointerSize),N=api.class_copyMethodList(k,T),z=I()?"+ ":"- ";try{let D=T.readUInt();for(let P=0;P!==D;P++){let R=N.add(P*pointerSize).readPointer(),F=api.method_getName(R),U=api.sel_getName(F).readUtf8String();if(C[U]!==void 0)continue;C[U]=U;let H=jsMethodName(U),te=2,Q=H;for(;g[Q]!==void 0;)te++,Q=H+te;g[Q]=!0;let re=z+U;if(h[re]===void 0){let ne={sel:F,handle:R,wrapper:null};h[re]=ne,h[Q]=ne}}}finally{api.free(N)}k=api.class_getSuperclass(k)}while(!k.isNull());y=Object.keys(g)}return["handle"].concat(y)},getOwnPropertyDescriptor(b,g){return{writable:!1,configurable:!0,enumerable:!0}}});return t&&(_=I()?null:W("- respondsToSelector:")),w;function j(b){if(objCObjectBuiltins.has(b))return!0;if(t){let g=L(b);return!!(g!==null&&g.implemented)}return M(b)!==null}function A(){return i===null&&(i=I()?e:api.object_getClass(e)),i}function I(){return r===void 0&&(api.object_isClass?r=!!api.object_isClass(e):r=!!api.class_isMetaClass(api.object_getClass(e))),r}function M(b){let g=h[b];if(g!==void 0)return g;let C=q(b),k=C[2];if(g=h[k],g!==void 0)return h[b]=g,g;let T=C[0],N=C[1],z=selector(N),D=I()?"+":"-";if(t){let P=L(k);P!==null&&(g={sel:z,types:P.types,wrapper:null,kind:T})}if(g===void 0){let P=T==="+"?api.class_getClassMethod(A(),z):api.class_getInstanceMethod(A(),z);if(!P.isNull())g={sel:z,handle:P,wrapper:null,kind:T};else{if(I()||T!=="-"||N==="forwardingTargetForSelector:"||N==="methodSignatureForSelector:")return null;let R=w;if("- forwardingTargetForSelector:"in w){let H=w.forwardingTargetForSelector_(z);if(H!==null&&H.$kind==="instance")R=H;else return null}else return null;let F=api.class_getInstanceMethod(api.object_getClass(R.handle),z);if(F.isNull())return null;let U=api.method_getTypeEncoding(F).readUtf8String();if((U===null||U==="")&&(U=B(R,k),U===null&&(U=B(w,k)),U===null))return null;g={sel:z,types:U,wrapper:null,kind:T}}}return h[k]=g,h[b]=g,T===D&&(h[jsMethodName(N)]=g),g}function B(b,g){let k=Object.keys(b.$protocols).map(T=>$({},b.$protocols[T])).reduce((T,N)=>(Object.assign(T,N),T),{})[g];return k===void 0?null:k.types}function $(b,g){return g.methods!==void 0&&Object.assign(b,g.methods),g.protocol!==void 0&&$(b,g.protocol),b}function L(b){let C=E()[b];return C!==void 0?C:null}function E(){if(p===null){let b={},g=collectProtocols(t),C=I()?"+":"-";Object.keys(g).forEach(function(k){let N=g[k].methods;Object.keys(N).forEach(function(z){let D=N[z],P=z.substr(2),R=z[0],F=!1,U=!1,H={types:D.types};Object.defineProperty(H,"implemented",{get(){return F||(D.required?U=!0:U=_!==null&&_.call(w,selector(P)),F=!0),U}}),b[z]=H,R===C&&(b[jsMethodName(P)]=H)})}),p=b}return p}function W(b){let g=M(b);if(g===null)return null;let C=g.wrapper;return C===null&&(C=makeMethodInvocationWrapper(g,w,n,J),g.wrapper=C),C}function q(b){let g=/([+\-])\s(\S+)/.exec(b),C,k;g===null?(k=I()?"+":"-",C=objcMethodName(b)):(k=g[1],C=g[2]);let T=[k,C].join(" ");return[k,C,T]}function le(){return{handle:e.toString()}}function ce(b){return e.equals(getHandle(b))}}function getReplacementMethodImplementation(e){let t=replacedMethods.get(e.toString());if(t===void 0)return null;let[,r]=t;return r}function replaceMethodImplementation(e,t){let r=e.toString(),n,i=replacedMethods.get(r);i!==void 0?[n]=i:n=api.method_getImplementation(e),t.equals(n)?replacedMethods.delete(r):replacedMethods.set(r,[n,t]),api.method_setImplementation(e,t)}function collectMethodNames(e,t){let r=[],n=Memory.alloc(pointerSize),i=api.class_copyMethodList(e,n);try{let s=n.readUInt();for(let a=0;a!==s;a++){let c=i.add(a*pointerSize).readPointer(),o=api.method_getName(c),l=api.sel_getName(o).readUtf8String();r.push(t+l)}}finally{api.free(i)}return r}function ObjCProtocol(e){let t=null,r=null,n=null,i=null;Object.defineProperty(this,"handle",{value:e,enumerable:!0}),Object.defineProperty(this,"name",{get(){return t===null&&(t=api.protocol_getName(e).readUtf8String()),t},enumerable:!0}),Object.defineProperty(this,"protocols",{get(){if(r===null){r={};let a=Memory.alloc(pointerSize),c=api.protocol_copyProtocolList(e,a);if(!c.isNull())try{let o=a.readUInt();for(let l=0;l!==o;l++){let u=c.add(l*pointerSize).readPointer(),d=new ObjCProtocol(u);r[d.name]=d}}finally{api.free(c)}}return r},enumerable:!0}),Object.defineProperty(this,"properties",{get(){if(n===null){n={};let a=Memory.alloc(pointerSize),c=api.protocol_copyPropertyList(e,a);if(!c.isNull())try{let o=a.readUInt();for(let l=0;l!==o;l++){let u=c.add(l*pointerSize).readPointer(),d=api.property_getName(u).readUtf8String(),y={},p=api.property_copyAttributeList(u,a);if(!p.isNull())try{let _=a.readUInt();for(let h=0;h!==_;h++){let S=p.add(h*(2*pointerSize)),v=S.readPointer().readUtf8String(),O=S.add(pointerSize).readPointer().readUtf8String();y[v]=O}}finally{api.free(p)}n[d]=y}}finally{api.free(c)}}return n},enumerable:!0}),Object.defineProperty(this,"methods",{get(){if(i===null){i={};let a=Memory.alloc(pointerSize);s(i,a,{required:!0,instance:!1}),s(i,a,{required:!1,instance:!1}),s(i,a,{required:!0,instance:!0}),s(i,a,{required:!1,instance:!0})}return i},enumerable:!0});function s(a,c,o){let l=api.protocol_copyMethodDescriptionList(e,o.required?1:0,o.instance?1:0,c);if(!l.isNull())try{let u=c.readUInt();for(let d=0;d!==u;d++){let y=l.add(d*(2*pointerSize)),p=(o.instance?"- ":"+ ")+selectorAsString(y.readPointer()),_=y.add(pointerSize).readPointer().readUtf8String();a[p]={required:o.required,types:_}}}finally{api.free(l)}}}let objCIvarsBuiltins=new Set(["prototype","constructor","hasOwnProperty","toJSON","toString","valueOf"]);function ObjCIvars(e,t){let r={},n=null,i=[],s=t;do i.unshift(s),s=api.class_getSuperclass(s);while(!s.isNull());let a=Memory.alloc(pointerSize);i.forEach(p=>{let _=api.class_copyIvarList(p,a);try{let h=a.readUInt();for(let S=0;S!==h;S++){let v=_.add(S*pointerSize).readPointer(),O=api.ivar_getName(v).readUtf8String();r[O]=[v,null]}}finally{api.free(_)}});let c=new Proxy(this,{has(p,_){return l(_)},get(p,_,h){switch(_){case"prototype":return p.prototype;case"constructor":return p.constructor;case"hasOwnProperty":return l;case"toJSON":return u;case"toString":return d;case"valueOf":return y;default:let S=o(_);return S===null?void 0:S.get()}},set(p,_,h,S){let v=o(_);if(v===null)throw new Error("Unknown ivar");return v.set(h),!0},ownKeys(p){return n===null&&(n=Object.keys(r)),n},getOwnPropertyDescriptor(p,_){return{writable:!0,configurable:!0,enumerable:!0}}});return c;function o(p){let _=r[p];if(_===void 0)return null;let h=_[1];if(h===null){let S=_[0],v=api.ivar_getOffset(S).toInt32(),O=e.handle.add(v),w=parseType(api.ivar_getTypeEncoding(S).readUtf8String()),j=w.fromNative||identityTransform,A=w.toNative||identityTransform,I,M;p==="isa"?(I=readObjectIsa,M=function(){throw new Error("Unable to set the isa instance variable")}):(I=w.read,M=w.write),h={get(){return j.call(e,I(O))},set(B){M(O,A.call(e,B))}},_[1]=h}return h}function l(p){return objCIvarsBuiltins.has(p)?!0:r.hasOwnProperty(p)}function u(){return Object.keys(c).reduce(function(p,_){return p[_]=c[_],p},{})}function d(){return"ObjCIvars"}function y(){return"ObjCIvars"}}let blockDescriptorAllocSize,blockDescriptorDeclaredSize,blockDescriptorOffsets,blockSize,blockOffsets;pointerSize===4?(blockDescriptorAllocSize=16,blockDescriptorDeclaredSize=20,blockDescriptorOffsets={reserved:0,size:4,rest:8},blockSize=20,blockOffsets={isa:0,flags:4,reserved:8,invoke:12,descriptor:16}):(blockDescriptorAllocSize=32,blockDescriptorDeclaredSize=32,blockDescriptorOffsets={reserved:0,size:8,rest:16},blockSize=32,blockOffsets={isa:0,flags:8,reserved:12,invoke:16,descriptor:24});let BLOCK_HAS_COPY_DISPOSE=1<<25,BLOCK_HAS_CTOR=1<<26,BLOCK_IS_GLOBAL=1<<28,BLOCK_HAS_STRET=1<<29,BLOCK_HAS_SIGNATURE=1<<30;function Block(e,t=J){if(this._options=t,e instanceof NativePointer){let r=e.add(blockOffsets.descriptor).readPointer();this.handle=e;let n=e.add(blockOffsets.flags).readU32();if((n&BLOCK_HAS_SIGNATURE)!==0){let i=(n&BLOCK_HAS_COPY_DISPOSE)!==0?2:0;this.types=r.add(blockDescriptorOffsets.rest+i*pointerSize).readPointer().readCString(),this._signature=parseSignature(this.types)}else this._signature=null}else{this.declare(e);let r=Memory.alloc(blockDescriptorAllocSize+blockSize),n=r.add(blockDescriptorAllocSize),i=Memory.allocUtf8String(this.types);r.add(blockDescriptorOffsets.reserved).writeULong(0),r.add(blockDescriptorOffsets.size).writeULong(blockDescriptorDeclaredSize),r.add(blockDescriptorOffsets.rest).writePointer(i),n.add(blockOffsets.isa).writePointer(classRegistry.__NSGlobalBlock__),n.add(blockOffsets.flags).writeU32(BLOCK_HAS_SIGNATURE|BLOCK_IS_GLOBAL),n.add(blockOffsets.reserved).writeU32(0),n.add(blockOffsets.descriptor).writePointer(r),this.handle=n,this._storage=[r,i],this.implementation=e.implementation}}Object.defineProperties(Block.prototype,{implementation:{enumerable:!0,get(){let e=this.handle.add(blockOffsets.invoke).readPointer().strip(),t=this._getSignature();return makeBlockInvocationWrapper(this,t,new NativeFunction(e.sign(),t.retType.type,t.argTypes.map(function(r){return r.type}),this._options))},set(e){let t=this._getSignature(),r=new NativeCallback(makeBlockImplementationWrapper(this,t,e),t.retType.type,t.argTypes.map(function(a){return a.type}));this._callback=r;let n=this.handle.add(blockOffsets.invoke),i=Memory.queryProtection(n),s=i.includes("w");s||Memory.protect(n,Process.pointerSize,"rw-"),n.writePointer(r.strip().sign("ia",n)),s||Memory.protect(n,Process.pointerSize,i)}},declare:{value(e){let t=e.types;t===void 0&&(t=unparseSignature(e.retType,["block"].concat(e.argTypes))),this.types=t,this._signature=parseSignature(t)}},_getSignature:{value(){let e=this._signature;if(e===null)throw new Error("block is missing signature; call declare()");return e}}});function collectProtocols(e,t){t=t||{},t[e.name]=e;let r=e.protocols;return Object.keys(r).forEach(function(n){collectProtocols(r[n],t)}),t}function registerProxy(e){let t=e.protocols||[],r=e.methods||{},n=e.events||{},i=new Set(Object.keys(r).filter(o=>/([+\-])\s(\S+)/.exec(o)!==null).map(o=>o.split(" ")[1])),s={"- dealloc":function(){let o=this.data.target;"- release"in o&&o.release(),unbind(this.self),this.super.dealloc();let l=this.data.events.dealloc;l!==void 0&&l.call(this)},"- respondsToSelector:":function(o){let l=selectorAsString(o);return i.has(l)?!0:this.data.target.respondsToSelector_(o)},"- forwardingTargetForSelector:":function(o){let l=this.data.events.forward;return l!==void 0&&l.call(this,selectorAsString(o)),this.data.target},"- methodSignatureForSelector:":function(o){return this.data.target.methodSignatureForSelector_(o)},"- forwardInvocation:":function(o){o.invokeWithTarget_(this.data.target)}};for(var a in r)if(r.hasOwnProperty(a)){if(s.hasOwnProperty(a))throw new Error("The '"+a+"' method is reserved");s[a]=r[a]}let c=registerClass({name:e.name,super:classRegistry.NSProxy,protocols:t,methods:s});return function(o,l){o=o instanceof NativePointer?new ObjCObject(o):o,l=l||{};let u=c.alloc().autorelease(),d=getBoundData(u);d.target="- retain"in o?o.retain():o,d.events=n;for(var y in l)if(l.hasOwnProperty(y)){if(d.hasOwnProperty(y))throw new Error("The '"+y+"' property is reserved");d[y]=l[y]}this.handle=u.handle}}function registerClass(e){let t=e.name;t===void 0&&(t=makeClassName());let r=e.super!==void 0?e.super:classRegistry.NSObject,n=e.protocols||[],i=e.methods||{},s=[],a=api.objc_allocateClassPair(r!==null?r.handle:NULL,Memory.allocUtf8String(t),ptr("0"));if(a.isNull())throw new Error("Unable to register already registered class '"+t+"'");let c=api.object_getClass(a);try{n.forEach(function(o){api.class_addProtocol(a,o.handle)}),Object.keys(i).forEach(function(o){let l=/([+\-])\s(\S+)/.exec(o);if(l===null)throw new Error("Invalid method name");let u=l[1],d=l[2],y,p=i[o];if(typeof p=="function"){let O=null;if(o in r)O=r[o].types;else for(let w of n){let j=w.methods[o];if(j!==void 0){O=j.types;break}}if(O===null)throw new Error("Unable to find '"+o+"' in super-class or any of its protocols");y={types:O,implementation:p}}else y=p;let _=u==="+"?c:a,h=y.types;h===void 0&&(h=unparseSignature(y.retType,[u==="+"?"class":"object","selector"].concat(y.argTypes)));let S=parseSignature(h),v=new NativeCallback(makeMethodImplementationWrapper(S,y.implementation),S.retType.type,S.argTypes.map(function(O){return O.type}));s.push(v),api.class_addMethod(_,selector(d),v,Memory.allocUtf8String(h))})}catch(o){throw api.objc_disposeClassPair(a),o}return api.objc_registerClassPair(a),a._methodCallbacks=s,Script.bindWeak(a,makeClassDestructor(ptr(a))),new ObjCObject(a)}function makeClassDestructor(e){return function(){api.objc_disposeClassPair(e)}}function registerProtocol(e){let t=e.name;t===void 0&&(t=makeProtocolName());let r=e.protocols||[],n=e.methods||{};r.forEach(function(a){if(!(a instanceof ObjCProtocol))throw new Error("Expected protocol")});let i=Object.keys(n).map(function(a){let c=n[a],o=/([+\-])\s(\S+)/.exec(a);if(o===null)throw new Error("Invalid method name");let l=o[1],u=o[2],d=c.types;return d===void 0&&(d=unparseSignature(c.retType,[l==="+"?"class":"object","selector"].concat(c.argTypes))),{kind:l,name:u,types:d,optional:c.optional}}),s=api.objc_allocateProtocol(Memory.allocUtf8String(t));if(s.isNull())throw new Error("Unable to register already registered protocol '"+t+"'");return r.forEach(function(a){api.protocol_addProtocol(s,a.handle)}),i.forEach(function(a){let c=a.optional?0:1,o=a.kind==="-"?1:0;api.protocol_addMethodDescription(s,selector(a.name),Memory.allocUtf8String(a.types),c,o)}),api.objc_registerProtocol(s),new ObjCProtocol(s)}function getHandle(e){if(e instanceof NativePointer)return e;if(typeof e=="object"&&e.hasOwnProperty("handle"))return e.handle;throw new Error("Expected NativePointer or ObjC.Object instance")}function bind(e,t){let r=getHandle(e),n=e instanceof ObjCObject?e:new ObjCObject(r);bindings.set(r.toString(),{self:n,super:n.$super,data:t})}function unbind(e){let t=getHandle(e);bindings.delete(t.toString())}function getBoundData(e){return getBinding(e).data}function getBinding(e){let t=getHandle(e),r=t.toString(),n=bindings.get(r);if(n===void 0){let i=e instanceof ObjCObject?e:new ObjCObject(t);n={self:i,super:i.$super,data:{}},bindings.set(r,n)}return n}function enumerateLoadedClasses(...e){let t=new ModuleMap,r=!1,n,i;e.length===1?n=e[0]:(n=e[1],i=e[0].ownedBy),i===void 0&&(i=t,r=!0);let s=api.class_getName,a=n.onMatch.bind(n),c=(pointerSize===8?8:11)*pointerSize,o=api.objc_getClassList(NULL,0),l=Memory.alloc(o*pointerSize);api.objc_getClassList(l,o);for(let u=0;u!==o;u++){let d=l.add(u*pointerSize).readPointer(),y=s(d),p=null,_=i.findPath(y);if(_===null&&(r||t.findPath(y)===null)&&(p=y.readCString(),p.indexOf(".")!==-1)){let v=d.add(c).readPointer();_=i.findPath(v)}_!==null&&(p===null&&(p=y.readUtf8String()),a(p,_))}n.onComplete()}function enumerateLoadedClassesSync(e={}){let t={};return enumerateLoadedClasses(e,{onMatch(r,n){let i=t[n];i===void 0&&(i=[],t[n]=i),i.push(r)},onComplete(){}}),t}function choose(e,t){let r=e,n=!0;if(!(e instanceof ObjCObject)&&typeof e=="object"&&(r=e.class,e.hasOwnProperty("subclasses")&&(n=e.subclasses)),!(r instanceof ObjCObject&&(r.$kind==="class"||r.$kind==="meta-class")))throw new Error("Expected an ObjC.Object for a class or meta-class");let i=oe().choose(r,n).map(s=>new ObjCObject(s));for(let s of i)if(t.onMatch(s)==="stop")break;t.onComplete()}function makeMethodInvocationWrapper(method,owner,superSpecifier,invocationOptions){let sel=method.sel,handle=method.handle,types;handle===void 0?(handle=null,types=method.types):types=api.method_getTypeEncoding(handle).readUtf8String();let signature=parseSignature(types),retType=signature.retType,argTypes=signature.argTypes.slice(2),objc_msgSend=superSpecifier?getMsgSendSuperImpl(signature,invocationOptions):getMsgSendImpl(signature,invocationOptions),argVariableNames=argTypes.map(function(e,t){return"a"+(t+1)}),callArgs=[superSpecifier?"superSpecifier":"this","sel"].concat(argTypes.map(function(e,t){return e.toNative?"argTypes["+t+"].toNative.call(this, "+argVariableNames[t]+")":argVariableNames[t]})),returnCaptureLeft,returnCaptureRight;retType.type==="void"?(returnCaptureLeft="",returnCaptureRight=""):retType.fromNative?(returnCaptureLeft="return retType.fromNative.call(this, ",returnCaptureRight=")"):(returnCaptureLeft="return ",returnCaptureRight="");let m=eval("var m = function ("+argVariableNames.join(", ")+") { "+returnCaptureLeft+"objc_msgSend("+callArgs.join(", ")+")"+returnCaptureRight+"; }; m;");Object.defineProperty(m,"handle",{enumerable:!0,get:getMethodHandle}),m.selector=sel,Object.defineProperty(m,"implementation",{enumerable:!0,get(){let e=getMethodHandle(),t=new NativeFunction(api.method_getImplementation(e),m.returnType,m.argumentTypes,invocationOptions),r=getReplacementMethodImplementation(e);return r!==null&&(t._callback=r),t},set(e){replaceMethodImplementation(getMethodHandle(),e)}}),m.returnType=retType.type,m.argumentTypes=signature.argTypes.map(e=>e.type),m.types=types,Object.defineProperty(m,"symbol",{enumerable:!0,get(){return`${method.kind}[${owner.$className} ${selectorAsString(sel)}]`}}),m.clone=function(e){return makeMethodInvocationWrapper(method,owner,superSpecifier,e)};function getMethodHandle(){if(handle===null){if(owner.$kind==="instance"){let e=owner;do if("- forwardingTargetForSelector:"in e){let t=e.forwardingTargetForSelector_(sel);if(t===null||t.$kind!=="instance")break;let r=api.class_getInstanceMethod(t.$class.handle,sel);r.isNull()?e=t:handle=r}else break;while(handle===null)}if(handle===null)throw new Error("Unable to find method handle of proxied function")}return handle}return m}function makeMethodImplementationWrapper(signature,implementation){let retType=signature.retType,argTypes=signature.argTypes,argVariableNames=argTypes.map(function(e,t){return t===0?"handle":t===1?"sel":"a"+(t-1)}),callArgs=argTypes.slice(2).map(function(e,t){let r=argVariableNames[2+t];return e.fromNative?"argTypes["+(2+t)+"].fromNative.call(self, "+r+")":r}),returnCaptureLeft,returnCaptureRight;retType.type==="void"?(returnCaptureLeft="",returnCaptureRight=""):retType.toNative?(returnCaptureLeft="return retType.toNative.call(self, ",returnCaptureRight=")"):(returnCaptureLeft="return ",returnCaptureRight="");let m=eval("var m = function ("+argVariableNames.join(", ")+") { var binding = getBinding(handle);var self = binding.self;"+returnCaptureLeft+"implementation.call(binding"+(callArgs.length>0?", ":"")+callArgs.join(", ")+")"+returnCaptureRight+"; }; m;");return m}function makeBlockInvocationWrapper(block,signature,implementation){let retType=signature.retType,argTypes=signature.argTypes.slice(1),argVariableNames=argTypes.map(function(e,t){return"a"+(t+1)}),callArgs=argTypes.map(function(e,t){return e.toNative?"argTypes["+t+"].toNative.call(this, "+argVariableNames[t]+")":argVariableNames[t]}),returnCaptureLeft,returnCaptureRight;retType.type==="void"?(returnCaptureLeft="",returnCaptureRight=""):retType.fromNative?(returnCaptureLeft="return retType.fromNative.call(this, ",returnCaptureRight=")"):(returnCaptureLeft="return ",returnCaptureRight="");let f=eval("var f = function ("+argVariableNames.join(", ")+") { "+returnCaptureLeft+"implementation(this"+(callArgs.length>0?", ":"")+callArgs.join(", ")+")"+returnCaptureRight+"; }; f;");return f.bind(block)}function makeBlockImplementationWrapper(block,signature,implementation){let retType=signature.retType,argTypes=signature.argTypes,argVariableNames=argTypes.map(function(e,t){return t===0?"handle":"a"+t}),callArgs=argTypes.slice(1).map(function(e,t){let r=argVariableNames[1+t];return e.fromNative?"argTypes["+(1+t)+"].fromNative.call(this, "+r+")":r}),returnCaptureLeft,returnCaptureRight;retType.type==="void"?(returnCaptureLeft="",returnCaptureRight=""):retType.toNative?(returnCaptureLeft="return retType.toNative.call(this, ",returnCaptureRight=")"):(returnCaptureLeft="return ",returnCaptureRight="");let f=eval("var f = function ("+argVariableNames.join(", ")+") { if (!this.handle.equals(handle))this.handle = handle;"+returnCaptureLeft+"implementation.call(block"+(callArgs.length>0?", ":"")+callArgs.join(", ")+")"+returnCaptureRight+"; }; f;");return f.bind(block)}function rawFridaType(e){return e==="object"?"pointer":e}function makeClassName(){for(let e=1;;e++){let t="FridaAnonymousClass"+e;if(!(t in classRegistry))return t}}function makeProtocolName(){for(let e=1;;e++){let t="FridaAnonymousProtocol"+e;if(!(t in protocolRegistry))return t}}function objcMethodName(e){return e.replace(/_/g,":")}function jsMethodName(e){let t=e.replace(/:/g,"_");return objCObjectBuiltins.has(t)&&(t+="2"),t}let isaMasks={x64:"0x7ffffffffff8",arm64:"0xffffffff8"},rawMask=isaMasks[Process.arch];if(rawMask!==void 0){let e=ptr(rawMask);readObjectIsa=function(t){return t.readPointer().and(e)}}else readObjectIsa=function(e){return e.readPointer()};function getMsgSendImpl(e,t){return resolveMsgSendImpl(msgSendBySignatureId,e,t,!1)}function getMsgSendSuperImpl(e,t){return resolveMsgSendImpl(msgSendSuperBySignatureId,e,t,!0)}function resolveMsgSendImpl(e,t,r,n){if(r!==J)return makeMsgSendImpl(t,r,n);let{id:i}=t,s=e.get(i);return s===void 0&&(s=makeMsgSendImpl(t,r,n),e.set(i,s)),s}function makeMsgSendImpl(e,t,r){let n=e.retType.type,i=e.argTypes.map(function(o){return o.type}),s=["objc_msgSend"];r&&s.push("Super"),n instanceof Array&&!typeFitsInRegisters(n)?s.push("_stret"):(n==="float"||n==="double")&&s.push("_fpret");let c=s.join("");return new NativeFunction(api[c],n,i,t)}function typeFitsInRegisters(e){return Process.arch!=="x64"?!1:sizeOfTypeOnX64(e)<=16}function sizeOfTypeOnX64(e){if(e instanceof Array)return e.reduce((t,r)=>t+sizeOfTypeOnX64(r),0);switch(e){case"bool":case"char":case"uchar":return 1;case"int16":case"uint16":return 2;case"int":case"int32":case"uint":case"uint32":case"float":return 4;default:return 8}}function unparseSignature(e,t){let r=typeIdFromAlias(e),n=t.map(typeIdFromAlias),i=n.map(c=>singularTypeById[c].size),s=i.reduce((c,o)=>c+o,0),a=0;return r+s+n.map((c,o)=>{let l=c+a;return a+=i[o],l}).join("")}function parseSignature(e){let t=[e,0];parseQualifiers(t);let r=readType(t);readNumber(t);let n=[],i=JSON.stringify(r.type);for(;dataAvailable(t);){parseQualifiers(t);let s=readType(t);readNumber(t),n.push(s),i+=JSON.stringify(s.type)}return{id:i,retType:r,argTypes:n}}function parseType(e){return readType([e,0])}function readType(e){let t=readChar(e);if(t==="@"){let n=peekChar(e);n==="?"?(t+=n,skipChar(e),peekChar(e)==="<"&&skipExtendedBlock(e)):n==='"'&&(skipChar(e),readUntil('"',e))}else if(t==="^"){let n=peekChar(e);n==="@"&&(t+=n,skipChar(e))}let r=singularTypeById[t];if(r!==void 0)return r;if(t==="["){let n=readNumber(e),i=readType(e);return skipChar(e),arrayType(n,i)}else if(t==="{"){if(!tokenExistsAhead("=","}",e))return readUntil("}",e),structType([]);readUntil("=",e);let n=[],i;for(;(i=peekChar(e))!=="}";)i==='"'&&(skipChar(e),readUntil('"',e)),n.push(readType(e));return skipChar(e),structType(n)}else if(t==="("){readUntil("=",e);let n=[];for(;peekChar(e)!==")";)n.push(readType(e));return skipChar(e),unionType(n)}else{if(t==="b")return readNumber(e),singularTypeById.i;if(t==="^")return readType(e),singularTypeById["?"];if(modifiers.has(t))return readType(e);throw new Error("Unable to handle type "+t)}}function skipExtendedBlock(e){let t;for(skipChar(e);(t=peekChar(e))!==">";)peekChar(e)==="<"?skipExtendedBlock(e):(skipChar(e),t==='"'&&readUntil('"',e));skipChar(e)}function readNumber(e){let t="";for(;dataAvailable(e);){let r=peekChar(e),n=r.charCodeAt(0);if(n>=48&&n<=57)t+=r,skipChar(e);else break}return parseInt(t)}function readUntil(e,t){let r=t[0],n=t[1],i=r.indexOf(e,n);if(i===-1)throw new Error("Expected token '"+e+"' not found");let s=r.substring(n,i);return t[1]=i+1,s}function readChar(e){return e[0][e[1]++]}function peekChar(e){return e[0][e[1]]}function tokenExistsAhead(e,t,r){let[n,i]=r,s=n.indexOf(e,i);if(s===-1)return!1;let a=n.indexOf(t,i);if(a===-1)throw new Error("Expected to find terminator: "+t);return s<a}function skipChar(e){e[1]++}function dataAvailable(e){return e[1]!==e[0].length}let qualifierById={r:"const",n:"in",N:"inout",o:"out",O:"bycopy",R:"byref",V:"oneway"};function parseQualifiers(e){let t=[];for(;;){let r=qualifierById[peekChar(e)];if(r===void 0)break;t.push(r),skipChar(e)}return t}let idByAlias={char:"c",int:"i",int16:"s",int32:"i",int64:"q",uchar:"C",uint:"I",uint16:"S",uint32:"I",uint64:"Q",float:"f",double:"d",bool:"B",void:"v",string:"*",object:"@",block:"@?",class:"#",selector:":",pointer:"^v"};function typeIdFromAlias(e){if(typeof e=="object"&&e!==null)return`@"${e.type}"`;let t=idByAlias[e];if(t===void 0)throw new Error("No known encoding for type "+e);return t}let fromNativeId=function(e){return e.isNull()?null:e.toString(16)===this.handle.toString(16)?this:new ObjCObject(e)},toNativeId=function(e){if(e===null)return NULL;let t=typeof e;return t==="string"?(cachedNSStringCtor===null&&(cachedNSString=classRegistry.NSString,cachedNSStringCtor=cachedNSString.stringWithUTF8String_),cachedNSStringCtor.call(cachedNSString,Memory.allocUtf8String(e))):t==="number"?(cachedNSNumberCtor===null&&(cachedNSNumber=classRegistry.NSNumber,cachedNSNumberCtor=cachedNSNumber.numberWithDouble_),cachedNSNumberCtor.call(cachedNSNumber,e)):e},fromNativeBlock=function(e){return e.isNull()?null:e.toString(16)===this.handle.toString(16)?this:new Block(e)},toNativeBlock=function(e){return e!==null?e:NULL},toNativeObjectArray=function(e){if(e instanceof Array){let t=e.length,r=Memory.alloc(t*pointerSize);for(let n=0;n!==t;n++)r.add(n*pointerSize).writePointer(toNativeId(e[n]));return r}return e};function arrayType(e,t){return{type:"pointer",read(r){let n=[],i=t.size;for(let s=0;s!==e;s++)n.push(t.read(r.add(s*i)));return n},write(r,n){let i=t.size;n.forEach((s,a)=>{t.write(r.add(a*i),s)})}}}function structType(e){let t,r;if(e.some(function(s){return!!s.fromNative})){let s=e.map(function(a){return a.fromNative?a.fromNative:identityTransform});t=function(a){return a.map(function(c,o){return s[o].call(this,c)})}}else t=identityTransform;if(e.some(function(s){return!!s.toNative})){let s=e.map(function(a){return a.toNative?a.toNative:identityTransform});r=function(a){return a.map(function(c,o){return s[o].call(this,c)})}}else r=identityTransform;let[n,i]=e.reduce(function(s,a){let[c,o]=s,{size:l}=a,u=align(c,l);return o.push(u),[u+l,o]},[0,[]]);return{type:e.map(s=>s.type),size:n,read(s){return e.map((a,c)=>a.read(s.add(i[c])))},write(s,a){a.forEach((c,o)=>{e[o].write(s.add(i[o]),c)})},fromNative:t,toNative:r}}function unionType(e){let t=e.reduce(function(i,s){return s.size>i.size?s:i},e[0]),r,n;if(t.fromNative){let i=t.fromNative;r=function(s){return i.call(this,s[0])}}else r=function(i){return i[0]};if(t.toNative){let i=t.toNative;n=function(s){return[i.call(this,s)]}}else n=function(i){return[i]};return{type:[t.type],size:t.size,read:t.read,write:t.write,fromNative:r,toNative:n}}let longBits=pointerSize==8&&Process.platform!=="windows"?64:32;modifiers=new Set(["j","A","r","n","N","o","O","R","V","+"]),singularTypeById={c:{type:"char",size:1,read:e=>e.readS8(),write:(e,t)=>{e.writeS8(t)},toNative(e){return typeof e=="boolean"?e?1:0:e}},i:{type:"int",size:4,read:e=>e.readInt(),write:(e,t)=>{e.writeInt(t)}},s:{type:"int16",size:2,read:e=>e.readS16(),write:(e,t)=>{e.writeS16(t)}},l:{type:"int32",size:4,read:e=>e.readS32(),write:(e,t)=>{e.writeS32(t)}},q:{type:"int64",size:8,read:e=>e.readS64(),write:(e,t)=>{e.writeS64(t)}},C:{type:"uchar",size:1,read:e=>e.readU8(),write:(e,t)=>{e.writeU8(t)}},I:{type:"uint",size:4,read:e=>e.readUInt(),write:(e,t)=>{e.writeUInt(t)}},S:{type:"uint16",size:2,read:e=>e.readU16(),write:(e,t)=>{e.writeU16(t)}},L:{type:"uint"+longBits,size:longBits/8,read:e=>e.readULong(),write:(e,t)=>{e.writeULong(t)}},Q:{type:"uint64",size:8,read:e=>e.readU64(),write:(e,t)=>{e.writeU64(t)}},f:{type:"float",size:4,read:e=>e.readFloat(),write:(e,t)=>{e.writeFloat(t)}},d:{type:"double",size:8,read:e=>e.readDouble(),write:(e,t)=>{e.writeDouble(t)}},B:{type:"bool",size:1,read:e=>e.readU8(),write:(e,t)=>{e.writeU8(t)},fromNative(e){return!!e},toNative(e){return e?1:0}},v:{type:"void",size:0},"*":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)},fromNative(e){return e.readUtf8String()}},"@":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)},fromNative:fromNativeId,toNative:toNativeId},"@?":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)},fromNative:fromNativeBlock,toNative:toNativeBlock},"^@":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)},toNative:toNativeObjectArray},"^v":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)}},"#":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)},fromNative:fromNativeId,toNative:toNativeId},":":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)}},"?":{type:"pointer",size:pointerSize,read:e=>e.readPointer(),write:(e,t)=>{e.writePointer(t)}}};function identityTransform(e){return e}function align(e,t){let r=e%t;return r===0?e:e+(t-r)}}var ge=new me,x=ge;function se(){var e=new Date().getTime(),t=typeof performance<"u"&&performance.now&&performance.now()*1e3||0;return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(r){var n=Math.random()*16;return e>0?(n=(e+n)%16|0,e=Math.floor(e/16)):(n=(t+n)%16|0,t=Math.floor(t/16)),(r==="x"?n:n&3|8).toString(16)})}function G(e){try{for(var t=new Uint8Array(e),r=[],n=0;n<t.length;n++){var i=t[n].toString(16);i.length<2&&(i="0"+i),r.push(i)}return r.join("")}catch{return"<hex-conversion-error>"}}function K(e,t){try{if(!e||e.isNull&&e.isNull())return!1;var r=Process.findRangeByAddress(e);if(!r)return!1;if(typeof t!="number"||t<=0)return!0;var n=e,i=e.add(t),s=r.base.add(r.size);return n.compare(r.base)>=0&&i.compare(s)<=0}catch{return!1}}function ie(e,t){var r={hex:null,base64:null};if(!t||t<0||!e||e.isNull&&e.isNull())return r;try{if(K(e,t)){var n=Memory.readByteArray(e,t);n&&(r.hex=G(n))}}catch{}if(r.hex===null&&x&&x.available)try{var i=x.classes.NSData.dataWithBytes_length_(e,t);if(i){try{r.base64=i.base64EncodedStringWithOptions_(0).toString()}catch{}try{var s=i.bytes();if(K(s,t)){var a=Memory.readByteArray(s,t);a&&(r.hex=G(a))}}catch{}}}catch{}if(r.hex===null&&K(e,t))try{var c=Memory.readByteArray(e,t);c&&(r.hex=G(c))}catch{}return r}function ye(e,t,r,n,i){var s=r&&r.name?r.name:"args["+t+"]",a=r&&r.type?r.type:"string",c=null,o=null;try{switch(a){case"string":if(e&&!(e.isNull&&e.isNull())&&K(e))try{c=e.readCString()}catch{c=e.toString()}else c="<null>";break;case"int32":c=e.toInt32();break;case"uint32":c=e.toUInt32();break;case"int64":try{c=e.toInt64().toString()}catch{c=e.toInt32()}break;case"pointer":c=e.toString();break;case"CFData":try{if(x&&x.available&&e&&!(e.isNull&&e.isNull())){var l=new x.Object(e);try{c=l.base64EncodedStringWithOptions_(0).toString(),o="base64"}catch{c="<bytes-read-error>",o="base64"}}else c="<null>",o="base64"}catch{c="<cf-data-error>",o="base64"}break;case"CFDictionary":try{if(x&&x.available&&e&&!(e.isNull&&e.isNull())){for(var u=new x.Object(e),d={},y=u.allKeys(),p=0;p<y.count();p++){var _=y.objectAtIndex_(p).toString(),h=u.objectForKey_(y.objectAtIndex_(p)),S;try{h===null?S=null:h.isKindOfClass_(x.classes.NSString)?S=h.toString():h.isKindOfClass_(x.classes.NSNumber)?S=Number(h.toString()):h.isKindOfClass_(x.classes.NSData)?S=h.base64EncodedStringWithOptions_(0).toString():h.isKindOfClass_(x.classes.NSDictionary)||h.isKindOfClass_(x.classes.NSArray)?S=h.description().toString():S=h.toString()}catch{S=String(h)}d[_]=S}c=JSON.stringify(d)}else c=e?e.toString():"<null>"}catch{c="<cf-dictionary-error>"}break;case"bytes":var v;if(r&&r.lengthInArg&&Array.isArray(i)){for(var O=r.lengthInArg,w=-1,j=0;j<i.length;j++)if(i[j]&&i[j].name===O){w=j;break}if(w!==-1&&n&&n[w])try{v=n[w].toUInt32()}catch{try{v=n[w].toInt32()}catch{v=64}}}if(v===void 0&&r&&typeof r.lengthArgIndex=="number"&&n&&n[r.lengthArgIndex])try{v=n[r.lengthArgIndex].toUInt32()}catch{v=64}v===void 0&&(v=r&&typeof r.length=="number"?r.length:64);var A=r&&typeof r.force<"u"?!!r.force:!0;if(!e||e.isNull&&e.isNull())c="<null>";else{var I=ie(e,v);if(!I.hex&&!I.base64&&A===!0)try{var M=Memory.readByteArray(e,v);M&&(I.hex=G(M))}catch{}c=I.base64!==null?I.base64:"<bytes-read-error>",o="base64"}break;case"bool":c=!!e.toInt32();break;case"double":try{c=e.readDouble()}catch{c=Number(e.toInt32())}break;default:if(K(e))try{c=e.readCString()}catch{try{c=e.toInt32()}catch{if(K(e,64))try{var B=Memory.readByteArray(e,64);c=B?G(B):e.toString()}catch{c=e.toString()}else c=e.toString()}}else c=e.toString();break}}catch(L){c="<error: "+L+">"}var $={name:s,type:a,value:c};return(a==="bytes"||a==="CFData")&&($.format="base64"),$}function he(e,t){if(!t||!t.length)return!0;for(var r=0;r<t.length;r++){var n=t[r];if(n&&Array.isArray(n.filter)&&n.filter.length){for(var i=e[r],s=i?i.value:null,a=!1,c=0;c<n.filter.length;c++){var o=n.filter[c];if(!(s===null||typeof s>"u")){if(typeof s=="string"){if(s.indexOf(o)!==-1){a=!0;break}}else if(typeof s=="number"){if(s===Number(o)||String(s).indexOf(String(o))!==-1){a=!0;break}}else if(typeof s=="boolean"){if(o===!0||o===!1?s===o:String(s).toLowerCase()===String(o).toLowerCase()){a=!0;break}}else if(String(s).indexOf(String(o))!==-1){a=!0;break}}}if(!a)return!1}}return!0}function _e(e){return e.native===!0}function be(e){return e.native===!0&&e.objClass!==void 0}function Se(e){try{if(e.module){var t=Process.getModuleByName(e.module);return t.getExportByName(e.symbol)}else return Module.getGlobalExportByName(e.symbol)}catch(r){return console.error("Failed to resolve native symbol '"+e.symbol+"'"+(e.module?" in module '"+e.module+"'":"")+": "+r),null}}function ve(e){try{if(!x.available)return console.error("ObjC runtime is not available."),null;var t=x.classes[e.objClass];if(!t)return console.error("ObjC class '"+e.objClass+"' not found."),null;var r=t[e.symbol];return r?r.implementation:(console.error("ObjC method '"+e.symbol+"' not found in class '"+e.objClass+"'."),null)}catch(n){return console.error("Failed to resolve ObjC method '"+e.symbol+"' in class '"+e.objClass+"': "+n),null}}function Ne(e,t,r){var n=Se(e);if(!n){console.error("Cannot attach to native symbol '"+e.symbol+"': address not resolved.");return}var i=typeof e.maxFrames=="number"?e.maxFrames:8;Interceptor.attach(n,{onEnter:function(s){e.__lastEnterArgs=[];for(var a=0;a<16&&s[a]!==void 0;a++)e.__lastEnterArgs[a]=s[a];var c=[];try{for(var o=Thread.backtrace(this.context,Backtracer.ACCURATE),l=0;l<o.length;l++)c.push(DebugSymbol.fromAddress(o[l]).toString())}catch(E){c.push("<backtrace unavailable: "+E+">")}if(e.filterEventsByStacktrace){for(var u=e.filterEventsByStacktrace,d=!1,y=0;y<c.length;y++)if(c[y].indexOf(u)!==-1){d=!0;break}if(!d)return}function p(E){if(e.filterEventsByStacktrace||i===-1)return E.slice();for(var W=[],q=0;q<E.length&&q<i;q++)W.push(E[q]);return W}var _=p(c),h=[],S=!1;try{var v=Array.isArray(e.args)?e.args:[];if(v.length>0)for(var O=0;O<v.length;O++){var w=s[O];if(w===void 0)break;var j=v[O];j&&(j.direction==="out"||j.returnValue===!0)?(S=!0,h.push({name:j.name||"args["+O+"]",type:j.type||"bytes",value:"<pending-out>"})):h.push(ye(w,O,j,s,v))}else for(var A=5,I=0;I<A;I++){var M=s[I];if(M===void 0)break;var B=null;try{if(K(M))try{B=M.readCString()}catch{try{B=M.toInt32()}catch{if(K(M,64))try{var $=Memory.readByteArray(M,64);B=$?G($):M.toString()}catch{B=M.toString()}else B=M.toString()}}else B=M.toString()}catch(E){B="<error: "+E+">"}h.push({name:"args["+I+"]",type:"auto",value:B})}}catch(E){h=[{name:"args",type:"auto",value:"<arg-decode-error: "+E+">"}]}try{var L=Array.isArray(e.args)?e.args:[];if(!he(h,L))return}catch{}this.event={id:se(),type:"native-hook",category:t,time:new Date().toISOString(),module:e.module||"<global>",symbol:e.symbol,address:n.toString(),stackTrace:_,inputParameters:h},S?this._deferEmit=!0:r(this.event)},onLeave:function(s){try{if(this.event&&this._deferEmit&&Array.isArray(e.args)){for(var a=e.args,c=e.__lastEnterArgs||[],o=0;o<a.length;o++){var l=a[o];if(l&&(l.direction==="out"||l.returnValue===!0)){var u=null;if(l.returnValue===!0?u=s:u=c[o],!!u)if(l.type==="bytes"){var d;if(l.lengthInArg){for(var y=l.lengthInArg,p=0;p<a.length;p++)if(a[p]&&a[p].name===y){try{if(a[p].type==="pointer"){var _=c[p];if(_&&!(_.isNull&&_.isNull()))try{d=_.readU64().toNumber()}catch{try{d=_.readU32()}catch{d=0}}else d=0}else{var h=c[p];try{d=h.toUInt32()}catch{try{d=h.toInt32()}catch{d=0}}}}catch{d=0}break}}if(d===void 0&&(d=typeof l.length=="number"?l.length:0),d>0&&K(u,d)){var S=ie(u,d);this.event.inputParameters[o].value=S.base64!==null?S.base64:"<bytes-read-error>",this.event.inputParameters[o].format="base64"}else this.event.inputParameters[o].value="<unreadable-output>",this.event.inputParameters[o].format="base64"}else if(l.type==="CFData")if(u&&!(u.isNull&&u.isNull())&&x&&x.available)try{var v=new x.Object(u),O=v.base64EncodedStringWithOptions_(0).toString();this.event.inputParameters[o].value=O,this.event.inputParameters[o].format="base64"}catch{this.event.inputParameters[o].value="<bytes-read-error>",this.event.inputParameters[o].format="base64"}else this.event.inputParameters[o].value="<unreadable-output>",this.event.inputParameters[o].format="base64";else{var w;try{w=u.readCString()}catch{try{w=u.toInt32()}catch{w=u.toString()}}this.event.inputParameters[o].value=w}}}this.event.retval=s?s.toString():"<no-retval>",r(this.event),e.__lastEnterArgs=void 0}}catch{this.event&&this._deferEmit&&r(this.event)}}})}function Ce(e,t,r){var n=ve(e);if(!n){console.error("Cannot attach to ObjC method '"+e.symbol+"' in class '"+e.objClass+"': implementation not resolved.");return}var i=typeof e.maxFrames=="number"?e.maxFrames:8;Interceptor.attach(n,{onEnter:function(s){var a=[];try{for(var c=Thread.backtrace(this.context,Backtracer.ACCURATE),o=0;o<c.length&&!(i!==-1&&o>=i);o++)a.push(DebugSymbol.fromAddress(c[o]).toString())}catch(l){a.push("<backtrace unavailable: "+l+">")}this.event={id:se(),type:"objc-hook",category:t,time:new Date().toISOString(),class:e.objClass,symbol:e.symbol,address:n.toString(),stackTrace:a},r(this.event)},onLeave:function(s){}})}function ae(e){function t(s){send(s)}var r=[],n=[];e.hooks.forEach(function(s){if(!_e(s)){console.warn("Non-native hooks are not supported on iOS. Skipping hook."),n.push("Non-native hook skipped: "+JSON.stringify(s));return}try{be(s)?(Ce(s,e.category,t),r.push({type:"objc",class:s.objClass,symbol:s.symbol})):(Ne(s,e.category,t),r.push({type:"native",module:s.module||"<global>",symbol:s.symbol}))}catch(c){var a="Failed to register hook: "+c;console.error(a),n.push(a)}});var i={type:"summary",hooks:r,totalHooks:r.length,errors:n,totalErrors:n.length};send(i)}rpc.exports={runFrookyAgent(e){ae(e)}};
@@ -0,0 +1,7 @@
1
+ {
2
+ "frida": "17.6.2",
3
+ "frida-java-bridge": "7.0.11",
4
+ "frida-swift-bridge": "3.0.2",
5
+ "frida-objc-bridge": "8.0.5",
6
+ "buildtime": "2026-02-06T08:01:29.790Z"
7
+ }
frooky/cli.py CHANGED
@@ -1,7 +1,9 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import sys
3
4
  import argparse
4
5
  from pathlib import Path
6
+ from importlib.resources import files
5
7
 
6
8
  from . import __version__
7
9
  from .frida_runner import FrookyRunner, RunnerOptions
@@ -10,10 +12,13 @@ from .frida_runner import FrookyRunner, RunnerOptions
10
12
  def build_parser() -> argparse.ArgumentParser:
11
13
  parser = argparse.ArgumentParser(
12
14
  prog="frooky",
13
- description="Run Frooky hooks using Frida's Python bindings.",
15
+ description="Run Frooky hooks using Frida's Python bindings."
14
16
  )
15
17
 
18
+ parser.suggest_on_error = True
19
+
16
20
  parser.add_argument(
21
+ "-v",
17
22
  "--version",
18
23
  action="version",
19
24
  version=f"frooky {__version__}",
@@ -40,19 +45,32 @@ def build_parser() -> argparse.ArgumentParser:
40
45
  )
41
46
  parser.add_argument("hooks", nargs="+", help="Path(s) to your input hook JSON file(s)")
42
47
  parser.add_argument("-o", "--output", default="output.json", help="Output JSON file")
43
- parser.add_argument(
44
- "--keep-artifacts",
45
- action="store_true",
46
- help="Keep temporary artifacts (tmp/, node_modules/, package.json, package-lock.json)",
47
- )
48
48
 
49
49
  return parser
50
50
 
51
51
 
52
52
  def main() -> int:
53
53
  parser = build_parser()
54
+ if len(sys.argv) == 1:
55
+ parser.print_help()
56
+ sys.exit(1)
57
+
54
58
  args = parser.parse_args()
55
59
 
60
+ # Validate that the android and ios agents are compiled and accessible
61
+ agent_dist_path = files('frooky') / "agent" / "dist"
62
+ required_files = [
63
+ agent_dist_path / "version.json",
64
+ agent_dist_path / "agent-android.js",
65
+ agent_dist_path / "agent-ios.js"
66
+ ]
67
+
68
+ if not all(file.exists() for file in required_files):
69
+ print(f"Frooky agent not found in: {agent_dist_path}\n"
70
+ f"If you don't use the distributed version, make sure to manually compile the agents first.\n",
71
+ file=sys.stderr)
72
+ sys.exit(1)
73
+
56
74
  # Validate device selection
57
75
  device_count = sum([args.usb, args.device is not None])
58
76
  if device_count > 1:
@@ -63,7 +81,7 @@ def main() -> int:
63
81
  hook_path = Path(hook)
64
82
  if not hook_path.exists():
65
83
  parser.error(f"Hooks file not found: {hook_path}")
66
- hook_paths.append(hook_path)
84
+ hook_paths.append(hook_path.resolve())
67
85
 
68
86
  options = RunnerOptions(
69
87
  platform=args.platform,
@@ -76,7 +94,6 @@ def main() -> int:
76
94
  attach_identifier=args.attach_identifier,
77
95
  attach_pid=args.attach_pid,
78
96
  spawn=args.spawn,
79
- keep_artifacts=args.keep_artifacts,
80
97
  )
81
98
 
82
99
  runner = FrookyRunner(options)