42 lines
1.8 KiB
Python
42 lines
1.8 KiB
Python
#!/usr/bin/env python3
|
|
"""Assert the exact GEL unique-work callsite in the immutable stock APK."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import hashlib
|
|
from pathlib import Path
|
|
import sys
|
|
import zipfile
|
|
|
|
ROOT = Path(__file__).resolve().parents[3]
|
|
HELPERS = ROOT / "diagnostics" / "deep-forensics" / "philips"
|
|
sys.path.insert(0, str(HELPERS))
|
|
from dex_disasm import Dex, fmt, iter_instructions # noqa: E402
|
|
|
|
APK = ROOT / "diagnostics" / "raw" / "storage" / "gel.apk"
|
|
EXPECTED = "29a68e6b09700ed4ccdf312c0b99eee0c3f67e329a537fe87ed4341a71d383d7"
|
|
METHOD = "Lorg/droidtv/gel/gathering/GatheringService;->onStartCommand(Landroid/content/Intent;II)I"
|
|
|
|
|
|
def main() -> None:
|
|
assert hashlib.sha256(APK.read_bytes()).hexdigest() == EXPECTED
|
|
with zipfile.ZipFile(APK) as zf:
|
|
dex = Dex(zf.read("classes.dex"), str(APK) + "!/classes.dex")
|
|
encoded = next(m for m in dex.encoded_methods if dex.methods[m.method_idx] == METHOD)
|
|
instructions = {pc: fmt(dex, pc, op, units)
|
|
for pc, op, units in iter_instructions(dex.data, encoded.code_off)}
|
|
expected = {
|
|
0x0000: "invoke-static {v3}, Lorg/droidtv/gel/gathering/GELWorker;->buildWorkRequest(Landroid/content/Intent;)Landroidx/work/OneTimeWorkRequest;",
|
|
0x000F: "const-string v0, 'GEL_WORK'",
|
|
0x0011: "const/4 v1, #4",
|
|
0x0012: "invoke-direct {v5, v4, v0, v1, v3}, Landroidx/work/impl/WorkContinuationImpl;-><init>(Landroidx/work/impl/WorkManagerImpl;Ljava/lang/String;ILjava/util/List;)V",
|
|
0x0015: "invoke-virtual {v5}, Landroidx/work/impl/WorkContinuationImpl;->enqueue()Landroidx/work/Operation;",
|
|
}
|
|
for pc, text in expected.items():
|
|
assert instructions.get(pc) == text, (hex(pc), instructions.get(pc), text)
|
|
print("PASS: stock GEL onStartCommand uses GEL_WORK with policy integer 4")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|