Sie sind auf Seite 1von 124

User Guide

No part of this publication may be stored in a retrieval system, reproduced or transmitted in any form by any means,
electronic, mechanical, photocopying, scanning, recording, or otherwise except as permitted by local statutory law,
without the prior written permission of the publisher. This material may not be translated into any other language or used
in any translated form. Requests for permission should be addressed to the above registered address of PeteFinnigan.com
Limited in writing.

Limit of Liability / Disclaimer of warranty. This information contained in this manual is distributed on an “as-is” basis
without warranty. Whilst every precaution has been taken in the preparation of this material, neither the author nor the
publisher shall have any liability to any person or entity with respect to any loss or damage caused or alleged to be caused
directly or indirectly by the instructions or guidance contained within this manual.

TradeMarks. Many of the designations used by manufacturers and resellers to distinguish their products are claimed as
trademarks. Oracle is a trademark of Oracle Corporation. Windows is a trademark of Microsoft Corporation. All other
trademarks are the property of their respective owners. All other product names or services identified throughout this
manual are used in an editorial fashion only and for the benefit of such companies with no intention of infringement of the
trademark. No such use, or the use of any trade name, is intended to convey endorsement or other affiliation with this
product or PeteFinnigan.com Limited.
February 1, 2017 PFCLOBfuscate Users Manual

Title PFCLSObfuscate Documentation


Synopsis This is the primary documentation for
PFCLObfuscate.
Status Production
Version 2.1.26.1209
Date 1st February 2017
Author Pete Finnigan
License This software is licensed not sold. Installing and
using the software is considered acceptance of
the EULA

Page 2 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Table of Contents
Introduction ............................................................................................................................................ 6
Caveats .................................................................................................................................................... 8
System Requirements ............................................................................................................................. 9
Installation and Activation .................................................................................................................... 10
Updates ............................................................................................................................................. 15
Installed Files..................................................................................................................................... 15
Location of Programs / Binaries ........................................................................................................ 16
Location of Data Files, Configuration Files and Samples .................................................................. 17
Activation .............................................................................................................................................. 17
Configuring and Using PFCLObfuscate .................................................................................................. 19
Character Set Support ....................................................................................................................... 20
How Does PFCLObfuscate work? ...................................................................................................... 21
Running PFCLObfuscate .................................................................................................................... 22
Command Line Arguments ............................................................................................................... 22
The Configuration File ....................................................................................................................... 23
Prepare Input Files ............................................................................................................................ 31
Running PFCLObfuscate .................................................................................................................... 33
Obfuscation Levels ............................................................................................................................ 39
Using Quoted Identifiers ................................................................................................................... 40
String Obfuscation ............................................................................................................................ 43
Stringmode 0 ................................................................................................................................. 43
Stringmode 1 ................................................................................................................................. 43
Stringmode 2 ................................................................................................................................. 45
Stringmode 3 ................................................................................................................................. 46
Stringmode 4 To Stringmode 7 ..................................................................................................... 50
String Omit Example ......................................................................................................................... 58
String Omit with <CR> ....................................................................................................................... 59
TransposeOnly Example .................................................................................................................... 61
Reverse Transpose Example ............................................................................................................. 64
SQL*Plus Variables ............................................................................................................................ 66
Debug ................................................................................................................................................ 67
Trace.................................................................................................................................................. 68
Obfuscation Examples........................................................................................................................... 69
Page 3 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Example 1 - Obfuscating a SQL*Plus script ....................................................................................... 70


Obfuscating a Complete Project ....................................................................................................... 73
Utilities .................................................................................................................................................. 80
Run Time Planning ................................................................................................................................ 80
Alias’s .................................................................................................................................................... 80
Using Wrap With PFCLObfuscate (9iR2) ............................................................................................... 81
Performance ..................................................................................................................................... 86
WrapProtect.......................................................................................................................................... 87
WrapProtect Command Line ............................................................................................................ 89
WrapProtect Options ........................................................................................................................ 90
WrapProtect Limits ........................................................................................................................... 92
Dynamic Obfuscation – Version 2.0 features ....................................................................................... 93
Introduction ...................................................................................................................................... 93
Limitations..................................................................................................................................... 93
Enabling Version 2.0 ......................................................................................................................... 95
Hook Points ................................................................................................................................... 95
Function File ...................................................................................................................................... 97
Writing Dynamic Obfuscation Scripts ............................................................................................... 98
Compiling PFCLLua ............................................................................................................................ 99
Dynamic Script Overview ................................................................................................................ 100
Lua Template................................................................................................................................... 101
Instrumentation .............................................................................................................................. 102
License Additions ............................................................................................................................ 103
License File .................................................................................................................................. 103
Dynamic Obfuscation Examples...................................................................................................... 103
Example 1 – Dynamic Obfuscation ............................................................................................. 103
Example 2 – License Example ..................................................................................................... 109
Example 3 – Obfuscate a Package............................................................................................... 113
Advanced License Settings .............................................................................................................. 122
Advanced Settings............................................................................................................................... 122
License Details..................................................................................................................................... 123
Known Issues....................................................................................................................................... 123
Support ............................................................................................................................................... 124

Page 4 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Page 5 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Introduction
Most companies that use the Oracle database server product to store their valuable customer data
and to process their business needs have inevitably implemented functionality or programs in the
PL/SQL language.

Your program source code often contains secrets, intellectual property, encryption keys, hard coded
data or proprietary algorithms that should remain hidden from competitors or prying eyes. As a
company you want these details to remain secret.

Oracles own efforts in securing our PL/SQL code and indeed their own code from prying eyes have
not been perfect. The algorithms used in their own obfuscation tool called “wrap.exe” have been
known for many years and a number of so called “un‐wrapper” tools exist commercially (for private
buyers), commercially (for public buyers) and also some are free for download. Oracles newer
version of “wrap.exe” for database versions 10g to 12c are even weaker than the earlier pre 9iR2
ones as the algorithm used can simply be reversed; there are even websites set up to allow you to
reverse engineer your code and other peoples code on‐line.

This situation had to change as there were no proper solutions available to protect your intellectual
property or to prevent theft of your code; this is where PFCLObfuscate comes in. License software
solutions are available for most other development platforms and languages such as C, .NET and
many more but not for PL/SQL.

PFCLObfuscate is a tool that can be used to make it much harder for someone to understand the
Intellectual Property Rights (IPR) held in your PL/SQL and SQL source code files. Obfuscation is not a
perfect solution to secure your IPR but it will make the task of reverse engineering much longer for a
skilled person and virtually impossible for an unskilled person. The obfuscation process is a “lossy”
process so that meaning is “lost” from the original code. This helps obscure the code as the actual
meaning of procedures, variables, tables and more is also lost from the source code.

This tool also removes comments and compacts the code to also make it harder to read. The main
purpose is to obfuscate the code to remove the meaning that can normally be gained by reading
code based on chosen variable and function names and also structure.

Obfuscation is not a perfect science and does not alone guarantee security. Obfuscation should be
combined with other techniques such as “wrap.exe” and “anti-unwrapper” techniques and also with
run time techniques to prevent tampering of the code and also tampering of security features
themselves.

PFCLOBfuscate supports SQL files, PL/SQL files and SQL*Plus scripts (using SQL*Plus commands, SQL
and PL/SQL) to provide the obfuscation layer of securing your PL/SQL.

Combining PFCLObfuscate with Oracles Wrap and also PeteFinnigan.com Limited’s “WrapProtect”
will afford the best protection for PL/SQL. PFCLOBfuscate is applied first to remove meaning and to
make reverse engineering hard. The resultant obfuscated PL/SQL can then be wrapped with Oracle’s
Wrap program for 9iR2. The reason to use the older wrap is because finding working unwrappers is
harder (an “unwrapper” is a tool created to reverse the wrap process) and the actual unwrapping
process itself is harder to achieve should an attacker try and create an unwrapper. When the code is

Page 6 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

wrapped there is no meaning left in the clear text at the start of the wrap file. Finally PFCLObfuscate
includes a simple wrap protect tool called “wfix.exe”, this can be used to provide a simple final layer
of protection that will prevent unwrappers from working. A more substantive protection is provided
by the WrapProtect tool which is also used on the Oracle wrapped output file.

PeteFinnigan.com Limited do not supply 9iR2 wrap.exe programs, you must locate and license this
yourself. The 9iR2 database is no longer supported by Oracle but loading 9i wrapped PL/SQL code
into current versions of the database is supported by Oracle (we have tested up to 12cR1 and this
works fine).

Also if your code is written “post” 9iR2 then you may use later features of PL/SQL that will not
“compile” with the 9iR2 wrap program. There is no way to make 9iR2 wrap work with the new
PL/SQL features so an approach of separating any new syntax code from older code that will
compile is a good one. The code that uses new syntax can still be obfuscated but should not be
wrapped with 9iR2 as it would error. If on the other hand unsupported SQL syntax is used and it
fails to compile with the 9iR2 wrap.exe then the additional command line parameter to wrap.exe,
the “edebug=wrap_new_sql” can be specified which allows non-supported syntax to be used; it
does this by transferring the SQL to clear text.

An alternate approach is to convert syntax that is not supported in 9ir2 into strings that are
executed via “execute immediate” or “open for” or DBMS_SQL so that the later syntax is now in a
string and not compiled. Doing this means that it will wrap with 9iR2 and will also be protected in
the wrapped file due to the obfuscations not allowing the code to be visible in the symbol table of
the wrapped file.

In general careful use of the older 9iR2 wrap.exe should be considered for critical functions in your
PL/SQL

PFCLObfuscate is a command line toolset which controlled via command line options and also
configuration files. Being command line is ideal for inclusion in existing build processes.

Note: the best protection is afforded when the code is in a type, procedure, package, function, type
body or package body as these can also be wrapped with Oracle wrap tool.

PFCLObfuscate basic functionality allows obfuscation of a PL/SQL source code file. This allows hiding
of strings and identifiers and also removal of comments and compaction of code. Version 2.0 brings
additional benefits that allow dynamic obfuscation. Standard version 1.0 obfuscation can be used in
version 2.0 with or without dynamic obfuscation. Dynamic obfuscation is controlled by one
configuration file parameter; set the functionfile= parameter to a valid functionfile to enable version
2.0 dynamic obfuscation.

The features of version 2.0 dynamic obfuscation provide the ability for stronger obfuscation but also
the ability to “re-write” PL/SQL. This dynamic obfuscation engine is described in the version 2.0
section of this manual later on. The dynamic obfuscation is based around a simple configuration file
that allows a set of three scripts written in the Lua language to be defined for each dynamic
insertion or modification point. These modification points are places in your PL/SQL code; these
include the start of a declaration section, the end of a declaration section, the start of a PL/SQL

Page 7 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

block, the end of a PL/SQL block, the location of specifically defined PL/SQL (such as a package call),
a comment or a string.

These insertion points or “hooks” allow dynamic changes to be made to your code. This allows us to
do three major things:

 Obfuscate code we would not normally be able to obfuscate such as package procedures
owned by SYS i.e. a call to DBMS_OUTPUT.PUT_LINE() in version 1.0 could not be obfuscated
unless we also obfuscated the SYS package source code. Now we can obfuscate by replacing
the call with dynamic PL/SQL
 Addition of license protection type code. This allows us to dynamically limit and protect
PL/SQL for such things as date/number of executions, user, locked to a database and much
more
 Addition of tamper proofing checks. This allows us to add code automatically that can test if
your PL/SQL has been modified by an attacker at run time.

We can also use dynamic obfuscation for non-security purposes such as instrumenting PL/SQL
automatically with debug calls.

The core feature of dynamic obfuscation is the three Lua scripts associated with each dynamic entry
in the configuration file. These scripts can contain any valid Lua code and can be used to write any
valid PL/SQL code. This gives PFCLObfuscate a lot of power.

Caveats
As PFCLObfuscate clearly processes your existing PL/SQL and re-writes it as obfuscated code or
even adds to it with version 2.0 dynamic obfuscation it is your responsibility to thoroughly test
that your code still functions exactly the same after you have protected it with PFCLObfuscate.

Page 8 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

System Requirements
The following requirements need to be met:

 Storage space - 5Mb for the PFCLObfuscate software plus space for your source code

 Windows Vista SP2 or higher, Windows Server 2008 or later - Home editions are not
supported but may work and are untested

 Adobe Acrobat reader 9.0 or later - see http://get.adobe.com/uk/reader/ for download details

 Internet Explorer version 7 or later - see


http://www.microsoft.com/download/en/details.aspx?id=2 for details

 Microsoft VC2015 Update 3 redistribution needs to be installed - the installer will install this if
required and if an internet connection is available else install separately first from
https://www.microsoft.com/en-us/download/details.aspx?id=52685

Note: IE is only required to visit the websites referenced (support) and Adobe reader is only required
to read this manual so these two requirements could be ignored if required.

Page 9 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Installation and Activation


The installation of PFCLObfuscate is easy. The package is shipped as a Zipped MSI Windows installer
file. Download to a temporary directory from the URL provided. Double click on the installer file
which is normally called PFCLObfuscate_Setup.msi. This starts the installer process:

Simply click “Next” in the welcome screen to start the installation process:

Page 10 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

In the license agreement screen scroll down and read the complete license agreement for
PFCLObfuscate. If you accept the terms of the license agreement then check the button “I accept the
terms of the License Agreement” or if you do not then check “I do not accept the terms of the
License Agreement”. If you do not accept then you must remove the downloaded file and all media
and contact PeteFinnigan.com Limited for a refund.

After clicking “Accept” then click “Next”:

Page 11 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

In the shortcuts screen edit any changes that you require for shortcuts. It is advisable to retain the
Start Menu Programs Folder” to allow easy access to PFCLOBfuscate. When you are happy click
“Next”:

Page 12 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

In the location screen you can choose a different directory for the PFCLOBfuscate programs if you do
not wish to use the default location in the “Program Files” folder. When you are satisfied click
“Next”:

The summary screen gives you an opportunity to go back and change any settings otherwise click
“Next” to start the installation (Note: You may need to accept the Windows UAC screen to continue
at this point – this is normal in Windows Vista and higher):

Page 13 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The software now installs and finally you are presented with the Finish screen:

That is it. PFCLObfuscate is now installed.

Page 14 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Updates
When PFCLObfuscate is updated after the initial installation the update will overwrite the binary files
and also the configuration files of your installation. There are a number of options available to
ensure you do not lose your work.

1. Ensure that you work in a different directory to the main PFCLObfuscate install directory –
the place where ob.conf or omit.txt is installed to – in this way when you upgrade your files
are not overwritten
2. Use different names for your working files. i.e. do not use ob.conf but use pete.conf for
instance
3. Backup all of the installation before an upgrade to ensure that you do not lose your work

After an update review the documentation and also the sample configuration file ob.conf.sample as
new configuration options may have been added that are mandatory. If any new configuration
options are added ensure that they are also added to your own working configuration file.

Installed Files
The files installed by PFCLOBfuscate are simple and are described in this table:

File Purpose
obs.exe The obfuscation program
ob.conf PFCLObfuscate configuration file
ob.conf.sample Sample PFCLObfuscate configuration file
key.txt List of PL/SQL and SQL keywords
reserved.txt List of reserved words (packages, schemas etc)
force.txt Sample force file
omit.txt Sample omit file
string.txt Sample string omit file
functionfile.txt Control configuration file for dynamic obfuscation
sqlplus.txt Sample sqlplus keyword file
transpose.txt Sample transposed words file
transpose.rev Sample reverse transpose file
PFCLObfuscate Manual.pdf This help Manual
PFCLSObfuscate_License.rtf Your personalised license file
PFCLObfuscate_release_notes.txt Latest release notes for the product
apex_omit.sql SQL*Plus script to populate the omit file with
APEX package parameters and global variables
gr.sql SQL Script to help generate the reserved.txt file
run.bat Runs PFCLObfuscate for multiple input files
setup.bat Batch file to set trace
clean.bat Batch file used to remove trace and version 2.0
output
wfix.exe Un-wrapper protector (Simple)
wrapprotect.exe Un-wrapper protector (More Advanced)
wp.conf WrapProtect configuration file
unix2dos.exe Convert Unix file endings to DOS file endings
dos2unix.exe Convert DOS file endings to Unix file endings
/samples directory Many sample SQL and PL/SQL files that can be

Page 15 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

used to test PFCLObfuscate


dbms*.lua Various Lua scripts used in version 2.0
functionality
license.txt License settings for PL/SQL
map.txt Character map file for extended character sets
obs.lua Lua library used in all lua scripts
template.lua Lua template used to write version 2.0 lua scripts
ls.exe Lua shell for testing version 2.0 dynamic
obfuscation scripts
lc.exe Lua compiler to allow compiled lua to be used
Blank.exe Tool to remove blank lines from files

The installation of PFCLObfuscate is done to two directories:

 The binaries to [drive]:\Program Files\PeteFinnigan.com Limited\PFCLObfuscate OR a


location chosen during PFCLObfuscate installation or a slight difference based on
Windows version/language. The location stated here is for Vista. This site gives
alternatives for Windows versions and languages -
http://en.wikipedia.org/wiki/Program_Files . The binaries directory holds the programs
and help files.
 The data directory is created separately and contains the configuration files such as
ob.conf and omit.txt. this directory is not changeable in the installer and defaults to
[drive]:\Users\[user name]\Appdata\Local\PeteFinnigan.com Limited\PFCLObfuscate

Location of Programs / Binaries


The files installed by PFCLOBfuscate are located in two places on your hard drive. By default the
programs are stored in [drive]\Program Files\PeteFinnigan.com Limited\PFCLObfuscate unless you
chose a different location during the installation:

Page 16 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Location of Data Files, Configuration Files and Samples


The sample files and configuration files are in your [user]\AppData\Local\PeteFinnigan.com
Limited\PFCLObfuscate:

Activation
PFCLObfuscate must be activated before first use. The simplest way to do this is to go to “start
menu” => Programs => PFCLObfuscate => “Execute PFCLObfuscate” – this opens a command
Window:

The command window opens in the PFCLObfuscate directory read to run. To activate the product
simply type “obs” at the command prompt and the following window opens:

Page 17 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Email the “site code” and the “MID” code to support@pfclsupport.com or open a new ticket on
http://www.pfclsupport.com; we will send you an activation code to unlock the product. When the
product code is received add it to the same dialog box:

Page 18 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

And click the continue button and the product is activated.

Configuring and Using PFCLObfuscate


This section explains at a high level how PFCLObfuscate works and how to use it. We start with the
configuration file and the input files and then walk through some simple examples of obfuscating
some PL/SQL

Page 19 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Character Set Support


PFCLObfuscate supports specific situations regarding character sets and extended characters. If you
are using English and specifically non-accented characters in your PL/SQL code files then everything
works fine for your now. We have a number of customers who do use accented characters in their
code. We also support ‘string omit’ – see “String Omit Example” section and also “The Configuration
File” section for more details. This feature allows selected strings to be omitted from the obfuscation
process.

PFCLObfuscate at this stage (Version 1.0) has the following support / features; this will be changed
on version 2.0 to allow mapping to CHR() functions:

 PFCLObfuscate only supports 8 bit ANSI source code files. We DO NOT CURRENTLY
support UNICODE or UTF-8 or endian Unicode. We support extended characters but
basically the ANSI format as created by saving a file as “ANSI” in notepad or TextPad on
Windows for instance. Extended characters are supported but these are influenced or
affected by Windows code pages and are specific to the language/code page used by the
PC. If a file is moved between machines with different languages then “visible” accented
characters “may change”; this is not an issue of PFCLObfuscate but Windows/character
sets...
 PFCLObfuscate is a Windows program so we support Windows file endings but we also
provide two utilities (See the “Utilities” section) that translate from DOS to Unix and
Unix to DOS. These utilities allow source code files to be created on Unix and managed
on DOS. These utilities only change the line endings.
 Accented and extended characters are supported in comments (if comments are
retained in the output). Accented and extended characters are supported in C style and
PL/SQL style comments. The comments are passed through; so if you currently develop
source code and that source code includes accented or extended characters in
comments and then deploy to the database they will work in the same way. Note: The
best approach is to use PFCLObfuscate to remove comments anyway.
 Variables (identifiers) are only supported using the standard Oracle character set A-Z0-
9_#$; i.e. variables that are encased in double quotes are not currently supported. We
will add support for identifiers in double quotes in the next major version.
 Strings are not currently supported where they also contain accented and extended
characters. Because the machine used to “work on” the source code may have different
language and character set that the database a simple language/character set solution is
not available. PFCLObfuscate supports obfuscation into sequences of chr(n)||chr(n) and
for all characters with a decimal value in the 0-127 range this works fine but when
characters in the extended range >127 are used then the results can be unpredictable
because of the character set used on the PC and also in the database. For instance “À”
will
 Transpose to 192 decimal and dependant on the PC this may display as “À” or indeed
anything else and if the database uses a different character set that can cause issues. A
number of solutions are available:
o If you use non-extended characters then the “stringmode=1” or “stringmode=5”
solution to change strings into chr(n)||chr(n)..
Page 20 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

o Use “stringmode=2” of “stringmode=6” to generate chr(n using


nchar_cs)||chr(n using nchar_cs)...This has shown to work for some clients
o Use “stringmode=3” or “stringmode=7”; in this mode a map file can be used to
map extended characters to extended characters used in chr(n) functions. This
allows a map as follows:

192|50048
193|50049
194|50050

This means that a 192 extended character becomes chr(50048) for instance.

How Does PFCLObfuscate work?


PFCLObfuscate is a command line program to parse PL/SQL, SQL and SQL*Plus scripts and locate
variables and function names and replace them with meaningless names that are very similar to
each other. The character space used – i.e. the letters used in the variables is specified in the
configuration as is the length of the variables to be generated. The PFCLObfuscate tool also
compacts source code and removes comments. PFCLObfuscate has these features:

 comment removal
 code compaction
 variable and identifier obfuscation - i.e my_var1 could become oill1O0o - the character
set as shown below is configurable
 choose character set
 choose variable length
 download all converted variables after obfuscation for reference
 command line for ease of integration with build tools/scripts
 choose output line length
 add keywords dynamically
 choose variables to not obfuscate
 works on multiple source files allowing correlation across all files
 omit public interfaces by listing
 configuration file
 omit strings from obfuscation by listing
 force obfuscation of variables if necessary
 string obfuscation
 obfuscate code in strings (dynamic code)
 able to obfuscate PL/SQL functions, procedures, packages, types
 able to obfuscate SQL*Plus scripts
 omit SQL hints
 obfuscate code in strings; i.e. dynamic code
 we have a user documentation manual and samples
 debug and trace interface to help resolve configuration issues
 simple wrap protect

Page 21 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Version 2.0 “dynamic obfuscation” also allows packages and other ID’s to be obfuscated and also
license protection to be added to your PL/SQL (i.e. limit how your customers can run your PL/SQL
code)

How does it work: The tool is the equivalent to the front-end of a compiler. It reads SQL, SQL*Plus
and PL/SQL files extracts source code tokens and obfuscates identifiers individually and also
correlates the same variable names across your multiple files. If an API (Application Programming
Interface) for instance is called TEST_PROC and it is obfuscated to a variable {random string for
instance “oOiil0ll”} in the implementation and also the same {random string} variable is used in all
files where the procedure is used allowing correlation between source codes.

Running PFCLObfuscate
The PFCLObfuscate tool-suite is comprised of command line tools.

Because PFCLObfuscate can be used on the command line it’s easy to integrate it with other build
tools such as “wrap” or command line build tools/scripts used to compile and install your Oracle
scripts.

Command Line Arguments


The tool is command line based and all instructions are passed as command line arguments or in the
configuration file. The command line arguments are shown here:

The command line parameters control the tool and are easy to understand and use. Some will be
explained throughout this manual but at a high level some are described here:

1. “-v” and “-s” can be used in scripts to silence output or make it loud
2. “-t” is used to add timing information to logs, debug and trace modes
3. “-c” is used to specify the configuration file described next
4. “-i” is the source input file
5. “-o” is the output file generated after obfuscation
6. “-l” is the log file if you choose to write the tools output to a log instead of the screen
7. “-?”, “-h” and “-H” all display the help

The help “-h” shows a little more details:

Page 22 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The Configuration File


PFCLOBfuscate uses a configuration file to control its inner workings. The control file must be
configured before PFCLObfuscate can be used. A sample configuration file is first shown here and
then each setting will be explained:

###############################################################################
# ob.conf
# Pete Finnigan 08-May-2003
#
# Who When Description
# === ======== ====================
# PF 02-Apr-2008 Update for new release
# PF 20-May-2011 Updated for WrapProtect
# PF 31-May-2011 Updated for PFCLObScan
# PF 31-Mar-2012 Updated for PFCLObfuscate Installer
# PF 01-Jan-2013 Added stringmode=2 and 3
# PF 18-Jan-2013 Added reverse transpose file
# PF 24-Apr-2013 Added facility to specifiy the buffer RAM size
# PF 14-Apr-2014 Version 2.0 parameters made public
# PF 30-Mar-2015 Added new parameter to allow tranpose only processing
# PF 31-Mar-2015 Added new stringmodes for obfuscation of code in strings
# PF 02-Apr-2015 Added new parameters for \r\n substitution, single quote
# substitution for processing code in strings, the string
# obfuscation config file, parameter to decide whether to
# keep string substitute intermediate files. Also the string
# parameters have been moved to one section just for strings
# PF 30-Apr-2015 Added new parameter to control the code in strings
# processing
#
# sample config file for PeteFinnigan.com Limited PFCLObfuscate
#
# This file supports PFCLObfuscate
#
#
############################################################################
# General Parameters
############################################################################
#
# verbose - make output noisy
#
verbose=yes
#
# normal logging is surpressed, error messages are still generated.
#
silent=no
#

Page 23 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

# when verysilent is set no output is generated, even error messages


# are suppressed
# CURRENTLY NOT SUPPORTED
#
verysilent=no
#
# setting timing enables the addition of timestamps to log entries.
#
timing=yes
#
# location of the log file if output is to be saved to a log.
#
#logfile=obs.log
#
############################################################################
# PFCLObfuscate parameters
############################################################################
#
# Name of the output file. This is the transpose file for the obfuscator
#
outputfile=transpose.txt
#
# Name of the reverse transpose file. This file can be used as an input to
# the obfuscation process by replacing the transpose.txt file with this one
# it is possible to reverse the identifier obfuscations.
#
reverseoutput=transpose.rev
#
# Name of the keyword file. This file specifies language keywords that are
# not to be obfuscated.
#
keyword=key.txt
#
# Name of the reserved word file. This file lists reserved words for the
# language. These words are not obfuscated.
#
reserved=reserved.txt
#
# Name of the omit words file. This file lists words that will not be obfuscated
#
omit=omit.txt
#
# Name of the force file. Words in this file are forced to be obfuscated even if
# contained in another file such as keywords.
#
force=force.txt
#
# Name of the string omit file. This file lists strings that will be omitted from
# the obfuscation process
#
stringomit=string.txt
#
# Name the file used to hold sqlplus command keywords
#
sqlplus=sqlplus.txt
#
# turn file compaction on. "yes/no". This removes white space from the file
#
compact=yes
#
# turn on comment removal.
#
comment=yes
#
# Obfuscate the PL/SQL yes
#

