1515from .vendor import frida_tools
1616from .vendor import gadget_config_file_listen , gadget_config_file_script_directory
1717from .vendor import gadget_files
18- from .vendor .platform_tools import adb
18+ from .vendor .platform_tools import adb , set_device
1919
2020here = Path (__file__ ).absolute ().parent
2121LIBGADGET = "libgadget.so"
@@ -35,13 +35,13 @@ def patch_apk_file(infile: Path, outfile: Path) -> None:
3535 ):
3636 outfile .unlink ()
3737
38- logging .info (f "Make APK debuggable..." )
38+ logging .info ("Make APK debuggable..." )
3939 frida_tools .apk .make_debuggable (
4040 str (infile ),
4141 str (outfile ),
4242 )
4343
44- logging .info (f "Zipalign & re-sign APK..." )
44+ logging .info ("Zipalign & re-sign APK..." )
4545 build_tools .zipalign (outfile )
4646 build_tools .sign (outfile )
4747
@@ -88,7 +88,7 @@ def install_apk(apk_files: list[Path]) -> None:
8888 if package_name in get_packages ():
8989 if not force :
9090 click .confirm (
91- f "About to install patched APK. This removes the existing app with all its data. Continue?" ,
91+ "About to install patched APK. This removes the existing app with all its data. Continue?" ,
9292 abort = True ,
9393 )
9494
@@ -108,7 +108,7 @@ def copy_files() -> None:
108108 """
109109 # TODO: We could later provide the option to use a custom script dir.
110110 ensure_device_connected ()
111- logging .info (f "Detect architecture..." )
111+ logging .info ("Detect architecture..." )
112112 abi = adb ("shell getprop ro.product.cpu.abi" ).stdout .strip ()
113113 if abi == "armeabi-v7a" :
114114 abi = "arm"
@@ -117,21 +117,21 @@ def copy_files() -> None:
117117 adb (f"push { gadget_file } /data/local/tmp/{ LIBGADGET } " )
118118 adb (f"push { gadget_config_file } /data/local/tmp/{ LIBGADGET_CONF } " )
119119
120- logging .info (
121- f"Copying builtin Frida scripts to /data/local/tmp/android-unpinner..."
122- )
120+ logging .info ("Copying builtin Frida scripts to /data/local/tmp/android-unpinner..." )
123121 adb (f"push { here / 'scripts' } /. /data/local/tmp/android-unpinner/" )
124- active_scripts = adb (
125- f"shell ls /data/local/tmp/android-unpinner"
126- ). stdout . splitlines ( keepends = False )
122+ active_scripts = adb ("shell ls /data/local/tmp/android-unpinner" ). stdout . splitlines (
123+ keepends = False
124+ )
127125 logging .info (f"Active frida scripts: { active_scripts } " )
128126
129127
130128def start_app_on_device (package_name : str ) -> None :
131129 ensure_device_connected ()
132130 logging .info ("Start app (suspended)..." )
133131 adb (f"shell am set-debug-app -w { package_name } " )
134- activity = adb (f"shell cmd \" package resolve-activity --brief { package_name } | tail -n 1\" " ).stdout .strip ()
132+ activity = adb (
133+ f'shell cmd "package resolve-activity --brief { package_name } | tail -n 1"'
134+ ).stdout .strip ()
135135 adb (f"shell am start -n { activity } " )
136136
137137 logging .info ("Obtain process id..." )
@@ -245,10 +245,25 @@ def _listen(ctx, param, val):
245245)
246246
247247
248+ def _device (ctx , param , val ):
249+ if val :
250+ set_device (val )
251+
252+
253+ device_option = click .option (
254+ "-d" ,
255+ "--device" ,
256+ help = "Device serial number to use when multiple devices are connected." ,
257+ callback = _device ,
258+ expose_value = False ,
259+ )
260+
261+
248262@cli .command ("all" )
249263@verbosity_option
250264@force_option
251265@listen_option
266+ @device_option
252267@click .argument (
253268 "apk-files" ,
254269 type = click .Path (path_type = Path , exists = True ),
@@ -278,6 +293,7 @@ def all_cmd(apk_files: list[Path]) -> None:
278293@cli .command ("install" )
279294@verbosity_option
280295@force_option
296+ @device_option
281297@click .argument (
282298 "apk-files" ,
283299 type = click .Path (path_type = Path , exists = True ),
@@ -313,6 +329,7 @@ def patch_apks(apks: list[Path]) -> None:
313329@verbosity_option
314330@force_option
315331@listen_option
332+ @device_option
316333def push_resources () -> None :
317334 """Copy Frida gadget and scripts to device."""
318335 copy_files ()
@@ -322,6 +339,7 @@ def push_resources() -> None:
322339@cli .command ()
323340@verbosity_option
324341@force_option
342+ @device_option
325343@click .argument ("package-name" )
326344def start_app (package_name : str ) -> None :
327345 """Start app on device and inject Frida gadget."""
@@ -331,10 +349,11 @@ def start_app(package_name: str) -> None:
331349
332350@cli .command ()
333351@verbosity_option
352+ @device_option
334353def list_packages () -> None :
335354 """List all packages installed on the device."""
336355 ensure_device_connected ()
337- logging .info (f "Enumerating packages..." )
356+ logging .info ("Enumerating packages..." )
338357 print ("\n " .join (get_packages ()))
339358 logging .info ("All done! 🎉" )
340359
@@ -349,6 +368,7 @@ def package_name(apk_file: Path) -> None:
349368@cli .command ()
350369@verbosity_option
351370@force_option
371+ @device_option
352372@click .argument ("package" , type = str )
353373@click .argument ("outdir" , type = click .Path (path_type = Path , file_okay = False ))
354374def get_apks (package : str , outdir : Path ) -> None :
0 commit comments