AndroidFridaManager 1.9.4__py3-none-any.whl → 1.9.5__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.
- AndroidFridaManager/about.py +1 -1
- AndroidFridaManager/job.py +29 -6
- AndroidFridaManager/job_manager.py +69 -24
- {androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/METADATA +2 -2
- androidfridamanager-1.9.5.dist-info/RECORD +11 -0
- {androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/WHEEL +1 -1
- androidfridamanager-1.9.4.dist-info/RECORD +0 -11
- {androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/entry_points.txt +0 -0
- {androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/licenses/LICENSE +0 -0
- {androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/top_level.txt +0 -0
AndroidFridaManager/about.py
CHANGED
AndroidFridaManager/job.py
CHANGED
|
@@ -134,15 +134,38 @@ class Job:
|
|
|
134
134
|
raise FridaBasedException("Connection is closed. Probably the target app crashed")
|
|
135
135
|
|
|
136
136
|
|
|
137
|
-
def close_job(self):
|
|
137
|
+
def close_job(self, timeout: float = 5.0) -> bool:
|
|
138
|
+
"""Stop the job and cleanup resources.
|
|
139
|
+
|
|
140
|
+
Args:
|
|
141
|
+
timeout: Maximum seconds to wait for thread to stop.
|
|
142
|
+
Default 5.0 seconds. Use 0 for no wait.
|
|
143
|
+
|
|
144
|
+
Returns:
|
|
145
|
+
True if job stopped cleanly, False if timed out.
|
|
146
|
+
"""
|
|
138
147
|
self.state = "stopping"
|
|
139
148
|
self.stop_event.set()
|
|
140
|
-
|
|
141
|
-
|
|
149
|
+
|
|
150
|
+
timed_out = False
|
|
151
|
+
if self.thread and self.thread.is_alive():
|
|
152
|
+
self.thread.join(timeout=timeout if timeout > 0 else None)
|
|
153
|
+
if self.thread.is_alive():
|
|
154
|
+
self.logger.warning(
|
|
155
|
+
f"Job {self.job_id} thread did not stop within {timeout}s"
|
|
156
|
+
)
|
|
157
|
+
timed_out = True
|
|
158
|
+
|
|
159
|
+
# Try to unload script even if thread timed out
|
|
142
160
|
if self.script:
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
161
|
+
try:
|
|
162
|
+
self.script.unload()
|
|
163
|
+
except Exception as e:
|
|
164
|
+
self.logger.warning(f"Error unloading script: {e}")
|
|
165
|
+
|
|
166
|
+
status = "timed out" if timed_out else "stopped"
|
|
167
|
+
self.logger.info(f"Job {self.job_id} {status}")
|
|
168
|
+
return not timed_out
|
|
146
169
|
|
|
147
170
|
|
|
148
171
|
def get_id(self):
|
|
@@ -424,29 +424,48 @@ class JobManager(object):
|
|
|
424
424
|
return None
|
|
425
425
|
|
|
426
426
|
|
|
427
|
-
def stop_jobs(self):
|
|
427
|
+
def stop_jobs(self, timeout_per_job: float = 3.0) -> dict:
|
|
428
|
+
"""Stop all running jobs.
|
|
429
|
+
|
|
430
|
+
Args:
|
|
431
|
+
timeout_per_job: Maximum seconds to wait per job.
|
|
432
|
+
|
|
433
|
+
Returns:
|
|
434
|
+
Dictionary mapping job_id to success status.
|
|
435
|
+
"""
|
|
436
|
+
results = {}
|
|
428
437
|
jobs_to_stop = [job_id for job_id, job in self.jobs.items() if job.state == "running"]
|
|
438
|
+
|
|
429
439
|
for job_id in jobs_to_stop:
|
|
430
440
|
try:
|
|
431
|
-
self.logger.info('[job manager] Job: {
|
|
432
|
-
self.stop_job_with_id(job_id)
|
|
441
|
+
self.logger.info(f'[job manager] Job: {job_id} - Stopping')
|
|
442
|
+
results[job_id] = self.stop_job_with_id(job_id, timeout=timeout_per_job)
|
|
433
443
|
except frida.InvalidOperationError:
|
|
434
|
-
self.logger.error('[job manager] Job: {
|
|
435
|
-
|
|
444
|
+
self.logger.error(f'[job manager] Job: {job_id} - Error stopping')
|
|
445
|
+
results[job_id] = False
|
|
446
|
+
|
|
447
|
+
return results
|
|
436
448
|
|
|
437
449
|
|
|
438
|
-
def stop_job_with_id(self, job_id: str) ->
|
|
450
|
+
def stop_job_with_id(self, job_id: str, timeout: float = 5.0) -> bool:
|
|
439
451
|
"""Stop a specific job by ID.
|
|
440
452
|
|
|
441
453
|
Args:
|
|
442
454
|
job_id: UUID of the job to stop.
|
|
455
|
+
timeout: Maximum seconds to wait for job to stop.
|
|
456
|
+
|
|
457
|
+
Returns:
|
|
458
|
+
True if job stopped cleanly, False if timed out or not found.
|
|
443
459
|
"""
|
|
444
|
-
if job_id in self.jobs:
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
460
|
+
if job_id not in self.jobs:
|
|
461
|
+
return False
|
|
462
|
+
|
|
463
|
+
job = self.jobs[job_id]
|
|
464
|
+
# Unregister hooks before closing
|
|
465
|
+
self.unregister_hooks(job_id)
|
|
466
|
+
success = job.close_job(timeout=timeout)
|
|
467
|
+
del self.jobs[job_id]
|
|
468
|
+
return success
|
|
450
469
|
|
|
451
470
|
|
|
452
471
|
def get_last_created_job(self):
|
|
@@ -461,10 +480,38 @@ class JobManager(object):
|
|
|
461
480
|
raise ValueError(f"Job with ID {job_id} not found.")
|
|
462
481
|
|
|
463
482
|
|
|
464
|
-
def detach_from_app(self):
|
|
465
|
-
|
|
483
|
+
def detach_from_app(self, timeout: float = 3.0) -> bool:
|
|
484
|
+
"""Detach from the current app session.
|
|
485
|
+
|
|
486
|
+
Args:
|
|
487
|
+
timeout: Maximum seconds to wait for detach.
|
|
488
|
+
|
|
489
|
+
Returns:
|
|
490
|
+
True if detached successfully, False if timed out or failed.
|
|
491
|
+
"""
|
|
492
|
+
if not self.process_session:
|
|
493
|
+
return True
|
|
494
|
+
|
|
495
|
+
import concurrent.futures
|
|
496
|
+
|
|
497
|
+
def _detach():
|
|
466
498
|
self.process_session.detach()
|
|
467
499
|
|
|
500
|
+
try:
|
|
501
|
+
with concurrent.futures.ThreadPoolExecutor(max_workers=1) as executor:
|
|
502
|
+
future = executor.submit(_detach)
|
|
503
|
+
future.result(timeout=timeout)
|
|
504
|
+
self.process_session = None
|
|
505
|
+
return True
|
|
506
|
+
except concurrent.futures.TimeoutError:
|
|
507
|
+
self.logger.warning(f"Detach timed out after {timeout}s")
|
|
508
|
+
self.process_session = None # Clear anyway to avoid reuse
|
|
509
|
+
return False
|
|
510
|
+
except Exception as e:
|
|
511
|
+
self.logger.warning(f"Detach failed: {e}")
|
|
512
|
+
self.process_session = None
|
|
513
|
+
return False
|
|
514
|
+
|
|
468
515
|
|
|
469
516
|
def stop_app(self, app_package):
|
|
470
517
|
cmd = self._build_adb_command(["shell", "am", "force-stop", app_package])
|
|
@@ -670,23 +717,21 @@ class JobManager(object):
|
|
|
670
717
|
"""Get the current session mode ('spawn' or 'attach')."""
|
|
671
718
|
return self._mode
|
|
672
719
|
|
|
673
|
-
def reset_session(self) -> None:
|
|
720
|
+
def reset_session(self, timeout_per_job: float = 2.0, detach_timeout: float = 2.0) -> None:
|
|
674
721
|
"""Reset the session state for a new connection.
|
|
675
722
|
|
|
676
|
-
|
|
723
|
+
Args:
|
|
724
|
+
timeout_per_job: Max seconds to wait per job when stopping.
|
|
725
|
+
detach_timeout: Max seconds to wait for session detach.
|
|
677
726
|
"""
|
|
678
|
-
# Stop all running jobs
|
|
679
|
-
self.stop_jobs()
|
|
727
|
+
# Stop all running jobs with timeout
|
|
728
|
+
self.stop_jobs(timeout_per_job=timeout_per_job)
|
|
680
729
|
|
|
681
730
|
# Clear hook registry
|
|
682
731
|
self._hook_registry.clear()
|
|
683
732
|
|
|
684
|
-
# Detach from app
|
|
685
|
-
|
|
686
|
-
try:
|
|
687
|
-
self.process_session.detach()
|
|
688
|
-
except Exception:
|
|
689
|
-
pass
|
|
733
|
+
# Detach from app with timeout
|
|
734
|
+
self.detach_from_app(timeout=detach_timeout)
|
|
690
735
|
|
|
691
736
|
# Reset state
|
|
692
737
|
self.process_session = None
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AndroidFridaManager
|
|
3
|
-
Version: 1.9.
|
|
3
|
+
Version: 1.9.5
|
|
4
4
|
Summary: A python API in order to install and run the frida-server on an Android device.
|
|
5
5
|
Home-page: https://github.com/fkie-cad/AndroidFridaManager
|
|
6
6
|
Author: Daniel Baier
|
|
@@ -33,7 +33,7 @@ Dynamic: requires-dist
|
|
|
33
33
|
Dynamic: requires-python
|
|
34
34
|
Dynamic: summary
|
|
35
35
|
|
|
36
|
-
 [](https://badge.fury.io/py/AndroidFridaManager) [](https://github.com/fkie-cad/AndroidFridaManager/actions/workflows/publish-to-pypi.yml)
|
|
37
37
|
|
|
38
38
|
# AndroidFridaManager
|
|
39
39
|
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
AndroidFridaManager/FridaManager.py,sha256=pTcis4oLPBN5U7CdBqdUufwuG6QQDWTPBleTC7rtTbI,32145
|
|
2
|
+
AndroidFridaManager/__init__.py,sha256=T6AKtrGSLQ9M5bJoWDQcsRTJbSEbksdgrx3AAAdozRI,171
|
|
3
|
+
AndroidFridaManager/about.py,sha256=wGo_88YOuzXo2vF1EyCEmIO4uxM7wOJLC-FrGLp__Mw,98
|
|
4
|
+
AndroidFridaManager/job.py,sha256=Yzir0XkkpFj5cFIcMRGJlLnIcIuDVZ9jBLFMqwQKTFA,7041
|
|
5
|
+
AndroidFridaManager/job_manager.py,sha256=Ce2lHLezRVKuj7r_RodH6Q8l43zL_cL5ZGhE1zGB-E8,27336
|
|
6
|
+
androidfridamanager-1.9.5.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
7
|
+
androidfridamanager-1.9.5.dist-info/METADATA,sha256=pjOCtO1KPNhyybRz8O5a56LXfeTqnKRcm0P0Kii5kpA,5141
|
|
8
|
+
androidfridamanager-1.9.5.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
|
|
9
|
+
androidfridamanager-1.9.5.dist-info/entry_points.txt,sha256=GmNngu2fDNCxUcquFRegBa7GWknPKG1jsM4lvWeyKnY,64
|
|
10
|
+
androidfridamanager-1.9.5.dist-info/top_level.txt,sha256=oH2lVMSRlghmt-_tVrOEUqvY462P9hd5Ktgp5-1qF3o,20
|
|
11
|
+
androidfridamanager-1.9.5.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
AndroidFridaManager/FridaManager.py,sha256=pTcis4oLPBN5U7CdBqdUufwuG6QQDWTPBleTC7rtTbI,32145
|
|
2
|
-
AndroidFridaManager/__init__.py,sha256=T6AKtrGSLQ9M5bJoWDQcsRTJbSEbksdgrx3AAAdozRI,171
|
|
3
|
-
AndroidFridaManager/about.py,sha256=st5zrhGhtBpwZErvuVGrS-VQL9AmtAxFwL9AYgf-rqI,98
|
|
4
|
-
AndroidFridaManager/job.py,sha256=sMkTk1rHdfNmh9jFNQuiL4oqsUEBCJcbP6p2DZQPbL0,6172
|
|
5
|
-
AndroidFridaManager/job_manager.py,sha256=oPkzFK8XpwFhDHKuJmAoqylUDaV6VIKL_AikJBcg3iQ,25772
|
|
6
|
-
androidfridamanager-1.9.4.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
7
|
-
androidfridamanager-1.9.4.dist-info/METADATA,sha256=bghFYQPx8KRnUXKXZNyfHkPmBuTx3yBjT5_jXSZD9HM,5141
|
|
8
|
-
androidfridamanager-1.9.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
-
androidfridamanager-1.9.4.dist-info/entry_points.txt,sha256=GmNngu2fDNCxUcquFRegBa7GWknPKG1jsM4lvWeyKnY,64
|
|
10
|
-
androidfridamanager-1.9.4.dist-info/top_level.txt,sha256=oH2lVMSRlghmt-_tVrOEUqvY462P9hd5Ktgp5-1qF3o,20
|
|
11
|
-
androidfridamanager-1.9.4.dist-info/RECORD,,
|
{androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{androidfridamanager-1.9.4.dist-info → androidfridamanager-1.9.5.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|