Page 24 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

obfuscate=yes
#
# Turn on debug of the parser. This outputs each token and its type to aid debugging
#
debug=no
#
# The character set to use for the variable names obfuscation
#
#charset=Oil10Q
charset=Abfjk10
#
# This is a subset of the characters specified for the obfuscation. This must not
# include digits, $# as these are not allowed in normal identifiers as the first
# character.
#
#firstseed=OilQ
firstseed=Abfjk
#
# Set the length of the variables that are obfuscated.
#
obfusvarlen=6
#
# set the line length for compacted lines
#
linelen=120
#
# Specify the file to be obfuscated
#
#inputfile=str.sql
#
#
# Name of the output file processed to an obfuscated state
#
#obfuscatedfile=str.opf
#
# This parameter specifies the map file. This is used to allow extended
# characters to be mapped to their correct values for chr(n) functions
#
mapfile=map.txt
#
# This parameter controls whether PFCLObfuscate attempts to obfuscate all tokens
# or only obfuscates those tokens already present in the transpose.txt file. A
# setting of no means obfuscate all tokens as normal and a setting of yes means
# only obfuscate based on existing entries in the transpose.txt file.
#
transposeonly=no
#
############################################################################
# String obfuscation parameters.
############################################################################
#
# string obfuscation mode. Currently supports only:
# 0) turn off string obfuscation
# 1) convert to chr(n)||chr(n)
# 2) convert to chr(n using nchar_cs)||chr(n using nchar_cs)
# 3) use map mode; the map file must be supplied
# 4) obfuscate any keyword in a string
# 5) obfuscate any keyword in a string and then convert to chr(n)||chr(n)
# 6) obfuscate any keyword in a string and then convert to
# chr(n using nchar_cs)||chr(n using nchar_cs)
# 7) obfuscate any keyword and then use map mode;
# the map file must be supplied
#
stringmode=1
#
# Parameter to define the string omit end of line character. This character is

Page 25 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

# substituted in the strings as they are processed to establish whether the


# string should be omited from obfuscation
#
stringcr=@
#
# This parameter specifies the quote substitution character used in string
# processing in modes 4 - 7. If a string is processed to substitute code
# in that string with obfuscated tokens then we first replace any embedded
# quotes to avoid recursion (or breakages if an unmatched string is passed)
#
stringquote=^
#
# Parameter to specify the ob.conf for embedded string obfuscation. This
# configuration file must be configured seperately and is a copy of this
# one.
#
stringconfig=sob.conf
#
# This parameter controls whether the intermediate string files created
# as part of embedded string processing are retained or removed after
# PFCLObfuscate exits.
#
stringkeep=no
#
# This parameter controls the method used for code in string obfuscation. This
# can be set to
#
# valid methods are:
# child - uses child processing with obs.exe. The performance is slow on
# big files bit for smaller ones it gives the best controls over
# the process
# token - uses a tokeniser to process strings as code. This method has
# less controls and functionfile, omit, force etc are not
# available. The tokeniser recognises tokens of the form
# a-zA-Z0-9_#$ but not double quoted identifiers (although these
# will most likely work provided the standard naming is used
# or no special characters are used. Only tokens in the transpose
# file are obfuscated.
#
stringmethod=token
#
############################################################################
# Version 2.0 Settings
############################################################################
#
# The function and string hide file. This file specifies a package to "hide" or
# strings to hide and then specifies the code to add new PL/SQL processing to
# deal with this and also PL/SQL substitute for the actual located string. This
# is detailed in the help
#
#functionfile=functionfile.txt
#
# This parameter controls whether the intermediate files generated via any lua
# scripts are saved or not. This is useful for debugging.
#
#keepintermediate=yes
#
# This parameter controls whether the source code file containing the injected
# PL/SQL code is kept for debugging. The Injected code file contains all inserted
# headers, functions and the calls where the replace packages or strings. These
# are encased with {{n:n:n}} variables for removal.
#
#keepinsert=yes
#
# This parameter is the file extension used for the intermediate files. This
# can be changed.

Page 26 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

#
#intermediatefile=.imm
#
############################################################################
# Advanced Settings
############################################################################
#
# This parameter controls the amount of RAM allocated for tghe token buffer.
# If a token buffer overflow error is detected by the parser then the size of
# the buffer can be dynamically increased to attempt to solve the problem. The
# buffer size is specified in bytes.
#
tokenbuffersize=2097152
#
# END CONFIG FILE
#

The sample configuration file above shows all of the settings allowed in PFCLObfuscate. The
configuration file does not need to contain comments (starting with “#”) to work so a configuration
file can be much smaller for use. Each setting is now explained:

 Comments are lines that start with a “#” character are comments. The comment line
must start with a “#” at the beginning of the line; the “#” cannot be anywhere else.
 “verbose=yes” will make the logging and error output noisy and show maximum
messages. The default setting is “yes”
 “silent=no|yes” – if set to “yes” then PFCLObfuscate will run silently and reduce the
amout of output. The default setting is “no”
 “timing=yes|no” will add time stamps to the screen output or log output. The default is
“yes”
 “logfile=logfilename.log” – if a filename is specified then the screen output is instead
written to the specified log file.
 “outputfile=transpose.txt” – the outputfile setting specifies the name of the file that will
be created that stores all of the transposed variable and identifier names. So if you have
a variable called “lv_var_val” it may be transformed to “Oill10”. After the processing all
of the source code in a file the file set to the outputfile variable will contain all of the
transformed values. This file should not be shipped with the source code of course.
 “reverseoutput=transpose.rev” – this parameter allows the creation of a reverse
transpose file. As with the transpose file itself, this file should never be shipped with
obfuscated source code as it can also be used to reverse the transpositions. This file
allows you to take it and replace the output file “transpose.txt” with it. This allows a
reversal of the obfuscation of identifiers. This would be useful for debugging/support
issues. If the original code is also compacted and comments removed the original line
numbers no longer match. So this file can be used to replace the “transpose.txt” file and
the snippit of code revealed in a support issue can be obfuscated returning all of the
correct variables.
 “keyword=key.txt” – this parameter allows a text file to be specified that includes all of
the keywords of the PL/SQL language. This file is used by the obfuscator to ensure that
keywords are not obfuscated. Keywords can be used in code as identifiers.
 “reserved=reserved.txt” - the reserved word file works in a similar way to the keyword
file. Oracle specifies a huge number of reserved words within the database itself. These
Page 27 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

can include package names, object names, users, roles and of course Oracle DDL words
such as ALTER. Reserved words cannot be used as identifiers.
 “omit=omit.txt” – the omit file allows you to specify words that should not be
obfuscated. This is useful where a public interface should not be obfuscated. This could
be a package name or function name that is used elsewhere when the name used
cannot be changed elsewhere. Note that SQL*Plus command words such as SET, DEFINE
etc should not be added to the omit.txt file
 “force=force.txt” – the force file allows you to override any word that is not obfuscated
because it is a keyword or reserved word. This force file is generally used on specific
source code files rather than generally. The reason to have a force file is to avoid the
need to modify the keyword or reserved word files for a specific obfuscation.
 “stringomit=string.txt” – the stringomit parameter allows you to specify strings that
should not be obfuscated by PFCLOBfuscate. In some cases such as in some
SYS_CONTEXT calls a string cannot be obfuscated otherwise the resulting PL/SQL code
will not work.
 “sqlplus=sqlplus.txt” – This parameter references the SQL*Plus command parameters. It
is used to specify SQL*plus commands such as SET to SPOOL to PFCLObfuscate
 “compact=yes|no” – This parameter controls whether source code compaction is turned
on or off. Compaction is the process that removes some of the white space from the
PL/SQL source code and makes it harder to read.
 “comment=yes|no” – This parameter controls whether comments are removed from
the source code or not. Note: SQL hints are not removed as part of this processing. This
includes hints written using C Language comments or PL/SQL language comments
 Stringmode; To turn off string obfuscation simply comment out the “stringmode” line in
the configuration file. It is also possible to turn off string obfuscation by setting
“stringmode=0”. It is also possible to omit strings from obfuscation using the string omit
functionality.
o “stringmode=0” – This turns off string obfuscation
o “stringmode=1” – The stringmode controls how the strings are obfuscated and
encoded within PFCLOBfuscate. This changes the string into chr(n)||chr(n)..
o “stringmode=2” – Similar to mode 2 except that the string is converted to chr(n
using nchar_cs)||chr(n using nchar_cs) sequences
o “stringmode=3” – This mode converts a string to sequences of chr(n)||chr(n)
except that when an ASCII string greater than 127 is found the value is
compared to a mapfile that maps values to 500... sequences. This is to allow
correct translation of extended characters
o “stringmode=4” – This mode passes each string in turn back through the parser
and obfuscates any keyword found in each string as a token. So if a token were
xxx but the word bbxxx was in the string it would not match and replace it.
There are limits described in the section on these modes later in the manual but
in general we can obfuscate dynamic code in strings in PL/SQL with this mode
o “Stringmode=5” - First “stringmode=4 “ is applied and then “stringmode=1” is
applied to the result string
o “Stringmode=6” - First “stringmode=4 “ is applied and then “stringmode=2” is
applied to the result string
Page 28 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

o “Stringmode=7” - First “stringmode=4 “ is applied and then “stringmode=3” is


applied to the result string
 “stringcr=@” – This parameter controls the character used to substitute <CR> or \r\n in
strings for the string omit checks. If the string you wish to omit from string obfuscation
includes carriage return then you must convert any carriage return to this character in
the string.txt file. This parameter now allow flexibility in specifying this substitution
 “stringquote=^” – This parameter is used for “code in strings” obfuscation. When
stringmode 4 – 7 is used then each string is passed back into obs.exe and obfuscated as
though it were code. To prevent recursion and broken strings any string identifier (single
quote or double quote) is replaced first with the character specified in this parameter.
After obfuscation (and before further obfuscation such as modes 5 - 7)
 “stringconfig=sob.conf” – This parameter allows specification of a separate ob.conf that
is used to control the obfuscation of individual strings in a source code file as they are
processed as code and not strings. You are free to change the settings in the demo
configuration file “sob.conf” that is shipped with the product.
 “stringkeep=no” – This parameter specifies whether the intermediate files generated as
part of the “strings as code” processing are retained or deleted. This can be used for
debugging.
 “stringmethod=child” – This parameter can be set to “child” or “token” – The “child”
setting causes the child processing of strings to take place. This means that all strings are
passed back into obs.exe as though they were code and all features such as omit, force
etc work. The setting of “token” uses an internal tokeniser to process every string. The
tokeniser recognises tokens made up of [a-zA-Z][a-zA-Z0-9_$#].* but no other
characters. Any token in the transpose file is transposed. The “transposeonly” parameter
does not need to be set for this to work but can be to apply the same logic to code not in
strings
 “debug=no|yes” – If we turn debug on then instead of processing the PL/SQL or SQL file
to obfuscate it, the debug output is instead sent to the output source file. This can be
used to help decide what a “word” in the source code is being processed as. This can
help decide on settings in the configuration files
 “charset=Abfjk10” – the charset parameter is used to specify the character set used by
the obfuscator when generating new random variable and identifier names. The
character set and the length affect the possible set of variables available. If you have
large source files or many source files the combination of length and character set
length must allow for enough variables to potentially be generated.
 “firstseed=Abfjk” – This parameter controls the first character in the generated variable
name. If invalid characters such as #_$0-9 are used in the character set for the variable
then these cannot generally be used as the first character of an identifier unless
protected by double quotes.
 “obfusvarlen=6” – This parameter controls the length of the generated random new
variable names. This length should be considered along with the “charset” variable
above to ensure that enough possible variables exist. For instance you choose to
obfuscate some large files with thousands of variables and you chose a three character
set and a length of 2 then there would only be 27 possible variables and the obfuscation
process would fail.
Page 29 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

 “linelen=120” – The linelen parameter controls the length of the generated source file
line lengths. When compact is enabled then all whitespace including carriage returns are
removed then the source line should be controlled.
 “inputfile=str.sql” – The input file to be obfuscated can be passed via the configuration
file but it is better practice to set up a configuration file that controls the obfuscation
process and to then pass in the input and output file names.
 “obfuscatedfile=str.opf” – This parameter controls the name of the output file after it
has been obfuscated. As with the input file whilst it is possible to pass in the name via
the configuration file it is better to pass the file names via the command line.
 “mapfile=mapfile.txt” – This parameter specifies the character map file used to translate
characters used in stringmode substitutions such as CHR(n) mappings where the
characters translated are extended characters
 “transposeonly=no” – This parameter defines whether the obfuscation of identifiers is
global or is controlled by the transpose file only. If set to “no” the normal operation
continues. This means that any new identifier is obfuscated as normal. If this parameter
is set to “yes” then an identifier is only obfuscated if it is already in the transpose file
 “functionfile=functionfile.txt” – This configuration file controls version 2.0 dynamic
obfuscation. It specifies all of the dynamic substitutions and is explained in detail later in
this manual.
 “keepintermediate=yes” – specifies whether the generated PL/SQL source code created
from each Lua script specified in the functionfile.txt are kept after processing. These files
can be used to help debug your own Lua scripts
 “keepinsert=yes” – specifies whether the intermediate file is retained after processing of
the original source code. This file contains the intermediate state of the dynamic
insertion and is useful for debugging
 “intermediatefile=.imm” – This is the file extension used for the intermediate processed
file. If you chose sample1.opf as the “-o” output file then if this parameter is set to
“.imm” the intermediate file will be “sample1.opf.imm”
 “tokenbuffersize=2097152” – This parameter allows dynamic specification of the
internal token buffer size. You should not normally need to change this but if you
process a very large input file it may be necessary. Consult support for advice on this

The same configuration file can generally be used for all files in a project. It is common to use the
same settings and for the omit file to include all of the public API’s. A later section discusses
obfuscating multiple files in one command.

For parameters where the value is the name of a file such as the “keyword” file or the “omit” file
then it is permissible to include the name of the file as just the name as the examples above show –
“keyword=key.txt” for instance. This means that the file must be in the working directory used by
PFCLObfuscate as no path is specified. It is also permissible to use the full path to a file such as
“keyword=c:\temp\key.txt” so that the file can be loaded from a fixed location.

Page 30 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Prepare Input Files


Before running PFCLObfuscate you must prepare the input files that are needed to control
PFCLObfuscates operation. In general for a project you will use the same input files for all source
files that you will obfuscate but in some cases you may decide to modify these files per source file.

In general you would also only configure these files and inputs once unless new PL/SQL code is to be
obfuscated and then you may need to re-visit these configuration files. These input files are
connected to the obfuscation process by inclusion in the configuration file as described above.

Add each word to the files in upper case. All of the identifiers in the source
code are converted to upper case for comparison so upper case words are
needed to get successful tests. Note: If you use double quoted identifiers in
your code such as “de” then if you wished to omit “de” you would add de to
the omit.txt file in the same case as the double quoted variable and also you
do not include the double quotes in the file.

Each input file is now described:

Keyword File

This file lists PL/SQL, SQL and SQL*Plus keywords. The tool ships a sample file but this is not
always perfect. The number of keywords used by Oracle is extensive and some although
described by Oracle as keywords would not be considered keywords in other languages. The
file shipped with PFCLObfuscate covers actual keywords such as BEGIN and some others that
are not strictly keywords but Oracle says that they are such as CHR which is really a function.
The keywords are resolved first so for performance reasons it is good to include very
common words here.

Reserved Words

This file lists other important words used in PL/SQL, SQL and SQL*Plus scripts. This can
include words like SYS or DBMS_OUTPUT or UTL_FILE which are common usernames,
packages and other objects. The tool ships an SQL script called gr.sql that can be used to
create an initial file. This includes all of the Oracle reserved words in the
SYS.V$RESERVED_WORDS view and also all usernames from your database and also role
names and also all SYS packages and procedures. Expect to extend this file to suite your own
obfuscation requirements and include database objects that are accessed by your code from
other default schemas or to include SYS tables and views for instance. You should edit the
script to add your own definitions or add more words manually.

The construction of this file is simply achieved by running the script. This is the script and
running it. The script is installed to your data directory:

Page 31 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Note: To run the gr.sql script you must connect to a database using SQL*Plus
or other tool such as TOAD or SQL*Developer or PL/SQL Developer. SQL*Plus
is the simplest option and is available as a free download along with the
Oracle Instant Client from Oracles website. An Oracle client is needed to
connect to the database. Simply search on a search engine for “download
Oracle instant client” for the latest download URL. We do not include the
Oracle client in PFCLObfuscate as it is Oracles software.

Omit File

The tool ships a sample empty file omit.txt. The purpose of the omit file is to specify variable
names that should not be obfuscated. Good examples to add to this file would be interface
names that cannot be obfuscated due to calling code not being changeable. For instance if
you have a package called TEST_PROC and that package is used from external sources then
the name TEST_PROC must remain so add the name to the omit.txt file.

An additional tool called apex_omit.sql is also available to use when you are protecting APEX
PL/SQL programs. This is a simple SQL*Plus script that can be executed and it produces an
output file called apex_omit.txt. This can then be edited and added to the omit.txt as
necessary.

Note that SQL*Plus commands such as SET or DEFINE should not be added to the omit file as
these are processed automatically.

Force File

This file includes a list of variables that should be “force” obfuscated even if they are
reserved words or keywords. The tool ships a sample empty file that you can add to. Some

Page 32 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

keywords can be used as variable names in PL/SQL and you may need to obfuscate these in
particular files so the force file becomes useful.

String Omit File

The string omit file is used to specify strings that should not be obfuscated. If string
obfuscation is enabled this will be used. It makes no sense if string obfuscation is not
specified.

There are some cases in PL/SQL where string obfuscation does not work as Oracle cannot
process calls to some features where the string has been converted to chr(nn)||chr(nn)..
statements. These are good candidates for the stringomit.txt file as the processed PL/SQL
without this would not work when it is installed into the database. The known places where
strings cannot be converted are:

1. SYS_CONTEXT
2. Java procedures – the java code itself must still be a string
3. XMLTABLE – the column Ids must be strings still
4. USERENV

Note: When creating the input files it is important to make sure that there are
no blank lines. If blank lines appear in the input files then they are replaced
with a variable of PFCLOBFUSCATEPFCLOBFUSCATE internally within
PFCLObfuscate to prevent blank searches.

The files are simple files with one word per line. Input the lines in upper text
except for the string omit file.

None of these files are mandatory but if the reserved words and keywords are not used then the
code generated will almost certainly never compile because keywords such as “begin” and “end”
would have been obfuscated.

Running PFCLObfuscate
PFCLObfuscate is run from the command line as described earlier. A sample session is shown here as
a tutorial in this section by taking a sample PL/SQL procedure that should be obfuscated and
showing the setup and use of the configuration file and input files and finally the obfuscation itself.

WORK THROUGH THIS EXAMPLE TO GET ACQUAINTED WITH HOW TO USE PFCLOBFUSCATE

It is assumed at the start of this tutorial that you have installed PFCLObfuscate and activated it, it is
also assumed that you have access to an Oracle database remotely or locally to test the PL/SQL code
we are using as an example.

Start PFCLObfuscate by going to Start => Programs => PFCLObfuscate => Execute PFCLObfuscate. You
will now have a DOS command window that started in the data directory for PFCLOBfuscate. In this
directory are a sample PFCLObfuscate configuration file and also sample input files.

Page 33 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

For this tutorial we will use these sample files and modify them where necessary but you can create
your own files either by copying the files shipped with PFCLObfuscate or by creating your own. The
start screen is shown here:

Ideally you should create a working directory; I am calling mine “work” and then copy the
configuration files and also the sample PL/SQL to this directory. This is shown here:

Change to the work directory and set up the reserved.txt file by running the gr.sql script described
earlier in this manual (note that you must have access to an Oracle database that runs the same
version of the Oracle database software as you intend to install my obfuscated PL/SQL code into).
The gr.sql script generates the reserved word file. This by default is called reserved.txt and is
referenced in the sample configuration file ob.conf with the name reserved.txt but you can choose
to name this file whatever you wish to. Change the name in gr.sql and in the configuration file. :

Page 34 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The above example shows that my reserved.txt file had a zero length as installed with
PFCLObfuscate and that i connected to my database as the user SYSTEM and ran the script gr.sql and
that now my file has all users names, roles names, SYS object names and also all reserved words in it.

In a real session with PFCLObfuscate it would make sense to modify this file
further with relevant reserved words dependant on what Oracle software you
access with your PL/SQL. This can be done easily by extending the gr.sql script.

The sample configuration file ob.conf contains references already to the input files that are available
in the software install directory so you can use the configuration file without modification if you
wish. In a real session you would probably want to change the character set and length and string
obfuscation.

The sample PL/SQL that we will obfuscate is shown here:

Page 35 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

For consistency with this example we will install this procedure into the sample database just to
prove that it works and it is valid PL/SQL to protect.

The above output shows that the PL/SQL code installs correctly and when executed it gives some
output. The output is a simple string that makes an extension on the traditional “hello world”
examples used in many programming languages. The code as you can see combines two strings and
a number to produce a simple line of output.

Before we run PFCLOBfuscate we should make one more setup change. The name of the procedure
TEST_PFCL should probably not be obfuscated as it would in real circumstances (i.e. not part of a
simple tutorial such as this) form part of a public interface so its name would need to remain the
same unless all external places it is called from can also be changed.

Add the name TEST_PFCL to the omit.txt file:

Page 36 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Save the file and we are ready for our first attempt to obfuscate this PL/SQL procedure. This is done
from the command line. A sample use of PFCLObfuscate to obfuscate the file tutorial1.sql as shown
above is here:

PFCLObfuscate runs very quickly on a single file of course but the tool shows output logging and
timing which could be useful in bigger projects to report on progress. Note the warning message
above that indicates that if you compact the source comment removal must also be on.

The output file is shown here:

Page 37 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

As you can see the procedure has been compacted, the editor has word wrap enabled but the
output is actually on two lines only:

The comments have been removed from the source code and the variables have been obfuscated
and a simple string obfuscation has been enabled.

Note: String obfuscation is an oxymoron because the strings themselves must


still be output for the end user to see. Any scheme used to encode, obscure,
obfuscate or encrypt strings is not perfect as the attacker if clever can extract
the runtime code he can simply run the code and see the strings turned back
into proper text.

It is still worth the effort on a number of levels to protect strings because


often reverse engineers use strings to search source code to identify areas of
code to attack. When the obfuscated PL/SQL is also wrapped with Oracle’s
wrap.exe program; particularly the 9iR2 and earlier wrap program encoded or
obfuscated strings can be hidden completely. PeteFinnigan.com Limited also
supplies a tool “WrapProtect” as part of this package that can be used to
protect wrapped programs from being unwrapped.

An alternate solution is to use encryption/encoding for strings in separate


obfuscated procedures that also offers run time protection to prevent simple
decoding of strings by an attacker.

Page 38 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

A final option is to have PFCLObfuscate remove strings completely from the


PL/SQL code and instead insert gibberish strings and provide a map file to use
for debugging. This can only work on non-public facing strings.

The final screen shot in this simple getting started tutorial is to show that the obfuscated PL/SQL we
have used for this simple example still compiles and runs and actually shows the same output:

Finally the output file transpose.txt is generated by PFCLObfuscate and it lists the transpositions that
have taken place. The name of this file is configurable in the PFCLObfuscate configuration file. The
contents of this file are the variables and a map of their new obfuscated names:

Note: the transpose file should never be shipped with the obfuscated source
code

Obfuscation Levels
PFCLObfuscate supports a number of types of obfuscation. These include:

 Comment=yes : This option removes comments from the source code. This mode
removes all comments from the source code. This includes PL/SQL comments which
start with “--" and end at the end of the same line. Multi-line comments are the same as
C code and start and end /* ... */. Note: SQL Hints written in C language comments or
PL/SQL language comments are not removed. These are /*+ ... */ or --+ ... <NL>
 Compact=yes: This option compacts the source code to remove all white space from the
source code and compacts all lines into random lines lengths structured around 120
characters. The line length is configured by a parameter
 Obfuscate=yes : This option tells PFCLObfuscate to obfuscate the source code variable
names. These include actual variables, function names, package names, constants etc.
Basically all language elements that are specified by the developer and which are not
Page 39 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

specifically excluded by the configuration file specified by the –m directive will be


obfuscated.
 Stringmode=1 : This option controls string obfuscation. The action assigned to this
parameter controls the level of string obfuscation:
o 0: Turns off string obfuscation
o 1: This simply converts each string such as ‘aa’ into chr(97)||chr(97). This is
improved upon with subsequent string concatenations
o 2: converts to use nchar_cs so the same example from stringmode 1 would be:
chr(97 using nchar_cs)||chr(97 using nchar_cs).
o 3: converts to chr(n)||chr(n) as normal but any extended character found that also
exists in the map file is converted to the value in the map file.

Using Quoted Identifiers


When your PL/SQL code uses identifiers that are surrounded by double quotes such as “de” then
PFCLObfuscate can handle this. A sample PL/SQL file is shown here:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type testdbl.sql


-- ---------------------------------------------------------------
-- Test case for double quoted identifiers
-- ---------------------------------------------------------------

create or replace procedure testdbl is


"de" constant number := 4.1234;
"DE" constant number := 8.234;
"2 de" constant number := 2 * "de";
begin
dbms_output.put_line('"de" => '||"de");
dbms_output.put_line('"DE" => '||”DE”);
dbms_output.put_line('"2 de" => '||"2 de");
end;
/

This can be loaded to the database:

SQL> @testdbl.sql

Procedure created.

SQL>

And executing the procedure will show:

SQL> set serveroutput on size unlimited


SQL> exec testdbl
"de" => 4.1234
"DE" => 8.234
"2 de" => 8.2468

PL/SQL procedure successfully completed.

SQL>

Note:
Page 40 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

This shows that a double quoted variable can be used with its double quotes
or if a variable is defined with double quotes such as “DE” but then a variable
de is referenced then it matches “DE”. This is because the PL/SQL compiler
converts all non quoted identifiers to upper case as it processes them. This
means that de is converted to DE which is the same as “DE”.

This is not a feature of PFCLObfuscate but of PL/SQL of course. Our program


can detect this and it will map “DE” to de but the code will not compile unless
the character set chosen is all upper case because the obfuscated variable say
“Jhgfd” will map to Jhgfd and it will no longer be found. If you use the double
quoted syntax you have probably done so for a reason and usually that is to
work with tools such as MS Access which needs this. We could drop the double
quotes on a double quoted variable such as “DE” as we know that this can
map to any other case insensitive version of DE without quotes BUT this can
break your code down-stream if the double quotes are actually needed.

The solution is to not create variables in double quotes where they are upper
case and then refer to them without quotes. The solution if you use double
quoted variables is to ensure consistency in your naming.

Next we can obfuscate the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


testdbl.sql -o testdbl.opf

PFCLObfuscate: Release 1.0.998.1833 - Production on Tue Apr 30 12:36:22 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Apr 30 11:36:22] obs: Starting PFCLObfuscate...


[2013 Apr 30 11:36:22] obs: Pre-Load Keywords from [key.txt]
[2013 Apr 30 11:36:22] obs: Pre-Load Omit words from [omit.txt]
[2013 Apr 30 11:36:22] obs: Pre-Load StringOmit words from [string.txt]
[2013 Apr 30 11:36:22] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Apr 30 11:36:23] obs: Pre-Load force words from [force.txt]
[2013 Apr 30 11:36:23] obs: Pre-Load function file list from [(null)]
[2013 Apr 30 11:36:23] obs: Pre-Load map file list from [map.txt]
[2013 Apr 30 11:36:23] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Apr 30 11:36:23] obs: Obfuscating PL/SQL Input File [ testdbl.sql ]
[2013 Apr 30 11:36:23] obs: Save the transposed variables
[2013 Apr 30 11:36:23] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The obfuscated code looks like this:

create or replace procedure testdbl is "Aff0jj" constant number := 4.1234; "j0101j" constant
number := 8.234; "ff1kAA" constant
number := 2 * "Aff0jj"; begin
dbms_output.put_line(chr(34)||chr(100)||chr(101)||chr(34)||chr(32)||chr(61)||chr(62)||chr(32)
||"Aff0jj");
dbms_output.put_line(chr(34)||chr(68)||chr(69)||chr(34)||chr(32)||chr(61)||chr(62)||chr(32)||"
j0101j");

Page 41 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

dbms_output.put_line(chr(34)||chr(50)||chr(32)||chr(100)||chr(101)||chr(34)||chr(32)||chr(61)|
|chr(62)||chr(32)||"ff1kAA");
end;
/

This can be loaded into the database and run and the output is the same as before obfuscation.

SQL> @testdbl.opf

Procedure created.

SQL> set serveroutput on


SQL> exec testdbl
"de" => 4.1234
"DE" => 8.234
"2 de" => 8.2468

PL/SQL procedure successfully completed.

SQL>

Adding identifiers to the omit file or the force file or any other input file is the same as normal
except that you must enter the word in its correct case. For normal identifiers we enter the word in
upper case to the files but for quoted identifiers we must use correct case.

For example if we wish to “omit” the variable “de” then we add de in lower case to the omit file:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


CREATE
REPLACE
PROCEDURE
IS
BEGIN
END
DBMS_OUTPUT
PUT_LINE
TESTDBL
de
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

If we now re-obfuscate the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


testdbl.sql -o testdbl.opf

PFCLObfuscate: Release 1.0.998.1833 - Production on Tue Apr 30 13:55:34 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Apr 30 12:55:34] obs: Starting PFCLObfuscate...


[2013 Apr 30 12:55:34] obs: Pre-Load Keywords from [key.txt]
[2013 Apr 30 12:55:34] obs: Pre-Load Omit words from [omit.txt]
[2013 Apr 30 12:55:34] obs: Pre-Load StringOmit words from [string.txt]
[2013 Apr 30 12:55:34] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Apr 30 12:55:34] obs: Pre-Load force words from [force.txt]
[2013 Apr 30 12:55:34] obs: Pre-Load function file list from [(null)]
[2013 Apr 30 12:55:34] obs: Pre-Load map file list from [map.txt]
[2013 Apr 30 12:55:34] obs: Running PFCLObfuscate PL/SQL Obfuscator

Page 42 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2013 Apr 30 12:55:34] obs: Obfuscating PL/SQL Input File [ testdbl.sql ]


[2013 Apr 30 12:55:34] obs: Save the transposed variables
[2013 Apr 30 12:55:34] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>
The output now looks like:

create or replace procedure testdbl is "de" constant number := 4.1234; "fb1bf1" constant
number := 8.234; "A0k10k" constant
number := 2 * "de"; begin
dbms_output.put_line(chr(34)||chr(100)||chr(101)||chr(34)||chr(32)||chr(61)||chr(62)||chr(32)
||"de");
dbms_output.put_line(chr(34)||chr(68)||chr(69)||chr(34)||chr(32)||chr(61)||chr(62)||chr(32)||"
fb1bf1");
dbms_output.put_line(chr(34)||chr(50)||chr(32)||chr(100)||chr(101)||chr(34)||chr(32)||chr(61)|
|chr(62)||chr(32)||"A0k10k");
end;
/
The variable “de” is omitted. If we wish to omit the identifier “2 de” then we add that to the omit file
as well. The omit file can handle spaces when used for a quoted identifier:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


CREATE
REPLACE
PROCEDURE
IS
BEGIN
END
DBMS_OUTPUT
PUT_LINE
TESTDBL
2 de

String Obfuscation
There are three modes for string obfuscation. Each of these is shown as an example below:

Stringmode 0
In addition to turning off string obfuscation by simply commenting out the “stringmode” parameter
in the configuration file you can now also turn off string obfuscation by simply setting the
stringmode parameter to “0”

Stringmode 1
This is the simplest string obfuscation method. The idea is to replace a string such as ‘aa’ with
chr(97)||chr(97). A simple example is now worked through. First we have a sample SQL file (s9.sql):

-- test string obfuscate


create or replace procedure TEST_RUN
is
lv_str varchar2(1000);
lv_str2 varchar2(1000);
lv_str3 varchar2(1000);
begin
lv_str:='test string';
dbms_output.put_line(lv_str);
end;
/

Page 43 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

This can be loaded and executed in the database:

SQL> @s9.sql

Procedure created.

SQL> set serveroutput on


SQL> exec test_run
test string

PL/SQL procedure successfully completed.

SQL>

Now we can obfuscate; first set “stringmode=1” in the config file (mine is the default ob.conf). Also
add “TEST_RUN”, “DBMS_OUTPUT” and “PUT_LINE” to the omit file (mine is called omit.txt)

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


TEST_RUN
DBMS_OUTPUT
PUT_LINE
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now obfuscate the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s9.sql


-o s9.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.912.1538 - Production on Thu Jan 03 10:10:15 2013

Copyright (c) 2012 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 03 10:10:15] obs: Starting PFCLObfuscate...


[2013 Jan 03 10:10:15] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 03 10:10:16] obs: Pre-Load Omit words from [omit.txt]
[2013 Jan 03 10:10:16] obs: Pre-Load StringOmit words from [string.txt]
[2013 Jan 03 10:10:16] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 03 10:10:16] obs: Pre-Load force words from [force.txt]
[2013 Jan 03 10:10:16] obs: Pre-Load function file list from [(null)]
[2013 Jan 03 10:10:16] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Jan 03 10:10:16] obs: Obfuscating PL/SQL Input File [ s9.sql ]
[2013 Jan 03 10:10:16] obs: Save the transposed variables
[2013 Jan 03 10:10:16] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The code now looks like:

create or replace procedure TEST_RUN is bjkbf0 varchar2(1000); k101kA varchar2(1000); k1kbb1


varchar2(1000); begin
bjkbf0:=chr(116)||chr(101)||chr(115)||chr(116)||chr(32)||chr(115)||chr(116)||chr(114)||chr(105
)||chr(110)||chr(103);
dbms_output.put_line(bjkbf0); end;
/

Installing and running:


Page 44 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

SQL> @s9.opf

Procedure created.

SQL> set serveroutput on


SQL> exec test_run
test string

PL/SQL procedure successfully completed.

SQL>

The code is now harder to read but functions exactly the same way as before. The transform to use
chr(n)||chr(n) seems weak but when combined with wrap.exe and wrapprotect.exe it is actually
very strong. The reason is that the wrap file is no longer unwrapable and the symbol table in the
wrap file no longer leaks string information.

Tip: A good trick is to include a variable in each source code scope that defines
all used characters. This variable does not need to be used but it means that
another layer of protection is added as there will no longer be a distinct list of
characters used in all strings shown in the symbol table as instead all
characters are listed (as numbers).

Stringmode 2
String mode 2 is similar to string mode 1 except that the code generated for ‘aa’ is chr(97 using
nchar_cs)||chr(97 using char_cs). This is to allow some sites to use extended characters. This
worked for some clients of ours and was added in version 0.7 and removed in 0.9 but due to
requests we have re-added it back to 1.0. Here is the same example as above but for mode 2.

First change the configuration file to “stringmode=2”, then run the obfuscator:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s9.sql


-o s9.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.912.1538 - Production on Fri Jan 04 15:11:15 2013

Copyright (c) 2012 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 04 15:11:15] obs: Starting PFCLObfuscate...


[2013 Jan 04 15:11:15] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 04 15:11:15] obs: Pre-Load Omit words from [omit.txt]
[2013 Jan 04 15:11:15] obs: Pre-Load StringOmit words from [string.txt]
[2013 Jan 04 15:11:15] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 04 15:11:15] obs: Pre-Load force words from [force.txt]
[2013 Jan 04 15:11:15] obs: Pre-Load function file list from [(null)]
[2013 Jan 04 15:11:15] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Jan 04 15:11:15] obs: Obfuscating PL/SQL Input File [ s9.sql ]
[2013 Jan 04 15:11:15] obs: Save the transposed variables
[2013 Jan 04 15:11:15] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The output now looks like this:

Page 45 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

create or replace procedure TEST_RUN is Afj1bA varchar2(1000); b1A1kj varchar2(1000); kfAbkj


varchar2(1000); begin Afj1bA:=chr(116 using nchar_cs)||chr(101 using nchar_cs)||chr(115 using
nchar_cs)||chr(116 using nchar_cs)||chr(32 using nchar_cs)||chr(115 using nchar_cs)||chr(116
using nchar_cs)||chr(114 using nchar_cs)||chr(105 using nchar_cs)||chr(110 using
nchar_cs)||chr(103 using nchar_cs);
dbms_output.put_line(Afj1bA); end;
/

Load and test in the database:

SQL> @s9.opf

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
test string

PL/SQL procedure successfully completed.

SQL>

This works the same way as stringmode=1

Stringmode 3
Stringmode=3 is used when there are extended characters and the character set is different on the
database and the PC used by PFCLObfuscate.

The map file functionality is described next:

My sample SQL file is s9.sql:

-- test string obfuscate


create or replace procedure TEST_RUN
is
lv_str varchar2(1000);
lv_str2 varchar2(1000);
lv_str3 varchar2(1000);
begin
lv_str:='ÀÁÂÃÄÅtest string';
dbms_output.put_line(lv_str);
end;
/

Now set up my omit.txt:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


TEST_RUN
DBMS_OUTPUT
PUT_LINE
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Load the SQL file into the database first and test (important to show an issue)

SQL> @s9.sql

Page 46 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
└┴┬├─┼test string

PL/SQL procedure successfully completed.

SQL>

Obfuscating with mode 1:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s9.sql


-o s9.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.912.1538 - Production on Mon Jan 07 15:47:24 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 07 15:47:24] obs: Starting PFCLObfuscate...


[2013 Jan 07 15:47:24] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 07 15:47:24] obs: Pre-Load Omit words from [omit.txt]
[2013 Jan 07 15:47:24] obs: Pre-Load StringOmit words from [string.txt]
[2013 Jan 07 15:47:24] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 07 15:47:24] obs: Pre-Load force words from [force.txt]
[2013 Jan 07 15:47:24] obs: Pre-Load function file list from [(null)]
[2013 Jan 07 15:47:24] obs: Pre-Load map file list from [map.txt]
[2013 Jan 07 15:47:24] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Jan 07 15:47:24] obs: Obfuscating PL/SQL Input File [ s9.sql ]
[2013 Jan 07 15:47:24] obs: Save the transposed variables
[2013 Jan 07 15:47:24] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

This produces:

create or replace procedure TEST_RUN is k1b10A varchar2(1000); bjkA11 varchar2(1000); jf0AAb


varchar2(1000); begin
k1b10A:=chr(192)||chr(193)||chr(194)||chr(195)||chr(196)||chr(197)||chr(116)||chr(101)||chr(11
5)||chr(116)||chr(32)||chr(115)||chr(116)||chr(114)||chr(105)||chr(110)||chr(103);
dbms_output.put_line(k1b10A); end;
/

Then installing this output into the database:

SQL> @s9.opf

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
└┴┬├─┼test string

PL/SQL procedure successfully completed.

SQL>

Page 47 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

This is not what we want. Clearly the ASCII values returned from the file system character set are
incorrect as they get translated into chr(192)||chr(193)||chr(194)||chr(195)||chr(196)||chr(197)
for the string ‘ÀÁÂÃÄÅ’ which gives us the box characters when we actually wanted accented
characters.

There are a number of factors to take into account; the PC character set and language used on the
PC to do the obfuscation and also the database character set and language especially where they do
not match. This needs to be understood and used as the map file parameters to get the correct input
for the database to display the correct characters.

Work out the database ASCII values for the accented characters that we would like map:

SQL> select ascii('À') from dual;

ASCII('À')
----------
183

SQL> select ascii('Á') from dual;

ASCII('Á')
----------
181

SQL> select ascii('Â') from dual;

ASCII('Â')
----------
182

SQL> select ascii('Ã') from dual;

ASCII('Ã')
----------
199

SQL> select ascii('Ä') from dual;

ASCII('Ä')
----------
142

SQL> select ascii('Å') from dual;

ASCII('Å')
----------
143

SQL>

Now add to the map file. First use the chr(n) values returned from a stringmode=1 example above
and combine with the ASCII() values returned from the database. Again be aware that the chr values
are found on the PC used for obfuscating and not the database server. The ASCII values for the same
extended character need to come from the database:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type map.txt


192|183
193|181

Page 48 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

194|182
195|199
196|142
197|143
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Set the stringmode=3 in the configuration file. Now obfuscate:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s9.sql


-o s9.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.912.1538 - Production on Mon Jan 07 16:02:28 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 07 16:02:28] obs: Starting PFCLObfuscate...


[2013 Jan 07 16:02:28] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 07 16:02:28] obs: Pre-Load Omit words from [omit.txt]
[2013 Jan 07 16:02:28] obs: Pre-Load StringOmit words from [string.txt]
[2013 Jan 07 16:02:28] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 07 16:02:28] obs: Pre-Load force words from [force.txt]
[2013 Jan 07 16:02:28] obs: Pre-Load function file list from [(null)]
[2013 Jan 07 16:02:28] obs: Pre-Load map file list from [map.txt]
[2013 Jan 07 16:02:28] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Jan 07 16:02:28] obs: Obfuscating PL/SQL Input File [ s9.sql ]
[2013 Jan 07 16:02:28] obs: Save the transposed variables
[2013 Jan 07 16:02:28] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The output is:

create or replace procedure TEST_RUN is k1b10A varchar2(1000); bjkA11 varchar2(1000); jf0AAb


varchar2(1000); begin
k1b10A:=chr(183)||chr(181)||chr(182)||chr(199)||chr(142)||chr(143)||chr(116)||chr(101)||chr(11
5)||chr(116)||chr(32)||chr(115)||chr(116)||chr(114)||chr(105)||chr(110)||chr(103);
dbms_output.put_line(k1b10A); end;
/

Install into the database and test:

SQL> @s9.opf

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
ÀÁÂÃÄÅtest string

PL/SQL procedure successfully completed.

SQL>

This now works correctly and shows the correct extended accented characters in the database after
being obfuscated.

Page 49 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Note: We may provide an automated tool to do this in a later version but for
now the process above can be followed manually. The tool will need to be run
from the obfuscation machine (PC) and would need to be able to connect to
the database to get the correct ASCII values. This utility may become available
soon and it will only require the extended character set to be passed to it and
it will generate the map.txt file

Stringmode 4 To Stringmode 7
Stringmodes 4 to 7 are provided to allow the obfuscation of strings BUT to also take into account the
need to obfuscate strings where the strings are actually code. An example of this would be a simple
dynamic piece of code such as:

lv_stmt:='begin test_proc(:var1,:varstr,:var2); end;';

If this string were obfuscated with modes 1-3 then the keyword test_proc would still be test_proc
but transformed into a string of chr(nn)||chr(nn)... statements. If test_proc were defined in a
separate source code file and this file is also obfuscated; say to KBAA1 then the code would actually
fail. We have two sample programs sam3.sql and sam4.sql located in the samples directory that can
be used to test modes 4 – 7 of string obfuscation. If we obfuscate sam3.sql and sam4.sql as normal
with stringmode set to 1 and simply try and run the code it will fail when the dynamic block is
executed. We can use the SQL*Plus script st.sql also located in the samples directory to execute the
original no-obfuscated code in sam3.sql and sam4.sql and also to run the obfuscated code output in
sam3.opf and sam4.opf.

First we will show some examples and then we will explain the modes and also the parameters and
limits. Here is an example walkthrough:

First add DEMO_RUN to the omit.txt file (not shown) and then obfuscate both files as normal
(stringmode=1 and stringkeep=no – we will change these later):

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam4.sql -o sam4.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Wed Apr 15 09:06:46 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Apr 15 08:06:46] obs: Starting PFCLObfuscate...


[2015 Apr 15 08:06:46] obs: Pre-Load Keywords from [key.txt]
[2015 Apr 15 08:06:46] obs: Pre-Load Omit words from [omit.txt]
[2015 Apr 15 08:06:46] obs: Pre-Load StringOmit words from [string.txt]
[2015 Apr 15 08:06:46] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Apr 15 08:06:46] obs: Pre-Load force words from [force.txt]
[2015 Apr 15 08:06:46] obs: Pre-Load function file list from [(null)]
[2015 Apr 15 08:06:46] obs: Pre-Load map file list from [map.txt]
[2015 Apr 15 08:06:46] obs: Initialise the string file list...
[2015 Apr 15 08:06:46] obs: Version 2.0 Initialisation...
[2015 Apr 15 08:06:46] obs: Initialise the file list...
[2015 Apr 15 08:06:46] obs: Initialise the Depth Stack...
[2015 Apr 15 08:06:46] obs: Initialise the FWD Function list...
[2015 Apr 15 08:06:46] obs: Initialise the FUNC function list...
[2015 Apr 15 08:06:46] obs: Initialise the NEW function list...
[2015 Apr 15 08:06:46] obs: Running PFCLObfuscate PL/SQL Obfuscator
Page 50 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2015 Apr 15 08:06:46] obs: Obfuscating PL/SQL Input File [ sam4.sql ]


[2015 Apr 15 08:06:47] obs: Save the transposed variables
[2015 Apr 15 08:06:47] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam3.sql -o sam3.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Wed Apr 15 09:06:52 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Apr 15 08:06:52] obs: Starting PFCLObfuscate...


[2015 Apr 15 08:06:52] obs: Pre-Load Keywords from [key.txt]
[2015 Apr 15 08:06:52] obs: Pre-Load Omit words from [omit.txt]
[2015 Apr 15 08:06:52] obs: Pre-Load StringOmit words from [string.txt]
[2015 Apr 15 08:06:52] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Apr 15 08:06:52] obs: Pre-Load force words from [force.txt]
[2015 Apr 15 08:06:52] obs: Pre-Load function file list from [(null)]
[2015 Apr 15 08:06:52] obs: Pre-Load map file list from [map.txt]
[2015 Apr 15 08:06:52] obs: Initialise the string file list...
[2015 Apr 15 08:06:52] obs: Version 2.0 Initialisation...
[2015 Apr 15 08:06:52] obs: Initialise the file list...
[2015 Apr 15 08:06:52] obs: Initialise the Depth Stack...
[2015 Apr 15 08:06:52] obs: Initialise the FWD Function list...
[2015 Apr 15 08:06:52] obs: Initialise the FUNC function list...
[2015 Apr 15 08:06:52] obs: Initialise the NEW function list...
[2015 Apr 15 08:06:52] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Apr 15 08:06:52] obs: Obfuscating PL/SQL Input File [ sam3.sql ]
[2015 Apr 15 08:06:52] obs: Save the transposed variables
[2015 Apr 15 08:06:52] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now run st.sql. This script creates a new database user OB and connects as that user. It then loads
sam4.sql and sam3.sql – the non obfuscated code. It then executes DEMO_RUN and this works fine.
Next the script drops the two procedures created (TEST_PROC and DEMO_RUN) and then loads the
normally obfuscated versions sam4.opf and sam3.opf:

SQL> @st
Connected.
USER is "SYSTEM"

User dropped.

User created.

Grant succeeded.

Grant succeeded.

Connected.
USER is "OB"
USER is "OB"

Procedure created.

Procedure created.

Page 51 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

e
Run TEST_PROC direct
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3
set up the dynamic test_pro call
[begin test_proc(:var1,:varstr,:var2); end;]
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
end of dyn TEST_P call

PL/SQL procedure successfully completed.

Procedure dropped.

Procedure dropped.

Procedure created.

Procedure created.

e
Run TEST_PROC direct
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3
set up the dynamic test_pro call
[begin test_proc(:var1,:varstr,:var2); end;]
BEGIN demo_run('hello again'); END;

*
ERROR at line 1:
ORA-06550: line 1, column 7:
PLS-00201: identifier 'TEST_PROC' must be declared
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored
ORA-06512: at "OB.DEMO_RUN", line 13
ORA-06512: at line 1

SQL>

The important part of the script output is the PLS-00201 error that states TEST_PROC must be
declared. This is because TEST_PROC is called in a dynamic piece of code. As you can see the
dynamic call to TEST_PROC failed because the procedure TEST_PROC was obfuscated to a different
name and the dynamic call was treated simply as a string and therefore not obfuscated as code.

Page 52 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Four new modes are available to now obfuscate strings “as code”. There are issues and limits related
to this which are listed at the end but in general we can obfuscate strings and treat them as code.
These string modes are described here:

 Mode 4: This mode obfuscates a string as though it were program text. This obfuscates any
token that is already in the transpose.txt file from any previous obfuscation and returns the
string as text (with the new transpositions).
 Mode 5: This mirrors mode 1 and mode 4. First the string is obfuscated as though it was
code and tokens transposed based on existing transpositions. Then this obfuscated code
string is obfuscated with the same rules as mode 1
 Mode 6: This mirrors mode 2 and mode 4. As with above, first mode 4 is applied and then
mode 2
 Mode 7: This mirrors mode 3 and mode 4. As with above, first mode 4 is applied and then
mode 3

These modes 4 - 7 are just as sophisticated as normal code obfuscation and all of the same controls
such as omit lists, force lists, string omit, comment removal, transpose only and even version 2.0
features work (note version 2.0 depends on the code in the string being obfuscated and should be
considered carefully).

Modes 4 – 7 work by extracting each string and then running each string through obs.exe again to
obfuscate it. This is controlled by a second ob.conf configuration file and you can configure this to
suit your needs. This file is specified in the main configuration file.

There are a number of new parameters added for modes 4 – 7; these are described in the
“Configuration File” section starting on page 22. Next is an example showing the steps to obfuscate
the same source code files; sam4.sql and sam3.sql used above. As you remember the dynamic call to
TEST_PROC failed in DEMO_RUN because the code string in which it is embedded was not
obfuscated.

Let us run the demo again. First obfuscate sam4.sql – the procedure:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam4.sql -o sam4.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Wed Apr 15 16:24:47 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Apr 15 15:24:47] obs: Starting PFCLObfuscate...


[2015 Apr 15 15:24:47] obs: Pre-Load Keywords from [key.txt]
[2015 Apr 15 15:24:47] obs: Pre-Load Omit words from [omit.txt]
[2015 Apr 15 15:24:47] obs: Pre-Load StringOmit words from [string.txt]
[2015 Apr 15 15:24:47] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Apr 15 15:24:47] obs: Pre-Load force words from [force.txt]
[2015 Apr 15 15:24:47] obs: Pre-Load function file list from [(null)]
[2015 Apr 15 15:24:47] obs: Pre-Load map file list from [map.txt]
[2015 Apr 15 15:24:47] obs: Initialise the string file list...
[2015 Apr 15 15:24:47] obs: Version 2.0 Initialisation...
[2015 Apr 15 15:24:47] obs: Initialise the file list...
[2015 Apr 15 15:24:47] obs: Initialise the Depth Stack...
[2015 Apr 15 15:24:47] obs: Initialise the FWD Function list...
[2015 Apr 15 15:24:47] obs: Initialise the FUNC function list...
[2015 Apr 15 15:24:47] obs: Initialise the NEW function list...
Page 53 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2015 Apr 15 15:24:47] obs: Running PFCLObfuscate PL/SQL Obfuscator


[2015 Apr 15 15:24:47] obs: Obfuscating PL/SQL Input File [ sam4.sql ]
[2015 Apr 15 15:24:47] obs: Save the transposed variables
[2015 Apr 15 15:24:47] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now we need to edit the ob.conf file and change stringmode=4 so that the strings are treated as
code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>findstr /irc:"string.*="


ob.conf
# PF 01-Jan-2013 Added stringmode=2 and 3
stringomit=string.txt
stringmode=4
stringcr=@
stringquote=^
stringconfig=sob.conf
stringkeep=no

Now we can obfuscate sam3.sql and see if the dynamic code is now obfuscated:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam3.sql -o sam3.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Wed Apr 15 18:17:49 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Apr 15 17:17:49] obs: Starting PFCLObfuscate...


[2015 Apr 15 17:17:49] obs: Pre-Load Keywords from [key.txt]
[2015 Apr 15 17:17:49] obs: Pre-Load Omit words from [omit.txt]
[2015 Apr 15 17:17:49] obs: Pre-Load StringOmit words from [string.txt]
[2015 Apr 15 17:17:49] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Apr 15 17:17:49] obs: Pre-Load force words from [force.txt]
[2015 Apr 15 17:17:49] obs: Pre-Load function file list from [(null)]
[2015 Apr 15 17:17:49] obs: Pre-Load map file list from [map.txt]
[2015 Apr 15 17:17:49] obs: Initialise the string file list...
[2015 Apr 15 17:17:49] obs: Version 2.0 Initialisation...
[2015 Apr 15 17:17:49] obs: Initialise the file list...
[2015 Apr 15 17:17:49] obs: Initialise the Depth Stack...
[2015 Apr 15 17:17:49] obs: Initialise the FWD Function list...
[2015 Apr 15 17:17:49] obs: Initialise the FUNC function list...
[2015 Apr 15 17:17:49] obs: Initialise the NEW function list...
[2015 Apr 15 17:17:49] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Apr 15 17:17:49] obs: Obfuscating PL/SQL Input File [ sam3.sql ]
[2015 Apr 15 17:17:49] obs: Save the transposed variables
[2015 Apr 15 17:17:49] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now run the st.sql SQL*Plus script again. This installs the pure PL/SQL versions of sam4.sql and
sam3.sql into a new schema called OB and then it drops the two procedures from the database and
installs the newly obfuscated versions in sam4.opf and sam3.opf and tries a stack call of TEST_PROC
and a dynamic call of TEST_PROC via DEMO_RUN:

SQL> @st
Connected.
Page 54 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

USER is "SYSTEM"

User dropped.

User created.

Grant succeeded.

Grant succeeded.

Connected.
USER is "OB"
USER is "OB"

Procedure created.

Procedure created.

e
Run TEST_PROC direct
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3
set up the dynamic test_pro call
[begin test_proc(:var1,:varstr,:var2); end;]
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
end of dyn TEST_P 'call

PL/SQL procedure successfully completed.

Procedure dropped.

Procedure dropped.

Procedure created.

Procedure created.

e
Run j10j1k direct
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3
set up the dynamic kkA01f call
[begin j10j1k(:var1,:varstr,:var2); end;]
This is a header
The number is 6
The case var is 3

