AndroidFridaManager 1.8.6__py3-none-any.whl → 1.8.8__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/FridaManager.py +11 -10
- AndroidFridaManager/about.py +1 -1
- AndroidFridaManager/job.py +4 -2
- AndroidFridaManager/job_manager.py +34 -17
- {androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/METADATA +2 -2
- androidfridamanager-1.8.8.dist-info/RECORD +11 -0
- androidfridamanager-1.8.6.dist-info/RECORD +0 -11
- {androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/WHEEL +0 -0
- {androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/entry_points.txt +0 -0
- {androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/licenses/LICENSE +0 -0
- {androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/top_level.txt +0 -0
|
@@ -80,11 +80,11 @@ class FridaManager():
|
|
|
80
80
|
Check if ADB is available in the system PATH
|
|
81
81
|
"""
|
|
82
82
|
if not shutil.which("adb"):
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
83
|
+
self.logger.info("Error: ADB (Android Debug Bridge) is not found in your system PATH.")
|
|
84
|
+
self.logger.info("Please install Android SDK platform-tools and add it to your PATH:")
|
|
85
|
+
self.logger.info(" - Download from: https://developer.android.com/studio/releases/platform-tools")
|
|
86
|
+
self.logger.info(" - Or install via package manager (e.g., 'brew install android-platform-tools' on macOS)")
|
|
87
|
+
self.logger.info(" - Make sure 'adb' command is accessible from your terminal")
|
|
88
88
|
sys.exit(1)
|
|
89
89
|
|
|
90
90
|
def run_frida_server(self, frida_server_path="/data/local/tmp/"):
|
|
@@ -114,7 +114,7 @@ class FridaManager():
|
|
|
114
114
|
if process.poll() is not None:
|
|
115
115
|
stdout, stderr = process.communicate()
|
|
116
116
|
if "Address already in use" in stderr.decode():
|
|
117
|
-
|
|
117
|
+
self.logger.info("[*] frida-server is already running on the device")
|
|
118
118
|
return
|
|
119
119
|
else:
|
|
120
120
|
self.logger.error(f"Failed to start frida-server: {stderr.decode()}")
|
|
@@ -385,9 +385,9 @@ def main():
|
|
|
385
385
|
if args.is_running:
|
|
386
386
|
afm_obj = FridaManager()
|
|
387
387
|
if afm_obj.is_frida_server_running():
|
|
388
|
-
|
|
388
|
+
afm_obj.logger.info("[*] frida-server is running on Android device")
|
|
389
389
|
else:
|
|
390
|
-
|
|
390
|
+
afm_obj.logger.info("[*] frida-server is not running on Android device")
|
|
391
391
|
|
|
392
392
|
sys.exit()
|
|
393
393
|
|
|
@@ -398,11 +398,12 @@ def main():
|
|
|
398
398
|
afm_obj = FridaManager()
|
|
399
399
|
|
|
400
400
|
afm_obj.install_frida_server()
|
|
401
|
+
afm_obj.run_frida_server()
|
|
401
402
|
result = afm_obj.is_frida_server_running()
|
|
402
403
|
if result:
|
|
403
|
-
|
|
404
|
+
afm_obj.logger.info("[*] succesfull installed and launched latest frida-server version on Android device")
|
|
404
405
|
else:
|
|
405
|
-
|
|
406
|
+
afm_obj.logger.error("[-] unable to run frida-server on Android device")
|
|
406
407
|
|
|
407
408
|
|
|
408
409
|
if __name__ == "__main__":
|
AndroidFridaManager/about.py
CHANGED
AndroidFridaManager/job.py
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
import threading
|
|
6
6
|
import frida
|
|
7
7
|
import uuid
|
|
8
|
+
import logging
|
|
8
9
|
|
|
9
10
|
# Define a custom exception for handling frida based exceptions
|
|
10
11
|
class FridaBasedException(Exception):
|
|
@@ -21,6 +22,7 @@ class Job:
|
|
|
21
22
|
self.process_session = process
|
|
22
23
|
self.thread = None
|
|
23
24
|
self.is_script_created = False
|
|
25
|
+
self.logger = logging.getLogger(__name__)
|
|
24
26
|
|
|
25
27
|
|
|
26
28
|
def create_job_script(self):
|
|
@@ -45,7 +47,7 @@ class Job:
|
|
|
45
47
|
self.script.on("message", self.wrap_custom_hooking_handler_with_job_id(self.custom_hooking_handler))
|
|
46
48
|
self.script.load()
|
|
47
49
|
self.state = "running"
|
|
48
|
-
|
|
50
|
+
self.logger.info("[+] hooks successfully loaded")
|
|
49
51
|
|
|
50
52
|
#if self.is_running_as_thread:
|
|
51
53
|
# Keep the thread alive to handle messages until stop_event is set
|
|
@@ -88,7 +90,7 @@ class Job:
|
|
|
88
90
|
if self.script:
|
|
89
91
|
self.script.unload()
|
|
90
92
|
|
|
91
|
-
|
|
93
|
+
self.logger.info(f"Job {self.job_id} stopped")
|
|
92
94
|
|
|
93
95
|
|
|
94
96
|
def get_id(self):
|
|
@@ -8,6 +8,7 @@ from typing import Optional, Dict, Union
|
|
|
8
8
|
from .job import Job, FridaBasedException
|
|
9
9
|
import time
|
|
10
10
|
import re
|
|
11
|
+
import logging
|
|
11
12
|
|
|
12
13
|
class JobManager(object):
|
|
13
14
|
""" A class representing the current Job manager. """
|
|
@@ -31,8 +32,24 @@ class JobManager(object):
|
|
|
31
32
|
self.first_instrumenation_script = None
|
|
32
33
|
self.last_created_job = None
|
|
33
34
|
self.init_last_job = False
|
|
35
|
+
self.logger = logging.getLogger(__name__)
|
|
36
|
+
self._ensure_logging_setup()
|
|
34
37
|
atexit.register(self.cleanup)
|
|
35
38
|
|
|
39
|
+
def _ensure_logging_setup(self):
|
|
40
|
+
"""
|
|
41
|
+
Ensure basic logging setup if not already configured.
|
|
42
|
+
This provides a fallback for when JobManager is used independently.
|
|
43
|
+
"""
|
|
44
|
+
root_logger = logging.getLogger()
|
|
45
|
+
if not root_logger.handlers:
|
|
46
|
+
# Set up basic logging if no handlers exist
|
|
47
|
+
root_logger.setLevel(logging.INFO)
|
|
48
|
+
handler = logging.StreamHandler()
|
|
49
|
+
formatter = logging.Formatter('[%(asctime)s] [%(levelname)-4s] - %(message)s',
|
|
50
|
+
datefmt='%d-%m-%y %H:%M:%S')
|
|
51
|
+
handler.setFormatter(formatter)
|
|
52
|
+
root_logger.addHandler(handler)
|
|
36
53
|
|
|
37
54
|
def cleanup(self) -> None:
|
|
38
55
|
"""
|
|
@@ -44,10 +61,10 @@ class JobManager(object):
|
|
|
44
61
|
:return:
|
|
45
62
|
"""
|
|
46
63
|
if len(self.jobs) > 0:
|
|
47
|
-
|
|
64
|
+
self.logger.info("[*] Program closed. Stopping active jobs...")
|
|
48
65
|
self.stop_jobs()
|
|
49
66
|
|
|
50
|
-
|
|
67
|
+
self.logger.info("\n[*] Have a nice day!")
|
|
51
68
|
|
|
52
69
|
|
|
53
70
|
def job_list(self):
|
|
@@ -62,16 +79,16 @@ class JobManager(object):
|
|
|
62
79
|
def running_jobs2(self):
|
|
63
80
|
tuple_jobs = [job for job in self.jobs.items()]
|
|
64
81
|
for job_id, job in tuple_jobs:
|
|
65
|
-
|
|
82
|
+
self.logger.debug(f"Job state of Job {job_id} in state {job.state}")
|
|
66
83
|
return tuple_jobs
|
|
67
84
|
'''
|
|
68
85
|
|
|
69
86
|
def spawn(self, target_process):
|
|
70
87
|
self.package_name = target_process
|
|
71
|
-
|
|
88
|
+
self.logger.info("[*] spawning app: "+ target_process)
|
|
72
89
|
pid = self.device.spawn(target_process)
|
|
73
90
|
self.process_session = self.device.attach(pid)
|
|
74
|
-
|
|
91
|
+
self.logger.info(f"Spawned {target_process} with PID {pid}")
|
|
75
92
|
return pid
|
|
76
93
|
|
|
77
94
|
|
|
@@ -128,15 +145,15 @@ class JobManager(object):
|
|
|
128
145
|
if foreground:
|
|
129
146
|
target_process = self.device.get_frontmost_application()
|
|
130
147
|
if target_process is None or len(target_process.identifier) < 2:
|
|
131
|
-
|
|
148
|
+
self.logger.error("[-] unable to attach to the frontmost application. Aborting ...")
|
|
132
149
|
|
|
133
150
|
target_process = target_process.identifier
|
|
134
151
|
|
|
135
152
|
if isinstance(target_process, int):
|
|
136
|
-
|
|
153
|
+
self.logger.info(f"[*] attaching to PID: {target_process}")
|
|
137
154
|
self.process_session = self.device.attach(target_process)
|
|
138
155
|
else:
|
|
139
|
-
|
|
156
|
+
self.logger.info(f"[*] attaching to app: {target_process}")
|
|
140
157
|
self.process_session = self.device.attach(int(target_process) if target_process.isnumeric() else target_process)
|
|
141
158
|
|
|
142
159
|
|
|
@@ -163,12 +180,12 @@ class JobManager(object):
|
|
|
163
180
|
job = Job(frida_script_name, custom_hooking_handler_name, self.process_session)
|
|
164
181
|
job.create_job_script()
|
|
165
182
|
self.init_last_job = True
|
|
166
|
-
|
|
183
|
+
self.logger.info(f"[*] created job: {job.job_id}")
|
|
167
184
|
self.jobs[job.job_id] = job
|
|
168
185
|
self.last_created_job = job
|
|
169
186
|
|
|
170
187
|
else:
|
|
171
|
-
|
|
188
|
+
self.logger.error("[-] no frida session. Aborting...")
|
|
172
189
|
|
|
173
190
|
except frida.TransportError as fe:
|
|
174
191
|
raise FridaBasedException(f"Problems while attaching to frida-server: {fe}")
|
|
@@ -199,7 +216,7 @@ class JobManager(object):
|
|
|
199
216
|
try:
|
|
200
217
|
if self.process_session:
|
|
201
218
|
job = Job(frida_script_name, custom_hooking_handler_name, self.process_session)
|
|
202
|
-
|
|
219
|
+
self.logger.info(f"[*] created job: {job.job_id}")
|
|
203
220
|
self.jobs[job.job_id] = job
|
|
204
221
|
self.last_created_job = job
|
|
205
222
|
job.run_job()
|
|
@@ -213,7 +230,7 @@ class JobManager(object):
|
|
|
213
230
|
return job
|
|
214
231
|
|
|
215
232
|
else:
|
|
216
|
-
|
|
233
|
+
self.logger.error("[-] no frida session. Aborting...")
|
|
217
234
|
|
|
218
235
|
|
|
219
236
|
except frida.TransportError as fe:
|
|
@@ -233,10 +250,10 @@ class JobManager(object):
|
|
|
233
250
|
jobs_to_stop = [job_id for job_id, job in self.jobs.items() if job.state == "running"]
|
|
234
251
|
for job_id in jobs_to_stop:
|
|
235
252
|
try:
|
|
236
|
-
|
|
253
|
+
self.logger.info('[job manager] Job: {0} - Stopping'.format(job_id))
|
|
237
254
|
self.stop_job_with_id(job_id)
|
|
238
255
|
except frida.InvalidOperationError:
|
|
239
|
-
|
|
256
|
+
self.logger.error('[job manager] Job: {0} - An error occurred stopping job. Device may '
|
|
240
257
|
'no longer be available.'.format(job_id))
|
|
241
258
|
|
|
242
259
|
|
|
@@ -277,7 +294,7 @@ class JobManager(object):
|
|
|
277
294
|
def stop_app_with_closing_frida(self, app_package):
|
|
278
295
|
jobs_to_stop = [job_id for job_id, job in self.jobs.items() if job.state == "running"]
|
|
279
296
|
for job_id in jobs_to_stop:
|
|
280
|
-
|
|
297
|
+
self.logger.info(f"[*] trying to close job: {job_id}")
|
|
281
298
|
self.stop_job_with_id(job_id)
|
|
282
299
|
|
|
283
300
|
self.detach_from_app()
|
|
@@ -298,14 +315,14 @@ class JobManager(object):
|
|
|
298
315
|
|
|
299
316
|
# to handle forks
|
|
300
317
|
def on_child_added(child):
|
|
301
|
-
|
|
318
|
+
self.logger.info(f"Attached to child process with pid {child.pid}")
|
|
302
319
|
if callable(self.first_instrumenation_script):
|
|
303
320
|
self.first_instrumenation_script(device.attach(child.pid))
|
|
304
321
|
device.resume(child.pid)
|
|
305
322
|
|
|
306
323
|
# if the target process is starting another process
|
|
307
324
|
def on_spawn_added(spawn):
|
|
308
|
-
|
|
325
|
+
self.logger.info(f"Process spawned with pid {spawn.pid}. Name: {spawn.identifier}")
|
|
309
326
|
if callable(self.first_instrumenation_script):
|
|
310
327
|
self.first_instrumenation_script(device.attach(spawn.pid))
|
|
311
328
|
device.resume(spawn.pid)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: AndroidFridaManager
|
|
3
|
-
Version: 1.8.
|
|
3
|
+
Version: 1.8.8
|
|
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=N00XTg1O0Uj5b5HY7Ir7-PCDhoAYHzGA9p9DU4BTOBA,16268
|
|
2
|
+
AndroidFridaManager/__init__.py,sha256=T6AKtrGSLQ9M5bJoWDQcsRTJbSEbksdgrx3AAAdozRI,171
|
|
3
|
+
AndroidFridaManager/about.py,sha256=2umUwxNgyJgOkE9ed1nVsmszzNOrR4NDigLOIoYcYEE,98
|
|
4
|
+
AndroidFridaManager/job.py,sha256=1NNcfCjkyUtwUkMXSgT4uswA8UStHo3jxbeJwJoWhc8,3352
|
|
5
|
+
AndroidFridaManager/job_manager.py,sha256=E4lNe4E9mvLcWdYCn2z-Rh4_b9fA_Fzv3LOqWE_bsvQ,13264
|
|
6
|
+
androidfridamanager-1.8.8.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
7
|
+
androidfridamanager-1.8.8.dist-info/METADATA,sha256=l5nMXSymNGbEn-MdzZ_8YL7528fFMT6p_rIQ0aiQsbo,5141
|
|
8
|
+
androidfridamanager-1.8.8.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
+
androidfridamanager-1.8.8.dist-info/entry_points.txt,sha256=GmNngu2fDNCxUcquFRegBa7GWknPKG1jsM4lvWeyKnY,64
|
|
10
|
+
androidfridamanager-1.8.8.dist-info/top_level.txt,sha256=oH2lVMSRlghmt-_tVrOEUqvY462P9hd5Ktgp5-1qF3o,20
|
|
11
|
+
androidfridamanager-1.8.8.dist-info/RECORD,,
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
AndroidFridaManager/FridaManager.py,sha256=ObPXR4vyyWR6rbvUU4c47fKmBBl1H3JPhSIbWQDNWfw,16114
|
|
2
|
-
AndroidFridaManager/__init__.py,sha256=T6AKtrGSLQ9M5bJoWDQcsRTJbSEbksdgrx3AAAdozRI,171
|
|
3
|
-
AndroidFridaManager/about.py,sha256=9l-wC6pQl7DaMefzQMAlccC5Di5RnLe7VtmITEpG6T4,98
|
|
4
|
-
AndroidFridaManager/job.py,sha256=QTSNjdV7XqawSTV19HQt53aiwoT3UaQeQw2K4AWPxY8,3265
|
|
5
|
-
AndroidFridaManager/job_manager.py,sha256=icdNlfqorEM3XVw4h_83IcoupEFDlkzb29VhEZ6dxrQ,12294
|
|
6
|
-
androidfridamanager-1.8.6.dist-info/licenses/LICENSE,sha256=OXLcl0T2SZ8Pmy2_dmlvKuetivmyPd5m1q-Gyd-zaYY,35149
|
|
7
|
-
androidfridamanager-1.8.6.dist-info/METADATA,sha256=RRh7PdeZr2utjTUCBHBTBFawd5bcGELHBOLUaOXE5XI,5141
|
|
8
|
-
androidfridamanager-1.8.6.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
9
|
-
androidfridamanager-1.8.6.dist-info/entry_points.txt,sha256=GmNngu2fDNCxUcquFRegBa7GWknPKG1jsM4lvWeyKnY,64
|
|
10
|
-
androidfridamanager-1.8.6.dist-info/top_level.txt,sha256=oH2lVMSRlghmt-_tVrOEUqvY462P9hd5Ktgp5-1qF3o,20
|
|
11
|
-
androidfridamanager-1.8.6.dist-info/RECORD,,
|
|
File without changes
|
{androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{androidfridamanager-1.8.6.dist-info → androidfridamanager-1.8.8.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|