Sunday, June 01, 2014

Wrap Utility

This is an example using the wrap utility, which allows you to hide stored code. Software suppliers can use it to prevent customers stealing their PL/SQL. First I created a table:
 
SQL> create table name_list
  2  as select 'ANDREW' name from dual
  3  /
 
Table created.
 
SQL> select * from name_list
  2  /
 
NAME
------
ANDREW
 
SQL>
 
Then I created a procedure to add names to the table:
 
SQL> create or replace procedure add_name
  2   (new_name char) as
  3  begin
  4   insert into name_list values(new_name);
  5  end;
  6  /
 
Procedure created.
 
SQL>
 
... and I tested it as follows:
 
SQL> execute add_name('BRIAN');
 
PL/SQL procedure successfully completed.
 
SQL> select * from name_list
  2  /
 
NAME
------
ANDREW
BRIAN
 
SQL>
 
The procedure was easy to see in the database so anybody could have stolen it:
 
SQL> l
  1  select text from dba_source
  2  where name = 'ADD_NAME'
  3* order by line
SQL> /
 
TEXT
-------------------------------------------------------
procedure add_name
(new_name char) as
begin
insert into name_list values(new_name);
end;
 
SQL>
 
The wrap utility was stored here:
 
ORACLE11 > which wrap
/oracle/app/oracle/product/11.2.0/bin/wrap
ORACLE11 >
 
I ran it on the source code. To do this you supply the name of the file containing the code to be wrapped as the iname parameter and the name of the file to store the wrapped code as the oname parameter:
 
ORACLE11 > cat procedure.sql
create or replace procedure add_name
(new_name char) as
begin
insert into name_list values(new_name);
end;
/
ORACLE11 > wrap iname=procedure.sql \
> oname=wrapped_procedure.sql
 
PL/SQL Wrapper: Release 11.2.0.1.0- 64bit Production on Thu Nov 03 13:07:53 2011
 
Copyright (c) 1993, 2009, Oracle.  All rights reserved.
 
Processing procedure.sql to wrapped_procedure.sql
ORACLE11 >
 
This encrypted the source code as follows:
 
ORACLE11 > cat wrapped_procedure.sql
create or replace procedure add_name wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
5b 92
d6K98qP2M1tFArx52RBb3rXsyPgwg5nnm7+fMr2ywFxaWaH0cgxHLkMJUKXHstD+x9IyXLgz
uHQlw7h0i8DAMv7Shgml0pmfsp77Caj5nspECCJBr6ieOEoia+KvuEzsPHHiP9E8dKYY7AS4
 
/
ORACLE11 >
 
I compiled the wrapped source code and checked that it was still encrypted in the database:
 
SQL> @wrapped_procedure
 
Procedure created.
 
SQL> select text from dba_source
  2  where name = 'ADD_NAME'
  3  order by line
  4  /
 
TEXT
-------------------------------------------------------
procedure add_name wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
5b 92
d6K98qP2M1tFArx52RBb3rXsyPgwg5nnm7+fMr2ywFxaWaH0cgxHLkM
JUKXHstD+x9IyXLgz
uHQlw7h0i8DAMv7Shgml0pmfsp77Caj5nspECCJBr6ieOEoia+KvuEz
sPHHiP9E8dKYY7AS4
 
SQL>
 
Finally, I checked that the procedure still worked:
 
SQL> execute add_name('COLIN');
 
PL/SQL procedure successfully completed.
 
SQL> select * from name_list
  2  /
 
NAME
------
ANDREW
BRIAN
COLIN
 
SQL>
 
Looking elsewhere on the Internet there seem to be a few points to bear in mind when using wrap. I have not checked any of these myself:
  1. It will increase the size of your source code.
  2. If you have strict security on $ORACLE_HOME/bin, you may wish to install a copy of wrap in a shared area for your developers.
  3. You should use the correct version of wrap for your database. Otherwise, if Oracle has introduced some new feature, an out of date version of wrap will not recognise it.
  4. You should only wrap package bodies. You should leave the package headers alone as they can provide useful documentation (I'm not sure if I agree with this one).

No comments: