Android Tutorial Code Obfuscation

This tutorial is relevant for B4A and B4J.
During compilation B4A generates Java code which is then compiled with the Java compiler and converted to Dalvik (Android byte code format).
There are tools that allow decompilation of Dalvik byte code into Java code.

The purpose of obfuscation is to make the decompiled code less readable, harder to understand and make it more difficult to extract strings like developer account keys.

It is important to understand how the obfuscator works.
The obfuscator does two things:

Strings obfuscation
Any string written in Process_Globals sub (and only in this sub) will be obfuscated, making it much harder to extract important keys. The strings are defuscated at runtime.
Note that several keys are used during obfuscation including the package name, version name and version code. Modifying these values with the manifest editor will break the defuscation process.

Variables renaming
The names of global variables and subs are converted to meaningless strings. Local variables are not affected as their names are lost anyway during the compilation.
The following identifiers are not renamed:
- Identifiers that contain an underscore (requires for the events handlers).
- Subs that appear in CallSub statements. Only if the sub name appears as a static string then the identifier will be kept as is.
- Designer views names.

Tip: If, for some reason, you need to prevent the obfuscator to rename an identifier you should add an underscore in the identifier name.

A file named ObfuscatorMap.txt will be created under the Objects folder. This file maps the original identifiers names to the obfuscated names. This mapping can be helpful to analyze crash reports.

Activating the obfuscator


There are three modes:
- Debug - in this mode the IDE debugger will connect to the running application (same as the previous Attach debugger option).
- Release - compiles the application without any debugging information.
- Release (obfuscation) - compiles the application and activates the obfuscator.

SS-2012.01.06-19.38.16.png


Pitfalls
Using CallSub with a non-static string.
The following code demonstrates this issue:
B4X:
Sub Activity_Resume
   CallSub("Main", "Test1") 'Works because it is a static string (Test sub will not be renamed)
   Dim subName As String
   subName = "Test2"
   CallSub("Main", subName) 'Skipped at runtime because Test2 sub is renamed
   subName = "Test_3"
   CallSub("Main", subName) 'Works because Test_3 includes an underscore and it will not be renamed.
End Sub
Sub Test1
   Log("a")
End Sub
Sub Test2
   Log("b")
End Sub
Sub Test_3
   Log("c")
End Sub

- LicenseChecker.SetVariableAndValue
This method references a variable using a string. This method will fail if the variable name doesn't include an underscore.
 
Last edited:

peacemaker

Expert
Licensed User
Longtime User
Oh, clear, was reading this, but as usual not to the finish :-(.....
 

pwme

Member
Licensed User
Longtime User
Code Module

I put some strings on "Sub Process_Globals" of an code module. Are these variables obfuscated too?

example:
'Code module
Sub Process_Globals
Public full_version_encrypted_value="@frgtfvfaajfr+!"
End Sub

is "full_version_encrypted_value" variable obfuscated?

Thank you in advance
 

socialnetis

Active Member
Licensed User
Longtime User
Does the obfuscation works for the process globals of a code module? I want to put some app-ids in there and make sure that they will be safe
 

kiki78

Active Member
Licensed User
Longtime User
Hi Erel,

I try to use obfuscation, but i'm disappointed when I examine generated Java code.
All code line are precede by comment line with clear code : //BA.debugLineNum = xx;BA.debugLine="Clear code"
So where is interest of obfuscation ?
Does I miss some B4A parameters to remove that ?

Regards,
 

kiki78

Active Member
Licensed User
Longtime User
Thank you Erel
One more time I write to quickly.
I make mistake and I thought that src directory was included inside apk.
Sorry for inconvenience :oops:
 

ArminKH

Well-Known Member
Exactly what is the static string?
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
If you write CallSub(Me, "SomeSub") then the compiler knows that that you are calling a sub named SomeSub. The compiler will not obfuscate the target sub name and everything will work.

However if you write:
B4X:
Dim x As String = "SomeSub")
CallSub(Me, x)
The compiler doesn't know that you are calling SomeSub in this code and it will obfuscate the sub name thus breaking your program.
 

ArminKH