Page 55 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The elsif clause


nested=:4
end of dyn j0k1kb 'call

PL/SQL procedure successfully completed.

SQL>

This now works correctly as the dynamic code was now obfuscated. The code now reads:

bf10bf:='begin j10j1k(:var1,:varstr,:var2); end;

TEST_PROC was transposed from TEST_PROC to J10J1K:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>findstr /irc:test_proc


transpose.txt
TEST_PROC|j10j1k

Next we can repeat the test and change the stringmode to 5 so that the dynamic string is obfuscated
as well; running through the same steps but choosing stringmode=5 obfuscated the code. The
relevant section in sam3.opf can be found by looking for := from the end of the file:

);
bfAjjA:=chr(98)||chr(101)||chr(103)||chr(105)||chr(110)||chr(32)||chr(98)||chr(106)||chr(107)|
|chr(48)||chr(106)||chr(48)

Now the code is obfuscated in the manner of stringmode=1 and it works:

...
e
Run bjk0j0 direct
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3
set up the dynamic bj10kf call
[begin bjk0j0(:var1,:varstr,:var2); end;]
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
end of dyn fkb1A0 'call

PL/SQL procedure successfully completed.

SQL>

The parameter stringquote is used to null quotes in strings in the source code file to prevent
recursive string processing problems. A single quote with no partner would be extracted incorrectly
when the string including it was passed back into obs.exe. If the strinquote parameter itself appears

Page 56 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

in the strings in the code then this will cause an issue as after the processing of the string the
stringquote parameter is replaced again in the processed string with the original quote. This would
be incorrect as the character was not a quote originally and would be changed to a quote. A
message is emitted to detect this. First add a stringquote character to a string in sam3.sql:

create or replace procedure DEMO_RUN(pv_input in varchar2)


is
lv_one number:=1;
lv_two number:=3;
lv_str varchar2(32767):='';
--
lv_stmt varchar2(32767);
--
procedure p(l in varchar2) is begin dbms_output.put_line(l); end;
function c(n pls_integer) return varchar2 is begin return(chr(n));end;
begin
dbms_output.put_line(c(101));
dbms_output.new_line();
p('Run ^TEST_PROC^ direct');
test_proc(lv_one,pv_input,lv_two);
p('return var='||lv_two);
dbms_output.put_line('set up the dynamic test_pro call');
lv_stmt:='begin test_proc(:var1,:varstr,:var2); end;';
dbms_output.put_line('['||lv_stmt||']');
execute immediate lv_stmt using lv_one,pv_input, in out lv_two;
dbms_output.put_line('end of dyn TEST_P ''call');
end;
/

Now obfuscate this:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam3.sql -o sam3.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Wed Apr 15 20:26:48 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Apr 15 19:26:48] obs: Starting PFCLObfuscate...


[2015 Apr 15 19:26:48] obs: Pre-Load Keywords from [key.txt]
[2015 Apr 15 19:26:48] obs: Pre-Load Omit words from [omit.txt]
[2015 Apr 15 19:26:48] obs: Pre-Load StringOmit words from [string.txt]
[2015 Apr 15 19:26:48] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Apr 15 19:26:48] obs: Pre-Load force words from [force.txt]
[2015 Apr 15 19:26:48] obs: Pre-Load function file list from [(null)]
[2015 Apr 15 19:26:48] obs: Pre-Load map file list from [map.txt]
[2015 Apr 15 19:26:48] obs: Initialise the string file list...
[2015 Apr 15 19:26:48] obs: Version 2.0 Initialisation...
[2015 Apr 15 19:26:48] obs: Initialise the file list...
[2015 Apr 15 19:26:48] obs: Initialise the Depth Stack...
[2015 Apr 15 19:26:48] obs: Initialise the FWD Function list...
[2015 Apr 15 19:26:48] obs: Initialise the FUNC function list...
[2015 Apr 15 19:26:48] obs: Initialise the NEW function list...
[2015 Apr 15 19:26:48] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Apr 15 19:26:48] obs: Obfuscating PL/SQL Input File [ sam3.sql ]
Warning: stringquote exists in the string [2] times
[2015 Apr 15 19:26:49] obs: Save the transposed variables
[2015 Apr 15 19:26:49] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Page 57 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The warning line captures the fact that the stringquote character “^” exists in the string. You should
take note of this and use a different stringquote for this source file in the ob.conf file.

Limits in code in string processing


 All strings in a file are processed in the same way so at present there is no way to target
some strings differently. In version 2.1 when string processing will be provided via the
functionfile and Lua scripts this may be possible. Until version 2.1 a source file can be
processed more than once and use stringomit to select strings to be processed differently.
 String processing is not recursive. Any string in the source code file is processed but any
embedded string in those strings is then not processed separately. The stringquote
parameter prevents this from happening and it is not possible to remove this limit
 The version 2.0 Functionfile processing (see the version 2.0 sections for details) needs
careful use if used within a string. The string must contain complete PL/SQL structure. If
other strings in the same source code do not contain the same the obfuscation will not work
correctly. Version 2.0 functionality in strings needs to be managed carefully but can work
provided the dynamic code is complete and in isolation. Note: stringomit can be used to
protect other strings
 Any token in a string that is not code will be obfuscated

There is a second mode to code in string processing. The “stringmethod” parameter can be set to
“child” for all of the above processing or “token” for simpler tokeniser processing. In this second
mode none of the above configuration is needed. The above parameters are only needed for “child”.
The “token” mode has some limits. The tokens must be of standard naming conventions. The token
must start with a letter and be composed of letters/digits and the three specials (_$#) only. All
tokens found in the transpose file are transposed but transposeonly does not affect the strings as in
child mode.

This “token” mode is much faster on larger source files.

String Omit Example


When using the string omit feature (used via stringomit=string.txt in the configuration file – note you
can choose any file name not just string.txt ) you must specify strings to omit in the specified file
with un-escaped quotes. For instance if the PL/SQL source code shows:

create or replace procedure test_string as


lv_str varchar2(40):='This is a string '' with a quote in it';
lv_2 varchar2(32):='';
begin
dbms_output.put_line('Hello this is a string');
dbms_output.put_line(lv_str);
dbms_output.put_line('hello another');
end;
/

And you would like to not obfuscate the string highlighted in yellow then the string must be added
to the string omit file specified via the configuration file without the beginning and end quotes and
without the escaped single quote – add the string exactly as below; one string is added per line:

Hello this is a string


Page 58 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

This is a string ' with a quote in it

Running this example:

The output file is shown:

create or replace procedure test_string as lliQlliO0i varchar2(40):='This is a string '' with


a quote in it';
OlQOiQii0i varchar2(32):=null; begin dbms_output.put_line('Hello this is a string');
dbms_output.put_line(lliQlliO0i); dbms_output.put_line(chr(104)||chr(101)
||chr(108)||chr(108)||chr(111)||chr(32)||chr(97)||chr(110)||chr(111)||chr(116)
||chr(104)||chr(101)||chr(114));
end;
/

The two strings specified are now not obfuscated. One example string included a single embedded
quote. This is preserved also.

String Omit with <CR>


If you have a string that you wish to not obfuscate but that string has a carriage return embedded in
it (Note: The source code must be a Windows/DOS file with \r\n end of lines (or 0x0D,0x0A) not Unix
line endings. The product includes tools to convert between DOS and Unix line endings).

Imagine we have a PL/SQL source code file that includes a string that has a carriage return in it:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type stringcr.sql


-- ------------------------------------------------------------
-- Sample file to show string omit working with a <CR> in the
-- string to be omitted.
-- ------------------------------------------------------------

create or replace procedure teststr is


lv_str varchar2(50):='this is a string with a <cr>
in it';
lv_str2 varchar2(50):='This is a string with a '' quote in it';
begin
dbms_output.put_line(lv_str);
end;
/
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Note: This file is included in the samples directory.


Page 59 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

If we wish to not obfuscate the string with string in it then we need to add the string to the string
omit text file (note: this is the stringomit file and you can give it any file name that you wish in the
config file. Ours is called string.txt). Here it is:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type string.txt


this is a string with a <cr> @ in it
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

This is the trickiest part of configuring string omit. You must copy the string that you do not want to
obfuscate from the source code file and add it to the string omit file but change the carriage return
to ‘@’ instead. The arbitrary choice of symbol, ‘@’ in this case is acceptable as we always replace the
‘\r\n’ with ‘@’ in the string omit file and the PFCLObfuscate program replaces the same in its
processing so the choice of character as a replacement is immaterial provided it actually replaces the
‘\r\n’. The simplest way to do this is copy the string into the string omit file including the carriage
return and then go to the end of the line and press delete once, this will remove the carriage return
and bring the next line into the current line. Then insert ‘@’. There can be any number of carriage
returns in a string, within the string length imposed by PL/SQL of course.

We can then test this by obfuscating:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


stringcr.sql -o stringcr.opf

PFCLObfuscate: Release 1.0.998.1833 - Production on Tue Apr 30 21:13:01 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Apr 30 20:13:01] obs: Starting PFCLObfuscate...


[2013 Apr 30 20:13:01] obs: Pre-Load Keywords from [key.txt]
[2013 Apr 30 20:13:01] obs: Pre-Load Omit words from [omit.txt]
[2013 Apr 30 20:13:01] obs: Pre-Load StringOmit words from [string.txt]
[2013 Apr 30 20:13:01] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Apr 30 20:13:01] obs: Pre-Load force words from [force.txt]
[2013 Apr 30 20:13:01] obs: Pre-Load function file list from [(null)]
[2013 Apr 30 20:13:01] obs: Pre-Load map file list from [map.txt]
[2013 Apr 30 20:13:01] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Apr 30 20:13:01] obs: Obfuscating PL/SQL Input File [ stringcr.sql ]
[2013 Apr 30 20:13:01] obs: Save the transposed variables
[2013 Apr 30 20:13:01] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

This produces:

create or replace procedure A1fjjj is fjjfbk varchar2(50):='this is a string with a <cr>


in it'; kbkf1j
varchar2(50):=chr(84)||chr(104)||chr(105)||chr(115)||chr(32)||chr(105)||chr(115)||chr(32)||chr
(97)||chr(32)||chr(115)||chr(116)||chr(114)||chr(105)||chr(110)||chr(103)||chr(32)||chr(119)||
chr(105)||chr(116)||chr(104)||chr(32)||chr(97)||chr(32)||chr(39)||chr(32)||chr(113)||chr(117)|
|chr(111)||chr(116)||chr(101)||chr(32)||chr(105)||chr(110)||chr(32)||chr(105)||chr(116);
begin dbms_output.put_line(fjjfbk); end;
/

Page 60 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The above obfuscated code output illustrates that the string with the carriage return is not
obfuscated.

TransposeOnly Example
The transposeonly functionality allows you to control the way identifiers are obfuscated. This
functionality is intended to be used across multiple source code files. When “transposeonly=no”
then normal mode is maintained and all identifiers that are located in source code files are
obfuscated where it is appropriate (i.e. the identifier is not in the force, omit, keyword, reserved or
functionfile lists).

If “transposeonly=yes” then the new transpose only functionality is enabled. In this mode the
obfuscation is limited by the current contents of the transpose.txt file. When it is valid for an
identifier to be obfuscated the force, omit, reserved, key and functionfiles are all consulted first as
normal. If an identifier could be obfuscated then at this stage the transposeonly parameter takes
over. If an identifier is in the transpose.txt file already then it is obfuscated; if not then the original
token text is returned.

A good use of this functionality is to avoid the need to list all interface variables (package procedure
parameters and globals) that are used in source code files in the omit.txt file. An example would be
APEX PL/SQL where a package can be obfuscated but the generated SQL*Plus scripts that access and
use the package need to refer to the calling context correctly and use the public parameter names.

A simple example is shown here:

We use sample files sam2.sql and sam1.sql seen in other examples in this manual. The goal is to
obfuscate the package TEST_PROC in sam2.sql as normal and then to turn on “transposeonly” before
obfuscating sam1.sql which uses the package TEST_PROC. We do not wish to do further obfuscation
in sam1.sql except to obfuscate any identifiers from sam2.sql. This parameter works well in this
respect and also remember that the force and omit files still work if necessary to override any
obfuscated variables in sam2.sql – careful use of this would be needed to ensure that code still
functions.

If we obfuscate sam2.sql with “transposeonly=no”:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam2.sql -o sam2.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Tue Mar 31 09:43:35 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Mar 31 08:43:35] obs: Starting PFCLObfuscate...


[2015 Mar 31 08:43:35] obs: Pre-Load Keywords from [key.txt]
[2015 Mar 31 08:43:35] obs: Pre-Load Omit words from [omit.txt]
[2015 Mar 31 08:43:35] obs: Pre-Load StringOmit words from [string.txt]
[2015 Mar 31 08:43:35] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Mar 31 08:43:35] obs: Pre-Load force words from [force.txt]
[2015 Mar 31 08:43:35] obs: Pre-Load function file list from [(null)]
[2015 Mar 31 08:43:35] obs: Pre-Load map file list from [map.txt]
[2015 Mar 31 08:43:35] obs: Version 2.0 Initialisation...
Page 61 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2015 Mar 31 08:43:35] obs: Initialise the file list...


[2015 Mar 31 08:43:35] obs: Initialise the Depth Stack...
[2015 Mar 31 08:43:35] obs: Initialise the FWD Function list...
[2015 Mar 31 08:43:35] obs: Initialise the FUNC function list...
[2015 Mar 31 08:43:35] obs: Initialise the NEW function list...
[2015 Mar 31 08:43:35] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Mar 31 08:43:35] obs: Obfuscating PL/SQL Input File [ sam2.sql ]
[2015 Mar 31 08:43:35] obs: Save the transposed variables
[2015 Mar 31 08:43:35] obs: Closing Down PFCLObfuscate

Then this results in the following entries in the transpose.txt file:

TEST_PROC|Affjbf
PV_NUM|jb1b01
PV_VAR|Af1Ajb
PV_VAR3|jfjffb
L_NUM|kkAAkf
L_VAR|kkjf10
J|jb0kAf
PV_LEN|b0bfjk
X|jbb1fb

Then we obfuscate sam1.sql with the same tranposeonly setting we get additional entries in the
transpose.txt file:

TEST_PROC|Affjbf
PV_NUM|jb1b01
PV_VAR|Af1Ajb
PV_VAR3|jfjffb
L_NUM|kkAAkf
L_VAR|kkjf10
J|jb0kAf
PV_LEN|b0bfjk
X|jbb1fb
PV_INPUT|bffb0j
LV_ONE|b0bjkb
LV_TWO|jkk1b1
L|kkjkfj
N|A0bb1k

We can see that obfuscating sam1.sql resulted in additional obfuscations (highlighted in yellow). If
we now repeat the experiment after clearing the transpose.txt file and obfuscate sam2.sql again we
get:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam2.sql -o sam2.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Tue Mar 31 09:47:12 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Mar 31 08:47:12] obs: Starting PFCLObfuscate...


[2015 Mar 31 08:47:12] obs: Pre-Load Keywords from [key.txt]
[2015 Mar 31 08:47:12] obs: Pre-Load Omit words from [omit.txt]
[2015 Mar 31 08:47:12] obs: Pre-Load StringOmit words from [string.txt]
[2015 Mar 31 08:47:12] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Mar 31 08:47:12] obs: Pre-Load force words from [force.txt]
[2015 Mar 31 08:47:12] obs: Pre-Load function file list from [(null)]

Page 62 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2015 Mar 31 08:47:12] obs: Pre-Load map file list from [map.txt]
[2015 Mar 31 08:47:12] obs: Version 2.0 Initialisation...
[2015 Mar 31 08:47:12] obs: Initialise the file list...
[2015 Mar 31 08:47:12] obs: Initialise the Depth Stack...
[2015 Mar 31 08:47:12] obs: Initialise the FWD Function list...
[2015 Mar 31 08:47:13] obs: Initialise the FUNC function list...
[2015 Mar 31 08:47:13] obs: Initialise the NEW function list...
[2015 Mar 31 08:47:13] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Mar 31 08:47:13] obs: Obfuscating PL/SQL Input File [ sam2.sql ]
[2015 Mar 31 08:47:13] obs: Save the transposed variables
[2015 Mar 31 08:47:13] obs: Closing Down PFCLObfuscate

And this results in the following entries in the transpose.txt file:

TEST_PROC|bb00ff
PV_NUM|j0kA0b
PV_VAR|j0kA1A
PV_VAR3|ffbjfk
L_NUM|A0j0fk
L_VAR|kj1bkk
J|k0kbk0
PV_LEN|bfkk1b
X|f110Aj

This is the same as before except that the obfuscated identifiers have changed to new names. Next
we enabled transposeonly in the ob.conf file by setting it to yes:

...
# This parameter controls whether PFCLObfuscate attempts to obfuscate all tokens
# or only obfuscates those tokens already present in the transpose.txt file. A
# setting of no means obfuscate all tokens as normal and a setting of yes means
# only obfuscate based on existing entries in the transpose.txt file.
#
transposeonly=yes
#
...

Now we obfuscate sam1.sql:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam1.sql -o sam1.opf

PFCLObfuscate: Release 2.0.219.1606 - Production on Tue Mar 31 09:48:55 2015

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2015 Mar 31 08:48:55] obs: Starting PFCLObfuscate...


[2015 Mar 31 08:48:55] obs: Pre-Load Keywords from [key.txt]
[2015 Mar 31 08:48:55] obs: Pre-Load Omit words from [omit.txt]
[2015 Mar 31 08:48:55] obs: Pre-Load StringOmit words from [string.txt]
[2015 Mar 31 08:48:55] obs: Pre-Load Reserved words from [reserved.txt]
[2015 Mar 31 08:48:55] obs: Pre-Load force words from [force.txt]
[2015 Mar 31 08:48:55] obs: Pre-Load function file list from [(null)]
[2015 Mar 31 08:48:55] obs: Pre-Load map file list from [map.txt]
[2015 Mar 31 08:48:55] obs: Version 2.0 Initialisation...
[2015 Mar 31 08:48:55] obs: Initialise the file list...
[2015 Mar 31 08:48:55] obs: Initialise the Depth Stack...
[2015 Mar 31 08:48:55] obs: Initialise the FWD Function list...
[2015 Mar 31 08:48:55] obs: Initialise the FUNC function list...

Page 63 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2015 Mar 31 08:48:55] obs: Initialise the NEW function list...


[2015 Mar 31 08:48:55] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2015 Mar 31 08:48:55] obs: Obfuscating PL/SQL Input File [ sam1.sql ]
[2015 Mar 31 08:48:55] obs: Save the transposed variables
[2015 Mar 31 08:48:55] obs: Closing Down PFCLObfuscate

This results in no additional entries to the transpose.txt file:

TEST_PROC|bb00ff
PV_NUM|j0kA0b
PV_VAR|j0kA1A
PV_VAR3|ffbjfk
L_NUM|A0j0fk
L_VAR|kj1bkk
J|k0kbk0
PV_LEN|bfkk1b
X|f110Aj

You can use this feature to limit the amount of obfuscation applied to external/public scripts so that
pre-obfuscated internal packages control the scope of obfuscation.

Reverse Transpose Example


The reverse transpose file functionality is intended to help with your support issues. If you have
normally received support requests that perhaps included output snippets of code from your PL/SQL
now after using PFCLObfuscate that output is obfuscated. To enable support requests the code can
be reversed by using the “transpose.rev” file to show the original identifiers. This then can be used
to either investigate your own PL/SQL issues or to map the obfuscated code into the original code. If
PFCLObfuscate has been used with comment removal and compaction then it is likely that the code
line numbers no longer match at all to the original code therefore this is a useful facility.

Here is a very simple example to show how this works. We start with a simple PL/SQL source file
(s1.sql):

-- sample
create or replace procedure tst is
lv_var varchar2(30):='Hello';
begin
dbms_output.put_line(lv_var);
end;
/

Running PFCLObfuscate to protect the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s1.sql


-o s1.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.962.2001 - Production on Tue Jan 19 09:11:00 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 19 09:11:00] obs: Starting PFCLObfuscate...


[2013 Jan 19 09:11:00] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 19 09:11:00] obs: Pre-Load Omit words from [omit.txt]

Page 64 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2013 Jan 19 09:11:00] obs: Pre-Load StringOmit words from [string.txt]


[2013 Jan 19 09:11:00] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 19 09:11:00] obs: Pre-Load force words from [force.txt]
[2013 Jan 19 09:11:00] obs: Pre-Load function file list from [(null)]
[2013 Jan 19 09:11:00] obs: Pre-Load map file list from [map.txt]
[2013 Jan 19 09:11:00] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2013 Jan 19 09:11:00] obs: Obfuscating PL/SQL Input File [ s1.sql ]
[2013 Jan 19 09:11:00] obs: Save the transposed variables
[2013 Jan 19 09:11:00] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The obfuscated output is here:

create or replace procedure fkf000 is k0bkAb


varchar2(30):=chr(72)||chr(101)||chr(108)||chr(108)||chr(111); begin kbj10f.kf11fA(k0bkAb);
end;
/

The transpose file is:

TST|bbb0k0
LV_VAR|kffjA1
DBMS_OUTPUT|AkfA1b
PUT_LINE|bjj0Ak

The reverse file is:

BBB0K0|TST
KFFJA1|LV_VAR
AKFA1B|DBMS_OUTPUT
BJJ0AK|PUT_LINE

We can now run PFCLOBfuscate again and get the original variables back; this is done by first
copying the reverse file to the transpose file and running PFCLObfuscate:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>copy transpose.rev


transpose.txt
Overwrite transpose.txt? (Yes/No/All): y
1 file(s) copied.

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s1.opf


-o s1.out
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.962.2001 - Production on Tue Jan 19 09:18:05 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

[2013 Jan 19 09:18:05] obs: Starting PFCLObfuscate...


[2013 Jan 19 09:18:05] obs: Pre-Load Keywords from [key.txt]
[2013 Jan 19 09:18:05] obs: Pre-Load Omit words from [omit.txt]
[2013 Jan 19 09:18:05] obs: Pre-Load StringOmit words from [string.txt]
[2013 Jan 19 09:18:05] obs: Pre-Load Reserved words from [reserved.txt]
[2013 Jan 19 09:18:05] obs: Pre-Load force words from [force.txt]
[2013 Jan 19 09:18:05] obs: Pre-Load function file list from [(null)]
[2013 Jan 19 09:18:05] obs: Pre-Load map file list from [map.txt]

Page 65 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2013 Jan 19 09:18:05] obs: Running PFCLObfuscate PL/SQL Obfuscator


[2013 Jan 19 09:18:05] obs: Obfuscating PL/SQL Input File [ s1.opf ]
[2013 Jan 19 09:18:05] obs: Save the transposed variables
[2013 Jan 19 09:18:05] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

This correctly reverses the obfuscation of identifiers:

create or replace procedure TST is LV_VAR


varchar2(30):=chr(72)||chr(101)||chr(108)||chr(108)||chr(111); begin
DBMS_OUTPUT.PUT_LINE(LV_VAR);
end;
/

NOTE: the strings are obfuscated by the original obfuscation pass but these are not reversed. The
reverse transpose functionality is simply for reversing identifiers. Note; that if you reverse the
Obfuscation using this feature be aware that the transpose file now contains the mapping in the
wrong direction so ensure that the transpose file is cleared before regular obfuscation begins again.

SQL*Plus Variables
PFCLObfuscate can be used to protect SQL scripts, PL/SQL and SQL*Plus scripts containing SQL*Plus
commands and also SQL and PL/SQL statements. Ideally your SQL and PL/SQL should be separated
for clarity. Also ideally each source code file should contain only one PL/SQL construct such as a
PROOCEDURE or FUNCTION or PACKAGE or TYPE.

Note: do not add SQL*Plus commands to the omit.txt file as they are
processed automatically.

PFCLObfuscate automatically supports most SQL*Plus commands but not all of them – the ones not
supported should not normally be scripted. Where a command is supported this should not be
included in the omit.txt file as this would cause it to be processed by the scanner instead and
because SQL*Plus is unforgiving in its entry formats this will in general break SQL*Plus scripts. So the
following commands are processed and left as defined:

SET
SP(OOL)
DE(FINE)
COL(UMN)
VAR(IABLE)
UNDEF(INE)
EXEC(UTE)
@
@@
ACC(EPT)
BRE(AK)
BTI(TLE)
CL(EAR)
COMP(UTE)
CONN(ECT)
DESC(RIBE)
DISC(ONNECT)

Page 66 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

EXIT
HO(ST)
L(IST)
PAU(SE)
PRI(NT)
PRO(MPT)
QUIT
REM(ARK)
REPF(OOTER)
REPH(EADER)
R(UN)
SHO(W)
STA(RT)
STORE
TTI(TLE)
TIMI(NG)
WHENEVER

Each of these can be added in the source SQL*Plus script in lower case or upper case. If they are in
mixed case i.e. WhenEVER then they will not be processed. All SQL*plus commands are processed
as-is, that is the content remains the same as the clear text.

All SQL*Plus commands must be on one line except EXECUTE which can be on multiple lines.

Each SQL*Plus command above should start in column 1 of each line.

Debug
PFCLObfuscate can also be run in debug mode. This mode does not produce obfuscated output but
instead runs in debug mode so that each lexeme can be assessed with its type to locate issues with
obfuscation. This is enabled by also specifying “debug=yes” in the configuration file. A sample is
here:

When the tool is run in debug mode the output file contains a debug file instead. A sample debug
output for this run is:

Page 67 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

You can turn on / off obfuscation, comments and compact whilst running debug. This mode is useful
to identify ID’s reserved words and keywords that may not be correctly mapped. This example is run
without the same settings as the obfuscation except that debug is enabled.

Trace
The PFCLObfuscate program is also fully instrumented. This mode is really useful when submitting
support issues with the tool to PeteFinnigan.com Limited. If the tool should crash or seem to have a
bug then the tool can be run in trace mode and the trace file will help PeteFinnigan.com Limited
identify the issue. This allows us to run the tool as you without being there. Trace can be enabled at
any level between 1 and 9. Level 1 shows minimal trace and errors. Level 9 shows full detail.

Trace is enabled by setting environment variables. A script setup.bat is provided to do this. You can
also specify a trace file name and also whether functions can be shown in the trace file (This is not
included in setup.bat currently). Here is a sample trace of obfuscating tutorial1.sql:

Page 68 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The trace file produced is huge so these trace files should only be created when necessary for
support assistance. A sample part of a trace file is here:

Note: Trace files can become very large so use only when necessary for support requests.

Obfuscation Examples
The next section shows a couple of example uses of the tool. The first example is the obfuscation of
a SQL*Plus script and the second example is the obfuscation of two PL/SQL code files that are linked.

Page 69 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Example 1 - Obfuscating a SQL*Plus script


SQL*Plus scripts can also be obfuscated. These scripts can include SQL statements, PL/SQL programs
and also SQL*plus commands. A good example program to obfuscate is the PeteFinnigan.com
Limited Oracle password cracker. The cracker can be downloaded from here –
http://www.petefinnigan.com/oracle_password_cracker.htm

