暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

warp和unwarp Oracle包


Oracle加密的原理就是先对源码进行lz压缩lzstr,然后对压缩数据进行SHA-1运算得到40位的加密串shstr,然后将加密串与压缩串拼接得到shstr+lzstr,然后对拼接后的字符串进行Oracle双字符转换(转换表)。最后将转换后的字符串进行base64编码,最终得到wrap的加密串。

unwarp

在线网页unwarp

https://www.codecrete.net/UnwrapIt/

set lines 400 pages 0 set long 999999 col ddl_sql for a400 select dbms_metadata.get_ddl('PACKAGE_BODY','DBMS_AUDIT_MGMT','AUDSYS') DDL_SQL from dual;

使用SQL Developer 的第三方扩展包

https://github.com/Trivadis/plsql-unwrapper-sqldev/releases

warp

https://docs.oracle.com/en/database/oracle/oracle-database/19/lnpls/plsql-source-text-wrapping.html#GUID-AB6FFBAD-DE20-4197-A885-AF81F3766FA2

可以加密以下类型

  • Package specification
  • Package body
  • Type specification
  • Type body
  • Function
  • Procedure

使用warp命令加密

wrap iname=input_file [ oname=output_file ] [ keep_comments=yes ] #参数keep_comments=yes 保存注释,默认会删除注释

示例

-- The following statement will not change. SELECT COUNT(*) FROM EMPLOYEES / /* The PL/SQL source text of the following two CREATE statements will be wrapped. */ CREATE OR REPLACE PROCEDURE wraptest AUTHID CURRENT_USER /* C style comment in procedure declaration */ IS TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER; all_emps emp_tab; BEGIN SELECT * BULK COLLECT INTO all_emps FROM employees; FOR i IN 1..10 LOOP /* C style in pl/sql source */ DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id); END LOOP; END; / CREATE OR REPLACE FUNCTION fibonacci ( n PLS_INTEGER ) RETURN PLS_INTEGER AUTHID CURRENT_USER -- PL/SQL style comment inside fibonacci function spec IS fib_1 PLS_INTEGER := 0; fib_2 PLS_INTEGER := 1; BEGIN IF n = 1 THEN -- terminating condition RETURN fib_1; ELSIF n = 2 THEN RETURN fib_2; -- terminating condition ELSE RETURN fibonacci(n-2) + fibonacci(n-1); -- recursive invocations END IF; END; /
wrap iname=wraptest2.sql oname=wraptest2.plb keep_comments=yes PL/SQL Wrapper: Release 19.0.0.0.0 - Production on Tue Dec 17 13:42:43 2024 Version 19.13.0.0.0 Copyright (c) 1982, 2019, Oracle and/or its affiliates. All rights reserved. Processing wraptest2.sql to wraptest2.plb
SQL> @wraptest2.plb COUNT(*) ---------- 107 Procedure created. Function created. -- 已经加密 SQL> r 1* SELECT text FROM USER_SOURCE WHERE name='WRAPTEST' PROCEDURE wraptest wrapped a000000 369 abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd abcd 7 128 138 Mxl1sU3cJLGCCwcVnbrv2czWD7swg+nwJK5qZ3SVWE4+GayDZaL1bF7RwYm2/zr1qjZY3FrN 48M1bKc/MG5aY9YB+DrtT4SJN370Rpq7ck5D0sc1D5sKAwTyX13HYvRmjwkdXa0vEZ4q/mCU EQusX23UZbZjxha7CtlCDCx8guGw/M/oHZXc8wDHXL8V8OsqQMv/Hj7z68gINl7OstalRScr uSZ/l/W1YaaA9Lj8Fbx5/nJw96aN+/bow2NdacAKXDFCg0h9HnS/z685sR4knx6fzbKjkFVi cZufAjLw3FVqLKnbLrQ= -- 可以正常使用 SQL> set serveroutput on SQL> BEGIN 2 wraptest; -- invoke procedure 3 DBMS_OUTPUT.PUT_LINE('fibonacci(5) = ' || fibonacci(5)); 4 END; 5 / Emp Id: 100 Emp Id: 101 Emp Id: 102 Emp Id: 103 Emp Id: 104 Emp Id: 105 Emp Id: 106 Emp Id: 107 Emp Id: 108 Emp Id: 109 fibonacci(5) = 3 PL/SQL procedure successfully completed.
sqlplus -s / as sysdba<<! set lines 200 pages 0 set long 999999 set feed off col ddl_sql for a200 EXECUTE DBMS_METADATA.SET_TRANSFORM_PARAM(DBMS_METADATA.SESSION_TRANSFORM,'SQLTERMINATOR',true); spool $4/$1_$2_$3\.sql select dbms_metadata.get_ddl('$1','$2','$3') ddl_sql from dual; exit spool off ! sed -i -E 's/\bEDITIONABLE\b//i' $4/$1_$2_$3\.sql wrap iname=$4/$1_$2_$3\.sql oname=$1_$2_$3.plb keep_comments=yes sqlplus -s / as sysdba<<! @$4/$1_$2_$3\.plb !
sh wrap.sh PROCEDURE WRAPTEST HR /home/oracle

