Android Tutorial Protect your application against copy and changes

This method uses the F5Steg and PackageUtils libraries from ProBundle.

There's a demo available in the Play Store: https://play.google.com/store/apps/details?id=b4a.protecthw.flm
The source code is attached to this message and is used as a reference in the following explanations. It will not work after compilation on your computer because some of the assets are protected. Only the creator of these resources (me) can compile a working version.

Protection against copy:
If you look at the source code, you can see that the copy protection is quite simple since it is all in these three lines:
B4X:
If PU.GetInstallerPackageName(PU.GetMyPackageName) = Null Or PU.GetInstallerPackageName(PU.GetMyPackageName) <> "com.android.vending" Then
   ExitApplication
End If
If the installation source is not the Play Store ("com.android.vending"), the program ends.
This protection would be very weak if a malicious person could remove these lines with a tool like apktool, so the APK must also be protected against modification.

Protection against changes:
To protect the APK against modification, I use the F5Steg library. It can encrypt data inside an image using the APK signature. No password is required from the user. The encryption password is automatically created by the library's C code from the signature (and I won't explain how, of course, because otherwise it would be a piece of cake to circumvent this protection). If someone modifies the program, he has to reassemble it and sign it with his own key. This will change the signature and therefore F5Steg will not be able to decrypt the image correctly.

In the demo, the image containing the encrypted data is "logo.jpg". In this image, I encoded a list with two entries: a password (which is used to decompress the "value.zip" archive) and a Map which contains three data (an integer, a floating number and the name of the image with my picture). Without these data, the application cannot calculate anything correctly when the user clicks the Test button.

If you use this method to protect your application, a small donation (by clicking on the Donate button in my signature) will be greatly appreciated.
 

Attachments

  • Challenge.zip
    71.3 KB · Views: 379

MarcoRome

Expert
Licensed User
Hi Informatix. Good work ( as usual ).
Where can i found library:

1586847374356.png


Thank you
Have a nice day
Marco
 

MarcoRome

Expert
Licensed User
Hi Fred.
When i try the example i have this error in this line (73):

B4X:
F5S.ExtractToArray(File.Combine(File.DirInternalCache, EncryptedImage), "B4A")

*** Service (starter) Create ***
** Service (starter) Start **
** Activity (main) Create, isFirst = true **
** Activity (main) Resume **
Error occurred on line: 73 (Main)
javax.crypto.BadPaddingException: EVP_CipherFinal_ex
at com.android.org.conscrypt.NativeCrypto.EVP_CipherFinal_ex(Native Method)
at com.android.org.conscrypt.OpenSSLCipher.doFinalInternal(OpenSSLCipher.java:430)
at com.android.org.conscrypt.OpenSSLCipher.engineDoFinal(OpenSSLCipher.java:466)
at javax.crypto.Cipher.doFinal(Cipher.java:1340)
at b4a.flm.buffers.NativeBuffers.getMyBuffer(Native Method)
at b4a.flm.buffers.NativeBuffers.b(SourceFile:21)
at a.a.a.b.a(SourceFile:197)
at a.a.a.b.<init>(SourceFile:38)
at a.a.a.b.<init>(SourceFile:28)
at b4a.flm.f5steg.F5Steg.ExtractToArray(SourceFile:59)
at b4a.protecthw.flm.main._activity_resume(main.java:473)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.shell.Shell.runMethod(Shell.java:732)
at anywheresoftware.b4a.shell.Shell.raiseEventImpl(Shell.java:348)
at anywheresoftware.b4a.shell.Shell.raiseEvent(Shell.java:255)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at anywheresoftware.b4a.ShellBA.raiseEvent2(ShellBA.java:144)
at anywheresoftware.b4a.BA.raiseEvent(BA.java:176)
at b4a.protecthw.flm.main.afterFirstLayout(main.java:110)
at b4a.protecthw.flm.main.access$000(main.java:17)
at b4a.protecthw.flm.main$WaitForLayout.run(main.java:82)
at android.os.Handler.handleCallback(Handler.java:739)
at android.os.Handler.dispatchMessage(Handler.java:95)
at android.os.Looper.loop(Looper.java:145)
at android.app.ActivityThread.main(ActivityThread.java:7007)
at java.lang.reflect.Method.invoke(Native Method)
at java.lang.reflect.Method.invoke(Method.java:372)
at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:1404)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:1199)
** Activity (main) Pause, UserClosed = true **

Thank you
Marco
 

Attachments

  • f5steg_64.jar
    353.8 KB · Views: 215

Informatix

Expert
Licensed User
Hi Fred.
When i try the example i have this error in this line (73):

