"""Enumerate CardsDLL instructions that write a dword-like value to object +0x1c.

This is intentionally a read-only listing query.  It finds explicit memory writes whose
rendered destination operand contains displacement 0x1c, then groups them by function.
"""

listing = prog.getListing()
seen = set()

for insn in listing.getInstructions(True):
    text = insn.toString().lower()
    if "0x1c" not in text and "+1ch" not in text:
        continue
    refs = insn.getReferencesFrom()
    has_write = any(ref.getReferenceType().isWrite() for ref in refs)
    # Register-relative memory writes do not always produce a Ghidra reference, so retain
    # the common write mnemonics and require the first rendered operand to contain +0x1c.
    mnemonic = insn.getMnemonicString().lower()
    dst = insn.getDefaultOperandRepresentation(0).lower()
    if "0x1c" not in dst and "+1ch" not in dst:
        continue
    if not has_write and mnemonic not in ("mov", "movzx", "and", "or", "xor", "inc", "dec"):
        continue
    owner = func(int(insn.getAddress().getOffset()))
    entry = int(owner.getEntryPoint().getOffset()) if owner else 0
    key = (entry, int(insn.getAddress().getOffset()))
    if key in seen:
        continue
    seen.add(key)
    print("%#x function=%#x %s :: %s" %
          (key[1], entry, owner.getName() if owner else "?", insn.toString()))
