Oninit Logo
The Down System Specialists
+1-913-732-8892
+44-2081-337529
Partnerships Contact

Oninit® Forensic Tools — ondebug CLI

ondebug is a single-file C front-end over the ondebug library, modelled after the Oninit reference tools ondump and onpatch. One invocation reads one encrypted page from a chunk file and emits the plaintext — either as a hex dump on stdout or as raw bytes to a file. With -w it also patches a single plaintext byte and writes the re-encrypted page back to the chunk in place.

Usage

ondebug -P <page_index> [-C <chunk_id>] [-p <page_size>]
        [-O | -x | -o <out.bin>
         | -w --row <hex> --col <hex> --value <hex>
         | -w --offset <hex> --value <hex>] <chunk_file>

# alternative key-material forms (no SEK file required at decrypt time):
ondebug --keystore <base> --dbsnum <N> -P <page_index> … <chunk_file>
ondebug --mek <file>      --dbsnum <N> -P <page_index> … <chunk_file>

# minimal form when $INFORMIXDIR is set (keystore + dbsnum auto-detected):
ondebug -P <page_index> -C <chunk_id> <chunk_file>

The standard read invocation reduces to the page address (-P / -C) and the chunk file. Page size auto-detects by decrypting page 1 at each candidate size and validating the post-decrypt storage-identity stamp; the cipher and mode default to Informix EAR's values. Each can be overridden when the situation calls for it.

Flags

  • -P N — logical page index in the chunk (required). Numeric argument; accepts hex (0x…), decimal, or octal.
  • -C N — chunk_id (default 0). Numeric, hex / decimal / octal.
  • -p N — page size in bytes (must be a positive multiple of 16). Optional; defaults to auto-detection by decrypting page 1 at each candidate size (2048, 4096, 6144, 8192, 16384) and validating the post-decrypt storage-identity stamp (page index in bytes 0..3, chunk id in bytes 4..5). Pass explicitly when the chunk file contains fewer than two pages, or when the SEK or chunk_id is wrong — in those cases auto-detect fails by design rather than locking onto a wrong size.
  • -Ooncheck-format pretty-print (header line, slot table, slot bodies) instead of a flat hex dump. See the Examples page for output.
  • -o FILE — write raw plaintext bytes to FILE.
  • -x — force hex dump to stdout. The hex dump format includes a column-index header row (00 01 02 … 0f) so each byte is addressable as row R, col C.
  • -w — patch mode: decrypt the page, splice one plaintext byte at the addressed position, re-encrypt the page, and pwrite the new ciphertext back to the chunk file in place. Required companion long options:
    • --value <hex> — the byte to write (00..ff). Always required when -w is set.
    • --row <hex> + --col <hex> — matrix-form addressing. Row is a hex byte offset, 16-byte aligned, copied straight off the column header in the hex dump; col is 0..f within that row.
    • --offset <hex> — flat byte offset within the page. Mutually exclusive with --row + --col.
    The engine MUST be offline before -w — the buffer cache otherwise serves the old in-memory copy on read and the next checkpoint flushes the cached page back, overwriting the patch. The CLI does NOT enforce this; the Patching examples page documents the full onmode -ky → -w → oninit -vw cycle.

Key material flags

For invocations that read the live keystore directly (instead of the default cached-SEK lookup — see the Examples — reading page §"Key material" for the two flows side-by-side):

  • --keystore <base> — keystore base path, with no .p12 / .sth suffix (e.g. /home/informix/live/etc/db_keystore). When set, ondebug reads the key from the live keystore in-process, so no separate key file is required at decrypt time. Optional when $INFORMIXDIR is set — if omitted, ondebug reads $INFORMIXDIR/etc/$ONCONFIG's DISK_ENCRYPTION line and auto-discovers the keystore path. Mutually exclusive with --mek.
  • --mek <file> — supply a 32-byte key file directly instead of reading the keystore. Useful when the keystore isn't accessible at decrypt time but the key is (key-escrow handover, prior-engagement capture). Requires --dbsnum; mutually exclusive with --keystore.
  • --dbsnum N — target dbspace number (1..65535). Tells ondebug which dbspace's key to use. Optional in keystore / MEK mode: if omitted, ondebug reads the rootdbs chunk descriptor table (path from $ONCONFIG's ROOTPATH) and matches the target chunk file's basename to pick the owning dbspace number automatically. Pass explicitly when auto-detect fails (e.g. chunk file renamed, operating on a chunk not in the rootdbs descriptor table). The operator looks this up via onstat -d's number column.

