Invisible Basic User's Guide
Version 4.1
Share your spreadsheets. Not your source code.
Copyright © 2005, 2006 John C. Gunther
under the terms of the BSD
open source
license.
All rights reserved.
Enhanced V4.0, 4.1 2012 Anthony@Berglas.org
Introduction
IB removes comments, and replaces identifiers like DoGoodStuff
with identifiers like O10l1ll101. This
makes the code essentially unreadable. Be careful to keep
the original!
E.g. (With comments showing source for debugging)'Public Property Get bb() As String
Public Property Get O1l10lOllO0() As String
'bb = "bb Long String to Encrypt"
O1l10lOllO0 = Ol001ll0O0l("19195B3714151C5B280F0912151C5B0F145B3E151809020B0F")
'End Property
(The
VBA passwords are worthless, there are cheap crackers available. They
just toggle a few bits in the .xla file, it does not matter how complex
your password is, it is still worthless.)
Just open InvisibleBasic.xla. It will create XL97 menus that
will load it on first usage thereafter. (They are under
AddIns tab in Excel 2007...)
Run
from the menu. The "Debugger" options include the original source as
comments interspersed with the code, essential while debugging, but
obviously do not ship these. Aggressive mode obsfucates additional
identifiers, but may require more #visible tags.
V4.0 is a substantial enhancement that greatly improves obsfucation
but can break some code.
Quickstart
- Ensure File > Options > Trust Center > Trust Center Settings > Macro Settings > Trust Access to VBA project model is set.
- In your program, mark any methods that are reflected upon
with a comment that includes the string "#visible".
Eg.
sub EntryPoint(par1, par2) ' #visible
Do this for methods that may be called by Application.Run("MyFun", ...)
etc. This will prevent IB from obscuring names on the line. (Not needed for OnAction methods, which ib will find.)
- If you are using Classes that are refered to by
typename(xxx) then they will also need to be marked visible.
Do that by marking a line that uses it as visible.
Eg.
public x as myvisibleclass ' #visible
(If a single variable
of type C is visible, then so must be its class otherwise you could not
declare it. Members of the class need to be explicitly made
#visible, one by one.) - If module names are used as part of external references (unlikely) then add
#If 0 Then '#begin_visible
myVisibleModule
#End If '#end_visible
- From the IB menu (under AddIns for Excel 2007+), run Debugging
Save Invisibly As. You will end up with
an *_ib.xls* file that has
the original source so that you can see what is happening.
(Alternatively,
and better, if you rename your module as *_src.xls* then
the "_src" suffix will be removed, producing the filename that you
actually want to ship.)
- Test it. It will not work first time.
Add ' #visible where necessary.
- When clean, Run IB again with Save as
for real obsfucation. Test again.
- To
encrypt strings, enable the option in the menu and copy the method
ibDecrypt (& ibUnHexDigit) from ibConfig module into your code.
Plain strings give a lot away.
- For a more obscure result, set the Aggression Option. This
will use a much shorter list of predefined words not
to obsfucate. You may need to rename type and class
member names if they are the same as a Excel method names that you use.
- Read the rest of this document. There are other
good features such as #remove_line. Also look at the Config
module in the source code.
- Enjoy.
Obsfucations, V4.0
Since V4.0, Invisible Basic
only obsfucates identifiers found in Dim, Public etc.
statements.
It does not obsfucate implicit Form variables, nor Option Implicit vars.
Importantly, V4.0 now also
recognises being/ends of subs and fucntions, and obsfucate the
same
local variable differently in different functions. This makes it much
more tedious to de-obsfucate by renaming variables.
The obsfucation is performed in two passes, the first builds up a
symbol table, and the second obsfucates. It can thus "look ahead"
to see how identifiers are used.
Parameters
to subroutines are normally obscured as local vars. But they
are
not obscured if they are used as a named parameter (:=), as IB
does not do a full parse and cannot easily work out which sub they are
from. However, if they end in "vv" (two "v"s) they
will be
obscured, but as global, not local names.
IB cannot fully resolve expressions like aaa.bbb.
It is just not possible to know in general what the static
type of aaa is, and thus which bbb
is being refered to if there are multiple. Thus if you
declare a Type member or Class method as Row
(say) it will also be substituted in myrange.Row
in aggressive mode. Also, all class and type member names are globally obsfucated to avoid
similar issues.
If a name appears in your code sandwiched between lines
containing
the #begin_visible and
#end_visible Invisible Basic directives or on
the same line as
the #visible directive (because
these directives are not valid VBA code, they usually appear
within comments).
With Basic obsfucation, IB uses a long list of reserved
words that it will not obsfucate for this reason. But every
unobscured name is a window onto your code. A better solution is
to enable Agressive obsfucation, and then ensure that your global names
do not conflict with
Excel ones.
You should prefix every class or member member with a letter or two from
the
type or class, eg myRow. This is good style anyway, and will also make
find/replace much easier as well.
(The list of names is in visible_names.txt or visible_names_safe.txt)
Names in the files starting with "_" are event procedures, eg "_click". The visiblize all "*_click" identifiers (say), without the need for a #visible tag.
Make
sure that the temporary *.txt files created by IB during processing are
not shipped with the addin -- they contain your source. (They may be left behind if ib crashes.)String Encryptions
Invisible Basic now (vsn 4.0) can encrypts all strings other
than constant strings.
They are replaced by ibDecrypt("755A98768D098C..."). Strings provide a lot of
visibility, so this is important, but the option needs to be enabled from the menu.
This
means that the method ibDecrypt (& ibUnHexDigit) need to be copied
from ibConfig module to one of your modules if string encryption is
enabled. (This method will also be obsfucted.)
Decryption is fast, about 0.01 microseconds per string, but make sure there are no string litterals within tight loops in
your code or they will be decrypted on each itteration.
Strings declared as constants obviously cannot be decrypted in this
way, replace them with variables.
String
shorter than MaxnoEncryptStringSize (4) chars are not encrypted to
minimize performance problems; unless the line contains #invisible_string.
Strings are also not encrypted on lines containing #visible_string.
The
encryption algorithm is weak, but the decryption algorithm will need to
be in your code somewhere anyway. The main point is that the
strings cannot be simply searched and read. Config.ibEncrypt can
be replaced if something stronger is desired.
obfuscated_line_hook$
You
can augment this method in the IB Config module to perform
arbitrary changes to code as it is being obsfucated. The example
one removes debug.print statements etc.
#remove_line
Lines
containging this string (as a comment) will be removed by IB.
This can be used to remove trace that gives to much
away,
or warnings about license tampering etc.
then Invisible Basic will implicitly make the objectName (in this case
myLabel)
visible.
Secret Decoder file
Each time you "save invisibly", Invisible Basic creates a
tab-delimited "secret decoder" file that shows each obfuscated
variable name in the first column, and the associated original
variable name in the second column. The file is automatically
generated (overwriting any previous such file), and has a name with
the general format:
yourWorkbooksName_secretDecoder.tmp
If your obfuscated program generates an error that throws
you into
the debugger, the secret decoder file can provide a quick way to
determine the
original names of the obfuscated variables that appear on the
offending line. Although running the test using source code generated
via "Debugging Save Invisibly As" (see below) can also provide such
information,
if you are debugging a problem reported by a user who only has
access to the obfuscated code, using the secret decoder file might be
more
convenient.
Obviously, do not distribute this file, it is secret.
Export Basic
Handy
utility that exports all modules, classes, and form code to a folder as
.bas files. Windif etc. are then your friends. Does not
export Userform meta data.
Issues
For
unknown reasons this can sometimes crash Excel. I optimized
the code reloading for Modules which seems to fix it, but not for
Classes etc. So if you have problems try moving code into modules.