Skip to content

Commit c7aebf5

Browse files
committed
fix adb execs for unix-like systems, use list-based adb args
1 parent 31f5a84 commit c7aebf5

File tree

2 files changed

+31
-26
lines changed

2 files changed

+31
-26
lines changed

android_unpinner/__main__.py

Lines changed: 23 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ def patch_apk_files(apks: list[Path]) -> list[Path]:
7272

7373
def ensure_device_connected() -> None:
7474
try:
75-
adb("get-state")
75+
adb(["get-state"])
7676
except subprocess.CalledProcessError:
7777
raise RuntimeError("No device connected via ADB.")
7878

@@ -93,13 +93,13 @@ def install_apk(apk_files: list[Path]) -> None:
9393
)
9494

9595
logging.info("Uninstall existing app...")
96-
adb(f"uninstall {package_name}")
96+
adb(["uninstall", package_name])
9797

9898
logging.info(f"Installing {package_name}...")
9999
if len(apk_files) > 1:
100-
adb(f"install-multiple --no-incremental {' '.join(str(x) for x in apk_files)}")
100+
adb(["install-multiple", "--no-incremental", *[str(x) for x in apk_files]])
101101
else:
102-
adb(f"install --no-incremental {apk_files[0]}")
102+
adb(["install", "--no-incremental", str(apk_files[0])])
103103

104104

105105
def copy_files() -> None:
@@ -109,17 +109,17 @@ def copy_files() -> None:
109109
# TODO: We could later provide the option to use a custom script dir.
110110
ensure_device_connected()
111111
logging.info("Detect architecture...")
112-
abi = adb("shell getprop ro.product.cpu.abi").stdout.strip()
112+
abi = adb(["shell", "getprop", "ro.product.cpu.abi"]).stdout.strip()
113113
if abi == "armeabi-v7a":
114114
abi = "arm"
115115
gadget_file = gadget_files.get(abi, gadget_files["arm64"])
116116
logging.info(f"Copying matching gadget: {gadget_file.name}...")
117-
adb(f"push {gadget_file} /data/local/tmp/{LIBGADGET}")
118-
adb(f"push {gadget_config_file} /data/local/tmp/{LIBGADGET_CONF}")
117+
adb(["push", str(gadget_file), f"/data/local/tmp/{LIBGADGET}"])
118+
adb(["push", str(gadget_config_file), f"/data/local/tmp/{LIBGADGET_CONF}"])
119119