使用存储过程加密

--整个ddl 32k DBMS_DDL.CREATE_WRAPPED ( ddl VARCHAR2); --支持单行最长256 bytes DBMS_DDL.CREATE_WRAPPED( ddl DBMS_SQL.VARCHAR2A, lb PLS_INTEGER, ub PLS_INTEGER); --支持单行32k(采用这种) DBMS_DDL.CREATE_WRAPPED( ddl DBMS_SQL.VARCHAR2S, lb PLS_INTEGER, ub PLS_INTEGER);
DECLARE l_source DBMS_SQL.VARCHAR2A; -- 用于存储源代码 l_wrap DBMS_SQL.VARCHAR2A; -- 用于存储加密后的代码 l_line NUMBER; -- 用于存储行号 l_text VARCHAR2(4000); -- 用于存储每一行的文本 l_object_name VARCHAR2(30) := 'WRAPTEST'; -- 对象名称 l_object_type VARCHAR2(30) := 'PROCEDURE'; -- 对象类型 BEGIN -- 从 USER_SOURCE 中获取源代码 FOR rec IN ( SELECT LINE, TEXT FROM USER_SOURCE WHERE NAME = l_object_name AND TYPE = l_object_type ORDER BY LINE ) LOOP l_line := rec.LINE; l_text := rec.TEXT; -- 如果是第一行,加上 "CREATE OR REPLACE" IF l_line = 1 THEN l_source(l_line) := 'CREATE OR REPLACE ' || l_text; ELSE l_source(l_line) := l_text; END IF; END LOOP; -- 使用 DBMS_DDL.CREATE_WRAPPED 加密源代码 SYS.DBMS_DDL.CREATE_WRAPPED( ddl => l_source, lb => 1, ub => l_source.count ); END; /

测试步骤