B4X:
F5S.ExtractToArray(File.Combine(File.DirInternalCache, EncryptedImage), "B4A")



Thank you
Marco
Please read the first post: "It will not work after compilation on your computer because some of the assets are protected. Only the creator of these resources (me) can compile a working version."
 

Informatix

Expert
Licensed User
I used the APKCombo downloader to retrieve my protected demo from the Play Store and installed it on a device, then ran it. It exited immediately. :) Here's the unfiltered log:
*** Service (starter) Create ***
** Service (starter) Start **
QUALCOMM build : bb5b86c, I77d3059488
Build Date : 06/07/18
OpenGL ES Shader Compiler Version: EV031.22.00.01_06
Local Branch :
Remote Branch : refs/tags/AU_LINUX_ANDROID_LA.UM.6.5.R1.08.01.00.312.086
Remote Branch : NONE
Reconstruct Branch : NOTHING
Loading /vendor/lib/hw/gralloc.msm8937.so from current namespace instead of sphal namespace.
** Activity (main) Create, isFirst = true **
PFP: 0x005ff087, ME: 0x005ff063
System.exit called, status: 0
VM exiting with result code 0, cleanup skipped.
handleConfigurationChanged -- mcc/mnc for sub: {id=1, iccId=893315001[****] simSlotIndex=0 displayName=SIM1 carrierName=Aucun service nameSource=0 iconTint=-16746133 dataRoaming=1 iconBitmap=android.graphics.Bitmap@7e672f3 mcc 208 mnc 15 isEmbedded false accessRules null status 0}
WIN DEATH: Window{c36f0dd u0 b4a.protecthw.flm/b4a.protecthw.flm.main}
Process b4a.protecthw.flm (pid 19594) has died: fore TOP
Scheduling restart of crashed service b4a.protecthw.flm/.starter in 1000ms
kill(-19594, 9) failed: No such process
Force removing ActivityRecord{f7a4ef9 u0 b4a.protecthw.flm/.main t31690}: app died, no saved state
 

peter93

Member
Licensed User
By testing this:
<If PU.GetInstallerPackageName(PU.GetMyPackageName) = Null Or PU.GetInstallerPackageName(PU.GetMyPackageName) <> "com.android.vending" then />
I don't get the "com.android.vending" response I was expecting.
but "com.google.android.packageinstaller". Is that normal?
 

Informatix

Expert
Licensed User
By testing this:
<If PU.GetInstallerPackageName(PU.GetMyPackageName) = Null Or PU.GetInstallerPackageName(PU.GetMyPackageName) <> "com.android.vending" then />
I don't get the "com.android.vending" response I was expecting.
but "com.google.android.packageinstaller". Is that normal?
Do you install from the Play Store ? Did you enable the automatic update of your app ?
 

peter93

Member
Licensed User
Do you install from the Play Store ? Did you enable the automatic update of your app ?
I upgraded directly with B4A Bridge and tested it.
But the app comes from the Google Play Store and the license check works well.
I will deliver the app on Google play and redo the test...
 

Informatix

Expert
Licensed User
I upgraded directly with B4A Bridge and tested it.
But the app comes from the Google Play Store and the license check works well.
I will deliver the app on Google play and redo the test...
You have to install directly from the Play Store or the protection means nothing.
Note that the license check is useless if your app is not protected against changes (it can be removed in 5 minutes).
 

peter93

Member
Licensed User
You have to install directly from the Play Store or the protection means nothing.
Note that the license check is useless if your app is not protected against changes (it can be removed in 5 minutes).
All is good by updating from the Google play store.
Merci Fred.
 

quansofts

Member
Hi Informatix,
What if I decompile the apk file =>dex file => get java class files => remove your protection code => recompile the apk

Regards,
 

Informatix

Expert
Licensed User
Hi Informatix,
What if I decompile the apk file =>dex file => get java class files => remove your protection code => recompile the apk

Regards,
Did you read the first post?
If you modify the code, you have to recompile with a different signature. With a different signature, you won't be able to retrieve the data stored in the image.
 

ArminKh1993

Active Member
You have to install directly from the Play Store or the protection means nothing.
Note that the license check is useless if your app is not protected against changes (it can be removed in 5 minutes).
So what about other markets? galaxy store, huawei , ...
 

73Challenger

Member
Licensed User
In this image, I encoded a list with two entries: a password (which is used to decompress the "value.zip" archive) and a Map which contains three data (an integer, a floating number and the name of the image with my picture). Without these data, the application cannot calculate anything correctly when the user clicks the Test button.
Question please. Could you post how we can create our own encoded jpg and zip file so it will work with your example code? Any guidance, a description, a link or sample code would be very helpful and appreciated. Thank you!
 
Top