AndroidFridaManager 1.0__tar.gz → 1.6__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.
Files changed (22) hide show
  1. androidfridamanager-1.6/AndroidFridaManager/__init__.py +4 -0
  2. androidfridamanager-1.6/AndroidFridaManager/job.py +87 -0
  3. androidfridamanager-1.6/AndroidFridaManager/job_manager.py +266 -0
  4. androidfridamanager-1.6/AndroidFridaManager.egg-info/PKG-INFO +111 -0
  5. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/AndroidFridaManager.egg-info/SOURCES.txt +5 -1
  6. androidfridamanager-1.6/AndroidFridaManager.egg-info/entry_points.txt +2 -0
  7. androidfridamanager-1.6/MANIFEST.in +1 -0
  8. androidfridamanager-1.6/PKG-INFO +111 -0
  9. androidfridamanager-1.6/README.md +89 -0
  10. androidfridamanager-1.6/requirements.txt +3 -0
  11. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/setup.py +1 -1
  12. AndroidFridaManager-1.0/AndroidFridaManager/__init__.py +0 -6
  13. AndroidFridaManager-1.0/AndroidFridaManager.egg-info/PKG-INFO +0 -69
  14. AndroidFridaManager-1.0/AndroidFridaManager.egg-info/entry_points.txt +0 -2
  15. AndroidFridaManager-1.0/PKG-INFO +0 -69
  16. AndroidFridaManager-1.0/README.md +0 -49
  17. /AndroidFridaManager-1.0/AndroidFridaManager/AndroidFridaManager.py → /androidfridamanager-1.6/AndroidFridaManager/FridaManager.py +0 -0
  18. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/AndroidFridaManager.egg-info/dependency_links.txt +0 -0
  19. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/AndroidFridaManager.egg-info/requires.txt +0 -0
  20. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/AndroidFridaManager.egg-info/top_level.txt +0 -0
  21. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/LICENSE +0 -0
  22. {AndroidFridaManager-1.0 → androidfridamanager-1.6}/setup.cfg +0 -0
