diff --git a/frida-python-common.props b/frida-python-common.props
index 62db9f4..6d2fb4f 100644
--- a/frida-python-common.props
+++ b/frida-python-common.props
@@ -17,28 +17,29 @@ mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)src\frida\*.py" $(OutDir)frida || exit 1
echo. > $(IntDir)frida-package.stamp
$(IntDir)frida-package.stamp
- $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
+ $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\lsd.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
rmdir /S /Q $(OutDir)frida 2>NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)src\frida\*.py" $(OutDir)frida || exit 1
echo. > $(IntDir)frida-package.stamp
$(IntDir)frida-package.stamp
- $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
+ $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\lsd.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
rmdir /S /Q $(OutDir)frida 2>NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)src\frida\*.py" $(OutDir)frida || exit 1
echo. > $(IntDir)frida-package.stamp
$(IntDir)frida-package.stamp
- $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
+ $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\lsd.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
rmdir /S /Q $(OutDir)frida 2>NUL
mkdir $(OutDir)frida || exit 1
copy /B /Y "$(ProjectDir)src\frida\*.py" $(OutDir)frida || exit 1
echo. > $(IntDir)frida-package.stamp
$(IntDir)frida-package.stamp
- $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
+ $(ProjectDir)src\frida\core.py;$(ProjectDir)src\frida\application.py;$(ProjectDir)src\frida\lsd.py;$(ProjectDir)src\frida\ps.py;$(ProjectDir)src\frida\discoverer.py;$(ProjectDir)src\frida\tracer.py;$(ProjectDir)src\frida\repl.py
+
diff --git a/frida-python27.vcxproj.filters b/frida-python27.vcxproj.filters
index ff75ecb..250ef41 100644
--- a/frida-python27.vcxproj.filters
+++ b/frida-python27.vcxproj.filters
@@ -29,6 +29,9 @@
Source Files\frida
+
+ Source Files\frida
+
Source Files\frida
diff --git a/frida-python34.vcxproj.filters b/frida-python34.vcxproj.filters
index f6b50b6..e38f744 100644
--- a/frida-python34.vcxproj.filters
+++ b/frida-python34.vcxproj.filters
@@ -29,6 +29,9 @@
Source Files\frida
+
+ Source Files\frida
+
Source Files\frida
diff --git a/src/frida/lsd.py b/src/frida/lsd.py
new file mode 100644
index 0000000..04a37a7
--- /dev/null
+++ b/src/frida/lsd.py
@@ -0,0 +1,85 @@
+# -*- coding: utf-8 -*-
+from __future__ import unicode_literals, print_function
+
+def main():
+ import frida
+ from frida.application import ConsoleApplication
+
+ class LSDApplication(ConsoleApplication):
+ def _usage(self):
+ return "usage: %prog [options]"
+
+ def _start(self):
+ try:
+ devices = frida.enumerate_devices()
+ except Exception as e:
+ self._update_status("Failed to enumerate devices: %s" % e)
+ self._exit(1)
+ return
+ id_column_width = max(map(lambda device: len(device.id), devices))
+ type_column_width = max(map(lambda device: len(device.type), devices))
+ name_column_width = max(map(lambda device: len(device.name), devices))
+ header_format = "%-" + str(id_column_width) + "s " + \
+ "%-" + str(type_column_width) + "s " + \
+ "%-" + str(name_column_width) + "s"
+ print(header_format % ("Id", "Type", "Name"))
+ print("%s %s %s" % (id_column_width * "-", type_column_width * "-", name_column_width * "-"))
+ line_format = "%-" + str(id_column_width) + "s " + \
+ "%-" + str(type_column_width) + "s " + \
+ "%-" + str(name_column_width) + "s"
+ for device in sorted(devices, key=cmp_to_key(compare_devices)):
+ print(line_format % (device.id, device.type, device.name))
+ self._exit(0)
+
+ def compare_devices(a, b):
+ a_score = score(a)
+ b_score = score(b)
+ if a_score == b_score:
+ if a.name > b.name:
+ return 1
+ elif a.name < b.name:
+ return -1
+ else:
+ return 0
+ else:
+ if a_score > b_score:
+ return -1
+ elif a_score < b_score:
+ return 1
+ else:
+ return 0
+
+ def score(device):
+ type = device.type
+ if type == 'local':
+ return 3
+ elif type == 'tether':
+ return 2
+ else:
+ return 1
+
+ def cmp_to_key(mycmp):
+ "Convert a cmp= function into a key= function"
+ class K:
+ def __init__(self, obj, *args):
+ self.obj = obj
+ def __lt__(self, other):
+ return mycmp(self.obj, other.obj) < 0
+ def __gt__(self, other):
+ return mycmp(self.obj, other.obj) > 0
+ def __eq__(self, other):
+ return mycmp(self.obj, other.obj) == 0
+ def __le__(self, other):
+ return mycmp(self.obj, other.obj) <= 0
+ def __ge__(self, other):
+ return mycmp(self.obj, other.obj) >= 0
+ def __ne__(self, other):
+ return mycmp(self.obj, other.obj) != 0
+ return K
+
+ device = LSDApplication()
+ device.run()
+
+
+if __name__ == '__main__':
+ main()
diff --git a/src/scripts/Makefile.am b/src/scripts/Makefile.am
index e3277d9..fcf512a 100644
--- a/src/scripts/Makefile.am
+++ b/src/scripts/Makefile.am
@@ -1,12 +1,14 @@
bin_SCRIPTS = \
frida \
frida-discover \
+ frida-ls-devices \
frida-ps \
frida-trace
CLEANFILES = $(bin_SCRIPTS)
EXTRA_DIST = \
frida.in \
frida-discover.in \
+ frida-ls-devices.in \
frida-ps.in \
frida-trace.in
@@ -24,6 +26,10 @@ frida-discover: frida-discover.in Makefile
$(do_substitution) < $(srcdir)/frida-discover.in > $@
chmod +x $@
+frida-ls-devices: frida-ls-devices.in Makefile
+ $(do_substitution) < $(srcdir)/frida-ls-devices.in > $@
+ chmod +x $@
+
frida-ps: frida-ps.in Makefile
$(do_substitution) < $(srcdir)/frida-ps.in > $@
chmod +x $@
diff --git a/src/scripts/frida-ls-devices.in b/src/scripts/frida-ls-devices.in
new file mode 100644
index 0000000..0116b4c
--- /dev/null
+++ b/src/scripts/frida-ls-devices.in
@@ -0,0 +1,9 @@
+#!@PYTHON@
+
+import sys
+sys.path.insert(1, '@pythondir@')
+
+import frida.lsd
+
+if __name__ == '__main__':
+ frida.lsd.main()
diff --git a/src/setup.py b/src/setup.py
index 6f1612e..69261a1 100755
--- a/src/setup.py
+++ b/src/setup.py
@@ -111,6 +111,7 @@ setup(
'console_scripts': [
"frida = frida.repl:main",
"frida-discover = frida.discoverer:main",
+ "frida-ls-devices = frida.lsd:main",
"frida-ps = frida.ps:main",
"frida-trace = frida.tracer:main"
]