#!/usr/bin/env python3 """Locate metadata-usage tokens / pointers inside an il2cpp binary. On metadata v27 the compiled code does not carry literal indices: a string literal is reached through a metadata-usage value `(type << 29) | (index << 1) | 1` (type 5 = string literal). That value shows up in the image either as an immediate operand in code or as the pre-loader content of a usage slot, so a plain byte scan is enough to find the referencing function - parse #29705's token with tools/sep-literals.py, scan here, then read the enclosing method from the runtime address map. Usage: python tools/sep-scan.py --binary --token 0xA000E813[,..] python tools/sep-scan.py --binary --pointer 0x1891B46E8[,..] python tools/sep-scan.py --binary --map --token ... Options: --section .text restrict the scan (repeatable; default: every section) --context N extra bytes of hex context to print (default 16) """ import argparse import os import struct import sys METADATA_USAGE_STRING_LITERAL = 5 def literal_token(index): return (METADATA_USAGE_STRING_LITERAL << 29) | (index << 1) | 1 def parse_number(text): return int(text, 0) def read_sections(blob): pe_offset = struct.unpack_from(" {module} {method} +{delta:#x}" print(line) context = blob[max(offset - 4, start) : offset + len(pattern) + args.context] print(f" ctx {context.hex(' ')}") total += 1 offset += 1 print(f"{total} occurrence(s)") if entries: print("map loaded: %d methods" % len(entries)) return 0 if __name__ == "__main__": sys.exit(main(sys.argv))