How to WRAP (encrypt/obfuscate) a PL/SQL procedure in Oracle

To WRAP (encrypt/obfuscate) a PL/SQL procedure in Oracle, you can use the Oracle Wrap Utility or the DBMS_DDL.WRAP function.

Below are the correct and practical methods.


1. Using Oracle WRAP Utility (Command Line Method)

This is the most common and recommended way.

Steps

  1. Create a file with your procedure (e.g., proc.sql)
  2. Run the wrap command:

Linux / UNIX

wrap iname=proc.sql oname=proc_wrapped.sql

Windows

wrap iname=proc.sql oname=proc_wrapped.sql

Your output file (proc_wrapped.sql) will contain unreadable wrapped code.


Example

File: proc.sql

CREATE OR REPLACE PROCEDURE test_wrap AS
BEGIN
   DBMS_OUTPUT.PUT_LINE('Hello');
END;
/

Run:

wrap iname=proc.sql oname=proc_wrapped.sql

Output file will contain something like:

CREATE OR REPLACE PROCEDURE test_wrap wrapped 
a000000
abcd123...

2. Wrap Using PL/SQL (DBMS_DDL.WRAP)

You can wrap code inside SQL*Plus, SQL Developer, or any PL/SQL session.

Example

SELECT DBMS_DDL.WRAP(
'CREATE OR REPLACE PROCEDURE test_wrap AS
 BEGIN
   DBMS_OUTPUT.PUT_LINE(''Hello'');
 END;'
) FROM dual;

It returns the wrapped PL/SQL code, which you can copy-paste and compile.


Output Example

CREATE OR REPLACE PROCEDURE test_wrap wrapped
a000000
abcd1234...

3. Wrap Using SQL Developer (GUI)

  1. Open your procedure in SQL Developer

  2. Right-click → Wrap

  3. SQL Developer generates the wrapped code automatically

❗ Works only in some versions of SQL Developer.


Important Notes About WRAPPING

  • Wrapping does NOT fully encrypt; it only obfuscates the code.
  • It protects logic from casual viewing, but not 100% secure.
  • Do NOT include comments in wrapped code—they are removed.
  • Always keep an unwrapped backup of your source code.


1. Script to Wrap a Single PL/SQL Program (Procedure/Function/Package)

SET LONG 200000 LONGCHUNKSIZE 200000 PAGESIZE 0 LINESIZE 2000 TRIMSPOOL ON
SPOOL wrapped_output.sql

SELECT DBMS_DDL.WRAP(
        REPLACE(
           DBMS_METADATA.GET_DDL(object_type, object_name, owner),
           'CREATE OR REPLACE', 'CREATE OR REPLACE'
        )
       ) AS wrapped_code
FROM dba_objects
WHERE owner = UPPER('&SCHEMA')
AND object_name = UPPER('&OBJECT_NAME')
AND object_type IN ('PROCEDURE','FUNCTION','PACKAGE','PACKAGE BODY');

SPOOL OFF;

2. Script to Wrap ALL PL/SQL Objects in a SCHEMA (Automated)

This script generates all wrapped code in a directory.

Run as a privileged user (or grant metadata access)

Step 1 — Set Output Directory

ALTER SESSION SET LONG=2000000;
ALTER SESSION SET LONGCHUNKSIZE=2000000;

Step 2 — Generate wrapped code for all procedures, functions, packages

SET PAGESIZE 0 LONGCHUNKSIZE 200000 LONG 200000 LINESIZE 2000 TRIMSPOOL ON FEEDBACK OFF

SPOOL all_wrapped_code.sql

SELECT DBMS_DDL.WRAP(DBMS_METADATA.GET_DDL(object_type, object_name, owner))
FROM   dba_objects
WHERE  owner = UPPER('&SCHEMA')
AND    object_type IN ('PROCEDURE', 'FUNCTION', 'PACKAGE', 'PACKAGE BODY')
ORDER BY object_type, object_name;

SPOOL OFF;

Output file:
📄 all_wrapped_code.sql → fully wrapped code for the entire schema.


3. Batch Wrap Script Using OS Wrap Utility (Fastest & Best)

Step 1 — Export all PL/SQL source into files

SET HEADING OFF FEEDBACK OFF LONG 500000
SPOOL ddl_extract.sql

SELECT DBMS_METADATA.GET_DDL(object_type, object_name, owner)
FROM   dba_objects
WHERE  owner = UPPER('&SCHEMA')
AND    object_type IN ('PROCEDURE','FUNCTION','PACKAGE','PACKAGE BODY');

SPOOL OFF;

Step 2 — Run wrap for all files in Linux

Place all .sql files in a folder then run:

for file in *.sql
do
    wrap iname=$file oname=wrapped_$file
done

Windows Version

for %%f in (*.sql) do (
  wrap iname=%%f oname=wrapped_%%f
)

This generates wrapped versions of all PL/SQL programs automatically.


4. Creating a Stored Procedure to Wrap PL/SQL Automatically

This PL/SQL procedure wraps any object dynamically:

CREATE OR REPLACE PROCEDURE wrap_object (
    p_owner       VARCHAR2,
    p_object_name VARCHAR2,
    p_object_type VARCHAR2
) AS
    v_source CLOB;
    v_wrapped CLOB;
BEGIN
    v_source :=
        DBMS_METADATA.GET_DDL(
            object_type => p_object_type,
            name        => p_object_name,
            schema      => p_owner
        );

    v_wrapped := DBMS_DDL.WRAP(v_source);

    DBMS_OUTPUT.PUT_LINE('Wrapped Code for ' || p_object_type || ' ' || p_object_name || ':');
    DBMS_OUTPUT.PUT_LINE(v_wrapped);
END;
/

Usage:

EXEC wrap_object('MYSCHEMA','MYPROC','PROCEDURE');


Post a Comment

And that's all there is to it!

If anyone has any other questions or requests for future How To posts, you can either ask them in the comments or email me. Please don't feel shy at all!

I'm certainly not an expert, but I'll try my hardest to explain what I do know and research what I don't know.

Previous Post Next Post