SQL> @wraptest2 COUNT(*) ---------- 107 Procedure created. Function created. SQL> set lines 222 SQL> col text for a120 SQL> SELECT LINE, TEXT FROM USER_SOURCE WHERE NAME = 'WRAPTEST' ORDER BY LINE; LINE TEXT ---------- ------------------------------------------------------------------------------------------------------------------------ 1 PROCEDURE wraptest AUTHID CURRENT_USER /* C style comment in procedure declaration */ IS 2 TYPE emp_tab IS TABLE OF employees%ROWTYPE INDEX BY PLS_INTEGER; 3 all_emps emp_tab; 4 BEGIN 5 SELECT * BULK COLLECT INTO all_emps FROM employees; 6 FOR i IN 1..10 LOOP /* C style in pl/sql source */ 7 DBMS_OUTPUT.PUT_LINE('Emp Id: ' || all_emps(i).employee_id); 8 END LOOP; 9 END; 9 rows selected. SQL> exec wraptest(); PL/SQL procedure successfully completed. SQL> SET SERVEROUTPUT ON SIZE UNLIMITED SQL> exec wraptest(); Emp Id: 100 Emp Id: 101 Emp Id: 102 Emp Id: 103 Emp Id: 104 Emp Id: 105 Emp Id: 106 Emp Id: 107 Emp Id: 108 Emp Id: 109 PL/SQL procedure successfully completed. SQL> SQL> DECLARE 2 l_source DBMS_SQL.VARCHAR2A; -- 用于存储源代码 3 l_wrap DBMS_SQL.VARCHAR2A; -- 用于存储加密后的代码 4 l_line NUMBER; -- 用于存储行号 5 l_text VARCHAR2(4000); -- 用于存储每一行的文本 6 l_object_name VARCHAR2(30) := 'WRAPTEST'; -- 对象名称 7 l_object_type VARCHAR2(30) := 'PROCEDURE'; -- 对象类型 8 BEGIN 9 -- 从 USER_SOURCE 中获取源代码 10 FOR rec IN ( 11 SELECT LINE, TEXT 12 FROM USER_SOURCE 13 WHERE NAME = l_object_name 14 AND TYPE = l_object_type 15 ORDER BY LINE 16 ) LOOP 17 l_line := rec.LINE; 18 l_text := rec.TEXT; 19 20 -- 如果是第一行,加上 "CREATE OR REPLACE" 21 IF l_line = 1 THEN 22 l_source(l_line) := 'CREATE OR REPLACE ' || l_text; 23 ELSE 24 l_source(l_line) := l_text; 25 END IF; 26 END LOOP; 27 28 -- 使用 DBMS_DDL.CREATE_WRAPPED 加密源代码 29 SYS.DBMS_DDL.CREATE_WRAPPED( 30 ddl => l_source, 31 lb => 1, 32 ub => l_source.count 33 ); 34 END; 35 / PL/SQL procedure successfully completed. SQL> set lines 222 SQL> col text for a120 SQL> SELECT LINE, TEXT FROM USER_SOURCE WHERE NAME = 'WRAPTEST' ORDER BY LINE; LINE TEXT ---------- ------------------------------------------------------------------------------------------------------------------------ 1 PROCEDURE wraptest wrapped a000000 369 abcd abcd abcd abcd abcd abcd abcd abcd LINE TEXT ---------- ------------------------------------------------------------------------------------------------------------------------ abcd abcd abcd abcd abcd abcd abcd 7 128 138 Mxl1sU3cJLGCCwcVnbrv2czWD7swg+nwJK5qZ3SVWE4+GayDZaL1bF7RwYm2/zr1qjZY3FrN 48M1bKc/MG5aY9YB+DrtT4SJN370Rpq7ck5D0sc1D5sKAwTyX13HYvRmjwkdXa0vEZ4q/mCU LINE TEXT ---------- ------------------------------------------------------------------------------------------------------------------------ EQusX23UZbZjxha7CtlCDCx8guGw/M/oHZXc8wDHXL8V8OsqQMv/Hj7z68gINl7OstalRScr uSZ/l/W1YaaA9Lj8Fbx5/nJw96aN+/bow2NdacAKXDFCg0h9HnS/z685sR4knx6fzbKjkFVi cZufAjLw3FVqLKnbLrQ= SQL> SQL> SET SERVEROUTPUT ON SIZE UNLIMITED SQL> exec wraptest(); Emp Id: 100 Emp Id: 101 Emp Id: 102 Emp Id: 103 Emp Id: 104 Emp Id: 105 Emp Id: 106 Emp Id: 107 Emp Id: 108 Emp Id: 109 PL/SQL procedure successfully completed.
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

文章被以下合辑收录

评论