Well-Known Member
In dim x as string="subname"
The x is none static string?
My problem is the difference between static and none static strings
 

ArminKH

Well-Known Member
This is only relevant for CallSub and CallSubDelayed calls.

In the case of CallSub(Me, x) the target sub is "dynamic".

You can add an underscore to the target subs to prevent the obfuscator from modifying the subs names.
We can use for example

Sub subname
'------------
End sub

in callsub (if use obfuscate release mode)?
 
Last edited:

vvg

Member
Licensed User
Longtime User
This tutorial is relevant for B4A and B4J.
During compilation B4A generates Java code which is then compiled with the Java compiler and converted to Dalvik (Android byte code format).
There are tools that allow decompilation of Dalvik byte code into Java code.

The purpose of obfuscation is to make the decompiled code less readable, harder to understand and make it more difficult to extract strings like developer account keys.

It is important to understand how the obfuscator works.
The obfuscator does two things:

Strings obfuscation
Any string written in Process_Globals sub (and only in this sub) will be obfuscated, making it much harder to extract important keys. The strings are defuscated at runtime.
Note that several keys are used during obfuscation including the package name, version name and version code. Modifying these values with the manifest editor will break the defuscation process.

Variables renaming
The names of global variables and subs are converted to meaningless strings. Local variables are not affected as their names are lost anyway during the compilation.
The following identifiers are not renamed:
- Identifiers that contain an underscore (requires for the events handlers).
- Subs that appear in CallSub statements. Only if the sub name appears as a static string then the identifier will be kept as is.
- Designer views names.

Tip: If, for some reason, you need to prevent the obfuscator to rename an identifier you should add an underscore in the identifier name.

A file named ObfuscatorMap.txt will be created under the Objects folder. This file maps the original identifiers names to the obfuscated names. This mapping can be helpful to analyze crash reports.

Activating the obfuscator


There are three modes:
- Debug - in this mode the IDE debugger will connect to the running application (same as the previous Attach debugger option).
- Release - compiles the application without any debugging information.
- Release (obfuscation) - compiles the application and activates the obfuscator.

SS-2012.01.06-19.38.16.png


Pitfalls
Using CallSub with a non-static string.
The following code demonstrates this issue:
B4X:
Sub Activity_Resume
   CallSub("Main", "Test1") 'Works because it is a static string (Test sub will not be renamed)
   Dim subName As String
   subName = "Test2"
   CallSub("Main", subName) 'Skipped at runtime because Test2 sub is renamed
   subName = "Test_3"
   CallSub("Main", subName) 'Works because Test_3 includes an underscore and it will not be renamed.
End Sub
Sub Test1
   Log("a")
End Sub
Sub Test2
   Log("b")
End Sub
Sub Test_3
   Log("c")
End Sub

- LicenseChecker.SetVariableAndValue
This method references a variable using a string. This method will fail if the variable name doesn't include an underscore.
Sir,
This is working excellent. Thank you very much.
I can understand that reverse engineering is always possible but we can make it harder....and same thing you have provided with obfuscator....
But i have a doubt and just for knowledge purpose i am asking this to you....
You have provided obfuscator map file...
If there is other b4a developer and if he tried to know my sourcecode or wanted to decompile my app, will it be easier for him to findout variable name refering obfuscator.map file in his b4a projects??
 

Erel

B4X founder
Staff member
Licensed User
Longtime User
If there is other b4a developer and if he tried to know my sourcecode or wanted to decompile my app, will it be easier for him to findout variable name refering obfuscator.map file in his b4a projects??
You shouldn't distribute the map together with your app. Other developers will not have access to this map.
 

vvg

Member
Licensed User
Longtime User
You shouldn't distribute the map together with your app. Other developers will not have access to this map.
No...obviously i wont let leave my obfuscator.map file with my app.
But he (other b4a developer (cum my app's ..may be.. hacker ) will be having his map file...so i just want to make it clear that is it that easy to guess the name of variables comparing decompiled main.java file to the one or more map file (or files) he is having with him???
I know you must have made it hard...but just asking you to clear my doubt...
Sorry for my ignorance...
 
Top