A tool for PS1 game decompilers to identify which PSY-Q SDK versions are used in their codebase by comparing function signatures.
When decompiling PS1 games, you often need to identify which version of Sony's PSY-Q SDK was used. This is tricky because:
- Games frequently mix functions from different SDK versions
- Manually comparing bytes against signature databases is tedious
- There are 10+ SDK versions, each with dozens of libraries
This tool speeds up the process by letting you visually diff signatures between versions and match your binary against the signature database.
pip install -r requirements.txt
python psyq-finder.pySelect two SDK versions and a library to see a color-coded byte diff of any function:
- Gray — identical bytes
- Blue — wildcards (
??) - Red/Green — bytes that differ between versions
Useful for quickly spotting the differences when you've narrowed it down to a few candidate versions.
Point the tool at your binary, specify an offset and function name, and it searches the signature database to find matching SDK versions.
- Select a specific library (e.g.,
LIBSPU.LIB) to search only that library across all SDK versions - Results show match percentage so you can see how confident the match is
Since old compilers linked entire objects (not individual functions), you can match a whole object signature for more reliable results.
- Select a library and object name from dropdowns
- Compares many more bytes than function matching, giving higher confidence results
- Shows matched bytes vs total signature size so you can see exactly how much data was compared
This is generally more reliable than function matching since you're comparing the entire compiled object file.
Search for a function by name to see which library and object it lives in across all SDK versions.
- Enter a function name (e.g.,
_spu_init) and optionally filter by library (this will significantly improve performance) - Results are collated: if a function lives in the same library/object across multiple versions, they're shown in one row
Point the tool at your entire PS1 binary and it will find every PSY-Q object present, reporting the offset, library, object name, functions within each object, and which SDK versions match.
How it works:
- Preprocess — Downloads and caches all SDK signatures, deduplicates identical signatures across versions, and extracts optimized search "anchors" (longest consecutive concrete byte runs) from each.
- Scan — For each unique signature, uses Python's C-optimized
bytes.find()(Boyer-Moore) to locate anchor candidates in the binary, then verifies full signatures with wildcard masks. Only checks 4-byte aligned offsets (MIPS). - Report — Shows every matched object with offset, size, SDK versions, and all function labels with their absolute addresses.
False Positives: Mark found results as False Positives using the [X] on the left side to remove an entry from the displayed results
Export: Results can be exported to CSV for use in your decompilation project.
Tip: Use the library filter during preprocessing if you only care about specific libraries — this speeds up both preprocessing and scanning.
Browse the raw contents of any PSY-Q library across SDK versions. Select a version and library from the dropdowns to see all objects in that library.
- Left panel: Filterable object list — search by object name or function name
- Right panel: Full details for the selected object including all function labels with offsets, internal labels (collapsed by default), and a hex view of the signature with label markers and ASCII column
Useful for quickly checking what functions live in an object, seeing exact signature bytes, or comparing how a library's structure changed between SDK versions without digging through raw JSON files.
Signature JSONs are fetched from lab313ru/psx_psyq_signatures and cached locally in ~/.cache/psyq_signatures/. First run will be slower as it downloads what you need; subsequent runs are fast.
- Scan Binary is the most powerful feature — point it at your binary and get a complete map of all PSY-Q objects, their offsets, versions, and functions
- Match Object is more reliable than Match Function — it compares way more bytes, so you get higher confidence matches
- If you know roughly which library a function is from, use the library dropdown to speed up searches
- The Compare Functions tab is great for understanding what changed between versions once you've identified candidates
- Object matching reads 64KB from your binary, function matching reads 4KB — make sure your offset is correct
- When scanning, use the library filter during preprocessing if you only need to check specific libraries
Signature data from lab313ru/psx_psyq_signatures