@@ -0,0 +1,4 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ __version__ = "1.6"
@@ -0,0 +1,87 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+
5
+ import threading
6
+ import frida
7
+ import uuid
8
+
9
+ # Define a custom exception for handling frida based exceptions
10
+ class FridaBasedException(Exception):
11
+ pass
12
+
13
+ class Job:
14
+ def __init__(self, frida_script_name, custom_hooking_handler, process):
15
+ self.frida_script_name = frida_script_name
16
+ self.job_id = str(uuid.uuid4())
17
+ self.state = "initialized"
18
+ self.custom_hooking_handler = custom_hooking_handler
19
+ self.script = None
20
+ self.stop_event = threading.Event()
21
+ self.process_session = process
22
+ self.thread = None
23
+
24
+
25
+ def run_job(self):
26
+ #self.is_running_as_thread = True
27
+ self.run_job_as_thread()
28
+
29
+
30
+ def run_job_as_thread(self):
31
+ self.thread = threading.Thread(target=self.invoke_handle_hooking)
32
+ self.thread.start()
33
+
34
+
35
+ def invoke_handle_hooking(self):
36
+ self.instrument(self.process_session)
37
+ self.script.on("message", self.wrap_custom_hooking_handler_with_job_id(self.custom_hooking_handler))
38
+ self.script.load()
39
+ self.state = "running"
40
+ print("[+] hooks succesfully loaded")
41
+
42
+ #if self.is_running_as_thread:
43
+ # Keep the thread alive to handle messages until stop_event is set
44
+ while not self.stop_event.is_set():
45
+ self.stop_event.wait(1) # Sleep for 1 second and check again
46
+
47
+
48
+ def wrap_custom_hooking_handler_with_job_id(self, handler):
49
+
50
+ def wrapped_handler(message, data):
51
+ # Add job_id to the message
52
+ message['job_id'] = self.job_id
53
+ handler(message, data)
54
+
55
+ return wrapped_handler
56
+
57
+
58
+ def instrument(self, process_session,runtime="qjs"):
59
+ try:
60
+ with open(self.frida_script_name, encoding='utf8', newline='\n') as f:
61
+ script_string = f.read()
62
+ self.script = process_session.create_script(script_string, runtime=runtime)
63
+ return self.script
64
+
65
+ except frida.ProcessNotFoundError:
66
+ raise FridaBasedException("Unable to find target process")
67
+ except frida.InvalidOperationError:
68
+ raise FridaBasedException("Invalid operation! Please run in debug mode in order to understand the source of this error and report it.")
69
+ except frida.TransportError:
70
+ raise FridaBasedException("Timeout error due to some internal frida error's. Try to restart frida-server again.")
71
+ except frida.ProtocolError:
72
+ raise FridaBasedException("Connection is closed. Probably the target app crashed")
73
+
74
+
75
+ def close_job(self):
76
+ self.state = "stopping"
77
+ self.stop_event.set()
78
+ if self.thread:
79
+ self.thread.join()
80
+ if self.script:
81
+ self.script.unload()
82
+
83
+ print(f"Job {self.job_id} stopped")
84
+
85
+
86
+ def get_id(self):
87
+ return self.job_id
@@ -0,0 +1,266 @@
1
+ #!/usr/bin/env python3
2
+ # -*- coding: utf-8 -*-
3
+
4
+ import atexit
5
+ import subprocess
6
+ import frida
7
+ from typing import Optional, Dict, Union
8
+ from job import Job, FridaBasedException
9
+ import time
10
+ import re
11
+
12
+ class JobManager(object):
13
+ """ A class representing the current Job manager. """
14
+
15
+
16
+ def __init__(self,host="", enable_spawn_gating=False) -> None:
17
+ """
18
+ Init a new job manager. This method will also
19
+ register an atexit(), ensuring that cleanup operations
20
+ are performed on jobs when this class is GC'd.
21
+ """
22
+
23
+ self.jobs = {}
24
+ self.is_first_job = True
25
+ self.process_session = None
26
+ self.host = host
27
+ self.pid = -1
28
+ self.device = None
29
+ self.package_name = ""
30
+ self.enable_spawn_gating = enable_spawn_gating
31
+ self.first_instrumenation_script = None
32
+ atexit.register(self.cleanup)
33
+
34
+
35
+ def cleanup(self) -> None:
36
+ """
37
+ Clean up all of the job in the job manager.
38
+
39
+ This method is typical called when at the end of an
40
+ session.
41
+
42
+ :return:
43
+ """
44
+ if len(self.jobs) > 0:
45
+ print("[*] Program closed. Stopping active jobs...")
46
+ self.stop_jobs()
47
+
48
+ print("\n[*] Have a nice day!")
49
+
50
+
51
+ def job_list(self):
52
+ return list(self.jobs.keys())
53
+
54
+
55
+ def running_jobs(self):
56
+ return [job_id for job_id, job in self.jobs.items() if job.state == "running"]
57
+
58
+ '''
59
+ # only used for debugging
60
+ def running_jobs2(self):
61
+ tuple_jobs = [job for job in self.jobs.items()]
62
+ for job_id, job in tuple_jobs:
63
+ print(f"Job state of Job {job_id} in state {job.state}")
64
+ return tuple_jobs
65
+ '''
66
+
67
+ def spawn(self, target_process):
68
+ self.package_name = target_process
69
+ print("[*] spawning app: "+ target_process)
70
+ pid = self.device.spawn(target_process)
71
+ self.process_session = self.device.attach(pid)
72
+ print(f"Spawned {target_process} with PID {pid}")
73
+ return pid
74
+
75
+
76
+ def start_android_app(self, package_name: str, main_activity: Optional[str] = None, extras: Optional[Dict[str, Union[str, bool]]] = None):
77
+ """
78
+ Start an Android app using adb.
79
+
80
+ :param package_name: The package name of the app.
81
+ :param main_activity: The main activity of the app (optional).
82
+ :param extras: A dictionary of extras to pass to the intent (optional).
83
+ """
84
+ if main_activity:
85
+ self.package_name = package_name
86
+ # Prepare the base command for starting the app with main activity
87
+ cmd = ['adb', 'shell', 'am', 'start', '-n', f'{package_name}/{main_activity}']
88
+
89
+ # Add extras if provided
90
+ if extras:
91
+ for key, value in extras.items():
92
+ if isinstance(value, bool):
93
+ cmd.extend(['--ez', key, 'true' if value else 'false'])
94
+ elif isinstance(value, str):
95
+ cmd.extend(['--es', key, value])
96
+ else:
97
+ # Command to start the app using monkey if no main activity is provided
98
+ cmd = ['adb', 'shell', 'monkey', '-p', package_name, '-c', 'android.intent.category.LAUNCHER', '1']
99
+
100
+ # Run the command and capture the output
101
+ result = subprocess.run(cmd, capture_output=True, text=True, check=True)
102
+
103
+ # Extract the PID from the output
104
+ pid = None
105
+ if 'ThisTime' in result.stdout:
106
+ # `am start` command includes the PID in the output
107
+ pid_match = re.search(r'(?<=ThisTime: \d+\s)Proc=\w+,\s(\d+)', result.stdout)
108
+ if pid_match:
109
+ pid = int(pid_match.group(1))
110
+ elif 'Events injected' in result.stdout:
111
+ # `monkey` command does not provide PID directly, need to get it separately
112
+ pid_cmd = ['adb', 'shell', 'pidof', package_name]
113
+ pid_result = subprocess.run(pid_cmd, capture_output=True, text=True, check=True)
114
+ if pid_result.stdout:
115
+ pid = int(pid_result.stdout.split()[0])
116
+
117
+ if pid is None:
118
+ raise RuntimeError("Failed to get PID of the started app")
119
+
120
+ return pid
121
+
122
+
123
+ def attach_app(self, target_process, foreground=False):
124
+ self.package_name = target_process
125
+
126
+ if foreground:
127
+ target_process = self.device.get_frontmost_application()
128
+ if target_process is None or len(target_process.identifier) < 2:
129
+ print("[-] unable to attach to the frontmost application. Aborting ...")
130
+
131
+ target_process = target_process.identifier
132
+
133
+ if isinstance(target_process, int):
134
+ print(f"[*] attaching to PID: {target_process}")
135
+ self.process_session = self.device.attach(target_process)
136
+ else:
137
+ print(f"[*] attaching to app: {target_process}")
138
+ self.process_session = self.device.attach(int(target_process) if target_process.isnumeric() else target_process)
139
+
140
+
141
+
142
+
143
+ def setup_frida_session(self, target_process, custom_hooking_handler_name, should_spawn=True,foreground=False):
144
+ self.first_instrumenation_script = custom_hooking_handler_name
145
+ self.device = self.setup_frida_handler(self.host, self.enable_spawn_gating)
146
+
147
+ try:
148
+ if should_spawn:
149
+ self.pid = self.spawn(target_process)
150
+ else:
151
+ self.attach_app(target_process,foreground)
152
+ except frida.TimedOutError as te:
153
+ raise FridaBasedException(f"TimeOutError: {te}")
154
+ except frida.ProcessNotFoundError as pe:
155
+ raise FridaBasedException(f"ProcessNotFoundError: {pe}")
156
+
157
+
158
+ def start_job(self,frida_script_name, custom_hooking_handler_name):
159
+ try:
160
+
161
+ if self.process_session:
162
+ job = Job(frida_script_name, custom_hooking_handler_name, self.process_session)
163
+ print(f"[*] created job: {job.job_id}")
164
+ self.jobs[job.job_id] = job
165
+ job.run_job()
166
+ if self.is_first_job:
167
+ self.is_first_job = False
168
+ self.first_instrumenation_script = custom_hooking_handler_name
169
+ if self.pid != -1:
170
+ self.device.resume(self.pid)
171
+ time.sleep(1) # without it Java.perform silently fails
172
+
173
+ else:
174
+ print("[-] no frida session. Aborting...")
175
+
176
+ except frida.TransportError as fe:
177
+ raise FridaBasedException(f"Problems while attaching to frida-server: {fe}")
178
+ except FridaBasedException as e:
179
+ raise FridaBasedException(f"Frida based error: {e}")
180
+ except frida.TimedOutError as te:
181
+ raise FridaBasedException(f"TimeOutError: {te}")
182
+ except frida.ProcessNotFoundError as pe:
183
+ raise FridaBasedException(f"ProcessNotFoundError: {pe}")
184
+ except KeyboardInterrupt:
185
+ self.stop_app_with_last_job(job,self.package_name)
186
+ pass
187
+
188
+
189
+ def stop_jobs(self):
190
+ jobs_to_stop = [job_id for job_id, job in self.jobs.items() if job.state == "running"]
191
+ for job_id in jobs_to_stop:
192
+ try:
193
+ print('[job manager] Job: {0} - Stopping'.format(job_id))
194
+ self.stop_job_with_id(job_id)
195
+ except frida.InvalidOperationError:
196
+ print('[job manager] Job: {0} - An error occurred stopping job. Device may '
197
+ 'no longer be available.'.format(job_id))
198
+
199
+
200
+ def stop_job_with_id(self,job_id):
201
+ if job_id in self.jobs:
202
+ job = self.jobs[job_id]
203
+ job.close_job()
204
+ del self.jobs[job_id]
205
+
206
+
207
+ def detach_from_app(self):
208
+ if self.process_session:
209
+ self.process_session.detach()
210
+
211
+
212
+ def stop_app(self, app_package):
213
+ subprocess.run(["adb", "shell", "am", "force-stop", app_package])
214
+
215
+
216
+ def stop_app_with_last_job(self, last_job, app_package):
217
+ last_job.close_job()
218
+ self.stop_app(app_package)
219
+
220
+
221
+
222
+ def stop_app_with_closing_frida(self, app_package):
223
+ jobs_to_stop = [job_id for job_id, job in self.jobs.items() if job.state == "running"]
224
+ for job_id in jobs_to_stop:
225
+ print(f"[*] trying to close job: {job_id}")
226
+ self.stop_job_with_id(job_id)
227
+
228
+ self.detach_from_app()
229
+ subprocess.run(["adb", "shell", "am", "force-stop", app_package])
230
+
231
+
232
+ def kill_app(self, pid):
233
+ subprocess.run(["adb", "shell", "kill", str(pid)])
234
+
235
+
236
+ def setup_frida_handler(self,host="", enable_spawn_gating=False):
237
+ try:
238
+ if len(host) > 4:
239
+ # we can also use the IP address ot the target machine instead of using USB - e.g. when we have multpile AVDs
240
+ device = frida.get_device_manager().add_remote_device(host)
241
+ else:
242
+ device = frida.get_usb_device()
243
+
244
+ # to handle forks
245
+ def on_child_added(child):
246
+ print(f"Attached to child process with pid {child.pid}")
247
+ self.first_instrumenation_script(device.attach(child.pid))
248
+ device.resume(child.pid)
249
+
250
+ # if the target process is starting another process
251
+ def on_spawn_added(spawn):
252
+ print(f"Process spawned with pid {spawn.pid}. Name: {spawn.identifier}")
253
+ self.first_instrumenation_script(device.attach(spawn.pid))
254
+ device.resume(spawn.pid)
255
+
256
+ device.on("child_added", on_child_added)
257
+ if enable_spawn_gating:
258
+ device.enable_spawn_gating()
259
+ device.on("spawn_added", on_spawn_added)
260
+
261
+ return device
262
+
263
+ except frida.InvalidArgumentError:
264
+ raise FridaBasedException("Unable to find device")
265
+ except frida.ServerNotRunningError:
266
+ raise FridaBasedException("Frida server not running. Start frida-server and try it again.")
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.1
2
+ Name: AndroidFridaManager
3
+ Version: 1.6
4
+ Summary: A python API in order to install and run the frida-server on an Android device.
5
+ Home-page: https://github.com/fkie-cad/AndroidFridaManager
6
+ Author: Daniel Baier
7
+ Author-email: daniel.baier@fkie.fraunhofer.de
8
+ License: GPL v3
9
+ Keywords: mobile,instrumentation,frida,hook,android
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: JavaScript
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: Software Development :: Debuggers
17
+ Requires-Python: >=3.6
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: frida>=15.0.0
21
+ Requires-Dist: colorlog
22
+
23
+ # AndroidFridaManager
24
+
25
+ AndroidFridaManager is a Python API designed to simplify the installation and management of Frida on Android devices. It provides an easy-to-use interface for installing and running the latest Frida server, as well as the flexibility to install specific versions as needed.
26
+
27
+ Key Features
28
+
29
+ Frida Server Management: Seamlessly install and run the latest Frida server on your Android device, or choose to install a specific version as required.
30
+ Job Management: Execute Frida scripts as independent jobs, managed by the `JobManager()`. This feature allows for concurrent execution of multiple Frida scripts, with each job running in its own thread.
31
+ `afrim` Tool Integration: Utilize the `afrim` tool to check for existing Frida server installations on your device and ensure you are always running the latest version.
32
+
33
+
34
+ The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
35
+
36
+ ## Install
37
+
38
+ Just install it via pip:
39
+ ```bash
40
+ pip install AndroidFridaManager
41
+ ```
42
+
43
+ This will install the `afrim`-command to your system.
44
+
45
+ ## Usage
46
+
47
+ In order to easily install the latest frida-server version to your Android device just run the following command:
48
+
49
+ ```bash
50
+ $ afrim
51
+ ```
52
+
53
+
54
+ In order to check only if frida-server is running invoke it with the `-r`-parameter:
55
+
56
+ ```bash
57
+ $ afrim -r
58
+ ```
59
+
60
+
61
+ ## API Usage
62
+
63
+ In order to install and run Frida on your Android device use the `FridaManager`-API:
64
+ ```python
65
+ from AndroidFridaManager import FridaManager
66
+ ...
67
+ afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
68
+ afm_obj.install_frida_server()
69
+ afm_obj.run_frida_server()
70
+ ```
71
+
72
+ For running Frida scripts as jobs use the `JobManager`-API:
73
+ ```python
74
+ from AndroidFridaManager import JobManager
75
+ ...
76
+ app_package = "net.classwindexampleyear.bookseapiececountry"
77
+ frida_script_path = "./frida_script1.js"
78
+ job_manager = JobManager()
79
+ job_manager.setup_frida_session(app_package, myAwesomeHookingHandler)
80
+ job_manager.start_job(frida_script_path, myAwesomeHookingHandler)
81
+ print("Running jobs:", job_manager.running_jobs())
82
+ job_manager.stop_app_with_closing_frida(app_package)
83
+ ```
84
+
85
+ The `setup_frida_session()` function accepts a callback function as its second parameter, typically provided by `script.on('message', on_message)`. This initializes the first job and, by default, is the only job where you can activate [child_gating and spawn_gating](https://frida.re/news/#child-gating). To execute the job, you must invoke the `start_job()` function.
86
+
87
+ ## API
88
+
89
+ ```python
90
+ install_frida_server(dst_dir="/data/local/tmp/", version="latest")
91
+ run_frida_server()
92
+ is_frida_server_running()
93
+ stop_frida_server()
94
+ remove_frida_server()
95
+
96
+ # JobManager
97
+ JobManager(host="", enable_spawn_gating=False)
98
+ running_jobs() # list running jobs
99
+ start_android_app(package_name, main_activity = None, extras = None) # returns the PID of the start app
100
+ setup_frida_session(target_process, frida_callback_function, should_spawn=True,foreground=False)
101
+ start_job(frida_script_name, frida_callback_function)
102
+ stop_jobs() # stops all running jobs
103
+ stop_job_with_id(job_id) # stop only job with job_id
104
+ detach_from_app() # will also be invoked when running stop_app_with_closing_frida()
105
+ stop_app_with_closing_frida(app_package)
106
+ stop_app(app_package)
107
+ kill_app(pid)
108
+ setup_frida_handler(host="", enable_spawn_gating=False) # returns the device object and is used by setup_frida_session()
109
+
110
+ # setup_frida_handler,setup_frida_session will raise the FridaBasedException(Exception). Ensure to handle it
111
+ ```
@@ -1,8 +1,12 @@
1
1
  LICENSE
2
+ MANIFEST.in
2
3
  README.md
4
+ requirements.txt
3
5
  setup.py
4
- AndroidFridaManager/AndroidFridaManager.py
6
+ AndroidFridaManager/FridaManager.py
5
7
  AndroidFridaManager/__init__.py
8
+ AndroidFridaManager/job.py
9
+ AndroidFridaManager/job_manager.py
6
10
  AndroidFridaManager.egg-info/PKG-INFO
7
11
  AndroidFridaManager.egg-info/SOURCES.txt
8
12
  AndroidFridaManager.egg-info/dependency_links.txt
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ afrim = AndroidFridaManager.FridaManager:main
@@ -0,0 +1 @@
1
+ include requirements.txt
@@ -0,0 +1,111 @@
1
+ Metadata-Version: 2.1
2
+ Name: AndroidFridaManager
3
+ Version: 1.6
4
+ Summary: A python API in order to install and run the frida-server on an Android device.
5
+ Home-page: https://github.com/fkie-cad/AndroidFridaManager
6
+ Author: Daniel Baier
7
+ Author-email: daniel.baier@fkie.fraunhofer.de
8
+ License: GPL v3
9
+ Keywords: mobile,instrumentation,frida,hook,android
10
+ Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Natural Language :: English
13
+ Classifier: Programming Language :: Python :: 3 :: Only
14
+ Classifier: Programming Language :: JavaScript
15
+ Classifier: Topic :: Security
16
+ Classifier: Topic :: Software Development :: Debuggers
17
+ Requires-Python: >=3.6
18
+ Description-Content-Type: text/markdown
19
+ License-File: LICENSE
20
+ Requires-Dist: frida>=15.0.0
21
+ Requires-Dist: colorlog
22
+
23
+ # AndroidFridaManager
24
+
25
+ AndroidFridaManager is a Python API designed to simplify the installation and management of Frida on Android devices. It provides an easy-to-use interface for installing and running the latest Frida server, as well as the flexibility to install specific versions as needed.
26
+
27
+ Key Features
28
+
29
+ Frida Server Management: Seamlessly install and run the latest Frida server on your Android device, or choose to install a specific version as required.
30
+ Job Management: Execute Frida scripts as independent jobs, managed by the `JobManager()`. This feature allows for concurrent execution of multiple Frida scripts, with each job running in its own thread.
31
+ `afrim` Tool Integration: Utilize the `afrim` tool to check for existing Frida server installations on your device and ensure you are always running the latest version.
32
+
33
+
34
+ The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
35
+
36
+ ## Install
37
+
38
+ Just install it via pip:
39
+ ```bash
40
+ pip install AndroidFridaManager
41
+ ```
42
+
43
+ This will install the `afrim`-command to your system.
44
+
45
+ ## Usage
46
+
47
+ In order to easily install the latest frida-server version to your Android device just run the following command:
48
+
49
+ ```bash
50
+ $ afrim
51
+ ```
52
+
53
+
54
+ In order to check only if frida-server is running invoke it with the `-r`-parameter:
55
+
56
+ ```bash
57
+ $ afrim -r
58
+ ```
59
+
60
+
61
+ ## API Usage
62
+
63
+ In order to install and run Frida on your Android device use the `FridaManager`-API:
64
+ ```python
65
+ from AndroidFridaManager import FridaManager
66
+ ...
67
+ afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
68
+ afm_obj.install_frida_server()
69
+ afm_obj.run_frida_server()
70
+ ```
71
+
72
+ For running Frida scripts as jobs use the `JobManager`-API:
73
+ ```python
74
+ from AndroidFridaManager import JobManager
75
+ ...
76
+ app_package = "net.classwindexampleyear.bookseapiececountry"
77
+ frida_script_path = "./frida_script1.js"
78
+ job_manager = JobManager()
79
+ job_manager.setup_frida_session(app_package, myAwesomeHookingHandler)
80
+ job_manager.start_job(frida_script_path, myAwesomeHookingHandler)
81
+ print("Running jobs:", job_manager.running_jobs())
82
+ job_manager.stop_app_with_closing_frida(app_package)
83
+ ```
84
+
85
+ The `setup_frida_session()` function accepts a callback function as its second parameter, typically provided by `script.on('message', on_message)`. This initializes the first job and, by default, is the only job where you can activate [child_gating and spawn_gating](https://frida.re/news/#child-gating). To execute the job, you must invoke the `start_job()` function.
86
+
87
+ ## API
88
+
89
+ ```python
90
+ install_frida_server(dst_dir="/data/local/tmp/", version="latest")
91
+ run_frida_server()
92
+ is_frida_server_running()
93
+ stop_frida_server()
94
+ remove_frida_server()
95
+
96
+ # JobManager
97
+ JobManager(host="", enable_spawn_gating=False)
98
+ running_jobs() # list running jobs
99
+ start_android_app(package_name, main_activity = None, extras = None) # returns the PID of the start app
100
+ setup_frida_session(target_process, frida_callback_function, should_spawn=True,foreground=False)
101
+ start_job(frida_script_name, frida_callback_function)
102
+ stop_jobs() # stops all running jobs
103
+ stop_job_with_id(job_id) # stop only job with job_id
104
+ detach_from_app() # will also be invoked when running stop_app_with_closing_frida()
105
+ stop_app_with_closing_frida(app_package)
106
+ stop_app(app_package)
107
+ kill_app(pid)
108
+ setup_frida_handler(host="", enable_spawn_gating=False) # returns the device object and is used by setup_frida_session()
109
+
110
+ # setup_frida_handler,setup_frida_session will raise the FridaBasedException(Exception). Ensure to handle it
111
+ ```
@@ -0,0 +1,89 @@
1
+ # AndroidFridaManager
2
+
3
+ AndroidFridaManager is a Python API designed to simplify the installation and management of Frida on Android devices. It provides an easy-to-use interface for installing and running the latest Frida server, as well as the flexibility to install specific versions as needed.
4
+
5
+ Key Features
6
+
7
+ Frida Server Management: Seamlessly install and run the latest Frida server on your Android device, or choose to install a specific version as required.
8
+ Job Management: Execute Frida scripts as independent jobs, managed by the `JobManager()`. This feature allows for concurrent execution of multiple Frida scripts, with each job running in its own thread.
9
+ `afrim` Tool Integration: Utilize the `afrim` tool to check for existing Frida server installations on your device and ensure you are always running the latest version.
10
+
11
+
12
+ The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
13
+
14
+ ## Install
15
+
16
+ Just install it via pip:
17
+ ```bash
18
+ pip install AndroidFridaManager
19
+ ```
20
+
21
+ This will install the `afrim`-command to your system.
22
+
23
+ ## Usage
24
+
25
+ In order to easily install the latest frida-server version to your Android device just run the following command:
26
+
27
+ ```bash
28
+ $ afrim
29
+ ```
30
+
31
+
32
+ In order to check only if frida-server is running invoke it with the `-r`-parameter:
33
+
34
+ ```bash
35
+ $ afrim -r
36
+ ```
37
+
38
+
39
+ ## API Usage
40
+
41
+ In order to install and run Frida on your Android device use the `FridaManager`-API:
42
+ ```python
43
+ from AndroidFridaManager import FridaManager
44
+ ...
45
+ afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
46
+ afm_obj.install_frida_server()
47
+ afm_obj.run_frida_server()
48
+ ```
49
+
50
+ For running Frida scripts as jobs use the `JobManager`-API:
51
+ ```python
52
+ from AndroidFridaManager import JobManager
53
+ ...
54
+ app_package = "net.classwindexampleyear.bookseapiececountry"
55
+ frida_script_path = "./frida_script1.js"
56
+ job_manager = JobManager()
57
+ job_manager.setup_frida_session(app_package, myAwesomeHookingHandler)
58
+ job_manager.start_job(frida_script_path, myAwesomeHookingHandler)
59
+ print("Running jobs:", job_manager.running_jobs())
60
+ job_manager.stop_app_with_closing_frida(app_package)
61
+ ```
62
+
63
+ The `setup_frida_session()` function accepts a callback function as its second parameter, typically provided by `script.on('message', on_message)`. This initializes the first job and, by default, is the only job where you can activate [child_gating and spawn_gating](https://frida.re/news/#child-gating). To execute the job, you must invoke the `start_job()` function.
64
+
65
+ ## API
66
+
67
+ ```python
68
+ install_frida_server(dst_dir="/data/local/tmp/", version="latest")
69
+ run_frida_server()
70
+ is_frida_server_running()
71
+ stop_frida_server()
72
+ remove_frida_server()
73
+
74
+ # JobManager
75
+ JobManager(host="", enable_spawn_gating=False)
76
+ running_jobs() # list running jobs
77
+ start_android_app(package_name, main_activity = None, extras = None) # returns the PID of the start app
78
+ setup_frida_session(target_process, frida_callback_function, should_spawn=True,foreground=False)
79
+ start_job(frida_script_name, frida_callback_function)
80
+ stop_jobs() # stops all running jobs
81
+ stop_job_with_id(job_id) # stop only job with job_id
82
+ detach_from_app() # will also be invoked when running stop_app_with_closing_frida()
83
+ stop_app_with_closing_frida(app_package)
84
+ stop_app(app_package)
85
+ kill_app(pid)
86
+ setup_frida_handler(host="", enable_spawn_gating=False) # returns the device object and is used by setup_frida_session()
87
+
88
+ # setup_frida_handler,setup_frida_session will raise the FridaBasedException(Exception). Ensure to handle it
89
+ ```
@@ -0,0 +1,3 @@
1
+ frida>=15.0.0
2
+ colorlog
3
+
@@ -72,7 +72,7 @@ setup(
72
72
 
73
73
  entry_points={
74
74
  'console_scripts': [
75
- 'afrim=AndroidFridaManager.AndroidFridaManager:main',
75
+ 'afrim=AndroidFridaManager.FridaManager:main',
76
76
  ],
77
77
  },
78
78
  )
@@ -1,6 +0,0 @@
1
- #!/usr/bin/env python3
2
- # -*- coding: utf-8 -*-
3
-
4
- from AndroidFridaManager.AndroidFridaManager import FridaManager
5
-
6
- __version__ = "1.0"
@@ -1,69 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: AndroidFridaManager
3
- Version: 1.0
4
- Summary: A python API in order to install and run the frida-server on an Android device.
5
- Home-page: https://github.com/fkie-cad/AndroidFridaManager
6
- Author: Daniel Baier
7
- Author-email: daniel.baier@fkie.fraunhofer.de
8
- License: GPL v3
9
- Keywords: mobile,instrumentation,frida,hook,android
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Natural Language :: English
13
- Classifier: Programming Language :: Python :: 3 :: Only
14
- Classifier: Programming Language :: JavaScript
15
- Classifier: Topic :: Security
16
- Classifier: Topic :: Software Development :: Debuggers
17
- Requires-Python: >=3.6
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
-
21
- # AndroidFridaManager
22
-
23
- A python API in order to install and run the frida-server on an Android device. The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
24
-
25
- ## Install
26
-
27
- Just install it via pip:
28
- ```bash
29
- pip install AndroidFridaManager
30
- ```
31
-
32
- This will install the `afrim`-command to your system.
33
-
34
- ## Usage
35
-
36
- In order to easily install the latest frida-server version to your Android device just run the following command:
37
-
38
- ```bash
39
- $ afrim
40
- ```
41
-
42
-
43
- In order to check only if frida-server is running invoke it with the `-r`-parameter:
44
-
45
- ```bash
46
- $ afrim -r
47
- ```
48
-
49
-
50
- ## API Usage
51
-
52
- ```python
53
- from AndroidFridaManager import FridaManager
54
- ...
55
- afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
56
- afm_obj.install_frida_server()
57
- afm_obj.run_frida_server()
58
- ```
59
-
60
-
61
- ## API
62
-
63
- ```python
64
- install_frida_server(dst_dir="/data/local/tmp/", version="latest")
65
- run_frida_server()
66
- is_frida_server_running()
67
- stop_frida_server()
68
- remove_frida_server()
69
- ```
@@ -1,2 +0,0 @@
1
- [console_scripts]
2
- afrim = AndroidFridaManager.AndroidFridaManager:main
@@ -1,69 +0,0 @@
1
- Metadata-Version: 2.1
2
- Name: AndroidFridaManager
3
- Version: 1.0
4
- Summary: A python API in order to install and run the frida-server on an Android device.
5
- Home-page: https://github.com/fkie-cad/AndroidFridaManager
6
- Author: Daniel Baier
7
- Author-email: daniel.baier@fkie.fraunhofer.de
8
- License: GPL v3
9
- Keywords: mobile,instrumentation,frida,hook,android
10
- Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
11
- Classifier: Operating System :: OS Independent
12
- Classifier: Natural Language :: English
13
- Classifier: Programming Language :: Python :: 3 :: Only
14
- Classifier: Programming Language :: JavaScript
15
- Classifier: Topic :: Security
16
- Classifier: Topic :: Software Development :: Debuggers
17
- Requires-Python: >=3.6
18
- Description-Content-Type: text/markdown
19
- License-File: LICENSE
20
-
21
- # AndroidFridaManager
22
-
23
- A python API in order to install and run the frida-server on an Android device. The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
24
-
25
- ## Install
26
-
27
- Just install it via pip:
28
- ```bash
29
- pip install AndroidFridaManager
30
- ```
31
-
32
- This will install the `afrim`-command to your system.
33
-
34
- ## Usage
35
-
36
- In order to easily install the latest frida-server version to your Android device just run the following command:
37
-
38
- ```bash
39
- $ afrim
40
- ```
41
-
42
-
43
- In order to check only if frida-server is running invoke it with the `-r`-parameter:
44
-
45
- ```bash
46
- $ afrim -r
47
- ```
48
-
49
-
50
- ## API Usage
51
-
52
- ```python
53
- from AndroidFridaManager import FridaManager
54
- ...
55
- afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
56
- afm_obj.install_frida_server()
57
- afm_obj.run_frida_server()
58
- ```
59
-
60
-
61
- ## API
62
-
63
- ```python
64
- install_frida_server(dst_dir="/data/local/tmp/", version="latest")
65
- run_frida_server()
66
- is_frida_server_running()
67
- stop_frida_server()
68
- remove_frida_server()
69
- ```
@@ -1,49 +0,0 @@
1
- # AndroidFridaManager
2
-
3
- A python API in order to install and run the frida-server on an Android device. The project was inspired by [Frida-Python-Binding](https://github.com/Mind0xP/Frida-Python-Binding/tree/master).
4
-
5
- ## Install
6
-
7
- Just install it via pip:
8
- ```bash
9
- pip install AndroidFridaManager
10
- ```
11
-
12
- This will install the `afrim`-command to your system.
13
-
14
- ## Usage
15
-
16
- In order to easily install the latest frida-server version to your Android device just run the following command:
17
-
18
- ```bash
19
- $ afrim
20
- ```
21
-
22
-
23
- In order to check only if frida-server is running invoke it with the `-r`-parameter:
24
-
25
- ```bash
26
- $ afrim -r
27
- ```
28
-
29
-
30
- ## API Usage
31
-
32
- ```python
33
- from AndroidFridaManager import FridaManager
34
- ...
35
- afm_obj = FridaManager(is_remote=False, socket="ip:port", verbose=False, frida_install_dst="/data/local/tmp/")
36
- afm_obj.install_frida_server()
37
- afm_obj.run_frida_server()
38
- ```
39
-
40
-
41
- ## API
42
-
43
- ```python
44
- install_frida_server(dst_dir="/data/local/tmp/", version="latest")
45
- run_frida_server()
46
- is_frida_server_running()
47
- stop_frida_server()
48
- remove_frida_server()
49
- ```