120120
logging.info("Copying builtin Frida scripts to /data/local/tmp/android-unpinner...")
121-
adb(f"push {here / 'scripts'}/. /data/local/tmp/android-unpinner/")
122-
active_scripts = adb("shell ls /data/local/tmp/android-unpinner").stdout.splitlines(
121+
adb(["push", f"{here / 'scripts'}/.", "/data/local/tmp/android-unpinner/"])
122+
active_scripts = adb(["shell", "ls", "/data/local/tmp/android-unpinner"]).stdout.splitlines(
123123
keepends=False
124124
)
125125
logging.info(f"Active frida scripts: {active_scripts}")
@@ -128,17 +128,21 @@ def copy_files() -> None:
128128
def start_app_on_device(package_name: str) -> None:
129129
ensure_device_connected()
130130
logging.info("Start app (suspended)...")
131-
adb(f"shell am set-debug-app -w {package_name}")
132-
activity = adb(
133-
f'shell cmd "package resolve-activity --brief {package_name} | tail -n 1"'
134-
).stdout.strip()
135-
adb(f"shell am start -n {activity}")
131+
adb(["shell", "am", "set-debug-app", "-w", package_name])
132+
activity_lines = adb([
133+
"shell", "cmd", "package", "resolve-activity",
134+
"--brief", package_name
135+
]).stdout.strip().splitlines()
136+
activity = activity_lines[-1] if activity_lines else ""
137+
if not activity or activity.lower().startswith("no activity found"):
138+
raise RuntimeError("Activity not found")
139+
adb(["shell", "am", "start", "-n", activity])
136140

137141
logging.info("Obtain process id...")
138142
pid = None
139143
for i in range(5):
140144
try:
141-
pid = adb(f"shell pidof {package_name}").stdout.strip()
145+
pid = adb(["shell", "pidof", package_name]).stdout.strip()
142146
break
143147
except subprocess.CalledProcessError:
144148
if i:
@@ -147,7 +151,7 @@ def start_app_on_device(package_name: str) -> None:
147151
raise
148152
sleep(1)
149153
logging.debug(f"{pid=}")
150-
local_port = int(adb(f"forward tcp:0 jdwp:{pid}").stdout)
154+
local_port = int(adb(["forward", "tcp:0", f"jdwp:{pid}"]).stdout)
151155
logging.debug(f"{local_port=}")
152156

153157
async def inject_frida():
@@ -175,7 +179,7 @@ async def inject_frida():
175179

176180

177181
def get_packages() -> list[str]:
178-
packages = adb("shell pm list packages").stdout.strip().splitlines()
182+
packages = adb(["shell", "pm", "list", "packages"]).stdout.strip().splitlines()
179183
return [p.removeprefix("package:") for p in sorted(packages)]
180184

181185

@@ -379,7 +383,7 @@ def get_apks(package: str, outdir: Path) -> None:
379383
if package not in get_packages():
380384
raise RuntimeError(f"Could not find package: {package}")
381385

382-
package_info = adb(f"shell pm path {package}").stdout
386+
package_info = adb(["shell", "pm", "path", package]).stdout
383387
if not package_info.startswith("package:"):
384388
raise RuntimeError(f"Unxepected output from pm path: {package_info!r}")
385389
apks = [p.removeprefix("package:") for p in package_info.splitlines()]
@@ -393,7 +397,7 @@ def get_apks(package: str, outdir: Path) -> None:
393397
f"Overwrite existing file: {outfile.absolute()}?", abort=True
394398
):
395399
outfile.unlink()
396-
adb(f"pull {apk} {outfile.absolute()}")
400+
adb(["pull", apk, str(outfile.absolute())])
397401

398402
logging.info("All done! 🎉")
399403

android_unpinner/vendor/platform_tools/__init__.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,21 +14,22 @@
1414
adb_binary = here / "linux" / "adb"
1515

1616

17-
def adb(cmd: str) -> subprocess.CompletedProcess[str]:
17+
def adb(cmd: list[str]) -> subprocess.CompletedProcess[str]:
1818
"""Helper function to call adb and capture stdout."""
19-
base = f"{adb_binary}"
19+
base = [str(adb_binary)]
2020
if device:
21-
base += f" -s {device}"
21+
base += ["-s", device]
2222
logging.debug(f"Using device: {device}")
23-
full_cmd = f"{base} {cmd}"
23+
full_cmd = base + cmd
24+
full_cmd_str = " ".join(full_cmd)
2425
try:
2526
proc = subprocess.run(
26-
full_cmd, shell=False, check=True, capture_output=True, text=True
27+
full_cmd, check=True, capture_output=True, text=True
2728
)
2829
except subprocess.CalledProcessError as e:
29-
logging.debug(f"cmd='{full_cmd}'\n" f"{e.stdout=}\n" f"{e.stderr=}")
30+
logging.debug(f"cmd='{full_cmd_str}'\n" f"{e.stdout=}\n" f"{e.stderr=}")
3031
raise
31-
logging.debug(f"cmd='{full_cmd}'\n" f"{proc.stdout=}\n" f"{proc.stderr=}")
32+
logging.debug(f"cmd='{full_cmd_str}'\n" f"{proc.stdout=}\n" f"{proc.stderr=}")
3233
return proc
3334

3435

0 commit comments

Comments
 (0)