Code Obfuscation (WRAP)
Wrapping converts PL/SQL source into an unreadable, portable form so you can ship code without exposing its logic. The wrapped unit still compiles and runs identically — only the human-readable source is hidden. Oracle offers two ways to wrap: the command-line wrap utility for whole files, and the DBMS_DDL package for dynamic, in-database wrapping.
The Command-Line wrap Utility
wrap is an OS-level tool that reads a .sql file of CREATE OR REPLACE statements and writes an obfuscated .plb file:
wrap iname=emp_pkg_body.sql oname=emp_pkg_body.plb
You then run the .plb exactly like the original script. After it is installed, the source in the data dictionary is the wrapped (unreadable) text:
-- Install the wrapped version
@emp_pkg_body.plb
-- The stored source is now obfuscated
SELECT text
FROM user_source
WHERE name = 'EMP_MGR' AND type = 'PACKAGE BODY'
FETCH FIRST 3 ROWS ONLY;
-- => "PACKAGE BODY emp_mgr wrapped\n a000000\n b2\n abcd... (gibberish)"
Dynamic Wrapping with DBMS_DDL
When you generate PL/SQL at runtime, DBMS_DDL wraps it without a separate file step:
DBMS_DDL.WRAP(ddl)— takes aCREATE OR REPLACEstring and returns the wrapped string.DBMS_DDL.CREATE_WRAPPED(ddl)— wraps and executes the statement in one call.
DECLARE
v_src VARCHAR2(32767) :=
'CREATE OR REPLACE FUNCTION secret_bonus(p_sal NUMBER) RETURN NUMBER IS
BEGIN
RETURN p_sal * 0.137; -- proprietary formula
END;';
BEGIN
-- Create the function directly in wrapped form
DBMS_DDL.CREATE_WRAPPED(v_src);
END;
/
-- secret_bonus works normally, but its body is not readable in USER_SOURCE
SELECT secret_bonus(10000) FROM dual; -- 1370
What Can (and Cannot) Be Wrapped
| Wrappable | Not wrappable |
|---|---|
| Package bodies | Package specifications (callers must see the interface) |
| Type bodies | Object type specifications |
| Standalone procedures & functions | Triggers |
| — | Anonymous blocks |
Important Limitations
Wrapping is obfuscation, not encryption. It raises the effort required to read your logic, but publicly available "unwrapper" tools can partially reverse it, and it provides no protection for data. Treat it as a deterrent against casual inspection, not as a security control.
.plb is a build artifact, never your master copy. You also cannot wrap across versions blindly: wrap with the oldest Oracle release you must support, since a newer wrap format may not load on an older database.
Verifying a Unit Is Wrapped
-- The first stored source line of a wrapped unit contains the word "wrapped"
SELECT name, type
FROM user_source
WHERE line = 1
AND LOWER(text) LIKE '%wrapped%';
Practical Workflow
- Develop and test with plain, readable source under version control.
- As a release step, wrap the package/type bodies you distribute (via
wraporDBMS_DDL). - Ship the readable specs plus the wrapped bodies to the customer.
- Keep the un-wrapped master safe — it is the only editable copy.
Summary
- Wrapping obfuscates PL/SQL source while leaving behaviour unchanged.
- The command-line
wrap iname=… oname=…utility wraps a whole.sqlfile into a.plb. DBMS_DDL.WRAPreturns wrapped text;DBMS_DDL.CREATE_WRAPPEDwraps and executes dynamically.- Wrap bodies (package, type) and standalone subprograms; you cannot wrap specs, triggers, or anonymous blocks.
- It is obfuscation, not encryption — unwrappers exist; never rely on it to protect secrets or data.
- Wrapped code can't be edited — keep the original source in version control and wrap with the oldest supported release.