The program includes SQL*Plus commands, SQL and PL/SQL, running it un-obfuscated shows the
following output (you can view the SQL*Plus, SQL and PL/SQL by downloading the tool from the
address just mentioned):

SQL> @cracker-v2.0.sql
cracker: Release 1.0.4.0.0 - Beta on Fri Mar 25 19:09:30 2011
Copyright (c) 2008 PeteFinnigan.com Limited. All rights reserved.

T Username Password CR FL STA


=======================================================

U "SYS" [ ] -- -- OP
U "SYSTEM" [ ] -- -- OP
U "OUTLN" [OUTLN ] DE CR EL
U "DIP" [DIP ] DE CR EL
U "ORACLE_OCM" [ ] -- -- EL
R "GLOBAL_AQ_USER_ROLE [GL-EX {GLOBAL} ] GE CR OP
U "DBSNMP" [ ] -- -- OP
U "APPQOSSYS" [APPQOSSYS ] PU CR EL
U "WMSYS" [WMSYS ] DE CR EL
U "XS$NULL" [ ] -- -- EL
U "EXFSYS" [ ] -- -- EL
U "CTXSYS" [ ] -- -- EL
U "XDB" [CHANGE_ON_INSTALL ] DE CR EL
U "ANONYMOUS" [IMP {anonymous} ] IM CR EL
U "OLAPSYS" [ ] -- -- EL
U "ORDSYS" [ORDSYS ] DE CR EL
U "ORDDATA" [ORDDATA ] PU CR EL
U "ORDPLUGINS" [ORDPLUGINS ] DE CR EL
U "SI_INFORMTN_SCHEMA" [SI_INFORMTN_SCHEMA ] DE CR EL
U "MDSYS" [MDSYS ] DE CR EL
U "MDDATA" [MDDATA ] DE CR EL
U "SPATIAL_WFS_ADMIN_U [SPATIAL_WFS_ADMIN_US] PU CR EL
R "WFS_USR_ROLE" [WFS_USR_ROLE ] PU CR OP
R "SPATIAL_CSW_ADMIN" [SPATIAL_CSW_ADMIN ] PU CR OP
U "SPATIAL_CSW_ADMIN_U [SPATIAL_CSW_ADMIN_US] PU CR EL
R "CSW_USR_ROLE" [CSW_USR_ROLE ] PU CR OP
U "SYSMAN" [ ] -- -- OP
U "MGMT_VIEW" [ ] -- -- OP
U "FLOWS_FILES" [ ] -- -- EL
U "APEX_PUBLIC_USER" [ ] -- -- EL
U "APEX_030200" [ ] -- -- EL
U "OWBSYS" [OWBSYS ] PU CR EL
R "OWB$CLIENT" [S ] BF CR OP
U "OWBSYS_AUDIT" [OWBSYS_AUDIT ] PU CR EL
U "SCOTT" [TIGER ] DE CR EL
U "HR" [CHANGE_ON_INSTALL ] DE CR EL
U "OE" [CHANGE_ON_INSTALL ] DE CR EL
U "IX" [CHANGE_ON_INSTALL ] DE CR EL
U "SH" [CHANGE_ON_INSTALL ] DE CR EL
U "PM" [CHANGE_ON_INSTALL ] DE CR EL
U "BI" [CHANGE_ON_INSTALL ] DE CR EL

INFO: Number of crack attempts = [47942]


INFO: Elapsed time = [2.49 Seconds]

Page 70 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

INFO: Cracks per second = [19250]

PL/SQL procedure successfully completed.

SQL>

This SQL*Plus script was obfuscated and some of the output is here. As you can see the output
makes it much more difficult to understand what the program does and how it does it:

...
l0O01l10OO varchar2(1):=chr(78); iQi111OQQO utl_file.file_type; OQ1QQ01Q10
varchar2(1):=chr(76); Q0QQQOQli0 varchar2(1):=chr(48); Ql0QQlilll raw(128); OOl0l0QliO
varchar2(100); type Q0i1i1011l is table of varchar2(30) index by binary_integer;
Oll01QiQQO Q0i1i1011l; type O0Q1iiii1O is table of varchar2(30) index
by binary_integer; dicts O0Q1iiii1O; type iQ1Q1010Q1 is record ( OOO0O1O1li
varchar2(1), username varchar2(30), lQOl00llOO varchar2(3), OQ0O11OOOl
varchar2(30), l0QOii00OQ varchar2(40), il01Qi1i00 varchar2(20), password
varchar2(38), l11iOO1lOO varchar2(30), ilQ1Q1O0OO number(10), QQQQQ0l010
number(10), O0liiOO1Oi number(10), OOiiliQO1i number(10), i1ll10OQO0
number(10), OliOlli1li number(10), OiO0O0lll1 number(10), Q0QiliO0Q1
varchar2(30), liiQ0010QQ varchar2(2), QiOiiO1Q1l boolean );
type lQillQQlOO is table of iQ1Q1010Q1 index by binary_integer; O01iQili1l
lQillQQlOO; l1Qiii11l0 varchar2(2); QlOQiiOll1 varchar2(30); l0QOlQ0Q00
varchar2(30); type liOQQQlQll is record ( user varchar2(30), hash varchar2(30)
); type Q1OOi1Q1QQ is table of liOQQQlQll index by binary_integer; QOlQ0ill0Q
Q1OOi1Q1QQ; Q0OOOiQ00l binary_integer; start_time number:=0; end_time
number:=0; iO1lOO0lO1 number(10,2):=0.0; OlQlQl10QO number(10,2):=0.0;
QOQi00OQ0l number(10):=0; Q1OiQ1i10i raw(128):= hextoraw(chr(48)||chr(49)
||chr(50)||chr(51)||chr(52)||chr(53)||chr(54)||chr(55)||chr(56)||chr(57)
||chr(65)||chr(66)||chr(67)||chr(68)||chr(69)||chr(70)); type Q0OiOO1Qli
is table of number(2) index by binary_integer; lQi0illl11 Q0OiOO1Qli;
charset varchar2(70):=chr(65)||chr(66)||chr(67)||chr(68)||chr(69)||chr(70)
||chr(71)||chr(72)||chr(73)||chr(74)||chr(75)||chr(76)||chr(77)||chr(78)
||chr(79)||chr(80)||chr(81)||chr(82)||chr(83)||chr(84)||chr(85)||chr(86)
||chr(87)||chr(88)||chr(89)||chr(90)||chr(49)||chr(50)||chr(51)||chr(52)
||chr(53)||chr(54)||chr(55)||chr(56)||chr(57)||chr(48)||chr(95)||chr(35)
||chr(36); lQ0Ql0iOQQ number:=26; OllQllQOlQ number; O0iOQ10O1Q
varchar2(15); procedure O1il1l11O1(QliOllOQQl in varchar2,OOill1Ql1Q
in varchar2) is begin l0O01l10OO:=chr(89); Q0QQQOQli0:=OOill1Ql1Q;
OQ1QQ01Q10:=QliOllOQQl;
if OQ1QQ01Q10=chr(76) then dbms_output.disable; dbms_output.enable(1000000);
end if; end O1il1l11O1; procedure OliiQi000l is begin l0O01l10OO:=chr(78);
end OliiQi000l; function timestamp return varchar2 is cursor OO1QQlQQi0
is select to_char(sysdate,chr(68)||chr(68)||chr(32)||chr(77)||chr(111)
||chr(110)||chr(32)||chr(89)||chr(89)||chr(89)||chr(89)||chr(32)||chr(72)
||chr(72)||chr(50)||chr(52)||chr(58)||chr(77)||chr(73)||chr(58)||chr(83)
||chr(83)) timestamp from sys.dual; i0liiO00OQ OO1QQlQQi0%rowtype;
QOQ0QilQl1 varchar2(20):=chr(32); begin open OO1QQlQQi0; fetch OO1QQlQQi0 into
i0liiO00OQ; QOQ0QilQl1:=i0liiO00OQ.timestamp; close OO1QQlQQi0; return
QOQ0QilQl1; end timestamp; procedure QllOi0i0Q0 (OQl1OiO0O1 in varchar2,
lliQOil1Q0 in varchar2) is begin iQi111OQQO:=utl_file.fopen(OQl1OiO0O1,
lliQOil1Q0,chr(65)); exception when utl_file.invalid_path then
dbms_output.put_line(chr(105)||chr(110)||chr(118)||chr(97)||chr(108)||chr(105)||chr(100)||chr(
32)||chr(112)||chr(97)||chr(116)||chr(104));
raise_application_error(-20100,chr(102)||chr(105)||chr(108)||chr(101)
||chr(32)||chr(101)||chr(114)||chr(114)||chr(111)||chr(114)); when utl_file.invalid_mode then
dbms_output.put_line(chr(105)||chr(110)||chr(118)||chr(97)||chr(108)||chr(105)||chr(100)||chr(
95)||chr(109)||chr(111)||chr(100)||chr(101));
raise_application_error(-20100,chr(102)||chr(105)||chr(108)||chr(101)
||chr(32)||chr(101)||chr(114)||chr(114)||chr(111)||chr(114)); when utl_file.invalid_filehandle
then
dbms_output.put_line(chr(105)||chr(110)||chr(118)||chr(97)||chr(108)||chr(105)
||chr(100)||chr(95)||chr(102)||chr(105)||chr(108)||chr(101)||chr(104)||chr(97)

Page 71 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

||chr(110)||chr(100)||chr(108)||chr(101)); raise_application_error(-20100,chr(102)||chr(105)
||chr(108)||chr(101)||chr(32)||chr(101)||chr(114)||chr(114)||chr(111)||chr(114)
); when utl_file.invalid_operation
then dbms_output.put_line(chr(105)||chr(110)||chr(118)||chr(97)||chr(108)
||chr(105)||chr(100)||chr(95)||chr(111)||chr(112)||chr(101)||chr(114)||chr(97)
||chr(116)||chr(105)||chr(111)||chr(110)); raise_application_error(-20100,chr(102)||chr(105)
||chr(108)||chr(101)||chr(32)||chr(101)||chr(114)||chr(114)||chr(111)||chr(114)
); when utl_file.read_error
...

When running the obfuscated version in SQL*Plus we get the same output:

SQL> @cracker-v2.0.sql.opf
cracker: Release 1.0.4.0.0 - Beta on Sat Mar 26 20:59:34 2011
Copyright (c) 2008 PeteFinnigan.com Limited. All rights reserved.

T Username Password CR FL STA


=======================================================

U "SYS" [ ] -- -- OP
U "SYSTEM" [ ] -- -- OP
U "OUTLN" [OUTLN ] DE CR EL
U "DIP" [DIP ] DE CR EL
U "ORACLE_OCM" [ ] -- -- EL
R "GLOBAL_AQ_USER_ROLE [GL-EX {GLOBAL} ] GE CR OP
U "DBSNMP" [ ] -- -- OP
U "APPQOSSYS" [APPQOSSYS ] PU CR EL
U "WMSYS" [WMSYS ] DE CR EL
U "XS$NULL" [ ] -- -- EL
U "EXFSYS" [ ] -- -- EL
U "CTXSYS" [ ] -- -- EL
U "XDB" [CHANGE_ON_INSTALL ] DE CR EL
U "ANONYMOUS" [IMP {anonymous} ] IM CR EL
U "OLAPSYS" [ ] -- -- EL
U "ORDSYS" [ORDSYS ] DE CR EL
U "ORDDATA" [ORDDATA ] PU CR EL
U "ORDPLUGINS" [ORDPLUGINS ] DE CR EL
U "SI_INFORMTN_SCHEMA" [SI_INFORMTN_SCHEMA ] DE CR EL
U "MDSYS" [MDSYS ] DE CR EL
U "MDDATA" [MDDATA ] DE CR EL
U "SPATIAL_WFS_ADMIN_U [SPATIAL_WFS_ADMIN_US] PU CR EL
R "WFS_USR_ROLE" [WFS_USR_ROLE ] PU CR OP
R "SPATIAL_CSW_ADMIN" [SPATIAL_CSW_ADMIN ] PU CR OP
U "SPATIAL_CSW_ADMIN_U [SPATIAL_CSW_ADMIN_US] PU CR EL
R "CSW_USR_ROLE" [CSW_USR_ROLE ] PU CR OP
U "SYSMAN" [ ] -- -- OP
U "MGMT_VIEW" [ ] -- -- OP
U "FLOWS_FILES" [ ] -- -- EL
U "APEX_PUBLIC_USER" [ ] -- -- EL
U "APEX_030200" [ ] -- -- EL
U "OWBSYS" [OWBSYS ] PU CR EL
R "OWB$CLIENT" [S ] BF CR OP
U "OWBSYS_AUDIT" [OWBSYS_AUDIT ] PU CR EL
U "SCOTT" [TIGER ] DE CR EL
U "HR" [CHANGE_ON_INSTALL ] DE CR EL
U "OE" [CHANGE_ON_INSTALL ] DE CR EL
U "IX" [CHANGE_ON_INSTALL ] DE CR EL
U "SH" [CHANGE_ON_INSTALL ] DE CR EL
U "PM" [CHANGE_ON_INSTALL ] DE CR EL
U "BI" [CHANGE_ON_INSTALL ] DE CR EL

INFO: Number of crack attempts = [47942]


INFO: Elapsed time = [2.55 Seconds]

Page 72 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

INFO: Cracks per second = [18800]

PL/SQL procedure successfully completed.

SQL>

There are some manual edits that had to be made to ensure that this program works. The SQL*Plus
commands in some cases include aliases or variables. The SQL*Plus keywords are not obfuscated
because of the way the tool “passes through” the SQL*Plus commands. These aliases or variables
are used later in the PL/SQL and these have been obfuscated. The solution is to use the omit file and
to not obfuscate these variables.

Obfuscating a Complete Project


It is more realistic with a real project that you would need to obfuscate multiple source code files
with PFCLObfuscate. This is handled by PFCLObfuscate via the “run.bat” program. “Run.bat” expects
an argument of the type of source code file to process and also a PFCLObfuscate configuration file.

This example shows how PFCLObfuscate can be used to obfuscate multiple source code files with
one command. The basic premise is the same as for a single source code file. First you must
configure a PFCLObfuscate configuration file and also prepare the input files discussed for the earlier
single source file example.

The batch program provided allows you to specify a set of files (such as .sql files) and process all of
them. This works well with PFCLObfuscate in a number of ways.

 Automates the processing of multiple source files


 Each file can use the same configuration file and input settings
 If necessary a single source file (or more) could be processed separately with different
settings; this is up to you.
 The interfaces will be obfuscated with the same obfuscated names thereby retaining
interfaces where needed.

For this example we are going to obfuscate the two sample files shipped in the samples directory
sample1.sql and sample2.sql. I am also going to use the sample PFCLObfuscate configuration file and
use the sample input files. I will create the API interface omit file and also will generate the reserved
words file. But first I will create a working environment in a new directory called “dual” and copy the
files into it ready. Here is the sequence:

Page 73 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Above you can see that I create a working directory I have called dual; I then copy all of the sample
PFCLObfuscate input files and the PFCLObfuscate configuration file. Then I also copied the sample
SQL files that we will obfuscate.

Next create the reserved word file:

The next step is to take a look at the two SQL files that we will obfuscate. We have two procedures
defined in two separate source code files (sample1.sql and sample2.sql). The procedure TEST_PROC
in sample2.sql is called by the procedure TEST_RUN in sample1.sql.

Page 74 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The second sample script sample1.sql has a procedure TEST_RUN that calls the procedure
TEST_PROC in sample2.sql. This is shown here:

Installing and running these two scripts shows:

Page 75 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

These are just demo procedures that show how two procedures link with each other and how we
can obfuscate both and also how the public interfaces can be maintained. The procedure TEST_RUN
calls the procedure TEST_PROC in the second file/procedure.

Two interesting aspects are shown in this simple example. Because we don’t want the interface API
(in this case TEST_RUN in sample1.sql) to be obfuscated we need to tell PFCLObfuscate not to
obfuscate the variable. This is done by adding the variable name TEST_RUN to the file defined as the
“omit” file – in this case omit.txt.

The second interesting aspect is that in this example the name of the internal API (TEST_PROC in
sample2.sql) is also a reserved word defined in the reserved.txt file. This means that PFCLObfuscate
will refuse to obfuscate it because it’s recognised as a reserved word. In this case we know that this
is not in fact a reserved word because I added the word TEST_PROC to the reserved.txt file for this
example:

Page 76 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Because TEST_PROC is now a reserved word it should not normally be obfuscated. Because we still
want to obfuscate this variable name we need to use the force file to specify the name TEST_PROC
so that it is ignored as a reserved word or a keyword.

Note: Normally the set up for a set of source code will need to be done once
and after that obfuscation can take place quickly and easily. The obfuscation

Page 77 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

process can be changed after the initial setup in terms of generated variables,
length, character set, string obfuscation and more without additional
preparation of input files.

Both of these source code files can now be obfuscated with the run command:

The warning was discussed in the tutorial1 example earlier. The run command backs up the source
code specified and then runs PFCLObfuscate on each file. The same set up is used for all of the files
and the same transpose.txt file is used which enables the same obfuscation to be used across files
where an interface is needed. For instance the procedure TEST_PROC is defined in one source file
and used in the second. The obfuscation still takes place but both are obfuscated. After obfuscation
the output files are copied back to the original source code files. The log status lines above show
what is happening.

After running PFCLObfuscate the source files now look like the following. Sample1.sql:

And sample2.sql:

Page 78 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Next we can re-install the obfuscated source files into the database and show that the resulting code
still works. This is shown here:

The obfuscated code can be much improved upon. The function “C” in sample1.sql and procedure
“P” in sample1.sql and also the function “NESTED” in sample2.sql can also be obfuscated by adding
their names to the force file as they are also key/reserved words but not in this context.

The string obfuscation can be made stronger by substitution of a global function that will encode the
strings and with run time preventions. Also strings could be removed and replaced completely if
suitable. Core SYS packages can also be hidden in the same with also with runtime protections.

But the above example is a good start on obfuscating multiple files.

Page 79 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Utilities
The product also includes two utilities to convert file endings between Windows operating systems
and Unix operating systems. If wrap.exe is run on a Unix operating system this tool is necessary to
convert file endings. These are called unix2dos and dos2unix. Their running is simple:

C:\> unix2dos <input file> <output file>


C:\> dos2unix <input file> <output file>

Run Time Planning


The use of PFCLObfuscate is not a totally automatic process. Some work must inevitably be
performed by the user of PFCLObfuscate. The use of omit and force variables must be considered
based on your PL/SQL API’s that must remain consistent with existing use and also where variables
are not obfuscated because they are key words. i.e. if your external code calls DEMOPKG.DEMO then
this name must remain to allow your code to work so add it to the omit.txt file.

The files supplied omit.txt, stringomit.txt, force.txt, key.txt and reserved.txt should all contain words
in Upper case, except when double quoted identifiers are used then the words should be added in
the same case as the double quoted identifier. The tool is not case sensitive for code being
obfuscated but in the current version all files (omit, force, reserved, stringomit and key) should
contain upper case words except as above.

The obfuscated code must be reviewed to ensure that is still correct and compiles. This should be
done in the same way as the simple examples show in this document by installing in the database.

Alias’s
Where key functions such as DBMS_OUTPUT or UTL_FILE or DBMS_SQL or similar are used regularly
in code that you would like to obfuscate then it makes sense to hide these words. If PFCLObfuscate
is used in standard configuration these words will still have their original names. It would be nice to
also obfuscate these calls. There are two options:

1. Create a synonym in the same schema as the package/procedure making the call – i.e.
“create synoym oli1iiOO for sys.dbms_output.put_line”
2. Or create an internal print (in this case) procedure in the package/procedure being
obfuscated – see the multiple file example above. This procedure should call
DBM_OUTPUT; in this example so that the name is not propagated throughout the code.

The synonym solution is not ideal as it provides a list of transposed words where this technique is
used.

Note: Version 2.0 dynamic obfuscation provides a new method to “hide”


package calls such as this call to DBMS_OUTPUT.PUT_LINE. This makes the
obfuscated code harder to understand. See the Version 2.0 section of this
manual

Page 80 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Using Wrap With PFCLObfuscate (9iR2)


One of the best ways to protect your IPR in your PL/SQL is to take a stepped approach to securing it.
This should include adding security features written in PL/SQL itself such as tamper proof
mechanisms or license type features. The next step is to obfuscate the PL/SQL code using this tool
PFCLObfuscate and then to wrap the code with Oracles 9iR2 wrap.exe program (you need to source
this yourself as we cannot supply this program). When PL/SQL has been obfuscated including string
obfuscation the exposed symbol table in a 9iR2 wrapped file (the supposed weakness) is not useable
as the entries are now just numbers so an attacker cannot easily modify the wrapped file to make it
do something else. The final step is to run WrapProtect.exe in this package or wfix.exe also from this
package. These programs stop unwrappers from working.

This most secure scenario can create issues though. Because the current supported databases are
10gR2 and 11gR1 and 11gR2 there can be issues using the 9iR2 wrap program. Because the 9iR2
wrap program is the front end of a PL/SQL compiler (the 10g and 11g is not) it compiles with 9iR2
rules and syntax. If newer SQL features are used in the PL/SQL code then there is a possibility to
allow that code to compile as follows:

c:\> wrap iname=some.sql edebug=wrap_new_sql oname=some.plb

The “edebug” parameter allows unsupported SQL to be compiled. This is done by internally turning
the SQL into a string and storing it in the wrap file symbol table. So whilst it will compile the SQL
string is now not compiled into DIANA and is now completely visible in the symbol table. If the SQL
was already obfuscated then this may be less of an issue.

It is possible to simulate the same situation yourself by converting explicit SQL in your PL/SQL into a
string but first let us see the wrap undocumented parameter in action:

PL/SQL Code

-- test procedure for wrap


create or replace procedure test_run is
lv_res varchar2(30);
begin
select sysdate into lv_res
from sys.dual;
dbms_output.put_line(lv_res);
end test_run;
/

If this procedure is installed then it can be run as follows:

SQL> @s8.sql

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
18-DEC-12

PL/SQL procedure successfully completed.

Page 81 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

SQL>

The code can then be wrapped with 9iR2 wrap.exe:

F:\unwrap\9iwrap>wrap iname=s8.sql oname=s8.opf

PL/SQL Wrapper: Release 9.2.0.1.0- Production on Tue Dec 18 16:32:20 2012

Copyright (c) Oracle Corporation 1993, 2001. All Rights Reserved.

Processing s8.sql to s8.opf

F:\unwrap\9iwrap>

The symbol table shows the elements of the code:

...
9200000
1
4
0
9
2 :e:
1TEST_RUN:
1LV_RES:
1VARCHAR2:
130:
1SYSDATE:
1SYS:
1DUAL:
1DBMS_OUTPUT:
1PUT_LINE:
0
...

Next we can run the 9iR2 wrap again but using the undocumented parameter; we would use this
where some particular SQL syntax will not compile:

...
9200000
1
4
0
a
2 :e:
1TEST_RUN:
1LV_RES:
1VARCHAR2:
130:
1SYSDATE:
1SYS:
1DUAL:
1SELECT sysdate into lv_res:n from sys.dual:
1DBMS_OUTPUT:
1PUT_LINE:
0
...

Page 82 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Note that the SQL is now converted into a string and that the actual symbols are still there. This has
not been investigated in detail but the assumption is that Oracle has converted the code into a
cursor. This method can be used to compile SQL that will not compile with 9iR2 but will compile with
10G or 11G.

The same can be simulated yourself. The code can be modified as:

-- test procedure for wrap


create or replace procedure test_run is
lv_res varchar2(30);
lv_str varchar2(50):='select sysdate from dual';
lv_cur sys_refcursor;
begin
open lv_cur for lv_str;
fetch lv_cur into lv_res;
dbms_output.put_line(lv_res);
close lv_cur;
end test_run;
/

Then this can be loaded and run:

SQL> @s8

Procedure created.

SQL> exec test_run


18-DEC-12

PL/SQL procedure successfully completed.

SQL>

This works the same of course. We can wrap this and we would not need the “edebug” parameter as
the SQL syntax is not parsed by the PL/SQL compiler but by the database. We can wrap:

F:\unwrap\9iwrap>wrap iname=s8.sql oname=s8.opf

PL/SQL Wrapper: Release 9.2.0.1.0- Production on Tue Dec 18 17:28:43 2012

Copyright (c) Oracle Corporation 1993, 2001. All Rights Reserved.

Processing s8.sql to s8.opf

F:\unwrap\9iwrap>

The symbol table includes:

...
9200000
1
4
0
d
2 :e:
1TEST_RUN:
1LV_RES:
Page 83 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

1VARCHAR2:
130:
1LV_STR:
150:
1select sysdate from dual:
1LV_CUR:
1SYS_REFCURSOR:
1OPEN:
1DBMS_OUTPUT:
1PUT_LINE:
1CLOSE:
0
...

The SQL statement is still shown but the ideal scenario is to have obfuscated the string first with
PFCLOBfuscate and then to wrap. This is not possible with the undocumented parameter approach
as the string with the SQL is not a string in PL/SQL terms.

The SQL is included as distinct symbols which shows that the SQL was actually compiled into DIANA
nodes. If this were real production code the column names and table names could all have been
obfuscated making it harder to read.

In version 1.0 you must make the changes yourself to use this technique.
Version 2.0 brings the ability to dynamically add code (PL/SQL) to your
existing code via hook points – see the version 2.0 section in this manual for
details. A later version may also support detecting SQL statements so that
they can be converted to strings for securing as described in this section.

The final step with this example is to use PFCLObuscate to obfuscate the modified code so that the
SQL string is no longer visible. This cannot be done with the “edebug” version of course. First
obfuscate:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i s8.sql


-o s8.opf
Warning: If compact is on, comments have to be deleted:[system error]: No error

PFCLObfuscate: Release 1.0.612.1149 - Production on Thu Dec 20 19:37:44 2012

Copyright (c) 2012 PeteFinnigan.com Limited. All rights reserved.

[2012 Dec 20 19:37:44] obs: Starting PFCLObfuscate...


[2012 Dec 20 19:37:44] obs: Pre-Load Keywords from [key.txt]
[2012 Dec 20 19:37:44] obs: Pre-Load Omit words from [omit.txt]
[2012 Dec 20 19:37:44] obs: Pre-Load StringOmit words from [string.txt]
[2012 Dec 20 19:37:44] obs: Pre-Load Reserved words from [reserved.txt]
[2012 Dec 20 19:37:44] obs: Pre-Load force words from [force.txt]
[2012 Dec 20 19:37:44] obs: Pre-Load function file list from [(null)]
[2012 Dec 20 19:37:44] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2012 Dec 20 19:37:44] obs: Obfuscating PL/SQL Input File [ s8.sql ]
[2012 Dec 20 19:37:44] obs: Save the transposed variables
[2012 Dec 20 19:37:44] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now view the code:


Page 84 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

create or replace procedure test_run is jbAAbj varchar2(30); kb00jk


