diff --git a/src/frida/ps.py b/src/frida/ps.py index ca28832..9c72aa9 100644 --- a/src/frida/ps.py +++ b/src/frida/ps.py @@ -2,25 +2,82 @@ def main(): from frida.application import ConsoleApplication class PSApplication(ConsoleApplication): + def _add_options(self, parser): + parser.add_option("-a", "--applications", help="list only applications", + action='store_true', dest="list_only_applications", default=False) + parser.add_option("-i", "--installed", help="include all installed applications", + action='store_true', dest="include_all_applications", default=False) + + def _initialize(self, parser, options, args): + if options.include_all_applications and not options.list_only_applications: + parser.error("-i cannot be used without -a") + self._list_only_applications = options.list_only_applications + self._include_all_applications = options.include_all_applications + def _usage(self): return "usage: %prog [options]" def _start(self): - try: - processes = self._device.enumerate_processes() - except Exception as e: - self._update_status("Failed to enumerate processes: %s" % e) - self._exit(1) - return - pid_column_width = max(map(lambda p: len("%d" % p.pid), processes)) - header_format = "%" + str(pid_column_width) + "s %s" - print(header_format % ("PID", "NAME")) - line_format = "%" + str(pid_column_width) + "d %s" - for process in sorted(processes, key=cmp_to_key(compare_devices)): - print(line_format % (process.pid, process.name)) + if self._list_only_applications: + try: + applications = self._device.enumerate_applications() + except Exception as e: + self._update_status("Failed to enumerate applications: %s" % e) + self._exit(1) + return + if not self._include_all_applications: + applications = filter(lambda app: app.pid != 0, applications) + if len(applications) > 0: + pid_column_width = max(map(lambda app: len("%d" % app.pid), applications)) + name_column_width = max(map(lambda app: len(app.name), applications)) + identifier_column_width = max(map(lambda app: len(app.identifier), applications)) + else: + pid_column_width = 0 + name_column_width = 0 + identifier_column_width = 0 + header_format = "%" + str(pid_column_width) + "s " + \ + "%-" + str(name_column_width) + "s " + \ + "%-" + str(identifier_column_width) + "s" + print(header_format % ("PID", "NAME", "IDENTIFIER")) + line_format = "%" + str(pid_column_width) + "s " + \ + "%-" + str(name_column_width) + "s " + \ + "%-" + str(identifier_column_width) + "s" + for app in sorted(applications, key=cmp_to_key(compare_applications)): + if app.pid == 0: + print(line_format % ("", app.name, app.identifier)) + else: + print(line_format % (app.pid, app.name, app.identifier)) + else: + try: + processes = self._device.enumerate_processes() + except Exception as e: + self._update_status("Failed to enumerate processes: %s" % e) + self._exit(1) + return + pid_column_width = max(map(lambda p: len("%d" % p.pid), processes)) + header_format = "%" + str(pid_column_width) + "s %s" + print(header_format % ("PID", "NAME")) + line_format = "%" + str(pid_column_width) + "d %s" + for process in sorted(processes, key=cmp_to_key(compare_processes)): + print(line_format % (process.pid, process.name)) self._exit(0) - def compare_devices(a, b): + def compare_applications(a, b): + a_is_running = a.pid != 0 + b_is_running = b.pid != 0 + if a_is_running == b_is_running: + if a.name > b.name: + return 1 + elif a.name < b.name: + return -1 + else: + return 0 + elif a_is_running: + return -1 + else: + return 1 + + def compare_processes(a, b): a_has_icon = a.get_small_icon() is not None b_has_icon = b.get_small_icon() is not None if a_has_icon == b_has_icon: