The case
A customer recovered an Oracle database that had been hit by ransomware. They used DBRECOVER (then under the legacy Parnassus DUL name, community edition) and successfully bridged user tables into a fresh Oracle instance — table data is back. However, the migration left out the schema-level DDL: views, procedures, packages, package bodies, functions, triggers, sequences, and synonyms. The DDL export menu lists those objects, but the community/trial license caps row export, and the question is whether there is a way to preview or recover them before paying for the enterprise license.
Short answer
Yes. Use the current build of DBRECOVER for Oracle, run the Examine Row Count step on every relevant SYS base table, and read the PL/SQL source and view text directly from SYS.SOURCE$ and SYS.VIEW$. The trial license limits how many rows you can export, but the row preview and DDL extraction in dictionary mode can usually reconstruct the missing DDL without exporting the entire base table at once.
Step 1 — install the current build
The legacy 5.x community release predates several DDL-recovery improvements. Download the current build:
https://s.dbrecover.com/dbrecover-for-oracle-latest-dist.zip
Re-open the same recovered datafiles in dictionary mode (assuming SYSTEM01.DBF is still readable). If the SYSTEM tablespace was damaged by ransomware, enable SCAN BASE TABLES so the tool stitches the dictionary back together from surviving blocks.
Step 2 — use Examine Row Count
The Examine Row Count function scans the data dictionary base tables and reports how many rows survived in each. It is the fastest way to confirm whether DDL recovery is even feasible before committing to an export.
Reference walkthrough video: https://youtu.be/vRZZR1YApFg
After the scan, look for non-zero counts in these base tables. If they all read zero, the SYSTEM tablespace is too damaged for in-place DDL recovery and you should switch to non-dictionary mode plus an external DDL backup.
Step 3 — where the missing DDL actually lives
Oracle stores every form of DDL inside SYS-owned base tables in SYSTEM01.DBF. Each base table is browsable in DBRECOVER once dictionary mode is loaded:
| Base table | What it stores | How to read it |
|---|---|---|
SYS.SOURCE$ |
Source code lines for procedures, functions, packages, package bodies, types, type bodies, triggers | Join with SYS.OBJ$ on OBJ# for the object name; lines are ordered by LINE |
SYS.VIEW$ |
View definitions (the SELECT text) | Join with SYS.OBJ$; the TEXT column is the view body |
SYS.TRIGGER$ |
Trigger headers and bodies (ACTION#, WHENCLAUSE) |
Join with SYS.OBJ$ for the trigger name and table |
SYS.SEQ$ |
Sequence definitions (min, max, increment, cycle, cache) | Join with SYS.OBJ$ for the sequence name |
SYS.SYN$ |
Synonyms (public and private) | Read directly; OWNER + NAME + NODE + target |
SYS.CON$ / SYS.CDEF$ |
Constraint names, definitions, and types (PK/UK/FK/CHECK) | Join through OBJ# to map back to tables |
SYS.IND$ / SYS.ICOL$ |
Indexes and indexed columns | Use to rebuild CREATE INDEX statements |
SYS.OBJ$ |
Object directory: every object name, owner, type, status | The lookup table for every base-table join above |
SYS.USER$ |
User accounts (username, password hash, default tablespace) | Useful to recreate schemas with the right defaults |
Step 4 — extract the missing PL/SQL from SOURCE$
To rebuild PL/SQL DDL by hand:
- Open
SYS.SOURCE$in DBRECOVER's data browser. - Filter or sort by
OBJ#. EachOBJ#represents one PL/SQL object. - Cross-reference
OBJ#againstSYS.OBJ$to retrieveOWNER#,NAME, andTYPE#(7=PROCEDURE, 8=FUNCTION, 9=PACKAGE, 11=PACKAGE BODY, 12=TRIGGER, 13=TYPE, 14=TYPE BODY). - Read the
SOURCEcolumn line by line inLINEorder. Concatenated lines reproduce the originalCREATE OR REPLACEbody verbatim. - Wrap the result with the appropriate
CREATE OR REPLACEheader and a trailing slash, then run it against the recovered Oracle instance.
For views, repeat the same flow against SYS.VIEW$: the TEXT column already contains the full SELECT body. Wrap it with CREATE OR REPLACE VIEW <owner>.<name> AS.
Trial-license considerations
The community / trial license caps each table's export at 10,000 rows. SYS.SOURCE$ stores one row per source line, so a large application schema can easily exceed the cap on this single table. Two practical workarounds before paying:
- Browse-and-copy in pages. The on-screen row preview is not subject to the export cap. You can scroll through the rows for a single
OBJ#, copy the source lines, and paste them into a SQL file. This is enough to recover the most critical packages and procedures. - Per-object filtering. Filter by a single
OBJ#at a time. A typical PL/SQL package body is well under 10,000 lines, so each filtered export fits comfortably inside the cap.
For triggers, sequences, synonyms, and constraints, the row counts are usually small enough that a normal filtered export stays under the cap.
If the SYSTEM tablespace was destroyed
Some ransomware variants encrypt SYSTEM01.DBF heavily enough that OBJ$, SOURCE$, and VIEW$ are unrecoverable. In that case the dictionary route is closed and DDL has to come from outside the database:
- A previous
expdpdump (even a metadata-only one) — re-import withimpdp ... CONTENT=METADATA_ONLYto land DDL into a fresh schema. - Source control: most teams keep DDL in Git, Liquibase, or Flyway. Reapply from there.
- Application installer scripts that ship with the product.
- An older
RMANbackup of the SYSTEM tablespace specifically — even an old one is enough for DDL since DDL changes slowly.
Post-ransomware hardening checklist
Once the data is back, fix the conditions that allowed encryption in the first place. Otherwise the next attacker re-encrypts what you just recovered:
- Patch the entry point — typically RDP or SSH exposed to the internet, an unpatched Oracle CPU, or a leaked SYS / SYSTEM password.
- Rotate all database passwords (
SYS,SYSTEM, schema owners, application users). - Move backups off the same host and the same domain. Ransomware that reaches the database almost always reaches network shares too.
- Enable Oracle Database Vault or at minimum strict
O7_DICTIONARY_ACCESSIBILITY=FALSEand audit DBA logins. - Verify backups by doing a full restore to a sandbox, not just a backup completion message.
If you need help running through SOURCE$ / VIEW$ extraction on your specific datafiles, contact [email protected] with the database version, the file list, and a short description of which DDL objects you need first.
DBRECOVER Recovery Options
For Oracle incidents, start with the DBRECOVER for Oracle trial to verify table visibility, row previews, and export readiness on copied datafiles. For MySQL and InnoDB incidents, DBRECOVER for MySQL is free software and can inspect.ibd files, ibdata1, and database directories locally.
When the case is urgent, preserve the original files first, work from copies, and contact paid emergency support with the database version, platform, error messages, file list, and recovery objective.