Skip to content

sigscan ​

Tool tools/triage/sigscan.py (program, Triage). Byte signatures with wildcards: make them from functions you have named, and find them in another build, a memory dump or a game that uses the same library.

Run it with ./gameframe run sigscan ARGS or python3 tools/triage/sigscan.py. Source on GitHub.

Its own help ​

This is the help text in the tool itself, as ./gameframe tool sigscan prints it.

text
Byte signatures with wildcards: make them from functions you have named, and find them in
another build, a memory dump or a game that uses the same library.

Usage: sigscan.py scan SIGS BINARY [--base ADDR] [--labels OUT.tsv]
       sigscan.py make BINARY ADDR[:LEN] [ADDR[:LEN] ...] [--names NAMES.tsv] [--len N] > SIGS
       sigscan.py make BINARY --names NAMES.tsv [--len N] > SIGS

  SIGS        a text file, one signature per line: "name: 55 8B EC ?? ?? 56 57" (?? is any
              byte; lines starting with # are comments). tools/dos/omf.py writes these from a
              compiler's libraries; `make` writes them from a binary.
  BINARY      a Windows PE (code sections, virtual addresses), a DOS MZ program (its load image;
              addresses as image offsets, and as Ghidra's seg:off from 1000:0000),
              or any other file (offsets, plus --base)
  --labels    write the matches as a labels file (address, name, evidence) for ghidra-run labels
  make        ADDR is a virtual address (PE), a seg:off or image offset (MZ), or a file offset;
              LEN the bytes to take (default --len, 32). --names takes the addresses and names
              from a labels file (labels/names.tsv), for every named function at once

A signature holds the first bytes of a function, with the bytes that change from one build to
the next replaced by ??: call and jump distances, absolute addresses of globals, and anything
the relocation table lists. What stays is the function's own instructions. So a signature
made from build A finds the same function in build B, without a Ghidra export of B
(match_functions.py does the same from two exports). A compiler's runtime library, turned
into signatures, names the runtime's functions inside a game, so they can be left unread.

The idea follows the library signatures of Cifuentes's dcc decompiler and the FLIRT
signatures of IDA. This is GameFrame's own, simple form. A match is a lead: two different
functions can begin with the same bytes, so the tool says when a signature matches more than
once. Needs capstone (.venv) for `make`.

Named by ​

Skills: re-inventory, re-ghidra.

Code: Apache 2.0. Content: CC0 1.0. No game material: bring your own copy.