varchar2(50):=chr(115)||chr(101)||chr(108)||chr(101)||chr(99)
||chr(116)||chr(32)||chr(115)||chr(121)||chr(115)||chr(100)||chr(97)||chr(116)||chr(101)||chr(
32)||chr(102)||chr(114)||chr(111)
||chr(109)||chr(32)||chr(100)||chr(117)||chr(97)||chr(108);
jb00k0 sys_refcursor; begin open jb00k0 for kb00jk; fetch jb00k0 into jbAAbj;
dbms_output.put_line(jbAAbj); close jb00k0;
end test_run;
/
Now install

SQL> @s8.opf

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
20-DEC-12

PL/SQL procedure successfully completed.

SQL>
This works fine of course. So now wrap this:

F:\unwrap\9iwrap>wrap iname=s8.opf oname=s8.ppl

PL/SQL Wrapper: Release 9.2.0.1.0- Production on Thu Dec 20 19:43:14 2012

Copyright (c) Oracle Corporation 1993, 2001. All Rights Reserved.

Processing s8.opf to s8.ppl

F:\unwrap\9iwrap>
See the code:

...
9200000
1
4
0
1c
2 :e:
1TEST_RUN:
1JBAABJ:
1VARCHAR2:
130:
1KB00JK:
150:
1CHR:
1115:
1||:
1101:
1108:
199:
1116:
132:
1121:
1100:
197:
1102:
1114:
1111:
1109:
1117:

Page 85 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

1JB00K0:
1SYS_REFCURSOR:
1OPEN:
1DBMS_OUTPUT:
1PUT_LINE:
1CLOSE:
0
...
As you can see the SQL string is no longer visible. This code obviously still installs and runs correctly:

SQL> @s8.ppl

Procedure created.

SQL> set serveroutput on


SQL> exec test_run;
20-DEC-12

PL/SQL procedure successfully completed.

SQL>

The final option with SQL syntax that is compiled with the 9iR2 wrap but that will not compile when
loaded into a 10g or 11g or 12cR1 database is to actually change the syntax to remove any later
feature so that it will compile with 9iR2. This of course could be counter-productive so this needs to
be considered carefully on a case-by-case basis.

This concludes the discussion on how to deal with SQL syntax intended for Oracle 10g or 11g or
12cR1 that will not compile with the 9iR2 wrap.exe program.

The next issue that can occur would be use of 10g or 11g or 12cR1 PL/SQL syntax that is not
supported by the 9iR2 wrap compiler. In this case there is no simple magic parameter that can be
used with wrap.exe.

Note: there is no simple documentation provided by Oracle that shows all new
PL/SQL syntax in 10g and 11g and 12c not supported in 9iR2

The syntax that is not supported by 9iR2 wrap.exe can be solved in one of the other two ways
described above for SQL; 1) turn the PL/SQL into a string so that wrap.exe no longer compiles it or 2)
re-write the specific PL/SQL code so that it works with 9iR2 syntax. There are often good reasons
that new syntax was used so removing it may not be good for functional or performance reasons.
Therefore any solution to protect your PL/SQL IPR should be pragmatic. Most customers of
PFCLObfuscate (which includes WrapProtect) take an approach that protects important and key
pieces of PL/SQL code using WrapProtect only and then just obfuscate the rest of their code or they
encase the security/license type features and WrapProtect those and then use those security
features from their existing code.

Performance
One final consideration is performance of the PL/SQL itself. Using 9iR2 wrap.exe is necessary to
achieve the best security of your PL/SQL to give the multi-layer protection that is harder to reverse
engineer both in terms of stealing your ideas and IPR and also potentially (provided that you create

Page 86 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

license type features) prevent running of your code when not authorised (either in the installed
database or by removal and running elsewhere). There is a consideration to be made though.

Whilst 9iR2 and indeed much earlier versions of wrapped PL/SQL code still load into newer
databases the wrap program is the “front end” of a PL/SQL compiler that compiles the PL/SQL down
into an intermediate form called DIANA which is then stored as IDL. The compilation phase
continues when the wrapped file is loaded into the database and the DIANA/IDL is then converted
and optimized into p-code. Consideration must be made that the 9iR2 compiler is not the 10g, 11g or
indeed 12c compiler therefore the optimisation at the DIANA phase may not be as good. You must
test your code because of this. As the idea is to protect your code be pragmatic with the use of
wrap.exe and wrapprotect.exe.

A number of people have asked whether Oracle support modification of


wrapped files. The answer at this stage is that we don’t know as we have not
asked them. If you need the best security for your code and IPR then the
methods afforded by PFCLObfuscate/wrap/WrapProtect are the best that can
be achieved. Remember that obfuscated code is completely “legal” code.
Wrapped code is completely legal code but WrapProtected code modifies the
wrapped files to prevent unwrappers from working but remember once the
file is loaded and compiled the fact that the WrapProtected code is visible in
sys.source$ is only relevant to an attacker (hence we protected it) and also for
re-compilation where relevant. This is the same approach taken in the
Windows binary/.NET/Java and many more worlds where output files
(programs) are modified to prevent reverse engineering from working.

Thorough testing of the WrapProtected code is recommended.

In summary the use of wrap.exe and wrapprotect.exe demands that you be pragmatic about the
possibilities and consider the trade-off between performance, features and security of your code.

WrapProtect
PFCLObfuscate also includes two tools to further protect PL/SQL, these are “wfix.exe” and
“wrapprotect.exe”. The ideal process to protect your PL/SQL is to do:

1. Start with your PL/SQL – just the plain code to be protected.


2. Add license protection features – i.e. code additional checks to test for instance that the
code runs in the desired database; hence check that the database name or dbid are set
to the correct values. Also you could check that the code runs for the correct database
user or that the code runs at the correct time and date; maybe only on weekends
between 9pm and 12am. (Note: Some of these features can be added automatically as
part of version 2.0 of PFCLOBfuscate) Add these features by hand with version 1.0
functionality.
3. Add tamperproofing protections. Add PL/SQL code that checks that the integrity of your
PL/SQL has not been changed. This could be checksum code that tests that code has not
been modified to remove license features. It could be a check to make sure that a
Page 87 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

function call has not been circumvented. (Note: These features will be added
automatically as part of version 2.1 of PFCLOBfuscate) Add these features by hand in
version 1.0.
4. Now protect this code with PFCLOBfuscate to remove meaning and to make it hard for
anyone to reverse engineer the code
5. To make your code much more secure the next step would be to wrap it with Oracles
wrap.exe program. The 10g and above wrap.exe program is not useful long term as it is
easy to unwrap code wrapped with the 10g wrap.exe program. The 9iR2 wrap program
can also have its output unwrapped but it is harder to find a working unwrapper – there
are none simply available on the internet for free. Also it is possible to protect wrap files
generated with a 9iR2 wrap program so that known unwrappers will not unwrap the
generated code but it will still load and work in the database.
6. WrapProtect the wrapped 9iR2 file with wrapprotect.exe. This will make it hard to
understand the code and also will make it hard to modify existing PL/SQL code when
wrapped. This is because the symbol table will not be visible. Because code has to be
wrapped with the 9iR2 wrap.exe program some features needed in PL/SQL code for later
versions will not be supported. There is an parameter to control the 9iR2 wrap.exe to
ignore later features. Also to use this method a 9iR2 client is needed that includes the
wrap.exe program. PeteFinnigan.com Limited cannot supply this. Also anyone using
WrapProtect should be aware that they are modifying code in a non-standard way so it
they should be careful with any support requests on their code.
7. Good practice would be to obfuscate all code and to add license features and tamper
proofing and to fully protect this and the important code with WrapProtect to limit any
support issues.

Here is a sample of wrapping an obfuscated PL/SQL file with the 9iR2 wrap program:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>wrap iname=sample3.opf


oname=sample3.plb

PL/SQL Wrapper: Release 9.2.0.1.0- Production on Tue Oct 16 16:20:30 2012

Copyright (c) Oracle Corporation 1993, 2001. All Rights Reserved.

Processing sample3.opf to sample3.plb

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Then we can use wrapprotect.exe to protect the generated wrap file:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>wrapprotect -c wp.conf -v -


i sample3.plb -o sample3.ppx

WrapProtect: Release 0.8.112 - Beta on Tue Oct 16 16:21:09 2012

Copyright (c) 2011 PeteFinnigan.com Limited. All rights reserved.

[2012 Oct 16 15:21:09] PFCLObScan: Starting WrapProtect...


[2012 Oct 16 15:21:09] PFCLObScan: Running WrapProtect
[2012 Oct 16 15:21:09] PFCLObScan: Protecting Wrapped Input File [ sample3.plb ]
[2012 Oct 16 15:21:09] PFCLObScan: Start Load Process....
[2012 Oct 16 15:21:09] PFCLObScan: Loading PLB File

Page 88 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2012 Oct 16 15:21:09] PFCLObScan: Opening Output File


[2012 Oct 16 15:21:09] PFCLObScan: Processing a wrap file
[2012 Oct 16 15:21:09] PFCLObScan: Parsing PLB File
[2012 Oct 16 15:21:09] PFCLObScan: Dumping PLB structures
[2012 Oct 16 15:21:09] PFCLObScan: ReCreate the Source...
[2012 Oct 16 15:21:09] PFCLObScan: Completed Loading Wrap File
[2012 Oct 16 15:21:09] PFCLObScan: Start Securing Process....
[2012 Oct 16 15:21:09] PFCLObScan: Completed Securing Process....
[2012 Oct 16 15:21:09] PFCLObScan: Closing Output File [sample3.ppx]
[2012 Oct 16 15:21:09] PFCLObScan: Closing Down WrapProtect

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The obfuscated PL/SQL and the wrap protected wrapped file can be loaded into the database; here I
load a file protected with 9iR2 wrap into an 11gR2 database

SQL> @sample3.opf

Procedure created.

SQL> @sample3.ppx

Procedure created.

SQL>

You have the freedom to simply obfuscate or also to add much higher levels of protection by
wrapping and then wrapprotecting the output (against unwrappers).

WrapProtect Command Line


Running WrapProtect.exe is simple. The parameters and method to run it are the same as for
PFCLObfuscate. With WrapProtect.exe there are less settings that the user can manipulate. To run
and see the possible parameters simply type its name in the “Execute PFCLObfuscate” Window as
follows:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>wrapprotect
Warning: Incorrect number of arguments passed

WrapProtect: Release 1.0.7.0953 - Production on Wed Jun 19 12:34:37 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

usage: wrapprotect [options]


-v -- verbose mode
-s -- silent mode
-t -- include timing information
-i <wrap input> -- Specify the input wrap file to protect
-c <config file> -- Specify the configuration file
-o <output file> -- specify the output file
-l <log file> -- Specify the log file name
-? -- for help
-h -- for help
-H -- for help

The possible WrapProtect.exe parameters are:

Page 89 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

1. “-v” and “-s” can be used in scripts to silence output or make it loud
2. “-t” is used to add timing information to logs, debug and trace modes
3. “-c” is used to specify the configuration file described next
4. “-i” is the wrapped input file
5. “-o” is the output file generated after wrap protection
6. “-l” is the log file if you choose to write the tools output to a log instead of the screen
7. “-?”, “-h” and “-H” all display the help

The help “-h” shows a little more details:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>wrapprotect -h

WrapProtect: Release 1.0.7.0953 - Production on Wed Jun 19 12:43:22 2013

Copyright (c) 2013 PeteFinnigan.com Limited. All rights reserved.

Details of command line options:


--------------------------------

-v Can be specified to obtain verbose output to stdout.


-s Silent: Can be used to reduce output to error messages
only
-t Adds timestamps to collected data, reports and
log files
-l <log file name> Write all output and errors to a log file. This can
be used in conjunction with silent mode
-i <wrap Input> The wrapped file to be protected
-o <output file> Specify the output file for results
-c <config file> Configuration file to specify parameters
-? Show this screen.
-h Show this screen.
-H Show this screen.

WrapProtect Options
WrapProtect uses a configuration file to control its processing of the wrapped code into wrap
protected code. There is a sample configuration file shipped with PFCLOBfuscate and this is called
wp.conf. You are free to edit this file or to use your own configuration file. The configuration file is
passed to wrapprotect.exe with the “-c” parameter.

A sample file is here:

###############################################################################
# wp.conf
# Pete Finnigan 08-May-2003
#
# Who When Description
# === ======== ====================
# PF 02-Apr-2008 Update for new release
# PF 20-May-2011 Updated for WrapProtect
# PF 19-Jun-2013 Removed unsupported parameters
#
# sample config file for PeteFinnigan.com Limited PFCLObfuscate
#
###############################################################################
#
# verbose - make output noisy
#
verbose=yes
#

Page 90 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

# normal logging is surpressed, error messages are still generated.


#
silent=no
#
# when verysilent is set no output is generated, even error messages
# are suppressed
# CURRENTLY NOT SUPPORTED
#
verysilent=no
#
# setting timing enables the addition of timestamps to log entries and also
# timing of each test.
#
timing=yes
#
# location of the log file if output is to be saved to a log.
#
#logfile=wp.log
#
# Name of the output file.
#
#outputfile=wp.op
#
############################################################################
# PL/SQL parameters
############################################################################
#
# Input file name. For PL/SQL scanning or unwrapping this is the PLB file
#
#inputfile=wp.plb
#
############################################################################
# WrapProtect Parameters
############################################################################
#
# The output file can include a comment at the top. This can be system
# generated by WrapProtect or can be user supplied.
#
# determines whether comments are on/off
comment=yes
#
# supply a customer generated comment in the form of a string
#
usercomment=Copyright (c) PeteFinnigan.com Limited, 2013. All rights reserved
#
#
# END CONFIG FILE
#

The sample configuration file above shows all of the settings allowed in WrapProtect. The
configuration file does not need to contain comments (starting with “#”) to work so a configuration
file can be much smaller for use. Each setting is now explained:

 Comments are lines that start with a “#” character are comments. The comment line
must start with a “#” at the beginning of the line; the “#” cannot be anywhere else.
 “verbose=yes” will make the logging and error output noisy and show maximum
messages. The default setting is “yes”
 “silent=no|yes” – if set to “yes” then WrapProtect will run silently and reduce the
amount of output. The default setting is “no”

Page 91 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

 “timing=yes|no” will add time stamps to the screen output or log output. The default is
“yes”
 “logfile=wp.log” – if a filename is specified then the screen output is instead written to
the specified log file.
 “inputfile=wp.plb” – The input file to be wrap protected can be passed via the
configuration file but it is better practice to set up a configuration file that controls the
wraprotect process and to then pass in the input and output file names.
 “outputfile=wp.op” – This parameter controls the name of the output file after it has
been wrapprotected. As with the input file whilst it is possible to pass in the name via
the configuration file it is better to pass the file names via the command line.
 “comment=yes” – This controls whether a comment is written to the output
wrapprotected file. If this is set to “no” the following parameter is ignored.
 “usercomment=Copyright (c) PeteFinnigan.com Limited 2013,All rights reserved” – This
parameter allows the user to supply a comment that will be added in the wrapprotected
file. If comments are enabled and no user comment is supplied then the internal
machine generated comment is added including the full product version numbers.

The same configuration file can generally be used for all files in a project. It is common to use the
same settings and for the omit file to include all of the public API’s. A later section discusses
obfuscating multiple files in one command.

For parameters where the value is the name of a file such as the “logfile” file then it is permissible to
include the name of the file as just the name as the examples above show – “logfile=wp.log” for
instance. This means that the file must be in the working directory used by PFCLObfuscate as no
path is specified. It is also permissible to use the full path to a file such as “logfile=c:\temp\log.wp”
so that the file can be loaded from a fixed location.

WrapProtect Limits
There are some limits that must be understood when creating files that will be wrap protected.
Wrapprotect tokenises the complete file and concatenates and removes white space. Because of
this any SQL*Plus commands and PL/SQL and SQL that is not wrapped must be carefully added.

The limits are:

1. Only one PL/SQL wrapped block per file to be processed


2. The file to be processed cannot include other none wrapped PL/SQL packages, procedures,
functions or types.
3. Other SQL and PL/SQL can be added but it must be tested after wrapprotect has processed
the wrapped source code.
4. Any SQL*Plus SET commands must be added just before the wrapped PL/SQL and if more
than one SET command is required they should be added all on one line

Ideally any pre-existing SQL*Plus file that contains a wrapped PL/SQL code that is to be
wrapprotected should be separated into two files. Move the wrapped code to its own file and retain
all features of the existing file and simply call the new wrapped file with @@filename.plb where
appropriate.

Page 92 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Dynamic Obfuscation – Version 2.0 features


Dynamic obfuscation adds a scripted interface to PFCLObfuscate to allow a much richer possibilities
for the obfuscation process allowing powerful obfuscation and also the possibility to insert code
such as license features.

Introduction
This section introduces the version 2.0 features of PFCLObfuscate. Version 2.0 is a major update and
a number of new features are added that allow a much better obfuscation and also the possibility to
obfuscate calls to standard packages and procedures that would not normally be possible to
obfuscate because the packages supplied also would need to be obfuscated with the same name. If
you supply your own code in a procedure called PROC_X and your code calls your own code in
another package called PACK_Y.PROC_A then you would obfuscate both the package and the call to
the same random string to make it work (This random string is the obfuscated name of the package).
If instead you called a SYS package such as DBMS_OUTPUT.PUT_LINE() then you could not obfuscate
this package name in your code as you would also need to obfuscate the SYS owned package
otherwise your use of this procedure would not work when its renamed as DFGFD.GHGDDA().

This obfuscation feature is achieved by “code insertion” which is driven by dynamic obfuscation.
When a PL/SQL source file is obfuscated with V2.0; “hook points” (described below) are processed
by PFCLOBfuscate and if required any number of dynamic scripts are executed for each “hook”.
These are written in PFCLLua (Lua script language with a small number of PFCL additions) and for
each of these PL/SQL code can be added via template or generated completely dynamically with
PFCLLua. This code is then obfuscated in-line itself as it is added. The process is driven by the “driver
hooks”. These are any named PL/SQL code – i.e. a package such as DBMS_OUTPUT.PUT_LINE() being
found in your code or a string being located or a special comment of the form --++ or the start or end
of a block being located. These are locations where the inserted code is used. Don’t worry we will
show some examples soon.

We also need to insert the actual new PL/SQL functional code so there are two hook points for
insertion only these are at the start of a declaration section and at the end of a declaration block.
The code insertion is controlled by a main parameter file that is defined in the main PFCLObfuscate
configuration file. This file then enables the user to define any number of dynamic obfuscations.
These are defined on the basis as described above. The details of configuration are shown below.

The configuration file allows you to decide how “deep” to insert forward declarations of PL/SQL and
also PL/SQL function bodies into the structure of PL/SQL so for instance if a PL/SQL procedure is
embedded into a PL/SQL procedures header then we can control whether the “new” inserted code is
added once to the outer procedure or in all embedded procedures or only to a certain depth. This is
controlled by the configuration file at a granularity of each piece of inserted code. The “use” of the
inserted code can be at any level of course.

Limitations
There are a number of limitations of the “dynamic obfuscation” functionality in version 2.0. Some of
these will be lifted in versions 2.1 and 2.2 as they are released.

Page 93 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

1. The inserted PL/SQL code is added into the stream of PL/SQL code being processed by
PFCLOBfuscate. This means that new PL/SQL code added is also obfuscated. Note, though
that the insertions are not recursive. This means that extra new PL/SQL code is not added to
the code that you add, ad infinitum. This is not a major issue as the PFCLLua that generates
the PL/SQL can be written such that recursive inserts are not necessary.
2. No code is added to anonymous blocks that do not include a declare section. No code is
added to package headers.
3. Currently you should use Version 2.0 features only with one PL/SQL block per file. Whilst
version 2.0 will execute against source code files with multiple blocks the behaviour is not
what you will expect as the insertions will occur as soon as possible in the file and not to
later code. Currently you control to what depth code is added in a PL/SQL block such as one
level deep or two or more. If you have multiple blocks in one file then the forward
declarations and function bodies will be added to code of this level BUT once. If the depth is
set to 1 in the functionfile.txt for a piece of PL/SQL code in the first block in a file it would
not be added to the second block due to the way the parser uses a stack to detect “scope” in
the PL/SQL. This means any “calls” to the same functions/procedures would not work. This
may change in a later version 2 release but to support multiple blocks and enable
uniqueness of code creates a much more complex parser – in essence the parser would need
to re-start mid-file and increment the block Ids. The simpler solution is to simply enforce
PL/SQL to be in separate files. An enhancement coming in a later version 2 release is to add
a project manager to make it easier to manage this.
4. Not all “hooks” are implemented in version 2.0. The hooks for strings and special comments
--++ are not implemented in version 2.0 but will be in 2.1
5. The use of the START or END block inserts (“hooks” 3 and 6) are limited to the first depth
that they encounter – see (1) above which is a similar issue. If the depth setting is set to 2
then a START or END block is only inserted into the first depth 2 code encountered and no
further ones. This will be changed in version 2.1 to allow insertion to depth 2 or deeper to be
done to all depth 2’s in a source file. This initial implementation makes the “dynamic
obfuscation” simpler to understand at this stage and should not impair the usability.
6. If a block at a depth that includes a “hook” 6 insert (END) also has an EXCEPTION clause in
the existing pre-obfuscated code then the “hook 6” code (END) will be inserted before END
and after EXCEPTION which is a known bug. This will be corrected in version 2.1. At the
moment in version 2.0 the workaround is to only use hook 6 when there is no exception
clause. This is not a major issue as license code should be inserted with hooks 3 and 5
7. All package bodies that are obfuscated with “dynamic obfuscation” should include an
initialisation section even if it only contains “NULL;”. This allows for license code to be added
at the lowest level in the package
8. All keywords IS, AS, DECLARE, BEGIN and END are supported as either all lower case or all
upper case and not mixed cases.
9. If a package header included a package that is obfuscated with “hook 5” then this would be
replaced with the obfuscated call and its forward declaration. Whilst this works it is not good
as the obfuscation code procedures are then public to the package. It is however unlikely
that substitution would occur at this level simply because people would not normally write
code that can be obfuscated but it is not impossible.

Page 94 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

10. The syntax “END {token};” is not supported in version 2.0. This is a known issue and will be
fixed in version 2.1. For now all procedures and packages should end with “END;” only.

Enabling Version 2.0


Version 2.0 features are enabled by creating a functionfile.txt (or any name that you choose in the
PFCLObfuscate configuration file). You can run PFCLObfuscate in version 1.0 mode by commenting
out the functionfile parameter in the configuration or conversely enable version 2.0 functionality by
enabling this configuration entry and file. Before enabling the functionfile must be configured and
also the referenced PFCLLua files must exist.

Hook Points
The Version 2.0 functionality is driven by “hook points”. These are the places in the PL/SQL code that
are used to automatically add new PL/SQL, either forward declarations, function/procedure bodies
or use of the new PL/SQL code.

There are 7 "hook" points and some work differently to others. A piece of PL/SQL can look like this:

CREATE|DECLARE|PROCEDURE|FUNCTION|PACKAGE IS
{{hook 1}}

{{hook 2}}
BEGIN
{{hook 3}}

'string' => {{hook 4}}

call package|function|procedure => {{hook5}}


‘--++’ => {{hook 7}}

{{hook 6}}
END

Each line in the functionfile.txt configuration file controls what happens at the hook points - there
are three main entries, "fwd code", "code body" and "code called". All lines in the configuration
insert code at hook 1 and hook 2, these are forward declarations for PL/SQL procedures/functions
and the function / procedure bodies themselves.

The code that is inserted is also obfuscated as it is inserted. All inserted code is surrounded by
variables of the form {{type:functioned:depth:random}} where the entries are numbers. The
functioneid is the entry in the functionfile configuration file. The depth is the depth in the PL/SQL
where the code is inserted and random is the randomness indicator. The developer of the PFCLLua
that writes the PL/SQL has the option to create multiple copies of the PL/SQL that he wishes to
insert so that the same code is not inserted every time or the “use” of the same code can vary, to
make it harder to identify identical pieces of code. The code generated can have as many random
copies as the developer wishes and the random indicator shows which one was used. The random
value is generated and passed from obs.exe to the Lua code on execution.

Then the use of the new PL/SQL code is the focus of each configuration line. So there are a number
of options:

1) hook 3 - This inserts a call to the function defined at the block start
2) hook 6 - this inserts a call to the function defined at the block end

Page 95 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

3) hook 5 - package name - where a named package is encountered its changed to the name of the
function defined and obfuscated automatically to the same obfuscated name. This is intended to be
used to hide common package names so that they are not readable in the obfuscated code. So for
instance you may wish to hide all calls to DBMS_OUTPUT.PUT_LINE so you can add a line to the
configuration file that targets DBMS_OUTPUT.PUT_LINE and this will insert a forward declaration of
a replacement procedure called "x" and also its body and then replace all calls to
DBMS_OUTPUT.PUT_LINE with X.

This is illustrated here as a concept of what is intended:

SQL> create or replace procedure procedurea is


2 begin
3 dbms_output.put_line('hello world');
4 end;
5 /

Procedure created.

SQL> set serveroutput on


SQL> exec procedurea
hello world

PL/SQL procedure successfully completed.

SQL>

Then after manual modification it becomes:

SQL> edit
Wrote file afiedt.buf

1 create or replace procedure procedurea is


2 procedure x(lv in varchar2) is
3 begin
4 execute immediate 'begin dbms_output.put_line(:st); end;' using lv;
5 end;
6 begin
7 x('hello world');
8* end;
SQL> /

Procedure created.

SQL> exec procedurea;


hello world

PL/SQL procedure successfully completed.

SQL>

This is manually coded of course as an illustration of the process rather than through the interface.
In the example above the string in procedure "x" will be obfuscated hiding the package call. Of
course the generated code can be any PL/SQL code that you wish as it is generated by a Lua script
defined in functionfile.txt

4) STRING - if the word string is added to the configuration file then instead of using standard chr(n)
string obfuscation the lua code can be used to create any custom string obfuscation. This will not be
recursive in version 2 as the inserted code for added functions cannot be then obfuscated with the
Page 96 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

same version 2 rules.

5) COMMENT - any "special comment" of the form --++ will be replaced by the specified PL/SQL via
LUA.
Note that “hooks 4 and 7” STRING and COMMENT are not implemented in version 2.0 and will be
added in 2.1. The reason for this is that these hooks directly relate to deployed licenses and this
functionality will be part of the 2.1 release.

Function File
Version 2.0 dynamic obfuscation is controlled by the functionfile.txt file. This file is specified in the
PFCLObfuscate configuration file and does not need to be called functionfile.txt that is simply a
default name. The structure of the file is as follows:

ID Type Object Name New Fwd Insert Enabled Depth Random


Lua Lua Lua

The fields have the following meanings:

Field Description
ID Unique ID for the entry
Type Type can be PACK – package replacement, STRING – process strings, START –
insert code at start of block, END – insert code at end of block and COMMENT
– add code in replacement for special comment
Object Name Object name is used when type is PACK. For other types set this field to
“BLANK”, not ||, i.e. not a null string but the word BLANK
New Lua The PFCLLua script that is used to generate the insertion. This could be to
replace the package call or to insert code instead of a comment or to insert
code at the start or end of a block
Fwd Lua The PFCLLua used to generate variables or forward declarations of PL/SQL
procedures or functions
Func Lua The PFCLLua code that generates the PL/SQL procedure itself
Enabled 1 = Enabled, 0 = Not Enabled
Depth Maximum depth to insert code to. If set to 1 then only add code to each outer
block of PL/SQL in a file. If set to 2 then insert code at depth 1 and depth 2.
The depth will be zero when not in an outer block of PL/SQL.
Random Max range of random numbers passed to the Lua engine. If Lua is set to 7 then
your “new lua” and “fwd lua” should generate code for seven functions. The
random number then inserts a random function in the “insert lua” from this
range. Any functions not used are removed in post processing. If the random
setting is 0 then randomness is not enabled.