Crypto-context overrides (rarely needed)

  • -c NAME — cipher: aes128, aes192, or aes256 (default aes256, matching Informix EAR).
  • -m NAME — mode: ecb, cbc, ctr, gcm, xts, or cfb (default cfb, matching the empirically-observed EAR transform — see Phase C Findings).

Exit codes

  • 0 — success.
  • 1 — I/O or library error (chunk file unreadable, SEK length wrong for cipher, mode/cipher not implemented, short read).
  • 2 — usage error (missing required flag, bad numeric).

Output format

With -o FILE, the page's plaintext bytes are written to FILE verbatim (exactly page_size bytes).

Without -o, the page is hex-dumped to stdout in the standard 16-bytes-per-row format with a column-index header (00 01 02 … 0f), the row offset prefix, and an ASCII gutter:

          00 01 02 03 04 05 06 07 08 09 0a 0b 0c 0d 0e 0f
00000000  36 00 00 00 04 00 e1 1b 02 00 01 00 e8 00 0c 07  |6...............|
00000010  00 00 00 00 00 00 00 00 00 00 00 01 49 6e 66 6f  |............Info|
00000020  72 6d 69 78 20 69 73 20 70 75 72 65 20 64 65 61  |rmix is pure dea|
…

The header row makes a byte position addressable as row R, col C — e.g. the page-header nslots field at row 0x00, col 08–09 reads as 0x0002.

With -w, no stdout output is produced — the page is modified on disk in place. A confirmation line goes to stderr:

ondebug: patched chunk=4 page=54 offset=0x32 (row=0x30 col=0x2): 0x62 -> 0x42

Subcommands

The default mode (page decrypt + optional patch, documented above) is the unnamed primary invocation. ondebug also accepts named subcommands for operations that don't fit the per-page read/write model.

rm-dbspace — offline dbspace removal

ondebug rm-dbspace --dbsnum <N> [--apply] [--backup] <rootdbs>
  • --dbsnum N — target dbspace number to remove. Required. Rootdbs (dbsnum 1) and the physical-log dbspace are refused; other dbspaces are accepted.
  • --apply — without this flag ondebug prints the planned edit and exits without writing (dry-run). With --apply the edit is committed to the rootdbs image file.
  • --backup — write a timestamped pre-edit backup before the --apply write. Required to combine with --apply; ondebug rejects --apply without --backup to keep a rollback path on disk.
  • <rootdbs> — path to the rootdbs chunk file. The engine MUST be offline; editing rootdbs while the engine has it open invites torn writes.

See Examples — dropping a dbspace for the full worked run.

unload-page — readable dump of one page

ondebug unload-page -P <page_index> [-C <chunk_id>] [-p <page_size>]
        [--unload-to <path>] <chunk_file>

Read-only render: decrypts the page, prints its slot table (always), and prints each slot's body in oncheck-format hex+ASCII when the page is a DATA page (header flag = 1). For any other page type (chunk reserved, freelist, bitmap, …) the slot table is shown and the slot bodies are skipped with a one-line non-DATA page (flag=N); slot bodies suppressed note. The render is byte-identical to the legacy -O mode on DATA pages.

  • --unload-to <path> — redirect the render to a named file (use - for stderr, the default). The flag also enables unload mode on its own — --unload-to without the unload-page subcommand prefix produces the same output.
  • -P / -C / -p / -k / --keystore / --mek / --dbsnum / -c / -m — same flag set as the page-decrypt primary mode; see §Flags + §"Key material flags" above. Page size and (in keystore mode) dbsnum auto-detect.

Mutually exclusive with -w / -O / -x / -o: pick one render per invocation.

rm-page — offline single-page removal from a table

ondebug rm-page --partpage <P> --target <T> [-C <chunk_id>]
                [-p <page_size>] [--unload-to <path>]
                [--apply] [--backup] <chunk_file>

Removes one page from a table by editing the owning partition page's extent map and aggregate counters. The operator looks up the partition page address via oncheck -pT <db>:<tab> (Physical Address column) and passes it as --partpage; the page to remove is --target. Before any edit, the target page is rendered via the same render unload-page produces (slot table + DATA bodies) so the operator sees what content is being orphaned.

  • --partpage P — page index of the owning partition page (header flag = 2). Required.
  • --target T — page index to remove from the partition. Required. Must be claimed by an extent of --partpage; must not equal --partpage.
  • --apply — commit the edit (default: dry-run prints the planned edit + the unload, exits without writing).
  • --backup — write a 2 KB sidecar containing the original ciphertext of the partition page; required when --apply is set. Rollback is dd if=<backup> of=<chunk_file> bs=<page_size> seek=<P> conv=notrunc.
  • --unload-to <path> — redirect the pre-removal target-page render to a named file (default: stderr).
  • -C / -p / key-material flags — same flag set as the page-decrypt primary mode; auto-detect applies.

