Oracle提供了一种简易的源代码保护方式,WRAP,它能把程序的代码变成一堆看不懂的字符。
Oracle很多内置程序都使用WRAP进行加密
比如下面是SYS用户下的一个函数:
create or replace function CUBE_TABLE wrapped
a000000
1
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
8
7f a2
QzUf5JyTzy3etZxTULoHHpFaVQgwg0wYf8upynSmkELpgEx2cZCew3msAmd/OJu1nXxgho9i
nHFIJgaJjKkKp9zp/U14pcB4zmqbzt2K30frpc1YoMk3JZfjJXrFbwkL00meVl1rb6eU4N3b
Ep6w/1VExmt2zw==
统计下源代码DBA_SOURCE里面含wrapped声明的程序,发现大量程序都是加密过的:
SQL> select type,count(1) from dba_source where instr(text,'wrapped')>0 group by type;
TYPE COUNT(1)
------------ ----------
PROCEDURE 49
PACKAGE BODY 1028
LIBRARY 122
PACKAGE 503
TYPE BODY 165
FUNCTION 127
TYPE 115
7 rows selected
用WRAP加密自己的一个程序
很多时候我们并不想让客户看到自己的程序代码,为了商业秘密或者掩盖自己的愚蠢(哈哈)
很简单,wrap是一个操作系统级命令,在Oracle安装目录的bin目录下,在配置好ORACLE_HOME环境变量后,只要执行以下语句即可
wrap iname=input_file [ oname=output_file ]
比如下面是一个简单的自定义函数:
create or replace procedure P_log
(v_guid varchar2
,v_spname varchar2 default null
,n_op number default 1
,dt_start date default sysdate
,dt_end date default null
,v_content varchar2 default null)
authid definer is
pragma autonomous_transaction;
begin
if n_op=0 then
--新增一条日志
insert into t_log(guid,
spname,
stime,
etime,
content)
values (v_guid,v_spname,dt_start,dt_end,v_content||chr(10));
else
--更新一条日志
update t_log set etime=dt_end
,content=content||'@'||TO_CHAR(SYSDATE,'YYYY-MM-DD HH24:MI:SS')||'#'||v_content||CHR(10)
where guid=v_guid;
end if;
commit;
end P_log;
将这段代码保存到一个.sql(任何后缀都可以)文件,然后执行wrap命令
C:\Users\Administrator>echo %ORACLE_HOME%
D:\oracle\product\11.2.0\dbhome_1
D:\>wrap iname=p_log.sql
PL/SQL Wrapper: Release 11.2.0.4.0- 64bit Production on Mon Mar 12 20:32:19 2018
Copyright (c) 1993, 2009, Oracle. All rights reserved.
Processing p_log.sql to p_log.plb
用文本方式打开p_log.plb,看到的是加密后的代码:
create or replace procedure P_log wrapped
a000000
354
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
abcd
7
2d8 1e2
+VJIocwRBuE/aNlDCT7fhkiOaM8wgxAJLvZqfHRVrZ3mS4TTWmti2io2ixsn4OPNcNmIADpT
2XCqyiQ/wCJFNQUpykcSKCmhm3Au8PDE54TOkvlZpsJ/oIff3X+eur8VHDfu4HRIUObuLFOv
baUANzMQLGx7dfuLUIeQs5sLt3Zmmmm4FFZ/VucX7tSYCm205eYA/p1eefDUaf0uTSktnG4q
FV7GXnxWMvVmpNbWlDvT94KDFoZMytWgtiqhjNldXzt3Vrcf44zDEg7L76Z8SSakwhIm+qYC
GaCTaMP33WpUPIGJbDpu27WFMtLPY4CzEvUFMUgXRWISVcG7/+gmuX6ftMFCiAxwu7g+DZEk
R/ZPwR0HoHUmp8XQYpT2Q/w8qBCusPRZ48T6PAVvKY0LsHfi3g4eSiBJbK7/Y63ZD5M/ILge
M7OoqlBXhw1ZvgTBrmaWCJP9YxSNoaJAfZjPOvttA03q
/
直接拿到sql命令行下执行,再看代码:
SQL> select TEXT from user_source where name='P_LOG';
TEXT
-------------------------------------------------------------------------
procedure P_log wrapped
a000000
354
abcd
..........(略)
abcd
7
2d8 1e2
+VJIocwRBuE/aNlDCT7fhkiOaM8wgxAJLvZqfHRVrZ3mS4TTWmti2io2ixsn4OPNcNmIADpT
2XCqyiQ/wCJFNQUpykcSKCmhm3Au8PDE54TOkvlZpsJ/oIff3X+eur8VHDfu4HRIUObuLFOv
baUANzMQLGx7dfuLUIeQs5sLt3Zmmmm4FFZ/VucX7tSYCm205eYA/p1eefDUaf0uTSktnG4q
FV7GXnxWMvVmpNbWlDvT94KDFoZMytWgtiqhjNldXzt3Vrcf44zDEg7L76Z8SSakwhIm+qYC
GaCTaMP33WpUPIGJbDpu27WFMtLPY4CzEvUFMUgXRWISVcG7/+gmuX6ftMFCiAxwu7g+DZEk
R/ZPwR0HoHUmp8XQYpT2Q/w8qBCusPRZ48T6PAVvKY0LsHfi3g4eSiBJbK7/Y63ZD5M/ILge
M7OoqlBXhw1ZvgTBrmaWCJP9YxSNoaJAfZjPOvttA03q
程序执行正常:
使用WRAP的注意事项
1.不能对存储过程名称进行加密;
2.不能加密匿名块;
3.不能加密触发器;
4.不能使用SQL*Plus替代变量(&)
5.加密的过程中不会检查语法错误,但在编译时会检查。
6.向上兼容,10g中wrap的程序可以在11g上运行,反之不行;
WRAP程序解密
看了上面2个 WRAP程序,可以发现有很多一样的程序代码,比如a000000、abcd等,可见Oracle并不是对代码做了真正的加密,而是一种“封装”。
因此很多人就开始对此进行研究,并研制了解密的算法。
我也不清楚谁是始作俑者,这里就贴一篇排版清楚点的文章,有兴趣可以试试。
Oracle 加密package解密(unwrap)