Verify a Mono Assembly with pedump
pedump opens a .NET assembly, dumps its PE and CLI headers, and runs Mono's IL verifier so you can catch a broken build before it ships. This guide uses the pedump shipped by Debian's mono-utils package, version 6.8.0.105+dfsg-3.6ubuntu2.
The route
Jump straight to the step you need, or tick off Done means at the end.
Allow about fifteen minutes. You need a shell, mono-utils, and an .exe or managed .dll to examine. Every example here only reads the input file: no repair, no rewrite, no signing, no execution, so no elevated privileges are normally needed.
1. Confirm the local command
Skip the manpage: pedump does not ship one and just points you at its help switch. Treat the binary on your machine as the contract, because pedump's interface is not a general-purpose .NET standard.
$ command -v pedump
/usr/bin/pedump
$ dpkg-query -W -f='${Package} ${Version}\n' mono-utils
mono-utils 6.8.0.105+dfsg-3.6ubuntu2
$ pedump --help
Usage is: pedump [--verify error,warn,cls,all,code,fail-on-verifiable,non-strict,valid-only,metadata] file.exe
Tip
The help command exits with status 1 on this installation after printing its usage line. Never use the exit status of --help as a health check for the utility; the useful part is the command shape and the verify modes it lists.
Checkpoint
If command -v finds nothing, stop here and install the distribution's Mono utilities through your normal package-management process. Do not download an unrelated binary merely because a blog example uses the same name.
2. Inspect the PE and CLI headers
Run pedump against a known assembly path, with the path in a quoted shell variable if it is not a fixed literal. A normal invocation prints the file's COFF, PE and managed metadata details:
$ ASSEMBLY='/path/to/application.exe'
$ pedump "$ASSEMBLY" | sed -n '1,35p'
COFF Header:
Machine: 0x014c
Sections: 0x0003
...
PE Header:
Magic (0x010b): 0x010b
Entry Point RVA: 0x000022fe
The exact numbers depend on the input and the compiler. The real first question is whether pedump can parse the image at all: a file extension is not proof that a file is a managed assembly, and a native Windows PE file is not automatically a suitable input.
Capture the status separately if this is going into a script:
if pedump "$ASSEMBLY" >/tmp/pedump-report.txt 2>/tmp/pedump-error.txt; then
printf '%s\n' 'pedump opened the image'
else
status=$?
printf 'pedump could not inspect the image, status %s\n' "$status" >&2
exit "$status"
fi
3. Run verification on a copy or build output
Use --verify to ask Mono to check the assembly's structure and IL. The argument is a comma-separated selection from the modes --help shows. Start with all for the broadest check this installed tool exposes:
$ pedump --verify all "$ASSEMBLY"
$ status=$?
$ printf 'verification status: %s\n' "$status"
verification status: 0
Checkpoint
A clean, ordinary assembly can print nothing and return 0. Silence is expected output here, not evidence the command was skipped. Redirect to a log when a build or audit needs a record:
report='/tmp/pedump-verify.txt'
if pedump --verify all "$ASSEMBLY" >"$report" 2>&1; then
printf 'verification passed: %s\n' "$report"
else
status=$?
printf 'verification failed or could not inspect the image, status %s\n' "$status" >&2
sed -n '1,80p' "$report" >&2
exit "$status"
fi
Warning
Do not overwrite the original assembly while investigating it. This command is read-only, but a later repair or signing step may not be. Keep the report and the original file together until you have decided what happens next.
4. Choose a narrower verification mode
The local help lists nine selectors. They are not interchangeable labels for a generic lint command:
metadatachecks the metadata side of the image.codefocuses the request on code verification.valid-onlyandnon-strictchange how verification treats accepted or strict cases; use them only when your build or compatibility policy calls for that distinction.fail-on-verifiablechanges failure handling, so read the exit status rather than trust the displayed text.error,warn,clsandallare the remaining selectors;allis the broadest, the others narrow the check to one class of problem.
This records a metadata-only check without claiming the method bodies were fully tested:
$ pedump --verify metadata "$ASSEMBLY"
$ printf 'metadata check status: %s\n' "$?"
metadata check status: 0
Use one mode at a time while diagnosing a failure. Once you know which category matters, combine selectors only if the output and status still have a clear meaning for your pipeline.
5. Separate input errors from verification findings
A path can fail before verification even starts. Here is the distinction, using a deliberately invalid temporary file:
$ printf '%s\n' 'not an assembly' >/tmp/not-an-assembly.bin
$ pedump /tmp/not-an-assembly.bin
Cannot open image /tmp/not-an-assembly.bin
$ printf 'status: %s\n' "$?"
status: 1
That result means pedump could not open the image. It does not prove the file contains invalid IL, and running verification again with a different selector will not fix it. Check the path, permissions and file type first. If the input came from an untrusted source, preserve it for analysis and do not execute it with Mono or another runtime.
A non-zero result from a file that does open needs the diagnostic output as well as the status. Save both streams, identify the failing assembly and method if reported, then compare the build artefact with a freshly produced copy. Do not suppress warnings in a release gate until you have documented why that is acceptable.
6. Keep the boundary clear
pedump inspects and verifies. It does not run the program, load it into a service, change its metadata or apply a signature. It also does not prove an assembly is trustworthy: a file can be structurally valid and still be malicious, inappropriate or built from the wrong source.
Warning
Use elevated privileges only if the input is readable exclusively by another account and your normal access-control process permits inspection. Do not make the assembly world-readable as a shortcut.
If you copied a report or test file into /tmp, remove only that known temporary file after review:
$ rm -- /tmp/pedump-verify.txt /tmp/not-an-assembly.bin
This cleanup is optional and touches only the named temporary files. There is nothing to undo in the assembly itself, because none of the pedump commands above modified it.
Done means
- Confirmed the tool. You checked the installed pedump path and Mono utilities version.
- Checked the input opens. You verified pedump can read the file before trusting any verification result.
- Ran the full check. You ran
--verify all, captured its output and checked the exit status. - Told errors apart. You can distinguish an unreadable or non-PE input from a genuine verification finding.
- Used narrow modes deliberately. Any narrower selector had a stated diagnostic or build-policy reason.
- Left the assembly untouched. Nothing was executed, rewritten, signed or published.