The four edit cases (sole-page extent, first page, last page, interior split) are detected automatically from the target's position within its extent. Descriptor counters (npused, npdata, nrows) are recomputed; chksum is recomputed per the V14 5-XOR formula. Engine MUST be offline.

See Examples — removing a page for the full worked run.

Examples

With key material in place and page size auto-detected, the standard form is just the page address and the output flag:

oncheck-format dump of encryptdbs page 54

ondebug -P 54 -C 4 -O /home/informix/data/encryptdbs

Hex dump of the same page (with column-index header)

ondebug -P 54 -C 4 /home/informix/data/encryptdbs

Decrypt to a binary file for further analysis

ondebug -P 54 -C 4 -o /tmp/page54_plain.bin \
        /home/informix/data/encryptdbs
xxd /tmp/page54_plain.bin | head

Decrypt against a live keystore (no SEK file required)

ondebug --keystore /home/informix/live/etc/db_keystore \
        --dbsnum 4 \
        -P 54 -C 4 -O /home/informix/data/encryptdbs

ondebug reads the key in-process from the live keystore; no ~/.ondebug/sek.bin cache file is required at decrypt time. See the Examples — reading page §"Key material" for the two key-source flows side-by-side.

Same decrypt with keystore and dbsnum auto-detected

ondebug -P 54 -C 4 -O /home/informix/data/encryptdbs

With $INFORMIXDIR and $ONCONFIG set, ondebug reads the keystore path from $ONCONFIG's DISK_ENCRYPTION line and reads the dbspace number from the rootdbs chunk descriptor table by matching the target chunk's basename. The bare form is equivalent to the explicit --keystore + --dbsnum form above when both sources are available; pass either flag explicitly to override.

Unload one page's slot table + row bodies to stderr

ondebug unload-page -P 54 -C 4 /home/informix/data/encryptdbs

Renders the page's slot table and (since flag=1, DATA) each slot's row bytes in hex+ASCII to stderr. With $INFORMIXDIR set the keystore + dbsnum auto-detect; otherwise pass --keystore + --dbsnum or -k explicitly.

Same render to a named file

ondebug unload-page -P 54 -C 4 \
        --unload-to /tmp/page54_unload.txt \
        /home/informix/data/encryptdbs
cat /tmp/page54_unload.txt

Remove a page from a table (dry-run)

oncheck -pT testdb:test_enc                # → Physical Address 4:5
                                           # → Extent at logical 0: 4:53 size 8
ondebug rm-page --partpage 5 --target 54 -C 4 \
        /home/informix/data/encryptdbs

Renders the target page (slot table + DATA rows) to stderr, then prints the planned edit: case (d) interior split of extent {start=53, count=8} into {start=53, count=1} + {start=55, count=6}; descriptor counters npused 2→1, npdata 1→0, nrows 2→0. No write happens without --apply.

Commit the removal (engine offline)

onmode -ky                                # take the engine offline first
ondebug rm-page --partpage 5 --target 54 -C 4 \
        --apply --backup \
        /home/informix/data/encryptdbs
oninit -vw                                # bring the engine back up

--backup writes a 2 KB sidecar of the original partition page next to the chunk file (path <chunk_file>.rm-page-<P>.<timestamp>); rollback is dd if=<sidecar> of=<chunk_file> bs=<page_size> seek=<P> conv=notrunc.

Patch one byte (engine offline)

onmode -ky                                # take the engine offline first
ondebug -P 54 -C 4 \
        -w --row 0x30 --col 0x02 --value 0x42 \
        /home/informix/data/encryptdbs
oninit -vw                                # bring the engine back up

Decrypts page 54, flips the byte at row 0x30, column 0x02 to 0x42, re-encrypts the page, and writes the new ciphertext back to the chunk file in place. See the Patching examples page for the full round trip with dbaccess verification.

To discuss how Oninit ® can assist please call on +1-913-732-8892 or alternatively just send an email specifying your requirements.


You get all this for free.. think about what you get if you pay us