Protect Your Intellectual Property: Obfuscate DB2 For i Source Code
June 27, 2012 Michael Sansoterra
Every “old timer” IBM i developer knows about the compiler option to include or exclude source statements within an OPM or ILE program. The CL compilers even have an option to allow CL source to be retrieved from the Retrieve CL Source (RTVCLSRC) command.
While high-level language programmers can decide whether or not to include source statements with their objects, DB2 SQL developers had no such option because anyone could use a tool like iNavigator to retrieve the SQL source. Thanks to the IBM i 7.1 technology refresh 4 update, SQL developers now have the option to obfuscate their source code.
First, understand that while HLL developers have the option to exclude source statements from their program objects, DB2 for i SQL developers can obfuscate or scramble the underlying source code. When obfuscated, the SQL source code is still present but it’s in a format that the average guy won’t bother trying to decipher.
Here’s a demonstration on how it works. Say you have written top secret SQL function “Pizza_Area” that receives the radius of a pizza and returns its area:
CREATE OR REPLACE FUNCTION dev.Pizza_Area(radius float) RETURNS float RETURN PI()*radius*radius
You know that any savvy developer can retrieve this SQL code via iNavigator or the Generate Data Definition Language (QSQGNDDL) API. To conceal the source, you decide to obfuscate it using the new WRAP function:
VALUES WRAP('CREATE OR REPLACE FUNCTION dev.Pizza_Area(radius float) RETURNS float RETURN PI()*radius*radius');
The WRAP function simply takes a CLOB string expression (containing a valid SQL CREATE statement) and returns an obfuscated version of the source. The result of the above statement is this string (WRAP does not create any objects):
CREATE OR REPLACE FUNCTION DEV . PIZZA_AREA ( RADIUS FLOAT ) WRAPPED QSQ07010 aacxW8plW8FjG8pzG8pfG8Vj68FH68Vjl9Vp1_ph1qpdW8pdW8pdW9pLaqebaqebad0 ses7slmf5lhnpUxaORQh:D5pVHrBDNaxQj6_NsGvkJBlyfmpBC4_jKkG8eJuNGi1j4eqaa
What do we have here? Simply the function name and parameter signature, followed by the WRAPPED keyword (indicating it has been obfuscated) and a special value (QSQ07010) that identifies the code as DB2 for i version 7.1. The remaining gobbly-gook characters are an obfuscation of the original source code. This obfuscated code returned by wrap is what should be executed to create the object instead of the original code.
Executing the output of the WRAP function will create the function and will execute identically to the original. After executing the obfuscated CREATE FUNCTION statement we can try it out:
VALUES dev.Pizza_Area(8); -- Returns 201.06
Now, the only real difference is that when the source code is retrieved, the obfuscated source will be returned instead of the original code. So the obfuscated SQL routine can still be retrieved and installed on other systems, it just can’t be read by a developer.
When using obfuscated code, make sure to keep safe backups of the original (maintainable) source!
Incidentally, IBM also has overridden “SET OPTION DBGVIEW=*LIST” so that a sneaky developer can’t take a peak at the code in the underlying C service program either.
Currently, the wrap function only supports CREATE FUNCTION (table or scalar) or CREATE PROCEDURE SQL routines. For some reason, CREATE TRIGGER is not yet supported.
Obfuscating source code has been an industry standard for some time, being oft-used in .NET, Java, and other development environments. It is a welcome addition to the DB2 for i arena.
Note: As an alternative to the WRAP function, DB2 for i also offers the CREATE_WRAPPED built in stored procedure as a method of obfuscating a source routine.