frida-fusion 0.1.15__tar.gz → 0.1.17__tar.gz
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.
Potentially problematic release.
This version of frida-fusion might be problematic. Click here for more details.
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/PKG-INFO +5 -1
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/README.md +4 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/__meta__.py +2 -2
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/fusion.py +78 -37
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/helpers.js +145 -24
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/crypto/crypto.js +136 -14
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/crypto/crypto.py +37 -1
- frida_fusion-0.1.17/frida_fusion/modules/okhttp-logging/okhttp-logging.js +1584 -0
- frida_fusion-0.1.17/frida_fusion/modules/okhttp-logging/okhttp-logging.py +80 -0
- frida_fusion-0.1.17/frida_fusion/modules/shared_preferences/shared_preferences.js +448 -0
- frida_fusion-0.1.17/frida_fusion/modules/shared_preferences/shared_preferences.py +184 -0
- frida_fusion-0.1.17/frida_fusion/modules/tls_unpinning/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/PKG-INFO +5 -1
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/SOURCES.txt +5 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/LICENSE +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/__main__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/args.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/config.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/exceptions.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/color.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/database.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/logger.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/libs/scriptlocation.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/module.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/android_setings/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/android_setings/settings.js +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/android_setings/settings.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/crypto/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/reflection/reflection-stalker.js +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/reflection/reflection-stalker.py +0 -0
- {frida_fusion-0.1.15/frida_fusion/modules/tls_unpinning → frida_fusion-0.1.17/frida_fusion/modules/shared_preferences}/__init__.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion/modules/tls_unpinning/frida_multiple_unpinning.py +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/dependency_links.txt +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/entry_points.txt +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/requires.txt +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/frida_fusion.egg-info/top_level.txt +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/pyproject.toml +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/setup.cfg +0 -0
- {frida_fusion-0.1.15 → frida_fusion-0.1.17}/setup.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: frida-fusion
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.17
|
|
4
4
|
Summary: Hook your mobile tests with Frida
|
|
5
5
|
Author-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
6
6
|
Maintainer-email: "Helvio Junior (M4v3r1ck)" <helvio_junior@hotmail.com>
|
|
@@ -92,6 +92,7 @@ The Frida Fusion define/expose several functions to be used at frida scripts. Fo
|
|
|
92
92
|
```java
|
|
93
93
|
# Send message/data to Frida-Fusion
|
|
94
94
|
void fusion_sendMessage(String level, String message);
|
|
95
|
+
void fusion_sendError(Error error);
|
|
95
96
|
void fusion_sendMessageWithTrace(String level, String message);
|
|
96
97
|
void fusion_sendKeyValueData(String module, Object items);
|
|
97
98
|
|
|
@@ -101,6 +102,9 @@ void fusion_printStackTrace();
|
|
|
101
102
|
# Print all methods of class 'name'
|
|
102
103
|
void fusion_printMethods(String name);
|
|
103
104
|
|
|
105
|
+
# Get value of a field inside an class instance
|
|
106
|
+
Object fusion_getFieldValue(Object obj, String fieldName);
|
|
107
|
+
|
|
104
108
|
# Wait until the class 'name' exists in memory to execute the callback function
|
|
105
109
|
void fusion_waitForClass(String name, CallbackFunction onReady)
|
|
106
110
|
|
|
@@ -57,6 +57,7 @@ The Frida Fusion define/expose several functions to be used at frida scripts. Fo
|
|
|
57
57
|
```java
|
|
58
58
|
# Send message/data to Frida-Fusion
|
|
59
59
|
void fusion_sendMessage(String level, String message);
|
|
60
|
+
void fusion_sendError(Error error);
|
|
60
61
|
void fusion_sendMessageWithTrace(String level, String message);
|
|
61
62
|
void fusion_sendKeyValueData(String module, Object items);
|
|
62
63
|
|
|
@@ -66,6 +67,9 @@ void fusion_printStackTrace();
|
|
|
66
67
|
# Print all methods of class 'name'
|
|
67
68
|
void fusion_printMethods(String name);
|
|
68
69
|
|
|
70
|
+
# Get value of a field inside an class instance
|
|
71
|
+
Object fusion_getFieldValue(Object obj, String fieldName);
|
|
72
|
+
|
|
69
73
|
# Wait until the class 'name' exists in memory to execute the callback function
|
|
70
74
|
void fusion_waitForClass(String name, CallbackFunction onReady)
|
|
71
75
|
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
__version__ = '0.1.
|
|
1
|
+
__version__ = '0.1.17'
|
|
2
2
|
__title__ = "Frida Fusion"
|
|
3
3
|
__description__ = "📱 frida-fusion - runtime mobile exploration"
|
|
4
4
|
__url__ = "https://github.com/helviojunior/frida-fusion"
|
|
5
|
-
__build__ =
|
|
5
|
+
__build__ = 0xe289b59
|
|
6
6
|
__author__ = "Helvio Junior (M4v3r1ck)"
|
|
7
7
|
__author_email__ = "helvio_junior@hotmail.com"
|
|
8
8
|
__license__ = "GPL-3.0"
|
|
@@ -35,6 +35,7 @@ class Fusion(object):
|
|
|
35
35
|
print_timestamp = False
|
|
36
36
|
max_filename = 28
|
|
37
37
|
|
|
38
|
+
_bundle_pattern = re.compile(r'(fusion_bundle\.js):(\d+)')
|
|
38
39
|
_script_name = Path(__file__).name
|
|
39
40
|
_db_jobs = queue.Queue()
|
|
40
41
|
|
|
@@ -108,25 +109,6 @@ class Fusion(object):
|
|
|
108
109
|
if v[0] <= loc.get_int_line() <= v[1]
|
|
109
110
|
]), loc)
|
|
110
111
|
|
|
111
|
-
@classmethod
|
|
112
|
-
def print_message(cls, level: str = "*", message: str = "",
|
|
113
|
-
script_location: ScriptLocation = None):
|
|
114
|
-
|
|
115
|
-
if Fusion.running is False and Logger.debug_level >= 2:
|
|
116
|
-
return
|
|
117
|
-
|
|
118
|
-
if script_location is None:
|
|
119
|
-
script_location = ScriptLocation(
|
|
120
|
-
file_name=Fusion._script_name
|
|
121
|
-
)
|
|
122
|
-
|
|
123
|
-
Logger.print_message(
|
|
124
|
-
level=level,
|
|
125
|
-
message=message,
|
|
126
|
-
script_location=script_location,
|
|
127
|
-
filename_col_len=Fusion.max_filename
|
|
128
|
-
)
|
|
129
|
-
|
|
130
112
|
def load_all_scripts(self):
|
|
131
113
|
self.script_trace = {}
|
|
132
114
|
offset = 1
|
|
@@ -334,10 +316,11 @@ class Fusion(object):
|
|
|
334
316
|
msg = base64.b64decode(msg).decode("UTF-8")
|
|
335
317
|
except:
|
|
336
318
|
pass
|
|
337
|
-
|
|
319
|
+
|
|
320
|
+
self.print_message_inst(mLevel, msg, script_location=script_location)
|
|
338
321
|
|
|
339
322
|
elif mType == "key_value_data":
|
|
340
|
-
self.
|
|
323
|
+
self.print_message_inst("V", "RAW JSON:\n %s" % (
|
|
341
324
|
json.dumps(jData, indent=4).replace("\n", "\n ")
|
|
342
325
|
), script_location=script_location)
|
|
343
326
|
|
|
@@ -367,7 +350,7 @@ class Fusion(object):
|
|
|
367
350
|
|
|
368
351
|
# Legacy
|
|
369
352
|
elif mType == "data":
|
|
370
|
-
self.
|
|
353
|
+
self.print_message_inst("V", "RAW JSON:\n %s" % (
|
|
371
354
|
json.dumps(jData, indent=4).replace("\n", "\n ")
|
|
372
355
|
), script_location=script_location)
|
|
373
356
|
|
|
@@ -391,15 +374,15 @@ class Fusion(object):
|
|
|
391
374
|
|
|
392
375
|
elif mType == "java-uncaught":
|
|
393
376
|
self.insert_history('frida', json.dumps(jData))
|
|
394
|
-
self.
|
|
377
|
+
self.print_message_inst("E", jData.get('stack', ''), script_location=script_location)
|
|
395
378
|
|
|
396
379
|
else:
|
|
397
|
-
self.
|
|
380
|
+
self.print_message_inst(mLevel, message, script_location=script_location)
|
|
398
381
|
|
|
399
382
|
except SilentKillError as sk:
|
|
400
383
|
skm = str(sk)
|
|
401
384
|
|
|
402
|
-
self.
|
|
385
|
+
self.print_message_inst("D", "Silent kill requested",
|
|
403
386
|
script_location=Logger.get_caller_info(stack_index=1))
|
|
404
387
|
Fusion.running = False
|
|
405
388
|
time.sleep(0.2)
|
|
@@ -410,8 +393,8 @@ class Fusion(object):
|
|
|
410
393
|
|
|
411
394
|
except Exception as err:
|
|
412
395
|
script_location = ScriptLocation(file_name=Fusion._script_name)
|
|
413
|
-
self.
|
|
414
|
-
self.
|
|
396
|
+
self.print_message_inst("E", message, script_location=script_location)
|
|
397
|
+
self.print_message_inst("E", payload, script_location=script_location)
|
|
415
398
|
self.print_exception(err)
|
|
416
399
|
|
|
417
400
|
else:
|
|
@@ -425,7 +408,6 @@ class Fusion(object):
|
|
|
425
408
|
stack = "Stack trace:\n"
|
|
426
409
|
stack += message.get('stack', '')
|
|
427
410
|
|
|
428
|
-
pattern = re.compile(r'(fusion_bundle\.js):(\d+)')
|
|
429
411
|
matches = [
|
|
430
412
|
(
|
|
431
413
|
m.group(0),
|
|
@@ -434,7 +416,7 @@ class Fusion(object):
|
|
|
434
416
|
line=m.group(2),
|
|
435
417
|
))
|
|
436
418
|
)
|
|
437
|
-
for m in
|
|
419
|
+
for m in Fusion._bundle_pattern.finditer(stack)
|
|
438
420
|
]
|
|
439
421
|
for m in matches:
|
|
440
422
|
stack = stack.replace(m[0], f"{m[1].file_name}:{m[1].line}")
|
|
@@ -453,18 +435,19 @@ class Fusion(object):
|
|
|
453
435
|
"stack": stack
|
|
454
436
|
}))
|
|
455
437
|
|
|
456
|
-
self.
|
|
438
|
+
self.print_message_inst("F", description + stack,
|
|
457
439
|
script_location=script_location)
|
|
458
440
|
Fusion.running = False
|
|
459
441
|
time.sleep(0.2)
|
|
460
442
|
Logger.pl('\n{+} {O}Exiting...{O}{W}')
|
|
461
443
|
self.done.set()
|
|
462
444
|
else:
|
|
463
|
-
self.
|
|
464
|
-
self.
|
|
465
|
-
except:
|
|
466
|
-
self.
|
|
467
|
-
self.
|
|
445
|
+
self.print_message_inst("I", message, script_location=script_location)
|
|
446
|
+
self.print_message_inst("I", payload, script_location=script_location)
|
|
447
|
+
except Exception as e:
|
|
448
|
+
self.print_message_inst("I", message, script_location=script_location)
|
|
449
|
+
self.print_message_inst("I", payload, script_location=script_location)
|
|
450
|
+
self.print_exception(e)
|
|
468
451
|
|
|
469
452
|
return handler
|
|
470
453
|
|
|
@@ -482,6 +465,27 @@ class Fusion(object):
|
|
|
482
465
|
Logger.pl("")
|
|
483
466
|
self.done.set()
|
|
484
467
|
|
|
468
|
+
|
|
469
|
+
def _replace_location(self, message: str) -> str:
|
|
470
|
+
try:
|
|
471
|
+
matches = [
|
|
472
|
+
(
|
|
473
|
+
m.group(0),
|
|
474
|
+
self.translate_location(dict(
|
|
475
|
+
file_name=m.group(1),
|
|
476
|
+
line=m.group(2),
|
|
477
|
+
))
|
|
478
|
+
)
|
|
479
|
+
for m in Fusion._bundle_pattern.finditer(message)
|
|
480
|
+
]
|
|
481
|
+
for m in matches:
|
|
482
|
+
message = message.replace(m[0], f"{m[1].file_name}:{m[1].line}")
|
|
483
|
+
except Exception as e:
|
|
484
|
+
print(e)
|
|
485
|
+
pass
|
|
486
|
+
|
|
487
|
+
return message
|
|
488
|
+
|
|
485
489
|
def _raise_key_value_event(self,
|
|
486
490
|
script_location: ScriptLocation = None,
|
|
487
491
|
stack_trace: str = None,
|
|
@@ -499,7 +503,7 @@ class Fusion(object):
|
|
|
499
503
|
raise ske
|
|
500
504
|
except Exception as e:
|
|
501
505
|
if Configuration.debug_level >= 2:
|
|
502
|
-
self.
|
|
506
|
+
self.print_message_inst("E", f"Error resizing event to module {m.name}: {str(e)}")
|
|
503
507
|
else:
|
|
504
508
|
self.print_exception(e)
|
|
505
509
|
|
|
@@ -518,10 +522,47 @@ class Fusion(object):
|
|
|
518
522
|
raise ske
|
|
519
523
|
except Exception as e:
|
|
520
524
|
if Configuration.debug_level >= 2:
|
|
521
|
-
self.
|
|
525
|
+
self.print_message_inst("E", f"Error resizing event to module {m.name}: {str(e)}")
|
|
522
526
|
else:
|
|
523
527
|
self.print_exception(e)
|
|
524
528
|
|
|
529
|
+
def print_message_inst(self, level: str = "*", message: str = "",
|
|
530
|
+
script_location: ScriptLocation = None):
|
|
531
|
+
|
|
532
|
+
return type(self)._print_message(
|
|
533
|
+
level=level,
|
|
534
|
+
message=self._replace_location(message),
|
|
535
|
+
script_location=script_location
|
|
536
|
+
)
|
|
537
|
+
|
|
538
|
+
@classmethod
|
|
539
|
+
def print_message(cls, level: str = "*", message: str = "",
|
|
540
|
+
script_location: ScriptLocation = None):
|
|
541
|
+
return cls._print_message(
|
|
542
|
+
level=level,
|
|
543
|
+
message=message,
|
|
544
|
+
script_location=script_location
|
|
545
|
+
)
|
|
546
|
+
|
|
547
|
+
@classmethod
|
|
548
|
+
def _print_message(cls, level: str = "*", message: str = "",
|
|
549
|
+
script_location: ScriptLocation = None):
|
|
550
|
+
|
|
551
|
+
if Fusion.running is False and Logger.debug_level >= 2:
|
|
552
|
+
return
|
|
553
|
+
|
|
554
|
+
if script_location is None:
|
|
555
|
+
script_location = ScriptLocation(
|
|
556
|
+
file_name=Fusion._script_name
|
|
557
|
+
)
|
|
558
|
+
|
|
559
|
+
Logger.print_message(
|
|
560
|
+
level=level,
|
|
561
|
+
message=message,
|
|
562
|
+
script_location=script_location,
|
|
563
|
+
filename_col_len=Fusion.max_filename
|
|
564
|
+
)
|
|
565
|
+
|
|
525
566
|
@classmethod
|
|
526
567
|
def insert_history(cls, source: str, data: str, stack_trace: str = ''):
|
|
527
568
|
Fusion._db_jobs.put(dict(
|
|
@@ -2,6 +2,60 @@
|
|
|
2
2
|
Author: Helvio Junior - M4v3r1ck
|
|
3
3
|
*/
|
|
4
4
|
|
|
5
|
+
// Lista de classes típicas do React Native (pode ampliar se quiser)
|
|
6
|
+
const FUSION_DEFAULT_REACT_CLASSES = [
|
|
7
|
+
"com.facebook.react.ReactApplication",
|
|
8
|
+
"com.facebook.react.ReactInstanceManager",
|
|
9
|
+
"com.facebook.react.bridge.ReactContext",
|
|
10
|
+
"com.facebook.react.bridge.JavaScriptModule",
|
|
11
|
+
"com.facebook.react.bridge.NativeModule",
|
|
12
|
+
"com.facebook.react.modules.core.DeviceEventManagerModule",
|
|
13
|
+
"com.facebook.react.bridge.ReactApplicationContext"
|
|
14
|
+
];
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Tenta determinar se a app tem indícios de ser React Native.
|
|
18
|
+
* Estratégia:
|
|
19
|
+
* - tenta Java.use em classes conhecidas (se lançar, ignora)
|
|
20
|
+
* - verifica classes já carregadas (enumerateLoadedClassesSync)
|
|
21
|
+
*
|
|
22
|
+
* Retorna true/false.
|
|
23
|
+
*/
|
|
24
|
+
function fusion_isReactNativeApp(reactClasses) {
|
|
25
|
+
reactClasses = reactClasses || FUSION_DEFAULT_REACT_CLASSES;
|
|
26
|
+
if (!Java.available) return false;
|
|
27
|
+
|
|
28
|
+
try {
|
|
29
|
+
// 1) tentativa de usar as classes (pode carregar a classe se presente)
|
|
30
|
+
for (var i = 0; i < reactClasses.length; i++) {
|
|
31
|
+
try {
|
|
32
|
+
Java.use(reactClasses[i]);
|
|
33
|
+
return true; // encontrou uma classe RN na ClassLoader
|
|
34
|
+
} catch (e) {
|
|
35
|
+
// não encontrado/erro: continuar
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
// 2) se nada foi encontrado via Java.use, verificar classes já carregadas
|
|
40
|
+
try {
|
|
41
|
+
var loaded = Java.enumerateLoadedClassesSync();
|
|
42
|
+
for (var j = 0; j < loaded.length; j++) {
|
|
43
|
+
var name = loaded[j];
|
|
44
|
+
for (var k = 0; k < reactClasses.length; k++) {
|
|
45
|
+
if (name.indexOf(reactClasses[k]) !== -1 || name === reactClasses[k]) {
|
|
46
|
+
return true;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
} catch (e) {
|
|
51
|
+
// enumerateLoadedClassesSync pode falhar em alguns contextos; ignorar
|
|
52
|
+
}
|
|
53
|
+
} catch (outer) {
|
|
54
|
+
// fallback
|
|
55
|
+
}
|
|
56
|
+
return false;
|
|
57
|
+
}
|
|
58
|
+
|
|
5
59
|
function fusion_rawSend(payload1){
|
|
6
60
|
send(payload1);
|
|
7
61
|
}
|
|
@@ -22,6 +76,10 @@ function fusion_Send(payload1, payload2){
|
|
|
22
76
|
send(message, payload2);
|
|
23
77
|
}
|
|
24
78
|
|
|
79
|
+
function fusion_classExists(name) { try { Java.use(name); return true; } catch (_) { return false; } }
|
|
80
|
+
|
|
81
|
+
function fusion_useOrNull(name) { try { return Java.use(name); } catch (e) { return null; } }
|
|
82
|
+
|
|
25
83
|
function fusion_waitForClass(name, onReady) {
|
|
26
84
|
var intv = setInterval(function () {
|
|
27
85
|
try {
|
|
@@ -38,6 +96,37 @@ function fusion_printStackTrace(){
|
|
|
38
96
|
fusion_sendMessage("I", trace);
|
|
39
97
|
}
|
|
40
98
|
|
|
99
|
+
function fusion_toLongPrimitive(v, fallback /* opcional */) {
|
|
100
|
+
const FB = (typeof fallback === 'number') ? fallback : -1;
|
|
101
|
+
|
|
102
|
+
try {
|
|
103
|
+
// Já é número JS
|
|
104
|
+
if (typeof v === 'number') {
|
|
105
|
+
// garante inteiro (contentLength é integral)
|
|
106
|
+
return Math.trunc(v);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
if (v === null || v === undefined) return FB;
|
|
110
|
+
|
|
111
|
+
// java.lang.Long / Integer / Short (ou qualquer Number com longValue/intValue)
|
|
112
|
+
if (v.longValue) { try { return v.longValue(); } catch (_) {} }
|
|
113
|
+
if (v.intValue) { try { return v.intValue(); } catch (_) {} }
|
|
114
|
+
if (v.shortValue) { try { return v.shortValue(); } catch (_) {} }
|
|
115
|
+
|
|
116
|
+
// String numérica
|
|
117
|
+
if (typeof v === 'string' || (v.toString && typeof v.toString() === 'function')) {
|
|
118
|
+
const s = String(v);
|
|
119
|
+
if (/^-?\d+$/.test(s)) {
|
|
120
|
+
const JLong = Java.use('java.lang.Long');
|
|
121
|
+
// parseia com Java para respeitar faixa de long
|
|
122
|
+
return JLong.parseLong(s);
|
|
123
|
+
}
|
|
124
|
+
}
|
|
125
|
+
} catch (_) {}
|
|
126
|
+
|
|
127
|
+
return FB;
|
|
128
|
+
}
|
|
129
|
+
|
|
41
130
|
function fusion_toBytes(message){
|
|
42
131
|
try{
|
|
43
132
|
const StringClass = Java.use('java.lang.String');
|
|
@@ -128,22 +217,26 @@ function fusion_getCallerInfo() {
|
|
|
128
217
|
}
|
|
129
218
|
|
|
130
219
|
function fusion_sendKeyValueData(module, items) {
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
var data = [];
|
|
220
|
+
try{
|
|
221
|
+
var st = fusion_getB64StackTrace();
|
|
134
222
|
|
|
135
|
-
|
|
136
|
-
for (let i = 0; i < items.length; i++) {
|
|
137
|
-
data = data.concat([{key: `${items[i].key}`, value:`${items[i].value}`}]);
|
|
138
|
-
}
|
|
223
|
+
var data = [];
|
|
139
224
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
stack_trace: st
|
|
145
|
-
}, null);
|
|
225
|
+
// Force as String
|
|
226
|
+
for (let i = 0; i < items.length; i++) {
|
|
227
|
+
data = data.concat([{key: `${items[i].key}`, value:`${items[i].value}`}]);
|
|
228
|
+
}
|
|
146
229
|
|
|
230
|
+
fusion_Send({
|
|
231
|
+
type: "key_value_data",
|
|
232
|
+
module: module,
|
|
233
|
+
data: data,
|
|
234
|
+
stack_trace: st
|
|
235
|
+
}, null);
|
|
236
|
+
} catch (err) {
|
|
237
|
+
fusion_sendMessage("W", `Error: ${err}`)
|
|
238
|
+
}
|
|
239
|
+
return null;
|
|
147
240
|
}
|
|
148
241
|
|
|
149
242
|
function fusion_sendMessage(level, message){
|
|
@@ -160,7 +253,7 @@ function fusion_sendMessage(level, message){
|
|
|
160
253
|
message: b64Msg
|
|
161
254
|
}, null)
|
|
162
255
|
} catch (err) {
|
|
163
|
-
fusion_sendMessage("W", err)
|
|
256
|
+
fusion_sendMessage("W", `Error: ${err}`)
|
|
164
257
|
}
|
|
165
258
|
}
|
|
166
259
|
|
|
@@ -184,15 +277,15 @@ function fusion_sendMessageWithTrace(level, message){
|
|
|
184
277
|
message: b64Msg
|
|
185
278
|
}, null)
|
|
186
279
|
} catch (err) {
|
|
187
|
-
fusion_sendMessage("W", err)
|
|
280
|
+
fusion_sendMessage("W", `Error: ${err}`)
|
|
188
281
|
}
|
|
189
282
|
}
|
|
190
283
|
|
|
191
284
|
function fusion_sendError(error) {
|
|
192
285
|
try{
|
|
193
|
-
fusion_sendMessage("E", error
|
|
286
|
+
fusion_sendMessage("E", `${error}\n${error.stack}`);
|
|
194
287
|
} catch (err) {
|
|
195
|
-
fusion_sendMessage("W", err)
|
|
288
|
+
fusion_sendMessage("W", `Error: ${err}`);
|
|
196
289
|
}
|
|
197
290
|
}
|
|
198
291
|
|
|
@@ -218,7 +311,7 @@ function fusion_getB64StackTrace(){
|
|
|
218
311
|
return b64Msg
|
|
219
312
|
|
|
220
313
|
} catch (err) {
|
|
221
|
-
fusion_sendMessage("W", err)
|
|
314
|
+
fusion_sendMessage("W", `Error: ${err}`)
|
|
222
315
|
return '';
|
|
223
316
|
}
|
|
224
317
|
}
|
|
@@ -232,6 +325,8 @@ function fusion_printMethods(targetClass)
|
|
|
232
325
|
});
|
|
233
326
|
}
|
|
234
327
|
|
|
328
|
+
|
|
329
|
+
//java.lang.Class
|
|
235
330
|
function fusion_getClassName(obj)
|
|
236
331
|
{
|
|
237
332
|
if (obj === null || obj === undefined) return "";
|
|
@@ -240,28 +335,54 @@ function fusion_getClassName(obj)
|
|
|
240
335
|
// Caso seja um objeto Java real
|
|
241
336
|
if (obj.$className !== undefined) {
|
|
242
337
|
// Objetos instanciados via Java.use
|
|
243
|
-
|
|
338
|
+
var name = obj.$className;
|
|
339
|
+
if (name == "java.lang.Class") return obj.getName();
|
|
340
|
+
return name;
|
|
244
341
|
}
|
|
245
342
|
|
|
246
343
|
// Caso seja uma instância Java (não necessariamente via Java.use)
|
|
247
|
-
if (
|
|
248
|
-
|
|
344
|
+
if (typeof obj === 'object' && typeof obj.getClass === 'function') {
|
|
345
|
+
var name = obj.getClass().getName();
|
|
346
|
+
if (name == "java.lang.Class" && typeof obj.getClass === 'function') return obj.getName();
|
|
347
|
+
return name;
|
|
249
348
|
}
|
|
250
349
|
|
|
251
350
|
// Caso seja uma classe Java carregada (Java.use)
|
|
252
|
-
if (
|
|
253
|
-
|
|
351
|
+
if (typeof obj === 'object' && obj.class !== undefined ) {
|
|
352
|
+
var name = obj.class.getName();
|
|
353
|
+
if (name == "java.lang.Class" && typeof obj.getClass === 'function') return obj.getName();
|
|
354
|
+
return name;
|
|
254
355
|
}
|
|
255
356
|
|
|
256
357
|
// Se for algo não Java, apenas retorna tipo do JS
|
|
257
358
|
return typeof obj;
|
|
258
359
|
} catch (err) {
|
|
259
|
-
fusion_sendMessage("W", err)
|
|
360
|
+
fusion_sendMessage("W", `Error: ${err}\n${err.stack}`)
|
|
260
361
|
return '';
|
|
261
362
|
}
|
|
262
363
|
|
|
263
364
|
}
|
|
264
365
|
|
|
366
|
+
function fusion_getFieldValue(obj, fieldName) {
|
|
367
|
+
if (obj === null || obj === undefined) return "";
|
|
368
|
+
try {
|
|
369
|
+
var cls = obj.getClass();
|
|
370
|
+
while (cls != null) {
|
|
371
|
+
try {
|
|
372
|
+
var f = cls.getDeclaredField(fieldName);
|
|
373
|
+
f.setAccessible(true);
|
|
374
|
+
return f.get(obj);
|
|
375
|
+
} catch (e) {
|
|
376
|
+
cls = cls.getSuperclass();
|
|
377
|
+
}
|
|
378
|
+
}
|
|
379
|
+
} catch (err) {
|
|
380
|
+
fusion_sendMessage("W", `Error: ${err}`)
|
|
381
|
+
return '';
|
|
382
|
+
}
|
|
383
|
+
}
|
|
384
|
+
|
|
385
|
+
|
|
265
386
|
function fusion_getReadableRange(p) {
|
|
266
387
|
try { p = ptr(p); } catch (_) { return null; }
|
|
267
388
|
const range = Process.findRangeByAddress(p); // não lança exceção
|