def analyze_recent_load_of(cls, store: Store, from_: Op, reg: str, stage: int = 0) -> Optional[Op]: for o in cls.looking_behind_from(store, from_): if o.t == 'id': if reg in cls.analyze_load(store, o): return o if reg.startswith('p'): index = int(reg.replace('p', '')) for caller in CodeFlows.callers_of(store, from_): if store.query().qualname_of( from_) != store.query().qualname_of(caller): caller_reg = cls.decoded_registers_of_list( caller.p[0])[index] ui.debug( f"analyze_recent_load_of: retrace: {from_!r} [{reg}] <-> {caller!r} [{caller_reg}] [stage: {stage}]" ) if stage < 5: retraced = cls.analyze_recent_load_of(store, caller, caller_reg, stage=stage + 1) if retraced: return retraced return None
def analyze_recent_instance_load_of(cls, store: Store, op: Op) -> Optional[Op]: assert len(op.p) == 3 assert op.t == 'id' and any(op.v.startswith(x) for x in ['iget-']) field = op.p[2].v instance_reg = cls.decoded_registers_of_list(op.p[1])[0] for o in itertools.chain(cls.looking_behind_from(store, op), store.query().iputs(field)): if o.t == 'id' and o.v.startswith('iput-') and o.p[2].v == field: return o return None
def analyze_recent_static_load_of(cls, store: Store, op: Op) -> Optional[Op]: assert op.t == 'id' and any(op.v.startswith(x) for x in ['sget-']) target = op.p[1].v for o in itertools.chain(cls.looking_behind_from(store, op), store.query().sputs(target)): if o.t == 'id' and o.v.startswith('sput-'): if o.p[1].v == target: return o else: ui.debug( f"analyze_recent_static_load_of: failed static trace: {op!r}") return None
def test_000(self): s = Store('.') f = io.StringIO(''' .class public final LA; .super Ljava/lang/Object; .method public a()V return-void return-void .end method ''') SmaliAnalyzer(s).analyze([f]) for o in s.query().ops(): print(o) for o in data.DataFlows.looking_behind_from(s, Op.of_id(12)): print(o) assert False with SmaliWorkBench().smali({ 'A', }) as wb: pass
def looking_behind_from(cls, store: Store, op: Op) -> Iterable[Op]: focus = None for o in store.query().reversed_insns_in_method(op): if focus is None: if o.t != 'label': yield o else: if not o.v.startswith("try_"): focus = o.v else: if o.t != 'id' or not any(p.v == focus for p in o.p): continue else: focus = None
def callers_of(cls, store: Store, method: Op) -> Iterable[Op]: yield from store.query().callers_of(method)
def should_be_secret(store: Store, k: Op, val: str) -> bool: name = store.query().qualname_of(k) if name: return name.lower() in ['inapp','billing','iab','sku','store','key'] else: return False
def store(self) -> Store: assert self.wd is not None from trueseeing.core.store import Store return Store(self.wd)