Android Question SubExists, CallSub and Obfuscation

Cyan

Member
Licensed User
Longtime User
I encountered a difficult-to-find error when compiling my app to release (obfuscated) when checking if a class implements a particular method with SubExists.

It appears that whilst CallSub works fine in obfuscated mode (e.g. CallSub(myObject, "mysub")) as the string "mysub" is translated, it appears that SubExists(myObject, "mysub") does not.

Consider the snippet below, with myobject as a custom class that has one method, "getTitle"

MyClass:
Private Sub Class_Globals
End Sub

Public Sub Initialize
End Sub

Public Sub getTitle as String
    Return "Hello World"
End Sub

Main:
Dim myobject as MyClass
myobject.Initialize

If SubExists(myobject, "getTitle") Then
    Log(CallSub(myobject, "getTitle"))
End If

This will log nothing.

If however, I change this slightly to the below, then I obtain something in the log:

Main:
Dim myobject as MyClass
myobject.Initialize

Log(CallSub(myobject, "getTitle"))

My question is, is this expected behaviour for SubExists versus CallSub when obfuscating?

I've attached a sample project. Running it in "Release" mode works fine, however, running it with "Release (obfuscated)" does not.
 

Attachments

  • SubExists.zip
    9.4 KB · Views: 52
Last edited:

edgar_ortiz

Active Member
Licensed User
Longtime User
Did you check:

 
Upvote 0

Cyan

Member
Licensed User
Longtime User
Did you check:


Thank you, I did have a read about the CallSub section, however I am using a static string so according to that the sub should not be renamed. However, when 'wrapping' it with a SubExists, it looks like it's renamed. I guess this is just a compiler quirk and I'll either have to rename over 60 methods or wrap my calls in a Try instead.
 
Upvote 0

Sandman

Expert
Licensed User
It appears that whilst CallSub works fine in obfuscated mode (e.g. CallSub(myObject, "mysub")) as the string "mysub" is translated, it appears that SubExists(myObject, "mysub") does not.
Assuming this is correctly described, I can't imagine it would be impossible to replace the "mysub" in the SubExist with the obfuscated name also? Perhaps you should post a Wish and point to this thread?
 
Upvote 0

Sandman

Expert
Licensed User
I'm not sure about the meaning either.

I'm thinking that perhaps it's some kind of ancient wisdom, like "it doesn't matter how big the banana is, the peel is always bigger".
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
Erel's description in that 'Code obfuscation' link is not 100% complete in describing the implementation of CallSub in obfuscation. Obfuscation is in fact renaming myClass.getTitle because it lacks an underscore. For this reason SubExists doesn't see it. However the compiler does a hack on CallSub if the Sub name is a literal string to implement an extra method in myClass that does a check on the unobfuscated name and if it matches calls the actual obfuscated implementation so the only solution to get SubExist to work is to add an underscore to the Sub names.
 
Upvote 0

Sandman

Expert
Licensed User
Yes, that sounds pretty much like I've understood it. My point was that perhaps the same hack could be made to SubExist?
 
Upvote 0

Cyan

Member
Licensed User
Longtime User
Erel's description in that 'Code obfuscation' link is not 100% complete in describing the implementation of CallSub in obfuscation. Obfuscation is in fact renaming myClass.getTitle because it lacks an underscore. For this reason SubExists doesn't see it. However the compiler does a hack on CallSub if the Sub name is a literal string to implement an extra method in myClass that does a check on the unobfuscated name and if it matches calls the actual obfuscated implementation so the only solution to get SubExist to work is to add an underscore to the Sub names.

Thank you!! This is the bit that I was missing, that makes it much clearer as to what is going on under the hood.

In this case, rather than renaming 60-odd methods, I will just wrap the single CallSub in a Try, as the methods return something.
 
Upvote 0

Erel

B4X founder
Staff member
Licensed User
Longtime User
Thank you, I did have a read about the CallSub section, however I am using a static string so according to that the sub should not be renamed. However, when 'wrapping' it with a SubExists, it looks like it's renamed. I guess this is just a compiler quirk and I'll either have to rename over 60 methods or wrap my calls in a Try instead.
I meant that the SubExists will never have any effect on the compiler. It isn't the reason that the sub name is being obfuscated. I can't say why it isn't obfuscated without a small project that demonstrates it.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
I meant that the SubExists will never have any effect on the compiler. It isn't the reason that the sub name is being obfuscated. I can't say why it isn't obfuscated without a small project that demonstrates it.
Repectfully I think you missed the point of the question. There is no problem here except that SubExists does not work when the method name being tested is obfuscated because, unlike CallSub, there is no provision in SubExists for testing the literal string against the original unobfuscated name.
 
Upvote 0

agraham

Expert
Licensed User
Longtime User
This means that if CallSub works then SubExists should also work.
I have looked at the generated code for the above project. It behaves as I have described. SubExists does not work when that project is obfuscated. Perhaps there is a compiler bug if you expect SubExists to work in this case.
 
Upvote 0
Top