"""q_cd_route_5 -- is column 1 of the action row really the URL-base index?

HYPOTHESIS
  Row N of the action table 0x1802caa20 (48-byte rows) has column 1 = index into the
  16-byte-stride (template, symbolic name) table at 0x18021df80, and the four club
  actions carry index 3.  RIP-displacement scan of .text on the on-disk PE finds only
  four references anywhere near that table: 0x180123713 (-24), 0x180123790 (-64),
  0x18012437e (+8) and 0x1801db62c (-64).  Decompiling their containers should show
  one of them doing table[i*2] / table[i*2+1] with i coming from the action row.

CONTROL / FALSIFIER
  ut/v2/%s/store (index 43) is a LIVE-PROVEN route and NO action row carries index 43.
  So if these functions show the index arriving only from the action row, the club
  bound is exact for every action in the table but the store proves some other path
  exists, and the bound must be stated with that caveat.  If instead they show a
  runtime override (a per-request base field, or a second table), the "exactly four
  club actions" claim is a default and not a closure, and this query is what says so.

  Every body is printed in full with len(src).
"""
import traceback

try:
    def show(label, ea):
        f = fm.getFunctionContaining(addr(ea))
        print("=" * 78)
        print("### %s  @ %s  -> %s" % (label, hex(ea), f.getName() if f else "NO FUNC"))
        if f is None:
            return
        print("    entry %s  body %s" % (f.getEntryPoint(), f.getBody()))
        src = dec(f)
        print("    len(src) = %d" % len(src))
        print(src)
        try:
            cs = sorted(set(int(x.getEntryPoint().getOffset())
                            for x in f.getCallingFunctions(mon)))
            print("    callers: %s" % ", ".join(hex(c) for c in cs))
        except Exception as e:
            print("    callers: <%s>" % e)

    for ea in (0x180123713, 0x180123790, 0x18012437e, 0x1801db62c):
        show("base-table ref", ea)
except Exception:
    traceback.print_exc()