Here is a sample entry for the functionfile.txt file:

1|PACK|DBMS_OUTPUT.PUT_LINE|dbms_op_new.lua|dbms_op_fwd.lua|dbms_op_func.lua|1|0|0
2|PACK|DBMS_OUTPUT.NEW_LINE|dbms_nl_new.lua|dbms_nl_fwd.lua|dbms_nl_func.lua|1|0|0

Page 97 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Writing Dynamic Obfuscation Scripts


The core functionality of PFCLOBfuscate Version 2.0 is driven by the ability to specify dynamic
PFCLLua scripts that are executed at the fixed “hook” points in each of your PL/SQL files as they are
processed and also when certain things are dynamically located such as strings and named packages.

This is a powerful feature that is used internally by the tool as shipped – i.e. we supply a pre-
configured functionfile and also a small number of pre-written PFCLLua scripts associated with each
entry as examples to develop your own code but also that you can use if you wish.

As a user of PFCLObfuscate you will find a need to write your own PFCLLua scripts and also add
functionfile entries to manage these scripts.

What you put in your scripts is entirely up to you and can be anything that is valid PFCLLua and its
purpose is to dynamically write PL/SQL.

Note: PFCLLua is simply the Lua language with two simple extensions. There
are two additional functions PFCLPrint and PFCLPrintN and PFCLSplit. These
print lines of text to the parser output stream that are then automatically
obfuscated. The version with “N” emits text with a newline on the end.

The Lua is used for three general purposes:

1. Create forward declarations for PL/SQL functions or to add types or PL/SQL variables. These
are added at the start of the declaration section
2. Add function or procedure bodies written in PL/SQL
3. Add code to the insertion point. This varies based on purpose but could be code to replace a
string or code to replace a package procedure call

Your Lua code in general therefore writes PL/SQL code but this code can simply be template based –
i.e. emit code with print statements or it could be dynamic, i.e. generate code based on rules written
into your code, that way you can generate PL/SQL code that is different for all insertion points
therefore making it harder for someone to take obfuscated code and do find/replace across all
instances.

Remember: Obfuscating PL/SQL code provides a simple level of protection


that would not stop a determined person. Adding protections such as license
type checks if the code is simply obfuscated and not wrapped would not
completely deter a skilled person. Therefore obfuscated code should also be
wrapped and ideally critical code should be wrapped with Oracle 9i and also
WrapProtected to provide deeper levels of protection

To enable you to write and test your own PFCLLua scripts we provide two tools “ls.exe” and “lc.exe”.
The first, “ls.exe” allows you to execute your scripts on the command line at the Windows CMD
prompt to test the output of your scripts. This can be demonstrated here. First we create a very
simple lua script:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type t.lua

Page 98 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

print "hello world"


C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Next this script can be executed to test it works using the “ls.exe” tool which is a program to execute
PFCLLua scripts. Here is an example execution of our simple script:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>ls t.lua

ls: Copyright (c) PeteFinnigan.com Limited 2013. All rights reserved

Run a LUA script, output is here ==> [

hello world

] <== Completed LUA Shell.

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The output will be shown between the “==> [“ and “] <==” symbols.

Compiling PFCLLua
PFCLObfuscate also includes a PFCLLua compiler so that you can also compile your PFCLLua scripts.
This is “lc.exe” and it allows you to pre-compile PFCLLua scripts into a binary format which gives you
better security of your own scripts if they are deployed to a build server where you do not
necessarily need anyone with access to read them. This is simple to use. We will use the same
example PFCLLua script from above t.lua. We can compile this with “lc.exe” as follows:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>lc t.lua t.bin


lc: Copyright (c) PeteFinnigan.com Limited 2013. All rights reserved
Compiling: t.lua
Completed compile, output in: t.bin

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The script is now a binary bytecode script and we run it just as before:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>ls t.bin

ls: Copyright (c) PeteFinnigan.com Limited 2013. All rights reserved

Run a LUA script, output is here ==> [

hello world

] <== Completed LUA Shell.

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

These examples are very simple but real dynamic PFCLLua scripts used in PFCLObfuscate will need to
be built using the provided template and also follow the writing rules.

Page 99 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Dynamic Script Overview


A script is at a high level used in one of three places:

 Start of declaration section – This can be forward declarations of PL/SQL procedures or


functions but also could be variables or types
 End of declaration block – This is generally function or procedure bodies
 Insert point – could be string replacement, package replacement, insert of code at start or
end of a block or special comment replacement

The code inserted at the points includes an identifier token of the form {{1:1:7:1}} where the
numbers have meanings in terms of how and where the code is inserted. You do not need to know
what these mean as the Lua template generates them for you and the obs.exe parser knows how to
interpret them.

When you write your PFCLLua scripts to generate the PL/SQL code you can create the PL/SQL and
not interact with the passed in values that generate the token but in some cases you may wish to do
so. Perhaps you would like to generate a different piece of PL/SQL based on “depth” or
“randomness”. These values also may need to be tested within your PFCLLua before it is used in
PFCLObfuscate and the tool “ls.exe” can be used to do this. For instance the simple script
dbms_op_func.lua generates a function body to allow DBMS_OUTPUT.PUT_LINE to be hidden; we
will use this script as an example. First run the “ls.exe” tool to execute the script:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>ls

ls: Copyright (c) PeteFinnigan.com Limited 2013. All rights reserved

Incorrect arguments: ls luafile.lua [d|r|f|d|u]

d = depth
r = random
f = functionid
d = debug
u = user supplied values

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

The “ls.exe” tool can be used to execute PFCLLua scripts but it can also pass in the needed values
that would normally be passed from PFCLOBfuscate. These values are explained here:

Variable Description
Depth The depth means the depth in the PL/SQL source code. If a PL/SQL
procedure has an embedded PL/SQL procedure and the main block of the
procedure also has an embedded BEGIN/END block then the depth of the
actual main procedure is depth=1; The depth of the embedded procedure
would be depth=2 and the depth of the embedded BEGIN/END block would
also be depth=1. The depth increases as more PL/SQL blocks are added
inside existing blocks
Random This value can be used in your PFCLLua code to generate different
functions based on the value of random
Functionid The function ID is the index of the insert action stored in the functionfile.txt
configuration file
Page 100 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Debug To turn debugging of the PFCLLua on then set this to 1, else set to 0 to turn
off
User Supplied The user supplied strings are passed back from one PFCLLua script to
PFCLOBfuscate and then passed to each subsequent PFCLLua script. This
feature is powerful as it allows PFCLLua scripts to “talk” to each other.
The depth and random values in PFCLObfuscate are also controlled. You can set these values in the
functionfile.txt configuration file. This is described earlier. The depth and random values can be
limited by PFCLObfuscate. Each of these values can be used to generate numerous PL/SQL codes so
that each insertion point does not use the same PL/SQL code. But they also control to what “depth”
of code or randomness code is inserted into your PL/SQL

Here is an example use of “ls.exe” with sample parameters for testing:

This allows you to test your PFCLLua as it would run in PFCLObfuscate without processing a PL/SQL
file. You can take the output if necessary and run it in an Oracle database to test that it works before
using it in a functionfile.txt entry. You will also notice that because we also passed in “1” for the
debug value the provided PFCLLua library we are also able to debug the passed in variables sent to
the PFCLLua from the interface.

Lua Template
When writing checks in PFCLLua a template is provided that wraps the tokens needed and also
includes the Lua library we have provided for PFCLObfuscate; this library is in the file obs.lua. The
template is in the distribution and is called template.lua. The body of this is shown here:

require "obs"

obs.header()

-- ----------------------------------------------------------------------------
-- Add your own Lua code between this marker and the END MARKER
Page 101 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

-- ----------------------------------------------------------------------------

-- PFCLPrint("Add Your Code Here - And Remove This")

-- ----------------------------------------------------------------------------
-- END MARKER
-- ----------------------------------------------------------------------------

obs.footer()

This is simple to use and needs two steps. You need to add your own PFCLLua code between the
markers and generate the PL/SQL code that you need. This can be any valid PFCLLua and also can
contain PFCLPrint() or PFCLPrintN() or PFCLSplit() to generate the actual output. You must also
specify obs.header() and obs.footer() to generate the delimiter tokens. You may also reference any
other obs package variable such as license values.

The calls to obs.header() and obs.footer() can also contain the flag “inline” or “trail”. Here is an
example from one of the shipped PFCLLua files:

require "obs"

obs.header("inline")

-- ----------------------------------------------------------------------------
-- Add your own Lua code between this marker and the END MARKER
-- ----------------------------------------------------------------------------

PFCLPrint("procedure new_op_func(a in varchar2);")

-- ----------------------------------------------------------------------------
-- END MARKER
-- ----------------------------------------------------------------------------

obs.footer("inline")

The flag “inline” means that the header – the identifier {{1:1:1:1}} is added inline with the PL/SQL
and if “trail” is specified then a <CR> is added. This simply allows the code to be cleaner when
added, it does not need the <CR> to work but its cleaner.

Instrumentation
The instrumentation features of PFCLObfuscate have been enhanced for “dynamic obfuscation” in
version 2.0. If trace is enabled for obs.exe by running the setup.bat script before using obs.exe then
debug is permeated to any Lua script that is executed. The script must be written using our shipped
lua template for this to work and automatically the obs.lua package adds PL/SQL comments to the
outputted PL/SQL source code with debug values. By default we debug out the internal settings such
as depth, functioned, random etc and also the license settings. You also can add custom debug
entries to your Lua that translates to output as comments in the generated PL/SQL. This can be
added by calling obs.d(“this is a debug”) package call where “this is a debug” is a sample debug
string.

Page 102 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

The “debug=yes” configuration setting has also been enhanced to also debug the “depth” for every
lexeme parsed by obs.exe. This enables debugging related to insertion at hook points based on the
depth settings in functionfile.txt.

The parser by default deletes its intermediate files but you can retain the output of each Lua script
that is executed by setting “keepintermediate=yes” in the ob.conf file. These output files are PL/SQL
generated by your Lua that are then inserted into the obfuscation stream. These can help debugging.

The parser also by default deletes the intermediate file that includes all of the inserted PL/SQL code
before it s parsed. Set “keepinsert=yes” to keep this file to aid debugging.

A good way to debug PFCLObfuscate for version 2.0 is to turn off compact, comments, obfuscation
and to set stringmode=0 in the ob.conf file and then execute again. This shows all inserted code in
clear text PL/SQL so it’s easier to debug.

License Additions
PFCLObfuscate version 2.0 is able to add license protection to your PL/SQL code automatically simply
by defining settings in the file license.txt. Currently this file must be called license.txt but this will be
changeable in later releases. The first version 2.0 allows simple date based licenses to be added and
also “trial” features. Version 2.1 will allow deployed licenses and hardware/software locks to lock
your PL/SQL to a database.

To enable licensing edit the license.txt file and then add a START entry to functionfile.txt that uses
out shipped license lua files.

A simple example is shown below

License File
A sample license.txt file is shown here:

expire_days=30 # number of days until the code will expire


expire_date=19-APR-2014 # last date the code will run DD-MON-YYYY
start_date=14-APR-2014 # start date for which the code will run from DD-MON-YYYY
type=trial # trial, live,

Additional comments have been added after the “#” symbol. These are not in the shipped license file
and are shown here for aid only

Dynamic Obfuscation Examples


This section is showing some simple examples of dynamic obfuscation

Example 1 – Dynamic Obfuscation

As with any normal obfuscation we must first do some configuration and also first check that the
PL/SQL that we wish to protect works normally beforehand. First create the reserved.txt file with the
gr.sql script:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
sys/oracle1@//192.168.1.86:1521/pdborcl.localdomain as sysdba
Page 103 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

SQL*Plus: Release 11.1.0.7.0 - Production on Tue Apr 15 11:42:47 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @gr
SQL>

Add the public name of the procedure DEMO_RUN to the omit.txt

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


DEMO_RUN
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Connect to the database and run the pre-obfuscated code to ensure that it works:

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @sam2.sql

Procedure created.

SQL> @sam1.sql

Procedure created.

SQL> set serveroutput on


SQL> exec demo_run('hello');
e
Run TEST_PROC
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3

PL/SQL procedure successfully completed.

SQL>

Now show the settings in the functionfile.txt

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type functionfile.txt


1|PACK|DBMS_OUTPUT.PUT_LINE|dbms_op_new.lua|dbms_op_fwd.lua|dbms_op_func.lua|1|1|0
2|PACK|DBMS_OUTPUT.NEW_LINE|dbms_nl_new.lua|dbms_nl_fwd.lua|dbms_nl_func.lua|1|1|0
3|START|BLANK|dbms_lic_begin_new.lua|dbms_lic_begin_fwd.lua|dbms_lic_begin_func.lua|1|1|0
4|END|BLANK|dbms_lic_end_new.lua|dbms_lic_end_fwd.lua|dbms_lic_end_func.lua|1|1|0
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Check that the version 2.0 settings are enabled in the ob.conf file:

Page 104 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Now obfuscate the two source code files:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam2.sql -o sam2.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 12:58:13 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 11:58:13] obs: Starting PFCLObfuscate...


[2014 Apr 15 11:58:13] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 15 11:58:13] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 15 11:58:13] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 15 11:58:13] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 11:58:14] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 11:58:14] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 11:58:14] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 11:58:14] obs: Version 2.0 Initialisation...
[2014 Apr 15 11:58:14] obs: Initialise the file list...
[2014 Apr 15 11:58:14] obs: Initialise the Depth Stack...
[2014 Apr 15 11:58:14] obs: Initialise the FWD Function list...
[2014 Apr 15 11:58:14] obs: Initialise the FUNC function list...
[2014 Apr 15 11:58:14] obs: Initialise the NEW function list...
[2014 Apr 15 11:58:14] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 11:58:14] obs: Obfuscating PL/SQL Input File [ sam2.sql ]
[2014 Apr 15 11:58:14] obs: Save the transposed variables
[2014 Apr 15 11:58:14] obs: Process intermediate file...
[2014 Apr 15 11:58:14] obs: Closing Down PFCLObfuscate
[2014 Apr 15 11:58:14] obs: Delete the intermediate file...

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam1.sql -o sam1.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 12:58:20 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 11:58:20] obs: Starting PFCLObfuscate...

Page 105 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2014 Apr 15 11:58:20] obs: Pre-Load Keywords from [key.txt]


[2014 Apr 15 11:58:20] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 15 11:58:20] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 15 11:58:20] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 11:58:20] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 11:58:20] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 11:58:20] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 11:58:20] obs: Version 2.0 Initialisation...
[2014 Apr 15 11:58:20] obs: Initialise the file list...
[2014 Apr 15 11:58:20] obs: Initialise the Depth Stack...
[2014 Apr 15 11:58:20] obs: Initialise the FWD Function list...
[2014 Apr 15 11:58:20] obs: Initialise the FUNC function list...
[2014 Apr 15 11:58:20] obs: Initialise the NEW function list...
[2014 Apr 15 11:58:20] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 11:58:20] obs: Obfuscating PL/SQL Input File [ sam1.sql ]
[2014 Apr 15 11:58:20] obs: Save the transposed variables
[2014 Apr 15 11:58:20] obs: Process intermediate file...
[2014 Apr 15 11:58:20] obs: Closing Down PFCLObfuscate
[2014 Apr 15 11:58:21] obs: Delete the intermediate file...

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Install the obfuscated code into the database and check it still works:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Tue Apr 15 13:09:48 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @sam1.opf

Procedure created.

SQL> set serveroutput on


SQL> exec demo_run('hello');
e
Run TEST_PROC
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3

PL/SQL procedure successfully completed.

SQL>

Everything works fine and the code is obfuscated. Compare this to the earlier sample2.sql script in
this manual. In this example we have obfuscated the code further and removed all of the standard
package calls making the code harder to understand for an attacker and obviously protecting your
IPR better:

Page 106 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

create or replace procedure li1Qll( Oi10Q0 in NUMBER, Q1O0Q1 in VARCHAR2, l0Q1il in out
INTEGER) IS procedure iili10(Q001O0
in varchar2); procedure Qi0OO1; procedure
lOQi11; QQii10 NUMBER:=3; l0iOll NUMBER; iO1O01 NUMBER:=1; procedure l01Q0Q( iiiil1 in out
NUMBER) is iOl10i
NUMBER; begin iOl10i:= iiiil1 * 5; end; procedure iili10(Q001O0 in varchar2) is begin execute
immediate chr(98)||chr(101)
||chr(103)||chr(105)||chr(110)||chr(32)||chr(100)||chr(98)||chr(109)||chr(115)||chr(95)||chr(1
11)||chr(117)||chr(116)||chr(112)
||chr(117)||chr(116)||chr(46)||chr(112)||chr(117)||chr(116)||chr(95)||chr(108)||chr(105)||chr(
110)||chr(101)||chr(40)||chr(58)
||chr(115)||chr(116)||chr(41)||chr(59)||chr(32)||chr(101)||chr(110)||chr(100)||chr(59)
using Q001O0; end; procedure Qi0OO1 is begin execute immediate
chr(100)||chr(101)||chr(99)||chr(108)||chr(97)||chr(114)
||chr(101)
||chr(32)||chr(108)||chr(118)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101)||chr(32)||chr(11
8)||chr(97)||chr(114)||chr(99)
||chr(104)||chr(97)||chr(114)||chr(40)||chr(49)||chr(49)||chr(41)||chr(59)
||chr(98)||chr(101)||chr(103)||chr(105)||chr(110)
||chr(32)||chr(115)||chr(101)||chr(108)||chr(101)||chr(99)||chr(116)||chr(32)
||chr(116)||chr(111)||chr(95)||chr(99)||chr(104)||chr(97)||chr(114)||chr(40)||chr(115)||chr(12
1)||chr(115)||chr(100)||chr(97)
||chr(116)||chr(101)||chr(44)||chr(39)||chr(68)||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||
chr(45)||chr(89)||chr(89)||chr(89)
||chr(89)||chr(39)||chr(41)
||chr(32)||chr(105)||chr(110)||chr(116)||chr(111)||chr(32)||chr(108)||chr(118)||chr(95)||chr(1
00)||chr(97)||chr(116)||chr(101)

||chr(32)||chr(102)||chr(114)||chr(111)||chr(109)||chr(32)||chr(100)||chr(117)||chr(97)||chr(1
08)||chr(59) ||chr(32)||chr(105)
||chr(102)||chr(40)||chr(116)||chr(111)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101)||chr(4
0)||chr(108)||chr(118)||chr(95)
||chr(100)||chr(97)||chr(116)||chr(101)||chr(44)||chr(39)||chr(68)||chr(68)||chr(45)||chr(77)|
|chr(79)||chr(78)||chr(45)
||chr(89)||chr(89)||chr(89)||chr(89)||chr(39)||chr(41)||chr(60)||chr(116)||chr(111)||chr(95)||
chr(100)||chr(97)||chr(116)
||chr(101)||chr(40)||chr(39)||chr(50)||chr(51)||chr(45)||chr(77)||chr(65)||chr(82)||chr(45)||c
hr(50)||chr(48)||chr(49)||chr(52)
||chr(39)||chr(44)||chr(39)||chr(68)||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||chr(45)||ch
r(89)||chr(89)||chr(89)||chr(89)
||chr(39)||chr(41)||chr(41)||chr(32)||chr(116)||chr(104)||chr(101)||chr(110)
||chr(32)||chr(32)||chr(32)||chr(32)||chr(32)||chr(32)||chr(114)||chr(97)||chr(105)||chr(115)|
|chr(101)||chr(95)||chr(97)
||chr(112)||chr(112)||chr(108)||chr(105)||chr(99)||chr(97)||chr(116)||chr(105)||chr(111)||chr(
110)||chr(95)||chr(101)||chr(114)
||chr(114)||chr(111)||chr(114)||chr(40)||chr(45)||chr(50)||chr(48)||chr(48)||chr(57)||chr(56)|
|chr(44)||chr(39)||chr(105)
||chr(110)||chr(118)||chr(97)||chr(108)||chr(105)||chr(100)||chr(32)||chr(108)||chr(105)||chr(
99)||chr(101)||chr(110)||chr(115)
||chr(101)||chr(40)||chr(49)||chr(41)||chr(39)||chr(41)||chr(59)
||chr(32)||chr(101)||chr(110)||chr(100)||chr(32)||chr(105)||chr(102)||chr(59)
||chr(32)||chr(105)||chr(102)||chr(40)||chr(116)
||chr(111)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101)||chr(40)||chr(108)||chr(118)||chr(9
5)||chr(100)||chr(97)||chr(116)
||chr(101)||chr(44)||chr(39)||chr(68)||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||chr(45)||c
hr(89)||chr(89)||chr(89)||chr(89)
||chr(39)||chr(41)||chr(62)||chr(116)||chr(111)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101
)||chr(40)||chr(39)||chr(50)
||chr(51)||chr(45)||chr(77)||chr(65)||chr(82)||chr(45)||chr(50)||chr(48)||chr(49)||chr(52)||ch
r(39)||chr(44)||chr(39)||chr(68)
||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||chr(45)||chr(89)||chr(89)||chr(89)||chr(89)||ch
r(39)||chr(41)||chr(43)||chr(51)
||chr(48)||chr(41)||chr(32)||chr(116)||chr(104)||chr(101)||chr(110)
||chr(32)||chr(32)||chr(32)||chr(32)||chr(32)||chr(114)||chr(97)||chr(105)||chr(115)||chr(101)
||chr(95)||chr(97)||chr(112)

Page 107 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

||chr(112)||chr(108)||chr(105)||chr(99)||chr(97)||chr(116)||chr(105)||chr(111)||chr(110)||chr(
95)||chr(101)||chr(114)||chr(114)
||chr(111)||chr(114)||chr(40)||chr(45)||chr(50)||chr(48)||chr(48)||chr(57)||chr(54)||chr(44)||
chr(39)||chr(105)||chr(110)
||chr(118)||chr(97)||chr(108)||chr(105)||chr(100)||chr(32)||chr(108)||chr(105)||chr(99)||chr(1
01)||chr(110)||chr(115)||chr(101)
||chr(40)||chr(50)||chr(41)||chr(39)||chr(41)||chr(59)
||chr(32)||chr(101)||chr(110)||chr(100)||chr(32)||chr(105)||chr(102)||chr(59)
||chr(32)||chr(105)||chr(102)||chr(40)||chr(116)
||chr(111)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101)||chr(40)||chr(108)||chr(118)||chr(9
5)||chr(100)||chr(97)||chr(116)
||chr(101)||chr(44)||chr(39)||chr(68)||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||chr(45)||c
hr(89)||chr(89)||chr(89)||chr(89)
||chr(39)||chr(41)||chr(62)||chr(116)||chr(111)||chr(95)||chr(100)||chr(97)||chr(116)||chr(101
)||chr(40)||chr(39)||chr(50)
||chr(50)||chr(45)||chr(77)||chr(65)||chr(82)||chr(45)||chr(50)||chr(48)||chr(49)||chr(52)||ch
r(39)||chr(44)||chr(39)||chr(68)
||chr(68)||chr(45)||chr(77)||chr(79)||chr(78)||chr(45)||chr(89)||chr(89)||chr(89)||chr(89)||ch
r(39)||chr(41)||chr(41)||chr(32)
||chr(116)||chr(104)||chr(101)||chr(110)
||chr(32)||chr(32)||chr(32)||chr(32)||chr(32)||chr(114)||chr(97)||chr(105)||chr(115)||chr(101)
||chr(95)||chr(97)||chr(112)
||chr(112)||chr(108)||chr(105)||chr(99)||chr(97)||chr(116)||chr(105)||chr(111)||chr(110)||chr(
95)||chr(101)||chr(114)||chr(114)
||chr(111)||chr(114)||chr(40)||chr(45)||chr(50)||chr(48)||chr(48)||chr(57)||chr(53)||chr(44)||
chr(39)||chr(105)||chr(110)
||chr(118)||chr(97)||chr(108)||chr(105)||chr(100)||chr(32)||chr(108)||chr(105)||chr(99)||chr(1
01)||chr(110)||chr(115)||chr(101)
||chr(40)||chr(51)||chr(41)||chr(39)||chr(41)||chr(59)
||chr(32)||chr(101)||chr(110)||chr(100)||chr(32)||chr(105)||chr(102)||chr(59)
||chr(101)||chr(110)||chr(100)||chr(59); end;
procedure lOQi11 is begin null; end; begin Qi0OO1(); case
QQii10 when 1 then l0iOll:=3;
iili10(chr(84)||chr(104)||chr(105)||chr(115)||chr(32)||chr(105)||chr(115)
||chr(32)||chr(97)||chr(32)||chr(104)||chr(101)||chr(97)||chr(100)||chr(101)||chr(114));

iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(110)||chr(117)||chr(109)||chr(98)||chr(101)||
chr(114)
||chr(32)||chr(105)||chr(115)||chr(32)
|| l0iOll);
iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(99)||chr(97)||chr(115)||chr(101)||chr(32)
||chr(118)||chr(97)||chr(114)||chr(32)||chr(105)||chr(115)||chr(32)
|| QQii10); when 2 then l0iOll:=4;
iili10(chr(84)||chr(104)||chr(105)||chr(115)||chr(32)||chr(105)
||chr(115)||chr(32)||chr(97)||chr(32)||chr(104)||chr(101)||chr(97)||chr(100)||chr(101)||chr(11
4));

iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(110)||chr(117)||chr(109)||chr(98)||chr(101)||
chr(114)
||chr(32)||chr(105)||chr(115)||chr(32)
|| l0iOll);
iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(99)||chr(97)||chr(115)||chr(101)||chr(32)
||chr(118)||chr(97)||chr(114)||chr(32)||chr(105)||chr(115)||chr(32)
|| QQii10); when 3 then l0iOll:=6;
iili10(chr(84)||chr(104)||chr(105)||chr(115)||chr(32)||chr(105)
||chr(115)||chr(32)||chr(97)||chr(32)||chr(104)||chr(101)||chr(97)||chr(100)||chr(101)||chr(11
4));

iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(110)||chr(117)||chr(109)||chr(98)||chr(101)||
chr(114)
||chr(32)||chr(105)||chr(115)||chr(32)
|| l0iOll);
iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(99)||chr(97)||chr(115)||chr(101)||chr(32)
||chr(118)||chr(97)||chr(114)||chr(32)||chr(105)||chr(115)||chr(32)
|| QQii10); else
iili10(chr(119)||chr(114)||chr(111)||chr(110)||chr(103)||chr(32)||chr(99)||chr(104)

Page 108 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

||chr(111)||chr(105)||chr(99)||chr(101));
end case; if ( ( iO1O01 = 1) and ( iO1O01 = 3)) then DBMS_OUTPUT.
PUT_LINE(chr(104)||chr(101)||chr(114)||chr(101)||chr(32)
||chr(105)||chr(115)||chr(32)||chr(73)||chr(70));
elsif ( ( iO1O01 = 2) or ( iO1O01 != 3)) then
iili10(chr(84)||chr(104)||chr(101)||chr(32)||chr(101)
||chr(108)||chr(115)||chr(105)||chr(102)||chr(32)||chr(99)||chr(108)||chr(97)||chr(117)||chr(1
15)||chr(101));
else
iili10(chr(101)||chr(108)||chr(115)||chr(101)||chr(32)||chr(99)||chr(108)||chr(97)||chr(117)
||chr(115)||chr(101));
end if; iO1O01:=4; l01Q0Q( iO1O01);
iili10(chr(110)||chr(101)||chr(115)||chr(116)||chr(101)||chr(100)
||chr(61)||chr(58)
|| iO1O01); for iO1O01 in reverse 1.. Oi10Q0 loop if MOD( iO1O01,2) = 0 then
iili10(chr(102)||chr(111)
||chr(114)||chr(32)||chr(108)||chr(111)||chr(111)||chr(112)||chr(32)||chr(119)||chr(105)||chr(
116)||chr(104)||chr(32)||chr(114)
||chr(101)||chr(118)||chr(101)||chr(114)||chr(115)||chr(101));
end if; end loop; lOQi11();end;
/

Compare this output with that earlier in the manual. The only visible package is DBMS_OUTPUT.
PUT_LINE – note the space character after the “.”. This should be fixed in the original source code to
allow it also to be obfuscated.

Example 2 – License Example


This example show how to use the simple license features in PFCLObfuscate dynamic obfuscation.
The license features in the first release of dynamic obfuscation are fairly simple but this will change
with the next service release. We will eventually also support hardware/software locking on many
fields, license deployment, tamper proofing and much more. This example shows obfuscation of the
same sample code but this time deploying a license lock.

Let us see the license file:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt


expire_days=30
expire_date=23-APR-2014
start_date=23-MAR-2014
license_type=trial
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Here is the functionfile.txt settings:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type functionfile.txt


1|PACK|DBMS_OUTPUT.PUT_LINE|dbms_op_new.lua|dbms_op_fwd.lua|dbms_op_func.lua|1|1|0
2|PACK|DBMS_OUTPUT.NEW_LINE|dbms_nl_new.lua|dbms_nl_fwd.lua|dbms_nl_func.lua|1|1|0
3|START|BLANK|dbms_lic_begin_new.lua|dbms_lic_begin_fwd.lua|dbms_lic_begin_func.lua|1|1|0
4|END|BLANK|dbms_lic_end_new.lua|dbms_lic_end_fwd.lua|dbms_lic_end_func.lua|1|1|0
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Here is the omit.txt file:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


DEMO_RUN

Page 109 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

We also add NESTED to the force.txt file as NESTED is a keyword/reserved word for Oracle:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type force.txt


NESTED
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Lets obfuscate using the license insert code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam1.sql -o sam1.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 22:00:48 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 21:00:48] obs: Starting PFCLObfuscate...


[2014 Apr 15 21:00:48] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 21:00:48] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 21:00:48] obs: Version 2.0 Initialisation...
[2014 Apr 15 21:00:48] obs: Initialise the file list...
[2014 Apr 15 21:00:48] obs: Initialise the Depth Stack...
[2014 Apr 15 21:00:48] obs: Initialise the FWD Function list...
[2014 Apr 15 21:00:48] obs: Initialise the FUNC function list...
[2014 Apr 15 21:00:48] obs: Initialise the NEW function list...
[2014 Apr 15 21:00:48] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 21:00:48] obs: Obfuscating PL/SQL Input File [ sam1.sql ]
[2014 Apr 15 21:00:48] obs: Save the transposed variables
[2014 Apr 15 21:00:48] obs: Process intermediate file...
[2014 Apr 15 21:00:48] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam2.sql -o sam2.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 22:01:03 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 21:01:03] obs: Starting PFCLObfuscate...


[2014 Apr 15 21:01:03] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 21:01:03] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 21:01:03] obs: Version 2.0 Initialisation...
[2014 Apr 15 21:01:03] obs: Initialise the file list...
[2014 Apr 15 21:01:03] obs: Initialise the Depth Stack...
[2014 Apr 15 21:01:03] obs: Initialise the FWD Function list...
[2014 Apr 15 21:01:03] obs: Initialise the FUNC function list...
[2014 Apr 15 21:01:03] obs: Initialise the NEW function list...
[2014 Apr 15 21:01:03] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 21:01:03] obs: Obfuscating PL/SQL Input File [ sam2.sql ]
[2014 Apr 15 21:01:03] obs: Save the transposed variables
[2014 Apr 15 21:01:03] obs: Process intermediate file...
Page 110 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2014 Apr 15 21:01:03] obs: Closing Down PFCLObfuscate

Next install the obfuscated code and test if it works:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Tue Apr 15 22:01:44 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @sam1.opf

Procedure created.

SQL> @sam2.opf

Procedure created.

SQL> set serveroutput on


SQL> exec demo_run('hello');
e
Run TEST_PROC
This is a header
The number is 6
The case var is 3
The elsif clause
nested=:4
return var=3

PL/SQL procedure successfully completed.

SQL>

This works fine as before as the license.txt file specified a valid license for this database. The system
date is 23rd March 2014 and we specified a 30 day license where it is valid for this date. Now let’s
make the license invalid:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt


expire_days=30
expire_date=22-MAR-2014
start_date=23-MAR-2014
license_type=trial
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>
Re-Obfuscate the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam1.sql -o sam1.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 22:03:20 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 21:03:20] obs: Starting PFCLObfuscate...


[2014 Apr 15 21:03:20] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 15 21:03:20] obs: Pre-Load Omit words from [omit.txt]

Page 111 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2014 Apr 15 21:03:20] obs: Pre-Load StringOmit words from [string.txt]


[2014 Apr 15 21:03:20] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 21:03:20] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 21:03:20] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 21:03:20] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 21:03:20] obs: Version 2.0 Initialisation...
[2014 Apr 15 21:03:20] obs: Initialise the file list...
[2014 Apr 15 21:03:20] obs: Initialise the Depth Stack...
[2014 Apr 15 21:03:20] obs: Initialise the FWD Function list...
[2014 Apr 15 21:03:20] obs: Initialise the FUNC function list...
[2014 Apr 15 21:03:20] obs: Initialise the NEW function list...
[2014 Apr 15 21:03:20] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 21:03:20] obs: Obfuscating PL/SQL Input File [ sam1.sql ]
[2014 Apr 15 21:03:20] obs: Save the transposed variables
[2014 Apr 15 21:03:20] obs: Process intermediate file...
[2014 Apr 15 21:03:20] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


sam2.sql -o sam2.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Tue Apr 15 22:03:22 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 15 21:03:22] obs: Starting PFCLObfuscate...


[2014 Apr 15 21:03:22] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load force words from [force.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 15 21:03:22] obs: Pre-Load map file list from [map.txt]
[2014 Apr 15 21:03:22] obs: Version 2.0 Initialisation...
[2014 Apr 15 21:03:22] obs: Initialise the file list...
[2014 Apr 15 21:03:22] obs: Initialise the Depth Stack...
[2014 Apr 15 21:03:22] obs: Initialise the FWD Function list...
[2014 Apr 15 21:03:22] obs: Initialise the FUNC function list...
[2014 Apr 15 21:03:22] obs: Initialise the NEW function list...
[2014 Apr 15 21:03:22] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 15 21:03:22] obs: Obfuscating PL/SQL Input File [ sam2.sql ]
[2014 Apr 15 21:03:22] obs: Save the transposed variables
[2014 Apr 15 21:03:22] obs: Process intermediate file...
[2014 Apr 15 21:03:22] obs: Closing Down PFCLObfuscate

Now re-install the licensed code into the database and test it:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Tue Apr 15 22:03:23 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @sam1.opf

Procedure created.

SQL> @sam2.opf

Procedure created.

Page 112 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

SQL> set serveroutput on


SQL> exec demo_run('hello');
BEGIN demo_run('hello'); END;

*
ERROR at line 1:
ORA-20095: invalid license(3)
ORA-06512: at line 1
ORA-06512: at "ORABLOG.DEMO_RUN", line 25
ORA-06512: at "ORABLOG.DEMO_RUN", line 119
ORA-06512: at line 1

SQL>

As you can see the license has expired and we are not permitted to run the PL/SQL code

Example 3 – Obfuscate a Package

The next example is very similar to the last except that this time we are protecting a package. Here is
the package header and body code:

--
-- demo3.sql
-- demonstration PL/SQL to use for package demo
--

create or replace package demopkg


is
procedure demo(pv in varchar2);
end;
/
And

--
-- demo5.sql
-- demonstration code for package body with no initialisation section
--

create or replace package body demopkg


as
-- package variables
pbv_serial varchar2(300);
--
--
procedure write(pv_str in varchar2)
is
lv_line number;
begin
lv_line:=9;
dbms_output.put_line(pv_str);
end;
--
procedure demo(pv in varchar2) is
-- variables
j number;
l number;
-- nested proceudre
procedure NESTED( PV_LEN in out NUMBER) is

Page 113 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

X NUMBER;
begin
X:= PV_LEN * 5;
pv_len:=x;
end;
-- nested nested procedure
procedure nestednested(pv in out number) is
x number;
function depth(pv_nest in number) return number is
begin
return(pv_nest*5);
end;
begin
x:=depth(pv);
pv:=x;
end;
begin
--
-- this code will run for all users
--
write('Start of demo');

-- run the nested proceudre


-- trial feature
j:=4;
nested(j);
write('j='||j);

-- run the nestednested procedure


-- premimium feature
begin
write('Start sub-block in procedure body');
l:=5;
nestednested(l);
write('l='||l);
write('End sub-block in procedure body');
end;
-- end
write('End of demo');

exception
when others then
dbms_output.put_line('Error has occured in demo');
end;
--
-- --------------------------------------------------------
-- Dummy init clause added for license use
-- --------------------------------------------------------
--begin
-- null;
end;
/

Install this into the database and test it:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Wed Apr 16 09:41:39 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:

Page 114 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @demo3.sql

Package created.

SQL> @demo5.sql

Package body created.

SQL> set serveroutput on


SQL> exec demopkg.demo('Hello');
Start of demo
j=20
Start sub-block in procedure body
l=25
End sub-block in procedure body
End of demo

PL/SQL procedure successfully completed.

SQL>
Now prepare for obfuscation. First change the demo5.sql script to include a dummy initialisation
section as defined earlier in the manual in the limitations section:

...
dbms_output.put_line('Error has occured in demo');
end;
--
-- --------------------------------------------------------
-- Dummy init clause added for license use
-- --------------------------------------------------------
begin
null;
end;
/

We simply edited the script and uncommented the initialisation section. The initialisation section is
discussed in the limitations section above. For packages and where license code is to be added then
an initialisation section is needed in the current release of PFCLObfuscate. Also it makes sense to
add license software in this way as every time a package is first used it executes the initialisation
section to it is a good global place to capture license violations

Add the package public name and procedure name to the omit.txt file:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type omit.txt


DEMO_RUN
DEMOPKG
DEMO
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Also add NESTED to the force.txt file as it is a keyword known to Oracle but in this instance we want
to force obfuscation as we know it is a procedure name in our package:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type force.txt


NESTED
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Page 115 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Check the license.txt file contents. We have applied a simple license that licenses use of this package
for one month:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt


expire_days=30
expire_date=23-APR-2014
start_date=23-MAR-2014
license_type=trial
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now obfuscate the packages:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo3.sql -o demo3.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 09:53:01 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 16 08:53:01] obs: Starting PFCLObfuscate...


[2014 Apr 16 08:53:01] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 08:53:01] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 08:53:01] obs: Version 2.0 Initialisation...
[2014 Apr 16 08:53:01] obs: Initialise the file list...
[2014 Apr 16 08:53:01] obs: Initialise the Depth Stack...
[2014 Apr 16 08:53:01] obs: Initialise the FWD Function list...
[2014 Apr 16 08:53:01] obs: Initialise the FUNC function list...
[2014 Apr 16 08:53:01] obs: Initialise the NEW function list...
[2014 Apr 16 08:53:01] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 16 08:53:01] obs: Obfuscating PL/SQL Input File [ demo3.sql ]
[2014 Apr 16 08:53:01] obs: Save the transposed variables
[2014 Apr 16 08:53:01] obs: Process intermediate file...
[2014 Apr 16 08:53:01] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo5.sql -o demo5.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 09:53:23 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 16 08:53:23] obs: Starting PFCLObfuscate...


[2014 Apr 16 08:53:23] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 08:53:23] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 08:53:23] obs: Version 2.0 Initialisation...
[2014 Apr 16 08:53:23] obs: Initialise the file list...
[2014 Apr 16 08:53:23] obs: Initialise the Depth Stack...
[2014 Apr 16 08:53:23] obs: Initialise the FWD Function list...
[2014 Apr 16 08:53:23] obs: Initialise the FUNC function list...
[2014 Apr 16 08:53:23] obs: Initialise the NEW function list...
[2014 Apr 16 08:53:23] obs: Running PFCLObfuscate PL/SQL Obfuscator
Page 116 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2014 Apr 16 08:53:23] obs: Obfuscating PL/SQL Input File [ demo5.sql ]


[2014 Apr 16 08:53:23] obs: Save the transposed variables
[2014 Apr 16 08:53:23] obs: Process intermediate file...
[2014 Apr 16 08:53:23] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now install the protected code into the database and check that it works:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Wed Apr 16 09:55:56 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @demo3.opf

Package created.

SQL> @demo5.opf

Package body created.

SQL> set serveroutput on


SQL> exec demopkg.demo('hello');
Start of demo
j=20
Start sub-block in procedure body
l=25
End sub-block in procedure body
End of demo

PL/SQL procedure successfully completed.

SQL>

Everything is fine, but let us test that the licensing works. First change the expiry date to 22-MAR-
2014 so that the license has expired:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type license.txt


expire_days=30
expire_date=22-MAR-2014
start_date=23-MAR-2014
license_type=trial
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now re-protect the code:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo3.sql -o demo3.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 09:59:37 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

Page 117 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

[2014 Apr 16 08:59:37] obs: Starting PFCLObfuscate...


[2014 Apr 16 08:59:37] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 08:59:37] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 08:59:37] obs: Version 2.0 Initialisation...
[2014 Apr 16 08:59:37] obs: Initialise the file list...
[2014 Apr 16 08:59:37] obs: Initialise the Depth Stack...
[2014 Apr 16 08:59:37] obs: Initialise the FWD Function list...
[2014 Apr 16 08:59:37] obs: Initialise the FUNC function list...
[2014 Apr 16 08:59:37] obs: Initialise the NEW function list...
[2014 Apr 16 08:59:37] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 16 08:59:37] obs: Obfuscating PL/SQL Input File [ demo3.sql ]
[2014 Apr 16 08:59:37] obs: Save the transposed variables
[2014 Apr 16 08:59:37] obs: Process intermediate file...
[2014 Apr 16 08:59:37] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo5.sql -o demo5.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 09:59:40 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 16 08:59:40] obs: Starting PFCLObfuscate...


[2014 Apr 16 08:59:40] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 08:59:40] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 08:59:40] obs: Version 2.0 Initialisation...
[2014 Apr 16 08:59:40] obs: Initialise the file list...
[2014 Apr 16 08:59:40] obs: Initialise the Depth Stack...
[2014 Apr 16 08:59:40] obs: Initialise the FWD Function list...
[2014 Apr 16 08:59:40] obs: Initialise the FUNC function list...
[2014 Apr 16 08:59:40] obs: Initialise the NEW function list...
[2014 Apr 16 08:59:40] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 16 08:59:40] obs: Obfuscating PL/SQL Input File [ demo5.sql ]
[2014 Apr 16 08:59:40] obs: Save the transposed variables
[2014 Apr 16 08:59:40] obs: Process intermediate file...
[2014 Apr 16 08:59:40] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

And install the code to the database and test:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Wed Apr 16 10:00:01 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @demo3.opf

Page 118 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Package created.

SQL> @demo5.opf

Package body created.

SQL> set serveroutput on


SQL> exec demopkg.demo('hello');
BEGIN demopkg.demo('hello'); END;

*
ERROR at line 1:
ORA-20095: invalid license(3)
ORA-06512: at line 1
ORA-06512: at "ORABLOG.DEMOPKG", line 41
ORA-06512: at "ORABLOG.DEMOPKG", line 135
ORA-06512: at line 1

SQL>

This correctly blocks use of our protected code as the license has expired. But as the license check is
in the package initialisation section it runs just once per session so if we run the same code twice:

SQL> exec demopkg.demo('hello');


Start of demo
j=20
Start sub-block in procedure body
l=25
End sub-block in procedure body
End of demo

PL/SQL procedure successfully completed.

SQL>

The code clearly works again and is not blocked by the license. This is not an issue with
PFCLObfuscate but is an issue with how PL/SQL works. A package initialisation is only run once at the
time the package is first used in a session. If your PL/SQL code is called in a new session every time it
is executed then it is fine to add the license protection only to the package initialisation section. If
your PL/SQL is to be used multiple times in the same session then additional checks are needed.

Change the functionfile.txt to set the depth for the START entry for the begin license to 2 so that the
license check code is also added to the first function call in the package. The functionfile.txt is here:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>type functionfile.txt


1|PACK|DBMS_OUTPUT.PUT_LINE|dbms_op_new.lua|dbms_op_fwd.lua|dbms_op_func.lua|1|1|0
2|PACK|DBMS_OUTPUT.NEW_LINE|dbms_nl_new.lua|dbms_nl_fwd.lua|dbms_nl_func.lua|1|1|0
3|START|BLANK|dbms_lic_begin_new.lua|dbms_lic_begin_fwd.lua|dbms_lic_begin_func.lua|1|2|0
4|END|BLANK|dbms_lic_end_new.lua|dbms_lic_end_fwd.lua|dbms_lic_end_func.lua|1|1|0
C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Note that the START entry now has a “depth” of 2.

Re-protect the code:


Page 119 of 124
(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo3.sql -o demo3.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 10:21:30 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 16 09:21:31] obs: Starting PFCLObfuscate...


[2014 Apr 16 09:21:31] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 09:21:31] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 09:21:31] obs: Version 2.0 Initialisation...
[2014 Apr 16 09:21:31] obs: Initialise the file list...
[2014 Apr 16 09:21:31] obs: Initialise the Depth Stack...
[2014 Apr 16 09:21:31] obs: Initialise the FWD Function list...
[2014 Apr 16 09:21:31] obs: Initialise the FUNC function list...
[2014 Apr 16 09:21:31] obs: Initialise the NEW function list...
[2014 Apr 16 09:21:31] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 16 09:21:31] obs: Obfuscating PL/SQL Input File [ demo3.sql ]
[2014 Apr 16 09:21:31] obs: Save the transposed variables
[2014 Apr 16 09:21:31] obs: Process intermediate file...
[2014 Apr 16 09:21:31] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>obs -v -c ob.conf -i


demo5.sql -o demo5.opf

PFCLObfuscate: Release 2.0.122.1937 - Production on Wed Apr 16 10:21:32 2014

Copyright (c) 2014 PeteFinnigan.com Limited. All rights reserved.

[2014 Apr 16 09:21:32] obs: Starting PFCLObfuscate...


[2014 Apr 16 09:21:32] obs: Pre-Load Keywords from [key.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load Omit words from [omit.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load StringOmit words from [string.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load Reserved words from [reserved.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load force words from [force.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load function file list from [functionfile.txt]
[2014 Apr 16 09:21:32] obs: Pre-Load map file list from [map.txt]
[2014 Apr 16 09:21:32] obs: Version 2.0 Initialisation...
[2014 Apr 16 09:21:32] obs: Initialise the file list...
[2014 Apr 16 09:21:32] obs: Initialise the Depth Stack...
[2014 Apr 16 09:21:32] obs: Initialise the FWD Function list...
[2014 Apr 16 09:21:32] obs: Initialise the FUNC function list...
[2014 Apr 16 09:21:32] obs: Initialise the NEW function list...
[2014 Apr 16 09:21:32] obs: Running PFCLObfuscate PL/SQL Obfuscator
[2014 Apr 16 09:21:32] obs: Obfuscating PL/SQL Input File [ demo5.sql ]
[2014 Apr 16 09:21:32] obs: Save the transposed variables
[2014 Apr 16 09:21:32] obs: Process intermediate file...
[2014 Apr 16 09:21:32] obs: Closing Down PFCLObfuscate

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>

Now install the code into the database and test:

C:\Users\Pete\AppData\Local\PeteFinnigan.com Limited\PFCLObfuscate>sqlplus
orablog/orablog@//192.168.1.86:1521/pdborcl.localdomain

SQL*Plus: Release 11.1.0.7.0 - Production on Wed Apr 16 10:22:01 2014

Copyright (c) 1982, 2008, Oracle. All rights reserved.

Page 120 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Connected to:
Oracle Database 12c Release 12.1.0.1.0 - 64bit Production

SQL> @demo3.opf

Package created.

SQL> @demo5.opf

Package body created.

SQL> set serveroutput on


SQL> exec demopkg.demo('hello');
BEGIN demopkg.demo('hello'); END;

*
ERROR at line 1:
ORA-20095: invalid license(3)
ORA-06512: at line 1
ORA-06512: at "ORABLOG.DEMOPKG", line 135
ORA-06512: at "ORABLOG.DEMOPKG", line 229
ORA-06512: at line 1

SQL>

This time if we run the code again because the license check is now installed to depth 2 it checks the
license for us every time the write() function is called:

SQL> exec demopkg.demo('hello');


Error has occured in demo

PL/SQL procedure successfully completed.

SQL> exec demopkg.demo('hello');


Error has occured in demo

PL/SQL procedure successfully completed.

SQL>

We cannot run the code as our license protection stops execution BUT you will notice that the error
message came from the original PL/SQL code:

...
write('End of demo');

exception
when others then
dbms_output.put_line('Error has occured in demo');
end;
--
...

Page 121 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

Installing of automatic license protection needs a little thought from the implementer to take into
account where the license checks are made, existing exception or error handlers and also how your
PL/SQL is used.

Note that the first procedure in your PL/SQL package should be used always by your code otherwise
the license test will never be made so move the order or create a new call. This highlights that unlike
a PC binary such as obs.exe which always executes the “main” C Function and therefore license
checks can be added at the start of main() PL/SQL can be installed and called from anyway and any
procedure in a package used randomly. This is why adding the license protection to an initialisation
section is a good idea as all first use of the package is restricted.

This example illustrates two of the limits (first procedure in a package affects depth and also
existence of an exception block will capture your exceptions) in the first version of “dynamic
obfuscation” (version 2.0). This functionality will be extended in the next release.

Also note that adding license check code automatically is not limited to installing a license check at
the start of a block or the end of a block. A license check can be added as a substitute call. So a PACK
entry in

Advanced License Settings


Adding a single variable in PL/SQL from your Lua :

lv_var varchar2(100):=’0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ’;

Is a useful trick if the code is also then wrapped and wrap protected as all symbols in wrap files are
reduced to a single representation so that if one is edited it potentially breaks the string in many
places. This can be added as a START entry with a lua script that outputs null for the begin call but
retains the variable

Advanced Settings
PFCLOBfuscate sometimes gets an error message from the internal lexer caused by token buffer
overflows; this is the size of the token read into the parser. The only scenario where this can be an
issue is where there is a large comment in the program source code. We have had customers
comment out megabytes of code as comments and PFCLObfuscate needs to read this as it parses.
PFCLOBfuscate has two solutions;

1. Increase the size of the token buffer. This used to be only possible by support changing
the source code and recompiling a new version of the software. It is now possible to
dynamically change this buffer size by setting the configuration parameter
“tokenbuffersize”, this is normally defaulted to 2097152 bytes. If the parameter is not
set the software will use this size internally. The value of the parameter can be set to a
size in bytes. This should be possible to allocate by your PC of course and is dependent
on the available memory. See (2) for a more permanent solution.

Page 122 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

2. Because this issue is really an unlimited problem in that a comment can be as big as you
want it the alternate solution is of course to remove the comment or reduce it in size.

License Details
PFCLOBfuscate (which includes all utilities including WrapProtect) is commercial software and is
licensed and not sold. A valid license is needed to continue to use PFCLOBfuscate otherwise you may
only use PFCLObfuscate under the terms of the demonstration clause of the license agreement. The
license agreement was presented to you as you installed PFCLOBfuscate to accept or cancel. The
license agreement is also available via the programs start menu entries. We also technically lock
PFCLObfuscate if your license is not valid.

LUA License

PFCLObfuscate uses LUA as the base for its scripting language used for some functionality.
PFCLObfuscate has added extensions to LUA to allow customised processing of source code
with PFCLOBfuscate; for instance the LUA interface allows code to be inserted at various
“hook” points but the core of the language is pure LUA. The use of the LUA libraries dictates
that the LUA license is included here:

Copyright © 1994–2011 Lua.org, PUC-Rio.

Permission is hereby granted, free of charge, to any person obtaining a copy of this
software and associated documentation files (the "Software"), to deal in the Software
without restriction, including without limitation the rights to use, copy, modify,
merge, publish, distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to the following
conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY


KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE
WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS
OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

Known Issues
Some issues are known to PeteFinnigan.com limited and some new features will be added to solve
them when appropriate. These include:

1. All versions: SQL Plus commands that include variables will be obfuscated. For example
currently if you have a line “define debug = 'OFF'” then this line is correctly output as a

Page 123 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.
February 1, 2017 PFCLOBfuscate Users Manual

single line otherwise SQL*Plus will not accept it. But use of “debug” (the variable name
in this instance) in a subsequent script in the same or further file will be transposed. This
must be turned off manually by adding the word – “debug” in this case – to the omit file.
This applies to VAR, DEFINE, EXEC, UNDEFINE and COL statements
2. All versions: SQL*Plus variables can start with underscore. These are currently not
recognised by PFCLObfuscate when found inside SQL*Plus variables but then when they
are used inside SQL or PL/SQL they are substituted as “_”{varname}. The tool will be
modified to locate these variables in SQL*Plus strings and to modify them. At present do
not use SQL*Plus variables starting with “_”.
3. Version 2.0: In version 2.0 parsing we currently do not support PL/SQL blocks that end
(where “;” is {SC}) - “END {token}{SC}”. We do support end of blocks that are of the form
“END{SC}”. This will be fixed in 2.1.
4. All Versions: We do not currently support the q’bracket ... bracket’ syntax where
bracket is either [],{},() or <> and where bracket could be ! or any other character. We
also do not support the nq versions. This will be supported in 2.1.

Support
PFCLObfuscate issues can be reported by opening a new ticket at http://www.pfclsupport.com –
ticket status can be reviewed there also.

Page 124 of 124


(C) Copyright PeteFinnigan.com Limited 2017. This document may not be reproduced in any form, in
whole or in part, in any media, by any means whatsoever.

Das könnte Ihnen auch gefallen