Rocq - Coq
Coq (now Rocq) is a proof assistant, and its compiled artifacts are not machine code at all: a .vo file holds the serialized terms of a development and the companion .glob file lists the names and cross-references. Reversing one means reading the inductive types and definitions, for example following a match that maps one constructor to another rather than disassembling instructions.
Inspecting a compiled module
Do not try to parse the binary .vo by hand (it is a marshalled OCaml structure). Instead, load it back into the toplevel and let Coq print the source-level terms.
Put the file on the load path and
Requireit, thenPrintits contents. The module name is the.vofilename, and-R/-Qmaps the physical directory to a logical path.# coqtop (or rocqtop on recent versions). The .vo must be built with a # compatible compiler version. coqtop -R . TopRequire Import Top.a. (* a.vo *) Print All. (* every inductive and definition of the module *) Print myFunction. (* a specific definition *) Search _ (_ -> _). (* find terms by type *)The companion
.globfile is plain text and lists every defined and referenced identifier with its kind and position. Read it directly to recover the names toPrint, even when no source is available.Other useful tools:
coqchktypechecks a.vostandalone, SerAPI (sertop) serializes terms programmatically, and coq-dpdgraph draws the dependency graph between definitions.
Reading the logic as a graph
A definition that decides something is usually a match over the constructors of an inductive type. Read the body as a mapping from constructor to constructor and treat it as a directed graph:
- the start is the constructor that is a source but never a target,
- follow each edge until you reach the terminal (a success/identity case),
- a decoy terminal is often present but never produced.
The constructor names along the path frequently spell the answer directly, so recovering the flag is just a matter of walking the chain in order.