{"id":19403887,"url":"https://github.com/travisgoodspeed/maskromtool","last_synced_at":"2025-05-16T07:06:55.830Z","repository":{"id":61070929,"uuid":"547980890","full_name":"travisgoodspeed/maskromtool","owner":"travisgoodspeed","description":"A CAD tool for extracting bits from Mask ROM photographs.","archived":false,"fork":false,"pushed_at":"2025-05-16T00:40:38.000Z","size":14023,"stargazers_count":357,"open_issues_count":25,"forks_count":21,"subscribers_count":12,"default_branch":"master","last_synced_at":"2025-05-16T01:27:17.337Z","etag":null,"topics":["maskrom","reverse-engineering","rom"],"latest_commit_sha":null,"homepage":"","language":"C++","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/travisgoodspeed.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"COPYING","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2022-10-08T17:37:27.000Z","updated_at":"2025-05-16T00:40:43.000Z","dependencies_parsed_at":"2023-01-31T17:16:36.223Z","dependency_job_id":"597c9aa4-daca-45bc-bd9f-e20bc604a4d7","html_url":"https://github.com/travisgoodspeed/maskromtool","commit_stats":{"total_commits":362,"total_committers":6,"mean_commits":"60.333333333333336","dds":0.03038674033149169,"last_synced_commit":"8a1904953b54fe2f339e44e2d41768a7581120a2"},"previous_names":[],"tags_count":13,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisgoodspeed%2Fmaskromtool","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisgoodspeed%2Fmaskromtool/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisgoodspeed%2Fmaskromtool/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/travisgoodspeed%2Fmaskromtool/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/travisgoodspeed","download_url":"https://codeload.github.com/travisgoodspeed/maskromtool/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254485064,"owners_count":22078767,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["maskrom","reverse-engineering","rom"],"created_at":"2024-11-10T11:31:28.722Z","updated_at":"2025-05-16T07:06:50.808Z","avatar_url":"https://github.com/travisgoodspeed.png","language":"C++","funding_links":[],"categories":[],"sub_categories":[],"readme":"Howdy y'all,\n\nThis is my CAD tool for taking photographs of a mask ROM and\nextracting the bits, so that the contents of the ROM can be recovered.\n\nThe keyboard shortcuts in this tool are *not* optional.  Please read\nthe GUI documentation below before starting to explore.\n\nIf you find this tool to be useful, please buy a copy of my book on\n[Microcontroller\nExploits](https://www.amazon.com/Microcontroller-Exploits-Travis-Goodspeed/dp/1718503881)\nfor yourself or a clever student.\n\n--Travis Goodspeed\n\n![Screenshot of the tool.](screenshots/screenshot.png)\n\n## Examples\n\n[gbrom-tutorial](https://github.com/travisgoodspeed/gbrom-tutorial)\nteaches you how to begin with photographs of the GameBoy's mask ROM\nand work your way to an accurate ROM image.\n\n[MYK82 ROM](https://github.com/travisgoodspeed/myk82rom) holds a\ncompleted dump of the ROM from the MYK82 chip in a Fortezza Card.\nThis is the successor to the Clipper Chip, and the repository includes\nnot just all ROM bits but also reshoots for error correction.\n\n[wersi-slm2-51173](https://github.com/travisgoodspeed/wersi-slm2-51173/)\nis a Zilog Z8 ROM from a music synthesize module.\n\n## Release Changelog\n\n`master` -- Performance improvements by avoiding deep copies in lists.\nProper bit count in status bar and the status bar now uses a\nfixed-width font.\n[GoodASM](https://github.com/travisgoodspeed/goodasm) now included as\nan assembler, through a git submodule.  Cut copy and paste key\nbindings now work as expected from other GUIs.\n\n2024-08-18 -- Gatorom's solver-set option now uses descriptive\nfiilenames.  GUI can now export a set of solved results with\nFile/Export/SolverSetBytes.  Clearer selection rectangle.  `R` and `C`\nwill now draw the correct line type when the user confuses them.  `^H`\nnow sets the home position.  Zooming and movement keys now work in the\nsecond view.  Perfectly duplicate lines are now culled during DRC by\nthe `V` key.  Rows and columns are now stored as sorted lists instead\nof sets.  Rows and columns are now in a consistent order in the file\nexport.  Performance boosts in bit marking, background bit marking and\nalignment.  Universal binary for macOS.  RomAlignerTilting works\nbetter for designs with a gap between banks.  Out-of-view bits are no\nlonger drawn during dragging, speeding up adjusting groups of long\nlines.\n\n2024-07-14 -- Fixes crash when deleting a double-selected item.  Delete\nand backspace now delete objects like `D`.  Multiple disassemblers.\nDecodings are now updated as decoding thresholds are changed.\n\n2024-06-23 -- Yara rule solving.  Stability improvements.  Crosshairs\nupdate to the angles of selected lines.  Space now repeats the last\nline, whether row or column.  Multiple items can be selected, and\nSHIFT+D duplicates them.  Select with SHIFT to add more lines or CTRL\n(CMD on macOS) to remove lines.  Right dragging moves multiple lines,\npreviewing only relevant bits.  Crosshair and selection colors are now\nselectable.  Background is no longer tiled when zooming out.\n\n2024-05-19 -- DRC violations are now cleared when bits are forced.\nHistogram export for ploting the color distributions in GNUPlot.\nSupport for Wayland.  Explicit wordsize support in CLI, GUI, solver\nand basic decoders.  Solver sets, exporting all potential solutions as\nbinary files.  Unreliable aligner has been deprecated.  GUI solver.\nDisassembler calls out to MAME's Unidasm.\n\n2024-01-28 -- Undo and Redo.  Strings dialog.  Backslash key for layer\nvisibility.  Reliable alignment algorithm.  Closing main window closes\napplication.\n\n2024-01-01 -- Fixes bus error in Z8 decoder when solving odd sizes.\nVerbose mode in the GatoROM CLI.  `squeeze-lr` mode now in GUI\ndecoder.  Edit menu item to clear all bit fixes.  `E` will select the\nnext DRC violation.  Perfectly vertical images no longer break the\nalignment algorithm.\n\n2023-12-07 -- Selection highlight.  Row/column counts in status bar.\nASCII solver.  Fixes multiple\n[crashes](https://github.com/travisgoodspeed/maskromtool/issues/59) in\nsolver from awkward ROM sizes.  GatoROM decoding in the GUI.  Removal\nof redundant decoders.  Hex viewer and highlighting of selected bytes.\nGatoROM CLI is now very strict about exiting on illegal access.\n[Zilog Z8](https://github.com/travisgoodspeed/maskromtool/issues/76)\nROM support.\n\n2023-09-13 -- CLI option to disable OpenGL.  Printing support.\nWorking Windows build.\n\n2023-08-06 -- OpenGL is now functional and default.  GatoROM included\nfor bit decoding.\n\n2023-07-20 -- Secondary display support.  Tall sampling.  Fixes\ncrash when hitting `V` after deleting a line.\n\n2023-06-17 -- Added macOS on X86_64 and ARM64.\n\n2023-05-30 -- First Windows release.\n\n## Building\n\nThis tool works in Windows, Linux, FreeBSD and MacOS, using QT6 with\nthe QtCharts extension.\n\nBuilding the tool is easiest from the CLI.  In Debian Bullseye (11.x),\n```\n% sudo apt install make gcc g++ cmake git qt6-base-dev libqt6charts6-dev \\\nqt6-translations-l10n linguist-qt6 qt6-l10n-tools qt6-tools-\\* qt6-image-formats-plugins \\\nlibreadline-dev\n% git clone https://github.com/travisgoodspeed/maskromtool/\n...\n% cd maskromtool\n% git submodule init\n...\n% git submodule update\n...\n% mkdir build; cd build\n% cmake ..\n% make -j 8 \u0026\u0026 sudo make install\n```\n\nIn Windows and macOS, use the [Qt for Open\nSource](https://www.qt.io/download-qt-installer-oss) installer, being\nsure to include the Charts and Image Formats extensions.  Then open\n`CMakeLists.txt` as a project.  `Ctrl+B` will then compile\n`maskromtool`.  If you have a problem with your import, such as\nchoosing the wrong Qt installation, delete `CMakeLists.txt.user` and\nreopen the project to try again.\n\nFor the convenience of Windows and macOS users, we have also made some\n[Prebuilt\nReleases](https://github.com/travisgoodspeed/maskromtool/releases).\n\n\n## GUI Usage\n\nFirst use File/Open ROM to open a ROM image as a photograph.  Try to\nuse uncompressed formats, but beware that macOS doesn't like TIFF\nfiles.\n\nHolding the control key (command on macOS) while rolling the mouse\nwheel will zoom in and out.  You can also pinch-zoom on a track pad.\nDragging with the middle button will pan, or scroll with two fingers\nas your operating system likes.\n\nBy arbitrary convention, the bits should be in long columns with shorter\nrows.  If decoder lines are visible, they ought to be at the top of\nthe image.  Feel free to photograph it one way, then rotate it for\nmarkup.\n\nWhen you save your project, the image's filename will be extended with\n`.json`.  This sorted and indented JSON file should be appropriate for\nuse in version control, such as Git repositories.\n\nThese keyboard buttons then provide most of your input.  For drawing\nlines, first click once to choose as start position and then press the\nkey when the mouse is above the end position.  Deleting an item or\nSetting its position will apply to the most recently placed line,\nunless you drag a box to select a line.\n\nSelect an item by dragging over it with a left mouse click and\nwatching for it to turn green.  The most recently placed item is\nautomatically selected.  Some commands work on multiple selected\nitems; others just one.\n\nYou can delete a mistake with `D` or adjust its position a little with\n`S`, the arrow keys, or a right-click drag.  During movement the bits\nof unrelated lines might be hidden for performance, and the `M` key or\nreleasing the right mouse button will redraw them.\n\n\nOn macOS, `^` means Command instead of Ctrl.\n\n```\nTab         -- Show/Hide bits.\n\\           -- Show/Hide rows and columns.\n^\\          -- Show/Hide background.\nALT \\       -- Show/Hide crosshair.\n\n\nR           -- Draw a row from the last left-click position.\nSHIFT R     -- Repeat the last row.\nC           -- Draw a column from the last left-click position.\nSHIFT C     -- Repeat the last column.\nSPACE       -- Repeat the last row or column.\n\n^X ^C ^V    -- Cut, Copy and Paste.\nD           -- Delete the selected objects.\nSHIFT D     -- Duplicate the selected lines.\nS           -- Set the selected object to the mouse position.\nF           -- Jump to the selected item.\nARROWS      -- Move the selected items.\n\nright-drag  -- Move the selected items. (SHIFT or ^)\nmiddle-drag -- Pan the view.\n^ wheel     -- Zoom.\n\nQ           -- Zoom to zero.\nA           -- Zoom in.\nZ           -- Zoom out.\nH           -- Jump to home position.\n^H          -- Set the home position.\n\n\nSHIFT F     -- Force a bit's value. (Again to flip.)\nSHIFT A     -- Force a bit's ambiguity.  (Again to flip.)\n\nM           -- Remark all of the bits.\nSHIFT M     -- Update hex decoding and disassembly.\nV           -- Run the Design Rule Checks.\nSHIFT V     -- Clear the DRC violations.\nE           -- Jump to next violation.\n\n^Z          -- Undo\nSHIFT ^Z    -- Redo\n\n^S          -- Save changes.\n```\n\nWhen you first begin to mark bits, the software won't yet know the\nthreshold between a one and a zero.  You can configure this with\n`View` / `Choose Bit Threshold`.\n\nEven the best bits won't all be perfectly marked, so use `SHIFT+F` to\nforce bit values where you see that the software is wrong.  `SHIFT+A`\nis similar, and marks a bit as being ambiguous or damaged.  The `DRC`\nmenu contains Design Rule Checks that will highlight problems in your\nproject, such as weak bits or broken alignment.\n\nIf placing many lines becomes tedious, select a group with your left\nmouse button and duplicate the entire set with `SHIFT+D`.  You can\nthen drag it with the right mouse button to the new position, leaving\nanother copy in the original position.  If the framerate drops for\nthis, use the `TAB` key to temporarily hide all bits, which greatly\nspeeds up moving many lines in dense areas.\n\nThe crosshairs will adjust themselves to your most recently placed row\nand column.  This should let them tilt a little to match the reality\nof your photographs.\n\nAfter you have marked the bits and spot checked that they are accurate\nwith DRC, run File/Export to dump them into ASCII for parsing with\nother tools, such as [GatoROM](GATOREADME.md),\n[Bitviewer](https://github.com/SiliconAnalysis/bitviewer) or\n[ZorRom](https://github.com/SiliconAnalysis/zorrom).\n\n\n## CLI Usage\n\nIn addition to the GUI, this tool has a command line interface that\ncan be useful in scripting.  Use the `--help` switch to see the latest\nparameters, and the `--exit` switch if you'd prefer the GUI not stay\nopen for interactive use.\n\n```\nforum% maskromtool --help\nUsage: maskromtool [options] image json\nMask ROM Tool\n\nOptions:\n  -h, --help                 Displays help on commandline options.\n  --help-all                 Displays help, including generic Qt options.\n  -v, --version              Displays version information.\n  -V, --verbose              Print verbose debugging messages.\n  --stress                   Stress test bit marking.\n  -e, --exit                 Exit after processing arguments.\n  --disable-opengl           Disable OpenGL.\n  --enable-opengl            Enable OpenGL.\n  -d, --drc                  Run default Design Rule Checks.\n  -D, --DRC                  Run all Design Rule Checks.\n  --sampler \u003cDefault\u003e        Bit Sampling Algorithm.\n  --diff-ascii \u003cfile\u003e        Compares against ASCII art, for finding errors.\n  -a, --export-ascii \u003cfile\u003e  Export ASCII bits.\n  -o, --export \u003cfile\u003e        Export ROM bytes.\n  --export-histogram \u003cfile\u003e  Export histogram.\n  --export-csv \u003cfile\u003e        Export CSV bits for use in Matlab or Excel.\n  --export-json \u003cfile\u003e       Export JSON bit positions.\n  --export-python \u003cfile\u003e     Export Python arrays.\n  --export-photo \u003cfile\u003e      Export a photograph.\n\nArguments:\n  image                      ROM photograph to open.\n  json                       JSON lines to open.\n```\n\nTo run without a GUI, pass `-platform offscreen`.  If the program\ncrashes under Wayland, force Xorg usage by passing `-platform xcb`.\n\nOn Windows, it's awkward for an executable to have a GUI while\nretaining a log on the CLI.  We solve this by producing two\nexecutables; please use `maskromtool.exe` for the GUI and\n`maskromtoolcli.exe` for the CLI.\n\nA separate executable, `gatorom`, wraps the ROM bit decoder without\nthe graphics.  See [GatoROM](GATOREADME.md) for details.\n\n```\nforum% gatorom \nUsage: gatorom [options] bitstream\nGato ROM: A Decoder for Mask ROM Bits\n\nOptions:\n  -h, --help                        Displays help on commandline options.\n  --help-all                        Displays help, including generic Qt\n                                    options.\n  -v, --version                     Displays version information.\n  -V, --verbose                     Talk too much.\n  -w, --wordsize \u003c8\u003e                Word size.bits\n  -r, --rotate \u003cdegrees\u003e            Rotates the image in multiples of 90\n                                    degrees.\n  --flipx                           Flips the bits along the X axis.\n  --flipy                           Flips the bits along the Y axis.\n  -i, --invert                      Inverts the bits.\n  -o, --output \u003cout.bin\u003e            Output file.\n  --random                          Randomize a ROM for testing.\n  --Random                          Randomize a crazy ROM.\n  --rawwidth, --seanriddle \u003cwidth\u003e  Width of a raw binary input, in Sean\n                                    Riddle's style.\n  -I, --info                        Info about input.\n  -d, --dis \u003carch\u003e                  Disassemble.\n  --print                           Print with a GUI dialog.\n  --printpdf \u003cfile.pdf\u003e             Print to a PDF file.\n  --decode-tlcs47font               Decodes as a TMP47C434N Font.\n  --decode-z86x1                    Decodes as a Zilog Z86x1.\n  --decode-cols-downl-swap          Decodes as a uCOM4 ROM.\n  --decode-cols-downr               Decodes first down then right like a\n                                    Gameboy.\n  --decode-cols-downl               Decodes first down then left.\n  --decode-cols-left                Decodes left-to-right.\n  --decode-cols-right               Decodes right-to-left.\n  --decode-squeeze-lr               Decodes even bits from the left, odd bits\n                                    from right like in the TMS32C15.\n  -z, --zorrom                      Zorrom compatibility mode, with flipx\n                                    before rotation.\n  --leftbank                        Only the left half of the bits.\n  --rightbank                       Only the right half of the bits.\n  -a, --print-bits                  Prints ASCII art of the transformed bits.\n  -A, --print-pretty-bits           Prints ASCII art with spaces.\n  --solve                           Solves for an unknown format.\n  --solve-bytes \u003cbytes\u003e             Bytes as a hint to the solver.\n                                    0:31,1:fe,2:ff\n  --solve-ascii                     Look for ASCII strings.\n  --solve-string \u003cbytes\u003e            Byte string as a hint to the solver.\n                                    31,fe,ff\n  --solve-yara \u003crule\u003e               Yara rule file.\n  --solve-set \u003cprefix\u003e              Exports all potential solutions.\n\nArguments:\n  bitstream                         ASCII art of ROM to decode.\n```\n\n\n## High Level Design\n\nI've designed the GUI around a `QGraphicsScene`.  The underlying data\nobjects use the QT coordinate system, with floats for\nbetter-than-pixel precision.\n\nAfter loading a ROM photograph, the user places Columns and Rows onto\nthe photograph.  Every intersection of a Column and a Row is\nconsidered to be a Bit, and a configurable color threshold determines\nthe value of that Bit.  Where the photograph is misread, you can also\nForce the bit to a known value.\n\nOnce all of the Bits have been marked and the Threshold chosen, the\nsoftware will mark every light bit as Blue (0) and every dark bit as\nRed (1).  These bits are then Aligned into linked lists of rows for\nexport as ASCII, for use in other tools.\n\nTo identify errors, a set of Design Rule Checks (DRC) will critique\nthe open project.  While the primary interface is the GUI, a CLI is\nalso available for scripting and testing.\n\n## Correcting Bit Errors\n\nWhile a few thousand bits might be marked without an error, larger\nprojects will inevitably need to manage their mistakes.\n\nA good start is to use the DRC checks and careful configuration of the\nbit thresholds until no obvious errors remain.  Then navigate the\nproject and hit the `tab` key to show and hide the annotations, making\nsure that each bit is recognized properly.\n\nWhen that is insufficient, such as for ROMs that are tens or hundreds\nof kilobits, it helps to annotate the same ROM multiple times,\npreferably from different photographs.  Bit errors will happen in\nannotating each photograph, of course, but they will happen in\ndifferent places.  You can then use the `--diff-ascii` feature against\nthe output of `--export-ascii` to compare images, reconciling their\ndifferences until all of your project files agree.\n\n## Sampling Algorithms\n\nMost ROMs can be read simply by reading the color of a single pixel at\nthe bit's center.  For those, the `Default` sampling algorithm will\nwork just fine.\n\n![Normal ROM Bits](screenshots/darkbits.png)\n\nFor diffusion ROMs whose bits have been a little too delayered, the\ncenter of the bit does not have a unique color, but it is surrounded\nby slightly darker lines.  The `Wide` algorithm will take the darkest\ncolor in each channel after sampling its size worth of bits in width,\nand `Tall` does the same but vertically.\n\n![Diffusion ROM Bits](screenshots/diffusion.png)\n\n## Development\n\nPatches and improvements to Mask ROM Tool are most welcome, but please\ndo not spam the issue tracker with feature requests.  Pull requests\nshould be submitted through the Github page, and they should not\nentangle the project with dependencies upon third-party libraries.\n\nThe code is written in a conservative dialect of C++, with minimal use\nof advanced features.  I've tried to comment the code and the class\ndefinitions thoroughly.\n\n\n## ROM Decoders\n\n[GatoROM](GATOREADME.md) is included as a command line decoder that\nsolves for bit arrangements.  Please see its own README file for CLI\ndocumentation, particularly for the solver methods that are not yet\nsupported in the GUI.\n\nSeparately, GatoROM is used as a library for decoding within the\nMaskRomTool GUI.  Use Edit/Decoding to define the decoding style and\nView/HexPreview to see a live decoding of the bits to hexadecimal.\n\n![Screenshot of MYK82 decoding.](screenshots/decoder.png)\n\nFrom the decoder, you can highlight hex bytes and use View/Highlight\nHex Selection to visualize the selected bytes.  Here we see the first\nthree words of the [MYK82\nROM](https://github.com/travisgoodspeed/myk82rom), which pack 32 bits\ninto each position.  Most disassemblers operate through the CLI path,\nbut [GoodASM](https://github.com/travisgoodspeed/goodasm) is\nstatically linked.\n\n![Screenshot of selected first three MYK82 words.](screenshots/selection.png)\n\nA scripted solver is also supported, in which simple masks or Yara\nrules describe the expected firmware.  All matches are enumerated, and\nby jumping between them you can quickly decipher images that do not\nuse interleving, row reversal, or other complications.\n\n![Screenshot of the Yara solver.](screenshots/solver.png)\n\n\n## Related Tools\n\nJohn McMaster's [ZorRom](https://github.com/SiliconAnalysis/zorrom) is\nan excellent decoder and the inspiration for the decoding library in\nthis tool.\n\nAdam Laurie's [RomPar](https://github.com/AdamLaurie/rompar) might be\nthe very first bit marking tool to be open sourced.\n\nChris Gerlinsky's\n[Bitract](https://github.com/SiliconAnalysis/bitract/) is another open\nsource tool for bit marking, and\n[Bitviewer](https://github.com/SiliconAnalysis/bitviewer) is his\nmatching tool for decoding bits to bytes.\n\nPeter Bosch's [PLA Decode](https://github.com/peterbjornx/pladecode)\nis a bit marking tool used for extracting old Intel microcode.  See\nhis [Hardwear.io](https://www.youtube.com/watch?v=4oFOpDflJMA) talk\nfrom 2020 for more details.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisgoodspeed%2Fmaskromtool","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftravisgoodspeed%2Fmaskromtool","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftravisgoodspeed%2Fmaskromtool/lists"}